| author | |
| committer | |
| log | 4307436b9945f814ff5731981df1d19febf3ba0a |
| tree | efaaec94a41d632d45f255d464d9787eb02c4c9b |
| parent | 5a02c938dafdf2bb11b2350b6ad3161ef93744f0 |
And fix test cases to make them pass. This is in preparation for
starting to pass behavior tests with self-hosted.311 files changed, 18518 insertions(+), 20310 deletions(-)
build.zig+1-1| ... | ... | @@ -265,7 +265,7 @@ pub fn build(b: *Builder) !void { |
| 265 | 265 | fmt_step.dependOn(&fmt_build_zig.step); |
| 266 | 266 | |
| 267 | 267 | // TODO for the moment, skip wasm32-wasi until bugs are sorted out. |
| 268 | test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, is_wasmtime_enabled, glibc_multi_dir)); | |
| 268 | test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, is_wasmtime_enabled, glibc_multi_dir)); | |
| 269 | 269 | |
| 270 | 270 | test_step.dependOn(tests.addPkgTests(b, test_filter, "lib/std/std.zig", "std", "Run the standard library tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, is_wasmtime_enabled, glibc_multi_dir)); |
| 271 | 271 |
lib/std/Thread/StaticResetEvent.zig+2-2| ... | ... | @@ -262,7 +262,7 @@ pub const AtomicEvent = struct { |
| 262 | 262 | while (true) { |
| 263 | 263 | if (waiting == WAKE) { |
| 264 | 264 | rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null); |
| 265 | assert(rc == .WAIT_0); | |
| 265 | assert(rc == windows.NTSTATUS.WAIT_0); | |
| 266 | 266 | break; |
| 267 | 267 | } else { |
| 268 | 268 | waiting = @cmpxchgWeak(u32, waiters, waiting, waiting - WAIT, .Acquire, .Monotonic) orelse break; |
| ... | ... | @@ -271,7 +271,7 @@ pub const AtomicEvent = struct { |
| 271 | 271 | } |
| 272 | 272 | return error.TimedOut; |
| 273 | 273 | }, |
| 274 | .WAIT_0 => {}, | |
| 274 | windows.NTSTATUS.WAIT_0 => {}, | |
| 275 | 275 | else => unreachable, |
| 276 | 276 | } |
| 277 | 277 | } |
lib/std/c/darwin.zig+3-2| ... | ... | @@ -7,6 +7,7 @@ const std = @import("../std.zig"); |
| 7 | 7 | const assert = std.debug.assert; |
| 8 | 8 | const builtin = @import("builtin"); |
| 9 | 9 | const macho = std.macho; |
| 10 | const native_arch = builtin.target.cpu.arch; | |
| 10 | 11 | |
| 11 | 12 | usingnamespace @import("../os/bits.zig"); |
| 12 | 13 | |
| ... | ... | @@ -34,13 +35,13 @@ extern "c" fn fstat(fd: fd_t, buf: *libc_stat) c_int; |
| 34 | 35 | /// On x86_64 Darwin, fstat has to be manully linked with $INODE64 suffix to force 64bit version. |
| 35 | 36 | /// Note that this is fixed on aarch64 and no longer necessary. |
| 36 | 37 | extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *libc_stat) c_int; |
| 37 | pub const _fstat = if (builtin.arch == .aarch64) fstat else @"fstat$INODE64"; | |
| 38 | pub const _fstat = if (native_arch == .aarch64) fstat else @"fstat$INODE64"; | |
| 38 | 39 | |
| 39 | 40 | extern "c" fn fstatat(dirfd: fd_t, path: [*:0]const u8, stat_buf: *libc_stat, flags: u32) c_int; |
| 40 | 41 | /// On x86_64 Darwin, fstatat has to be manully linked with $INODE64 suffix to force 64bit version. |
| 41 | 42 | /// Note that this is fixed on aarch64 and no longer necessary. |
| 42 | 43 | extern "c" fn @"fstatat$INODE64"(dirfd: fd_t, path_name: [*:0]const u8, buf: *libc_stat, flags: u32) c_int; |
| 43 | pub const _fstatat = if (builtin.arch == .aarch64) fstatat else @"fstatat$INODE64"; | |
| 44 | pub const _fstatat = if (native_arch == .aarch64) fstatat else @"fstatat$INODE64"; | |
| 44 | 45 | |
| 45 | 46 | pub extern "c" fn mach_absolute_time() u64; |
| 46 | 47 | pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void; |
lib/std/os/bits/linux/arm-eabi.zig+1-3| ... | ... | @@ -242,7 +242,6 @@ pub const SYS = enum(usize) { |
| 242 | 242 | tgkill = 268, |
| 243 | 243 | utimes = 269, |
| 244 | 244 | fadvise64_64 = 270, |
| 245 | arm_fadvise64_64 = 270, | |
| 246 | 245 | pciconfig_iobase = 271, |
| 247 | 246 | pciconfig_read = 272, |
| 248 | 247 | pciconfig_write = 273, |
| ... | ... | @@ -313,8 +312,7 @@ pub const SYS = enum(usize) { |
| 313 | 312 | set_robust_list = 338, |
| 314 | 313 | get_robust_list = 339, |
| 315 | 314 | splice = 340, |
| 316 | sync_file_range2 = 341, | |
| 317 | arm_sync_file_range = 341, | |
| 315 | sync_file_range = 341, | |
| 318 | 316 | tee = 342, |
| 319 | 317 | vmsplice = 343, |
| 320 | 318 | move_pages = 344, |
lib/std/os/bits/linux/arm64.zig-1| ... | ... | @@ -101,7 +101,6 @@ pub const SYS = enum(usize) { |
| 101 | 101 | sync = 81, |
| 102 | 102 | fsync = 82, |
| 103 | 103 | fdatasync = 83, |
| 104 | sync_file_range2 = 84, | |
| 105 | 104 | sync_file_range = 84, |
| 106 | 105 | timerfd_create = 85, |
| 107 | 106 | timerfd_settime = 86, |
lib/std/os/bits/linux/powerpc.zig+1-1| ... | ... | @@ -321,7 +321,7 @@ pub const SYS = enum(usize) { |
| 321 | 321 | signalfd = 305, |
| 322 | 322 | timerfd_create = 306, |
| 323 | 323 | eventfd = 307, |
| 324 | sync_file_range2 = 308, | |
| 324 | sync_file_range = 308, | |
| 325 | 325 | fallocate = 309, |
| 326 | 326 | subpage_prot = 310, |
| 327 | 327 | timerfd_settime = 311, |
lib/std/os/bits/linux/powerpc64.zig+1-1| ... | ... | @@ -312,7 +312,7 @@ pub const SYS = enum(usize) { |
| 312 | 312 | signalfd = 305, |
| 313 | 313 | timerfd_create = 306, |
| 314 | 314 | eventfd = 307, |
| 315 | sync_file_range2 = 308, | |
| 315 | sync_file_range = 308, | |
| 316 | 316 | fallocate = 309, |
| 317 | 317 | subpage_prot = 310, |
| 318 | 318 | timerfd_settime = 311, |
lib/std/os/windows.zig+4-4| ... | ... | @@ -9,7 +9,7 @@ |
| 9 | 9 | // * When null-terminated or UTF16LE byte buffers are required, provide APIs which accept |
| 10 | 10 | // slices as well as APIs which accept null-terminated UTF16LE byte buffers. |
| 11 | 11 | |
| 12 | const builtin = std.builtin; | |
| 12 | const builtin = @import("builtin"); | |
| 13 | 13 | const std = @import("../std.zig"); |
| 14 | 14 | const mem = std.mem; |
| 15 | 15 | const assert = std.debug.assert; |
| ... | ... | @@ -985,7 +985,7 @@ pub fn QueryObjectName( |
| 985 | 985 | } |
| 986 | 986 | } |
| 987 | 987 | test "QueryObjectName" { |
| 988 | if (comptime builtin.os.tag != .windows) | |
| 988 | if (comptime builtin.target.os.tag != .windows) | |
| 989 | 989 | return; |
| 990 | 990 | |
| 991 | 991 | //any file will do; canonicalization works on NTFS junctions and symlinks, hardlinks remain separate paths. |
| ... | ... | @@ -1140,7 +1140,7 @@ pub fn GetFinalPathNameByHandle( |
| 1140 | 1140 | } |
| 1141 | 1141 | |
| 1142 | 1142 | test "GetFinalPathNameByHandle" { |
| 1143 | if (comptime builtin.os.tag != .windows) | |
| 1143 | if (comptime builtin.target.os.tag != .windows) | |
| 1144 | 1144 | return; |
| 1145 | 1145 | |
| 1146 | 1146 | //any file will do |
| ... | ... | @@ -1554,7 +1554,7 @@ pub fn SetFileTime( |
| 1554 | 1554 | } |
| 1555 | 1555 | |
| 1556 | 1556 | pub fn teb() *TEB { |
| 1557 | return switch (builtin.arch) { | |
| 1557 | return switch (builtin.target.cpu.arch) { | |
| 1558 | 1558 | .i386 => asm volatile ( |
| 1559 | 1559 | \\ movl %%fs:0x18, %[ptr] |
| 1560 | 1560 | : [ptr] "=r" (-> *TEB) |
lib/std/os/windows/ntstatus.zig+10-1802| ... | ... | @@ -3,5603 +3,3811 @@ |
| 3 | 3 | // This file is part of [zig](https://ziglang.org/), which is MIT licensed. |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | // NTSTATUS codes from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55? | |
| 6 | ||
| 7 | /// NTSTATUS codes from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55? | |
| 7 | 8 | pub const NTSTATUS = enum(u32) { |
| 9 | /// The caller specified WaitAny for WaitType and one of the dispatcher | |
| 10 | /// objects in the Object array has been set to the signaled state. | |
| 11 | pub const WAIT_0: NTSTATUS = .SUCCESS; | |
| 12 | /// The caller attempted to wait for a mutex that has been abandoned. | |
| 13 | pub const ABANDONED_WAIT_0: NTSTATUS = .ABANDONED; | |
| 14 | /// The maximum number of boot-time filters has been reached. | |
| 15 | pub const FWP_TOO_MANY_BOOTTIME_FILTERS: NTSTATUS = .FWP_TOO_MANY_CALLOUTS; | |
| 16 | ||
| 8 | 17 | /// The operation completed successfully. |
| 9 | 18 | SUCCESS = 0x00000000, |
| 10 | ||
| 11 | /// The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. | |
| 12 | WAIT_0 = 0x00000000, | |
| 13 | ||
| 14 | 19 | /// The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. |
| 15 | 20 | WAIT_1 = 0x00000001, |
| 16 | ||
| 17 | 21 | /// The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. |
| 18 | 22 | WAIT_2 = 0x00000002, |
| 19 | ||
| 20 | 23 | /// The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. |
| 21 | 24 | WAIT_3 = 0x00000003, |
| 22 | ||
| 23 | 25 | /// The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state. |
| 24 | 26 | WAIT_63 = 0x0000003F, |
| 25 | ||
| 26 | 27 | /// The caller attempted to wait for a mutex that has been abandoned. |
| 27 | 28 | ABANDONED = 0x00000080, |
| 28 | ||
| 29 | /// The caller attempted to wait for a mutex that has been abandoned. | |
| 30 | ABANDONED_WAIT_0 = 0x00000080, | |
| 31 | ||
| 32 | 29 | /// The caller attempted to wait for a mutex that has been abandoned. |
| 33 | 30 | ABANDONED_WAIT_63 = 0x000000BF, |
| 34 | ||
| 35 | 31 | /// A user-mode APC was delivered before the given Interval expired. |
| 36 | 32 | USER_APC = 0x000000C0, |
| 37 | ||
| 38 | 33 | /// The delay completed because the thread was alerted. |
| 39 | 34 | ALERTED = 0x00000101, |
| 40 | ||
| 41 | 35 | /// The given Timeout interval expired. |
| 42 | 36 | TIMEOUT = 0x00000102, |
| 43 | ||
| 44 | 37 | /// The operation that was requested is pending completion. |
| 45 | 38 | PENDING = 0x00000103, |
| 46 | ||
| 47 | 39 | /// A reparse should be performed by the Object Manager because the name of the file resulted in a symbolic link. |
| 48 | 40 | REPARSE = 0x00000104, |
| 49 | ||
| 50 | 41 | /// Returned by enumeration APIs to indicate more information is available to successive calls. |
| 51 | 42 | MORE_ENTRIES = 0x00000105, |
| 52 | ||
| 53 | 43 | /// Indicates not all privileges or groups that are referenced are assigned to the caller. |
| 54 | 44 | /// This allows, for example, all privileges to be disabled without having to know exactly which privileges are assigned. |
| 55 | 45 | NOT_ALL_ASSIGNED = 0x00000106, |
| 56 | ||
| 57 | 46 | /// Some of the information to be translated has not been translated. |
| 58 | 47 | SOME_NOT_MAPPED = 0x00000107, |
| 59 | ||
| 60 | 48 | /// An open/create operation completed while an opportunistic lock (oplock) break is underway. |
| 61 | 49 | OPLOCK_BREAK_IN_PROGRESS = 0x00000108, |
| 62 | ||
| 63 | 50 | /// A new volume has been mounted by a file system. |
| 64 | 51 | VOLUME_MOUNTED = 0x00000109, |
| 65 | ||
| 66 | 52 | /// This success level status indicates that the transaction state already exists for the registry subtree but that a transaction commit was previously aborted. The commit has now been completed. |
| 67 | 53 | RXACT_COMMITTED = 0x0000010A, |
| 68 | ||
| 69 | 54 | /// Indicates that a notify change request has been completed due to closing the handle that made the notify change request. |
| 70 | 55 | NOTIFY_CLEANUP = 0x0000010B, |
| 71 | ||
| 72 | 56 | /// Indicates that a notify change request is being completed and that the information is not being returned in the caller's buffer. |
| 73 | 57 | /// The caller now needs to enumerate the files to find the changes. |
| 74 | 58 | NOTIFY_ENUM_DIR = 0x0000010C, |
| 75 | ||
| 76 | 59 | /// {No Quotas} No system quota limits are specifically set for this account. |
| 77 | 60 | NO_QUOTAS_FOR_ACCOUNT = 0x0000010D, |
| 78 | ||
| 79 | 61 | /// {Connect Failure on Primary Transport} An attempt was made to connect to the remote server %hs on the primary transport, but the connection failed. |
| 80 | 62 | /// The computer WAS able to connect on a secondary transport. |
| 81 | 63 | PRIMARY_TRANSPORT_CONNECT_FAILED = 0x0000010E, |
| 82 | ||
| 83 | 64 | /// The page fault was a transition fault. |
| 84 | 65 | PAGE_FAULT_TRANSITION = 0x00000110, |
| 85 | ||
| 86 | 66 | /// The page fault was a demand zero fault. |
| 87 | 67 | PAGE_FAULT_DEMAND_ZERO = 0x00000111, |
| 88 | ||
| 89 | 68 | /// The page fault was a demand zero fault. |
| 90 | 69 | PAGE_FAULT_COPY_ON_WRITE = 0x00000112, |
| 91 | ||
| 92 | 70 | /// The page fault was a demand zero fault. |
| 93 | 71 | PAGE_FAULT_GUARD_PAGE = 0x00000113, |
| 94 | ||
| 95 | 72 | /// The page fault was satisfied by reading from a secondary storage device. |
| 96 | 73 | PAGE_FAULT_PAGING_FILE = 0x00000114, |
| 97 | ||
| 98 | 74 | /// The cached page was locked during operation. |
| 99 | 75 | CACHE_PAGE_LOCKED = 0x00000115, |
| 100 | ||
| 101 | 76 | /// The crash dump exists in a paging file. |
| 102 | 77 | CRASH_DUMP = 0x00000116, |
| 103 | ||
| 104 | 78 | /// The specified buffer contains all zeros. |
| 105 | 79 | BUFFER_ALL_ZEROS = 0x00000117, |
| 106 | ||
| 107 | 80 | /// A reparse should be performed by the Object Manager because the name of the file resulted in a symbolic link. |
| 108 | 81 | REPARSE_OBJECT = 0x00000118, |
| 109 | ||
| 110 | 82 | /// The device has succeeded a query-stop and its resource requirements have changed. |
| 111 | 83 | RESOURCE_REQUIREMENTS_CHANGED = 0x00000119, |
| 112 | ||
| 113 | 84 | /// The translator has translated these resources into the global space and no additional translations should be performed. |
| 114 | 85 | TRANSLATION_COMPLETE = 0x00000120, |
| 115 | ||
| 116 | 86 | /// The directory service evaluated group memberships locally, because it was unable to contact a global catalog server. |
| 117 | 87 | DS_MEMBERSHIP_EVALUATED_LOCALLY = 0x00000121, |
| 118 | ||
| 119 | 88 | /// A process being terminated has no threads to terminate. |
| 120 | 89 | NOTHING_TO_TERMINATE = 0x00000122, |
| 121 | ||
| 122 | 90 | /// The specified process is not part of a job. |
| 123 | 91 | PROCESS_NOT_IN_JOB = 0x00000123, |
| 124 | ||
| 125 | 92 | /// The specified process is part of a job. |
| 126 | 93 | PROCESS_IN_JOB = 0x00000124, |
| 127 | ||
| 128 | 94 | /// {Volume Shadow Copy Service} The system is now ready for hibernation. |
| 129 | 95 | VOLSNAP_HIBERNATE_READY = 0x00000125, |
| 130 | ||
| 131 | 96 | /// A file system or file system filter driver has successfully completed an FsFilter operation. |
| 132 | 97 | FSFILTER_OP_COMPLETED_SUCCESSFULLY = 0x00000126, |
| 133 | ||
| 134 | 98 | /// The specified interrupt vector was already connected. |
| 135 | 99 | INTERRUPT_VECTOR_ALREADY_CONNECTED = 0x00000127, |
| 136 | ||
| 137 | 100 | /// The specified interrupt vector is still connected. |
| 138 | 101 | INTERRUPT_STILL_CONNECTED = 0x00000128, |
| 139 | ||
| 140 | 102 | /// The current process is a cloned process. |
| 141 | 103 | PROCESS_CLONED = 0x00000129, |
| 142 | ||
| 143 | 104 | /// The file was locked and all users of the file can only read. |
| 144 | 105 | FILE_LOCKED_WITH_ONLY_READERS = 0x0000012A, |
| 145 | ||
| 146 | 106 | /// The file was locked and at least one user of the file can write. |
| 147 | 107 | FILE_LOCKED_WITH_WRITERS = 0x0000012B, |
| 148 | ||
| 149 | 108 | /// The specified ResourceManager made no changes or updates to the resource under this transaction. |
| 150 | 109 | RESOURCEMANAGER_READ_ONLY = 0x00000202, |
| 151 | ||
| 152 | 110 | /// An operation is blocked and waiting for an oplock. |
| 153 | 111 | WAIT_FOR_OPLOCK = 0x00000367, |
| 154 | ||
| 155 | 112 | /// Debugger handled the exception. |
| 156 | 113 | DBG_EXCEPTION_HANDLED = 0x00010001, |
| 157 | ||
| 158 | 114 | /// The debugger continued. |
| 159 | 115 | DBG_CONTINUE = 0x00010002, |
| 160 | ||
| 161 | 116 | /// The IO was completed by a filter. |
| 162 | 117 | FLT_IO_COMPLETE = 0x001C0001, |
| 163 | ||
| 164 | 118 | /// The file is temporarily unavailable. |
| 165 | 119 | FILE_NOT_AVAILABLE = 0xC0000467, |
| 166 | ||
| 167 | 120 | /// The share is temporarily unavailable. |
| 168 | 121 | SHARE_UNAVAILABLE = 0xC0000480, |
| 169 | ||
| 170 | 122 | /// A threadpool worker thread entered a callback at thread affinity %p and exited at affinity %p. |
| 171 | 123 | /// This is unexpected, indicating that the callback missed restoring the priority. |
| 172 | 124 | CALLBACK_RETURNED_THREAD_AFFINITY = 0xC0000721, |
| 173 | ||
| 174 | 125 | /// {Object Exists} An attempt was made to create an object but the object name already exists. |
| 175 | 126 | OBJECT_NAME_EXISTS = 0x40000000, |
| 176 | ||
| 177 | 127 | /// {Thread Suspended} A thread termination occurred while the thread was suspended. The thread resumed, and termination proceeded. |
| 178 | 128 | THREAD_WAS_SUSPENDED = 0x40000001, |
| 179 | ||
| 180 | 129 | /// {Working Set Range Error} An attempt was made to set the working set minimum or maximum to values that are outside the allowable range. |
| 181 | 130 | WORKING_SET_LIMIT_RANGE = 0x40000002, |
| 182 | ||
| 183 | 131 | /// {Image Relocated} An image file could not be mapped at the address that is specified in the image file. Local fixes must be performed on this image. |
| 184 | 132 | IMAGE_NOT_AT_BASE = 0x40000003, |
| 185 | ||
| 186 | 133 | /// This informational level status indicates that a specified registry subtree transaction state did not yet exist and had to be created. |
| 187 | 134 | RXACT_STATE_CREATED = 0x40000004, |
| 188 | ||
| 189 | 135 | /// {Segment Load} A virtual DOS machine (VDM) is loading, unloading, or moving an MS-DOS or Win16 program segment image. |
| 190 | 136 | /// An exception is raised so that a debugger can load, unload, or track symbols and breakpoints within these 16-bit segments. |
| 191 | 137 | SEGMENT_NOTIFICATION = 0x40000005, |
| 192 | ||
| 193 | 138 | /// {Local Session Key} A user session key was requested for a local remote procedure call (RPC) connection. |
| 194 | 139 | /// The session key that is returned is a constant value and not unique to this connection. |
| 195 | 140 | LOCAL_USER_SESSION_KEY = 0x40000006, |
| 196 | ||
| 197 | 141 | /// {Invalid Current Directory} The process cannot switch to the startup current directory %hs. |
| 198 | 142 | /// Select OK to set the current directory to %hs, or select CANCEL to exit. |
| 199 | 143 | BAD_CURRENT_DIRECTORY = 0x40000007, |
| 200 | ||
| 201 | 144 | /// {Serial IOCTL Complete} A serial I/O operation was completed by another write to a serial port. (The IOCTL_SERIAL_XOFF_COUNTER reached zero.) |
| 202 | 145 | SERIAL_MORE_WRITES = 0x40000008, |
| 203 | ||
| 204 | 146 | /// {Registry Recovery} One of the files that contains the system registry data had to be recovered by using a log or alternate copy. The recovery was successful. |
| 205 | 147 | REGISTRY_RECOVERED = 0x40000009, |
| 206 | ||
| 207 | 148 | /// {Redundant Read} To satisfy a read request, the Windows NT operating system fault-tolerant file system successfully read the requested data from a redundant copy. |
| 208 | 149 | /// This was done because the file system encountered a failure on a member of the fault-tolerant volume but was unable to reassign the failing area of the device. |
| 209 | 150 | FT_READ_RECOVERY_FROM_BACKUP = 0x4000000A, |
| 210 | ||
| 211 | 151 | /// {Redundant Write} To satisfy a write request, the Windows NT fault-tolerant file system successfully wrote a redundant copy of the information. |
| 212 | 152 | /// This was done because the file system encountered a failure on a member of the fault-tolerant volume but was unable to reassign the failing area of the device. |
| 213 | 153 | FT_WRITE_RECOVERY = 0x4000000B, |
| 214 | ||
| 215 | 154 | /// {Serial IOCTL Timeout} A serial I/O operation completed because the time-out period expired. |
| 216 | 155 | /// (The IOCTL_SERIAL_XOFF_COUNTER had not reached zero.) |
| 217 | 156 | SERIAL_COUNTER_TIMEOUT = 0x4000000C, |
| 218 | ||
| 219 | 157 | /// {Password Too Complex} The Windows password is too complex to be converted to a LAN Manager password. |
| 220 | 158 | /// The LAN Manager password that returned is a NULL string. |
| 221 | 159 | NULL_LM_PASSWORD = 0x4000000D, |
| 222 | ||
| 223 | 160 | /// {Machine Type Mismatch} The image file %hs is valid but is for a machine type other than the current machine. |
| 224 | 161 | /// Select OK to continue, or CANCEL to fail the DLL load. |
| 225 | 162 | IMAGE_MACHINE_TYPE_MISMATCH = 0x4000000E, |
| 226 | ||
| 227 | 163 | /// {Partial Data Received} The network transport returned partial data to its client. The remaining data will be sent later. |
| 228 | 164 | RECEIVE_PARTIAL = 0x4000000F, |
| 229 | ||
| 230 | 165 | /// {Expedited Data Received} The network transport returned data to its client that was marked as expedited by the remote system. |
| 231 | 166 | RECEIVE_EXPEDITED = 0x40000010, |
| 232 | ||
| 233 | 167 | /// {Partial Expedited Data Received} The network transport returned partial data to its client and this data was marked as expedited by the remote system. The remaining data will be sent later. |
| 234 | 168 | RECEIVE_PARTIAL_EXPEDITED = 0x40000011, |
| 235 | ||
| 236 | 169 | /// {TDI Event Done} The TDI indication has completed successfully. |
| 237 | 170 | EVENT_DONE = 0x40000012, |
| 238 | ||
| 239 | 171 | /// {TDI Event Pending} The TDI indication has entered the pending state. |
| 240 | 172 | EVENT_PENDING = 0x40000013, |
| 241 | ||
| 242 | 173 | /// Checking file system on %wZ. |
| 243 | 174 | CHECKING_FILE_SYSTEM = 0x40000014, |
| 244 | ||
| 245 | 175 | /// {Fatal Application Exit} %hs |
| 246 | 176 | FATAL_APP_EXIT = 0x40000015, |
| 247 | ||
| 248 | 177 | /// The specified registry key is referenced by a predefined handle. |
| 249 | 178 | PREDEFINED_HANDLE = 0x40000016, |
| 250 | ||
| 251 | 179 | /// {Page Unlocked} The page protection of a locked page was changed to 'No Access' and the page was unlocked from memory and from the process. |
| 252 | 180 | WAS_UNLOCKED = 0x40000017, |
| 253 | ||
| 254 | 181 | /// %hs |
| 255 | 182 | SERVICE_NOTIFICATION = 0x40000018, |
| 256 | ||
| 257 | 183 | /// {Page Locked} One of the pages to lock was already locked. |
| 258 | 184 | WAS_LOCKED = 0x40000019, |
| 259 | ||
| 260 | 185 | /// Application popup: %1 : %2 |
| 261 | 186 | LOG_HARD_ERROR = 0x4000001A, |
| 262 | ||
| 263 | 187 | /// A Win32 process already exists. |
| 264 | 188 | ALREADY_WIN32 = 0x4000001B, |
| 265 | ||
| 266 | 189 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 267 | 190 | WX86_UNSIMULATE = 0x4000001C, |
| 268 | ||
| 269 | 191 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 270 | 192 | WX86_CONTINUE = 0x4000001D, |
| 271 | ||
| 272 | 193 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 273 | 194 | WX86_SINGLE_STEP = 0x4000001E, |
| 274 | ||
| 275 | 195 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 276 | 196 | WX86_BREAKPOINT = 0x4000001F, |
| 277 | ||
| 278 | 197 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 279 | 198 | WX86_EXCEPTION_CONTINUE = 0x40000020, |
| 280 | ||
| 281 | 199 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 282 | 200 | WX86_EXCEPTION_LASTCHANCE = 0x40000021, |
| 283 | ||
| 284 | 201 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 285 | 202 | WX86_EXCEPTION_CHAIN = 0x40000022, |
| 286 | ||
| 287 | 203 | /// {Machine Type Mismatch} The image file %hs is valid but is for a machine type other than the current machine. |
| 288 | 204 | IMAGE_MACHINE_TYPE_MISMATCH_EXE = 0x40000023, |
| 289 | ||
| 290 | 205 | /// A yield execution was performed and no thread was available to run. |
| 291 | 206 | NO_YIELD_PERFORMED = 0x40000024, |
| 292 | ||
| 293 | 207 | /// The resume flag to a timer API was ignored. |
| 294 | 208 | TIMER_RESUME_IGNORED = 0x40000025, |
| 295 | ||
| 296 | 209 | /// The arbiter has deferred arbitration of these resources to its parent. |
| 297 | 210 | ARBITRATION_UNHANDLED = 0x40000026, |
| 298 | ||
| 299 | 211 | /// The device has detected a CardBus card in its slot. |
| 300 | 212 | CARDBUS_NOT_SUPPORTED = 0x40000027, |
| 301 | ||
| 302 | 213 | /// An exception status code that is used by the Win32 x86 emulation subsystem. |
| 303 | 214 | WX86_CREATEWX86TIB = 0x40000028, |
| 304 | ||
| 305 | 215 | /// The CPUs in this multiprocessor system are not all the same revision level. |
| 306 | 216 | /// To use all processors, the operating system restricts itself to the features of the least capable processor in the system. |
| 307 | 217 | /// If problems occur with this system, contact the CPU manufacturer to see if this mix of processors is supported. |
| 308 | 218 | MP_PROCESSOR_MISMATCH = 0x40000029, |
| 309 | ||
| 310 | 219 | /// The system was put into hibernation. |
| 311 | 220 | HIBERNATED = 0x4000002A, |
| 312 | ||
| 313 | 221 | /// The system was resumed from hibernation. |
| 314 | 222 | RESUME_HIBERNATION = 0x4000002B, |
| 315 | ||
| 316 | 223 | /// Windows has detected that the system firmware (BIOS) was updated [previous firmware date = %2, current firmware date %3]. |
| 317 | 224 | FIRMWARE_UPDATED = 0x4000002C, |
| 318 | ||
| 319 | 225 | /// A device driver is leaking locked I/O pages and is causing system degradation. |
| 320 | 226 | /// The system has automatically enabled the tracking code to try and catch the culprit. |
| 321 | 227 | DRIVERS_LEAKING_LOCKED_PAGES = 0x4000002D, |
| 322 | ||
| 323 | 228 | /// The ALPC message being canceled has already been retrieved from the queue on the other side. |
| 324 | 229 | MESSAGE_RETRIEVED = 0x4000002E, |
| 325 | ||
| 326 | 230 | /// The system power state is transitioning from %2 to %3. |
| 327 | 231 | SYSTEM_POWERSTATE_TRANSITION = 0x4000002F, |
| 328 | ||
| 329 | 232 | /// The receive operation was successful. |
| 330 | 233 | /// Check the ALPC completion list for the received message. |
| 331 | 234 | ALPC_CHECK_COMPLETION_LIST = 0x40000030, |
| 332 | ||
| 333 | 235 | /// The system power state is transitioning from %2 to %3 but could enter %4. |
| 334 | 236 | SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 0x40000031, |
| 335 | ||
| 336 | 237 | /// Access to %1 is monitored by policy rule %2. |
| 337 | 238 | ACCESS_AUDIT_BY_POLICY = 0x40000032, |
| 338 | ||
| 339 | 239 | /// A valid hibernation file has been invalidated and should be abandoned. |
| 340 | 240 | ABANDON_HIBERFILE = 0x40000033, |
| 341 | ||
| 342 | 241 | /// Business rule scripts are disabled for the calling application. |
| 343 | 242 | BIZRULES_NOT_ENABLED = 0x40000034, |
| 344 | ||
| 345 | 243 | /// The system has awoken. |
| 346 | 244 | WAKE_SYSTEM = 0x40000294, |
| 347 | ||
| 348 | 245 | /// The directory service is shutting down. |
| 349 | 246 | DS_SHUTTING_DOWN = 0x40000370, |
| 350 | ||
| 351 | 247 | /// Debugger will reply later. |
| 352 | 248 | DBG_REPLY_LATER = 0x40010001, |
| 353 | ||
| 354 | 249 | /// Debugger cannot provide a handle. |
| 355 | 250 | DBG_UNABLE_TO_PROVIDE_HANDLE = 0x40010002, |
| 356 | ||
| 357 | 251 | /// Debugger terminated the thread. |
| 358 | 252 | DBG_TERMINATE_THREAD = 0x40010003, |
| 359 | ||
| 360 | 253 | /// Debugger terminated the process. |
| 361 | 254 | DBG_TERMINATE_PROCESS = 0x40010004, |
| 362 | ||
| 363 | 255 | /// Debugger obtained control of C. |
| 364 | 256 | DBG_CONTROL_C = 0x40010005, |
| 365 | ||
| 366 | 257 | /// Debugger printed an exception on control C. |
| 367 | 258 | DBG_PRINTEXCEPTION_C = 0x40010006, |
| 368 | ||
| 369 | 259 | /// Debugger received a RIP exception. |
| 370 | 260 | DBG_RIPEXCEPTION = 0x40010007, |
| 371 | ||
| 372 | 261 | /// Debugger received a control break. |
| 373 | 262 | DBG_CONTROL_BREAK = 0x40010008, |
| 374 | ||
| 375 | 263 | /// Debugger command communication exception. |
| 376 | 264 | DBG_COMMAND_EXCEPTION = 0x40010009, |
| 377 | ||
| 378 | 265 | /// A UUID that is valid only on this computer has been allocated. |
| 379 | 266 | RPC_NT_UUID_LOCAL_ONLY = 0x40020056, |
| 380 | ||
| 381 | 267 | /// Some data remains to be sent in the request buffer. |
| 382 | 268 | RPC_NT_SEND_INCOMPLETE = 0x400200AF, |
| 383 | ||
| 384 | 269 | /// The Client Drive Mapping Service has connected on Terminal Connection. |
| 385 | 270 | CTX_CDM_CONNECT = 0x400A0004, |
| 386 | ||
| 387 | 271 | /// The Client Drive Mapping Service has disconnected on Terminal Connection. |
| 388 | 272 | CTX_CDM_DISCONNECT = 0x400A0005, |
| 389 | ||
| 390 | 273 | /// A kernel mode component is releasing a reference on an activation context. |
| 391 | 274 | SXS_RELEASE_ACTIVATION_CONTEXT = 0x4015000D, |
| 392 | ||
| 393 | 275 | /// The transactional resource manager is already consistent. Recovery is not needed. |
| 394 | 276 | RECOVERY_NOT_NEEDED = 0x40190034, |
| 395 | ||
| 396 | 277 | /// The transactional resource manager has already been started. |
| 397 | 278 | RM_ALREADY_STARTED = 0x40190035, |
| 398 | ||
| 399 | 279 | /// The log service encountered a log stream with no restart area. |
| 400 | 280 | LOG_NO_RESTART = 0x401A000C, |
| 401 | ||
| 402 | 281 | /// {Display Driver Recovered From Failure} The %hs display driver has detected a failure and recovered from it. Some graphical operations might have failed. |
| 403 | 282 | /// The next time you restart the machine, a dialog box appears, giving you an opportunity to upload data about this failure to Microsoft. |
| 404 | 283 | VIDEO_DRIVER_DEBUG_REPORT_REQUEST = 0x401B00EC, |
| 405 | ||
| 406 | 284 | /// The specified buffer is not big enough to contain the entire requested dataset. |
| 407 | 285 | /// Partial data is populated up to the size of the buffer. |
| 408 | 286 | /// The caller needs to provide a buffer of the size as specified in the partially populated buffer's content (interface specific). |
| 409 | 287 | GRAPHICS_PARTIAL_DATA_POPULATED = 0x401E000A, |
| 410 | ||
| 411 | 288 | /// The kernel driver detected a version mismatch between it and the user mode driver. |
| 412 | 289 | GRAPHICS_DRIVER_MISMATCH = 0x401E0117, |
| 413 | ||
| 414 | 290 | /// No mode is pinned on the specified VidPN source/target. |
| 415 | 291 | GRAPHICS_MODE_NOT_PINNED = 0x401E0307, |
| 416 | ||
| 417 | 292 | /// The specified mode set does not specify a preference for one of its modes. |
| 418 | 293 | GRAPHICS_NO_PREFERRED_MODE = 0x401E031E, |
| 419 | ||
| 420 | 294 | /// The specified dataset (for example, mode set, frequency range set, descriptor set, or topology) is empty. |
| 421 | 295 | GRAPHICS_DATASET_IS_EMPTY = 0x401E034B, |
| 422 | ||
| 423 | 296 | /// The specified dataset (for example, mode set, frequency range set, descriptor set, or topology) does not contain any more elements. |
| 424 | 297 | GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET = 0x401E034C, |
| 425 | ||
| 426 | 298 | /// The specified content transformation is not pinned on the specified VidPN present path. |
| 427 | 299 | GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED = 0x401E0351, |
| 428 | ||
| 429 | 300 | /// The child device presence was not reliably detected. |
| 430 | 301 | GRAPHICS_UNKNOWN_CHILD_STATUS = 0x401E042F, |
| 431 | ||
| 432 | 302 | /// Starting the lead adapter in a linked configuration has been temporarily deferred. |
| 433 | 303 | GRAPHICS_LEADLINK_START_DEFERRED = 0x401E0437, |
| 434 | ||
| 435 | 304 | /// The display adapter is being polled for children too frequently at the same polling level. |
| 436 | 305 | GRAPHICS_POLLING_TOO_FREQUENTLY = 0x401E0439, |
| 437 | ||
| 438 | 306 | /// Starting the adapter has been temporarily deferred. |
| 439 | 307 | GRAPHICS_START_DEFERRED = 0x401E043A, |
| 440 | ||
| 441 | 308 | /// The request will be completed later by an NDIS status indication. |
| 442 | 309 | NDIS_INDICATION_REQUIRED = 0x40230001, |
| 443 | ||
| 444 | 310 | /// {EXCEPTION} Guard Page Exception A page of memory that marks the end of a data structure, such as a stack or an array, has been accessed. |
| 445 | 311 | GUARD_PAGE_VIOLATION = 0x80000001, |
| 446 | ||
| 447 | 312 | /// {EXCEPTION} Alignment Fault A data type misalignment was detected in a load or store instruction. |
| 448 | 313 | DATATYPE_MISALIGNMENT = 0x80000002, |
| 449 | ||
| 450 | 314 | /// {EXCEPTION} Breakpoint A breakpoint has been reached. |
| 451 | 315 | BREAKPOINT = 0x80000003, |
| 452 | ||
| 453 | 316 | /// {EXCEPTION} Single Step A single step or trace operation has just been completed. |
| 454 | 317 | SINGLE_STEP = 0x80000004, |
| 455 | ||
| 456 | 318 | /// {Buffer Overflow} The data was too large to fit into the specified buffer. |
| 457 | 319 | BUFFER_OVERFLOW = 0x80000005, |
| 458 | ||
| 459 | 320 | /// {No More Files} No more files were found which match the file specification. |
| 460 | 321 | NO_MORE_FILES = 0x80000006, |
| 461 | ||
| 462 | 322 | /// {Kernel Debugger Awakened} The system debugger was awakened by an interrupt. |
| 463 | 323 | WAKE_SYSTEM_DEBUGGER = 0x80000007, |
| 464 | ||
| 465 | 324 | /// {Handles Closed} Handles to objects have been automatically closed because of the requested operation. |
| 466 | 325 | HANDLES_CLOSED = 0x8000000A, |
| 467 | ||
| 468 | 326 | /// {Non-Inheritable ACL} An access control list (ACL) contains no components that can be inherited. |
| 469 | 327 | NO_INHERITANCE = 0x8000000B, |
| 470 | ||
| 471 | 328 | /// {GUID Substitution} During the translation of a globally unique identifier (GUID) to a Windows security ID (SID), no administratively defined GUID prefix was found. |
| 472 | 329 | /// A substitute prefix was used, which will not compromise system security. |
| 473 | 330 | /// However, this might provide a more restrictive access than intended. |
| 474 | 331 | GUID_SUBSTITUTION_MADE = 0x8000000C, |
| 475 | ||
| 476 | 332 | /// Because of protection conflicts, not all the requested bytes could be copied. |
| 477 | 333 | PARTIAL_COPY = 0x8000000D, |
| 478 | ||
| 479 | 334 | /// {Out of Paper} The printer is out of paper. |
| 480 | 335 | DEVICE_PAPER_EMPTY = 0x8000000E, |
| 481 | ||
| 482 | 336 | /// {Device Power Is Off} The printer power has been turned off. |
| 483 | 337 | DEVICE_POWERED_OFF = 0x8000000F, |
| 484 | ||
| 485 | 338 | /// {Device Offline} The printer has been taken offline. |
| 486 | 339 | DEVICE_OFF_LINE = 0x80000010, |
| 487 | ||
| 488 | 340 | /// {Device Busy} The device is currently busy. |
| 489 | 341 | DEVICE_BUSY = 0x80000011, |
| 490 | ||
| 491 | 342 | /// {No More EAs} No more extended attributes (EAs) were found for the file. |
| 492 | 343 | NO_MORE_EAS = 0x80000012, |
| 493 | ||
| 494 | 344 | /// {Illegal EA} The specified extended attribute (EA) name contains at least one illegal character. |
| 495 | 345 | INVALID_EA_NAME = 0x80000013, |
| 496 | ||
| 497 | 346 | /// {Inconsistent EA List} The extended attribute (EA) list is inconsistent. |
| 498 | 347 | EA_LIST_INCONSISTENT = 0x80000014, |
| 499 | ||
| 500 | 348 | /// {Invalid EA Flag} An invalid extended attribute (EA) flag was set. |
| 501 | 349 | INVALID_EA_FLAG = 0x80000015, |
| 502 | ||
| 503 | 350 | /// {Verifying Disk} The media has changed and a verify operation is in progress; therefore, no reads or writes can be performed to the device, except those that are used in the verify operation. |
| 504 | 351 | VERIFY_REQUIRED = 0x80000016, |
| 505 | ||
| 506 | 352 | /// {Too Much Information} The specified access control list (ACL) contained more information than was expected. |
| 507 | 353 | EXTRANEOUS_INFORMATION = 0x80000017, |
| 508 | ||
| 509 | 354 | /// This warning level status indicates that the transaction state already exists for the registry subtree, but that a transaction commit was previously aborted. |
| 510 | 355 | /// The commit has NOT been completed but has not been rolled back either; therefore, it can still be committed, if needed. |
| 511 | 356 | RXACT_COMMIT_NECESSARY = 0x80000018, |
| 512 | ||
| 513 | 357 | /// {No More Entries} No more entries are available from an enumeration operation. |
| 514 | 358 | NO_MORE_ENTRIES = 0x8000001A, |
| 515 | ||
| 516 | 359 | /// {Filemark Found} A filemark was detected. |
| 517 | 360 | FILEMARK_DETECTED = 0x8000001B, |
| 518 | ||
| 519 | 361 | /// {Media Changed} The media has changed. |
| 520 | 362 | MEDIA_CHANGED = 0x8000001C, |
| 521 | ||
| 522 | 363 | /// {I/O Bus Reset} An I/O bus reset was detected. |
| 523 | 364 | BUS_RESET = 0x8000001D, |
| 524 | ||
| 525 | 365 | /// {End of Media} The end of the media was encountered. |
| 526 | 366 | END_OF_MEDIA = 0x8000001E, |
| 527 | ||
| 528 | 367 | /// The beginning of a tape or partition has been detected. |
| 529 | 368 | BEGINNING_OF_MEDIA = 0x8000001F, |
| 530 | ||
| 531 | 369 | /// {Media Changed} The media might have changed. |
| 532 | 370 | MEDIA_CHECK = 0x80000020, |
| 533 | ||
| 534 | 371 | /// A tape access reached a set mark. |
| 535 | 372 | SETMARK_DETECTED = 0x80000021, |
| 536 | ||
| 537 | 373 | /// During a tape access, the end of the data written is reached. |
| 538 | 374 | NO_DATA_DETECTED = 0x80000022, |
| 539 | ||
| 540 | 375 | /// The redirector is in use and cannot be unloaded. |
| 541 | 376 | REDIRECTOR_HAS_OPEN_HANDLES = 0x80000023, |
| 542 | ||
| 543 | 377 | /// The server is in use and cannot be unloaded. |
| 544 | 378 | SERVER_HAS_OPEN_HANDLES = 0x80000024, |
| 545 | ||
| 546 | 379 | /// The specified connection has already been disconnected. |
| 547 | 380 | ALREADY_DISCONNECTED = 0x80000025, |
| 548 | ||
| 549 | 381 | /// A long jump has been executed. |
| 550 | 382 | LONGJUMP = 0x80000026, |
| 551 | ||
| 552 | 383 | /// A cleaner cartridge is present in the tape library. |
| 553 | 384 | CLEANER_CARTRIDGE_INSTALLED = 0x80000027, |
| 554 | ||
| 555 | 385 | /// The Plug and Play query operation was not successful. |
| 556 | 386 | PLUGPLAY_QUERY_VETOED = 0x80000028, |
| 557 | ||
| 558 | 387 | /// A frame consolidation has been executed. |
| 559 | 388 | UNWIND_CONSOLIDATE = 0x80000029, |
| 560 | ||
| 561 | 389 | /// {Registry Hive Recovered} The registry hive (file): %hs was corrupted and it has been recovered. Some data might have been lost. |
| 562 | 390 | REGISTRY_HIVE_RECOVERED = 0x8000002A, |
| 563 | ||
| 564 | 391 | /// The application is attempting to run executable code from the module %hs. This might be insecure. |
| 565 | 392 | /// An alternative, %hs, is available. Should the application use the secure module %hs? |
| 566 | 393 | DLL_MIGHT_BE_INSECURE = 0x8000002B, |
| 567 | ||
| 568 | 394 | /// The application is loading executable code from the module %hs. |
| 569 | 395 | /// This is secure but might be incompatible with previous releases of the operating system. |
| 570 | 396 | /// An alternative, %hs, is available. Should the application use the secure module %hs? |
| 571 | 397 | DLL_MIGHT_BE_INCOMPATIBLE = 0x8000002C, |
| 572 | ||
| 573 | 398 | /// The create operation stopped after reaching a symbolic link. |
| 574 | 399 | STOPPED_ON_SYMLINK = 0x8000002D, |
| 575 | ||
| 576 | 400 | /// The device has indicated that cleaning is necessary. |
| 577 | 401 | DEVICE_REQUIRES_CLEANING = 0x80000288, |
| 578 | ||
| 579 | 402 | /// The device has indicated that its door is open. Further operations require it closed and secured. |
| 580 | 403 | DEVICE_DOOR_OPEN = 0x80000289, |
| 581 | ||
| 582 | 404 | /// Windows discovered a corruption in the file %hs. This file has now been repaired. |
| 583 | 405 | /// Check if any data in the file was lost because of the corruption. |
| 584 | 406 | DATA_LOST_REPAIR = 0x80000803, |
| 585 | ||
| 586 | 407 | /// Debugger did not handle the exception. |
| 587 | 408 | DBG_EXCEPTION_NOT_HANDLED = 0x80010001, |
| 588 | ||
| 589 | 409 | /// The cluster node is already up. |
| 590 | 410 | CLUSTER_NODE_ALREADY_UP = 0x80130001, |
| 591 | ||
| 592 | 411 | /// The cluster node is already down. |
| 593 | 412 | CLUSTER_NODE_ALREADY_DOWN = 0x80130002, |
| 594 | ||
| 595 | 413 | /// The cluster network is already online. |
| 596 | 414 | CLUSTER_NETWORK_ALREADY_ONLINE = 0x80130003, |
| 597 | ||
| 598 | 415 | /// The cluster network is already offline. |
| 599 | 416 | CLUSTER_NETWORK_ALREADY_OFFLINE = 0x80130004, |
| 600 | ||
| 601 | 417 | /// The cluster node is already a member of the cluster. |
| 602 | 418 | CLUSTER_NODE_ALREADY_MEMBER = 0x80130005, |
| 603 | ||
| 604 | 419 | /// The log could not be set to the requested size. |
| 605 | 420 | COULD_NOT_RESIZE_LOG = 0x80190009, |
| 606 | ||
| 607 | 421 | /// There is no transaction metadata on the file. |
| 608 | 422 | NO_TXF_METADATA = 0x80190029, |
| 609 | ||
| 610 | 423 | /// The file cannot be recovered because there is a handle still open on it. |
| 611 | 424 | CANT_RECOVER_WITH_HANDLE_OPEN = 0x80190031, |
| 612 | ||
| 613 | 425 | /// Transaction metadata is already present on this file and cannot be superseded. |
| 614 | 426 | TXF_METADATA_ALREADY_PRESENT = 0x80190041, |
| 615 | ||
| 616 | 427 | /// A transaction scope could not be entered because the scope handler has not been initialized. |
| 617 | 428 | TRANSACTION_SCOPE_CALLBACKS_NOT_SET = 0x80190042, |
| 618 | ||
| 619 | 429 | /// {Display Driver Stopped Responding and recovered} The %hs display driver has stopped working normally. The recovery had been performed. |
| 620 | 430 | VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED = 0x801B00EB, |
| 621 | ||
| 622 | 431 | /// {Buffer too small} The buffer is too small to contain the entry. No information has been written to the buffer. |
| 623 | 432 | FLT_BUFFER_TOO_SMALL = 0x801C0001, |
| 624 | ||
| 625 | 433 | /// Volume metadata read or write is incomplete. |
| 626 | 434 | FVE_PARTIAL_METADATA = 0x80210001, |
| 627 | ||
| 628 | 435 | /// BitLocker encryption keys were ignored because the volume was in a transient state. |
| 629 | 436 | FVE_TRANSIENT_STATE = 0x80210002, |
| 630 | ||
| 631 | 437 | /// {Operation Failed} The requested operation was unsuccessful. |
| 632 | 438 | UNSUCCESSFUL = 0xC0000001, |
| 633 | ||
| 634 | 439 | /// {Not Implemented} The requested operation is not implemented. |
| 635 | 440 | NOT_IMPLEMENTED = 0xC0000002, |
| 636 | ||
| 637 | 441 | /// {Invalid Parameter} The specified information class is not a valid information class for the specified object. |
| 638 | 442 | INVALID_INFO_CLASS = 0xC0000003, |
| 639 | ||
| 640 | 443 | /// The specified information record length does not match the length that is required for the specified information class. |
| 641 | 444 | INFO_LENGTH_MISMATCH = 0xC0000004, |
| 642 | ||
| 643 | 445 | /// The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s. |
| 644 | 446 | ACCESS_VIOLATION = 0xC0000005, |
| 645 | ||
| 646 | 447 | /// The instruction at 0x%08lx referenced memory at 0x%08lx. |
| 647 | 448 | /// The required data was not placed into memory because of an I/O error status of 0x%08lx. |
| 648 | 449 | IN_PAGE_ERROR = 0xC0000006, |
| 649 | ||
| 650 | 450 | /// The page file quota for the process has been exhausted. |
| 651 | 451 | PAGEFILE_QUOTA = 0xC0000007, |
| 652 | ||
| 653 | 452 | /// An invalid HANDLE was specified. |
| 654 | 453 | INVALID_HANDLE = 0xC0000008, |
| 655 | ||
| 656 | 454 | /// An invalid initial stack was specified in a call to NtCreateThread. |
| 657 | 455 | BAD_INITIAL_STACK = 0xC0000009, |
| 658 | ||
| 659 | 456 | /// An invalid initial start address was specified in a call to NtCreateThread. |
| 660 | 457 | BAD_INITIAL_PC = 0xC000000A, |
| 661 | ||
| 662 | 458 | /// An invalid client ID was specified. |
| 663 | 459 | INVALID_CID = 0xC000000B, |
| 664 | ||
| 665 | 460 | /// An attempt was made to cancel or set a timer that has an associated APC and the specified thread is not the thread that originally set the timer with an associated APC routine. |
| 666 | 461 | TIMER_NOT_CANCELED = 0xC000000C, |
| 667 | ||
| 668 | 462 | /// An invalid parameter was passed to a service or function. |
| 669 | 463 | INVALID_PARAMETER = 0xC000000D, |
| 670 | ||
| 671 | 464 | /// A device that does not exist was specified. |
| 672 | 465 | NO_SUCH_DEVICE = 0xC000000E, |
| 673 | ||
| 674 | 466 | /// {File Not Found} The file %hs does not exist. |
| 675 | 467 | NO_SUCH_FILE = 0xC000000F, |
| 676 | ||
| 677 | 468 | /// The specified request is not a valid operation for the target device. |
| 678 | 469 | INVALID_DEVICE_REQUEST = 0xC0000010, |
| 679 | ||
| 680 | 470 | /// The end-of-file marker has been reached. |
| 681 | 471 | /// There is no valid data in the file beyond this marker. |
| 682 | 472 | END_OF_FILE = 0xC0000011, |
| 683 | ||
| 684 | 473 | /// {Wrong Volume} The wrong volume is in the drive. Insert volume %hs into drive %hs. |
| 685 | 474 | WRONG_VOLUME = 0xC0000012, |
| 686 | ||
| 687 | 475 | /// {No Disk} There is no disk in the drive. Insert a disk into drive %hs. |
| 688 | 476 | NO_MEDIA_IN_DEVICE = 0xC0000013, |
| 689 | ||
| 690 | 477 | /// {Unknown Disk Format} The disk in drive %hs is not formatted properly. |
| 691 | 478 | /// Check the disk, and reformat it, if needed. |
| 692 | 479 | UNRECOGNIZED_MEDIA = 0xC0000014, |
| 693 | ||
| 694 | 480 | /// {Sector Not Found} The specified sector does not exist. |
| 695 | 481 | NONEXISTENT_SECTOR = 0xC0000015, |
| 696 | ||
| 697 | 482 | /// {Still Busy} The specified I/O request packet (IRP) cannot be disposed of because the I/O operation is not complete. |
| 698 | 483 | MORE_PROCESSING_REQUIRED = 0xC0000016, |
| 699 | ||
| 700 | 484 | /// {Not Enough Quota} Not enough virtual memory or paging file quota is available to complete the specified operation. |
| 701 | 485 | NO_MEMORY = 0xC0000017, |
| 702 | ||
| 703 | 486 | /// {Conflicting Address Range} The specified address range conflicts with the address space. |
| 704 | 487 | CONFLICTING_ADDRESSES = 0xC0000018, |
| 705 | ||
| 706 | 488 | /// The address range to unmap is not a mapped view. |
| 707 | 489 | NOT_MAPPED_VIEW = 0xC0000019, |
| 708 | ||
| 709 | 490 | /// The virtual memory cannot be freed. |
| 710 | 491 | UNABLE_TO_FREE_VM = 0xC000001A, |
| 711 | ||
| 712 | 492 | /// The specified section cannot be deleted. |
| 713 | 493 | UNABLE_TO_DELETE_SECTION = 0xC000001B, |
| 714 | ||
| 715 | 494 | /// An invalid system service was specified in a system service call. |
| 716 | 495 | INVALID_SYSTEM_SERVICE = 0xC000001C, |
| 717 | ||
| 718 | 496 | /// {EXCEPTION} Illegal Instruction An attempt was made to execute an illegal instruction. |
| 719 | 497 | ILLEGAL_INSTRUCTION = 0xC000001D, |
| 720 | ||
| 721 | 498 | /// {Invalid Lock Sequence} An attempt was made to execute an invalid lock sequence. |
| 722 | 499 | INVALID_LOCK_SEQUENCE = 0xC000001E, |
| 723 | ||
| 724 | 500 | /// {Invalid Mapping} An attempt was made to create a view for a section that is bigger than the section. |
| 725 | 501 | INVALID_VIEW_SIZE = 0xC000001F, |
| 726 | ||
| 727 | 502 | /// {Bad File} The attributes of the specified mapping file for a section of memory cannot be read. |
| 728 | 503 | INVALID_FILE_FOR_SECTION = 0xC0000020, |
| 729 | ||
| 730 | 504 | /// {Already Committed} The specified address range is already committed. |
| 731 | 505 | ALREADY_COMMITTED = 0xC0000021, |
| 732 | ||
| 733 | 506 | /// {Access Denied} A process has requested access to an object but has not been granted those access rights. |
| 734 | 507 | ACCESS_DENIED = 0xC0000022, |
| 735 | ||
| 736 | 508 | /// {Buffer Too Small} The buffer is too small to contain the entry. No information has been written to the buffer. |
| 737 | 509 | BUFFER_TOO_SMALL = 0xC0000023, |
| 738 | ||
| 739 | 510 | /// {Wrong Type} There is a mismatch between the type of object that is required by the requested operation and the type of object that is specified in the request. |
| 740 | 511 | OBJECT_TYPE_MISMATCH = 0xC0000024, |
| 741 | ||
| 742 | 512 | /// {EXCEPTION} Cannot Continue Windows cannot continue from this exception. |
| 743 | 513 | NONCONTINUABLE_EXCEPTION = 0xC0000025, |
| 744 | ||
| 745 | 514 | /// An invalid exception disposition was returned by an exception handler. |
| 746 | 515 | INVALID_DISPOSITION = 0xC0000026, |
| 747 | ||
| 748 | 516 | /// Unwind exception code. |
| 749 | 517 | UNWIND = 0xC0000027, |
| 750 | ||
| 751 | 518 | /// An invalid or unaligned stack was encountered during an unwind operation. |
| 752 | 519 | BAD_STACK = 0xC0000028, |
| 753 | ||
| 754 | 520 | /// An invalid unwind target was encountered during an unwind operation. |
| 755 | 521 | INVALID_UNWIND_TARGET = 0xC0000029, |
| 756 | ||
| 757 | 522 | /// An attempt was made to unlock a page of memory that was not locked. |
| 758 | 523 | NOT_LOCKED = 0xC000002A, |
| 759 | ||
| 760 | 524 | /// A device parity error on an I/O operation. |
| 761 | 525 | PARITY_ERROR = 0xC000002B, |
| 762 | ||
| 763 | 526 | /// An attempt was made to decommit uncommitted virtual memory. |
| 764 | 527 | UNABLE_TO_DECOMMIT_VM = 0xC000002C, |
| 765 | ||
| 766 | 528 | /// An attempt was made to change the attributes on memory that has not been committed. |
| 767 | 529 | NOT_COMMITTED = 0xC000002D, |
| 768 | ||
| 769 | 530 | /// Invalid object attributes specified to NtCreatePort or invalid port attributes specified to NtConnectPort. |
| 770 | 531 | INVALID_PORT_ATTRIBUTES = 0xC000002E, |
| 771 | ||
| 772 | 532 | /// The length of the message that was passed to NtRequestPort or NtRequestWaitReplyPort is longer than the maximum message that is allowed by the port. |
| 773 | 533 | PORT_MESSAGE_TOO_LONG = 0xC000002F, |
| 774 | ||
| 775 | 534 | /// An invalid combination of parameters was specified. |
| 776 | 535 | INVALID_PARAMETER_MIX = 0xC0000030, |
| 777 | ||
| 778 | 536 | /// An attempt was made to lower a quota limit below the current usage. |
| 779 | 537 | INVALID_QUOTA_LOWER = 0xC0000031, |
| 780 | ||
| 781 | 538 | /// {Corrupt Disk} The file system structure on the disk is corrupt and unusable. Run the Chkdsk utility on the volume %hs. |
| 782 | 539 | DISK_CORRUPT_ERROR = 0xC0000032, |
| 783 | ||
| 784 | 540 | /// The object name is invalid. |
| 785 | 541 | OBJECT_NAME_INVALID = 0xC0000033, |
| 786 | ||
| 787 | 542 | /// The object name is not found. |
| 788 | 543 | OBJECT_NAME_NOT_FOUND = 0xC0000034, |
| 789 | ||
| 790 | 544 | /// The object name already exists. |
| 791 | 545 | OBJECT_NAME_COLLISION = 0xC0000035, |
| 792 | ||
| 793 | 546 | /// An attempt was made to send a message to a disconnected communication port. |
| 794 | 547 | PORT_DISCONNECTED = 0xC0000037, |
| 795 | ||
| 796 | 548 | /// An attempt was made to attach to a device that was already attached to another device. |
| 797 | 549 | DEVICE_ALREADY_ATTACHED = 0xC0000038, |
| 798 | ||
| 799 | 550 | /// The object path component was not a directory object. |
| 800 | 551 | OBJECT_PATH_INVALID = 0xC0000039, |
| 801 | ||
| 802 | 552 | /// {Path Not Found} The path %hs does not exist. |
| 803 | 553 | OBJECT_PATH_NOT_FOUND = 0xC000003A, |
| 804 | ||
| 805 | 554 | /// The object path component was not a directory object. |
| 806 | 555 | OBJECT_PATH_SYNTAX_BAD = 0xC000003B, |
| 807 | ||
| 808 | 556 | /// {Data Overrun} A data overrun error occurred. |
| 809 | 557 | DATA_OVERRUN = 0xC000003C, |
| 810 | ||
| 811 | 558 | /// {Data Late} A data late error occurred. |
| 812 | 559 | DATA_LATE_ERROR = 0xC000003D, |
| 813 | ||
| 814 | 560 | /// {Data Error} An error occurred in reading or writing data. |
| 815 | 561 | DATA_ERROR = 0xC000003E, |
| 816 | ||
| 817 | 562 | /// {Bad CRC} A cyclic redundancy check (CRC) checksum error occurred. |
| 818 | 563 | CRC_ERROR = 0xC000003F, |
| 819 | ||
| 820 | 564 | /// {Section Too Large} The specified section is too big to map the file. |
| 821 | 565 | SECTION_TOO_BIG = 0xC0000040, |
| 822 | ||
| 823 | 566 | /// The NtConnectPort request is refused. |
| 824 | 567 | PORT_CONNECTION_REFUSED = 0xC0000041, |
| 825 | ||
| 826 | 568 | /// The type of port handle is invalid for the operation that is requested. |
| 827 | 569 | INVALID_PORT_HANDLE = 0xC0000042, |
| 828 | ||
| 829 | 570 | /// A file cannot be opened because the share access flags are incompatible. |
| 830 | 571 | SHARING_VIOLATION = 0xC0000043, |
| 831 | ||
| 832 | 572 | /// Insufficient quota exists to complete the operation. |
| 833 | 573 | QUOTA_EXCEEDED = 0xC0000044, |
| 834 | ||
| 835 | 574 | /// The specified page protection was not valid. |
| 836 | 575 | INVALID_PAGE_PROTECTION = 0xC0000045, |
| 837 | ||
| 838 | 576 | /// An attempt to release a mutant object was made by a thread that was not the owner of the mutant object. |
| 839 | 577 | MUTANT_NOT_OWNED = 0xC0000046, |
| 840 | ||
| 841 | 578 | /// An attempt was made to release a semaphore such that its maximum count would have been exceeded. |
| 842 | 579 | SEMAPHORE_LIMIT_EXCEEDED = 0xC0000047, |
| 843 | ||
| 844 | 580 | /// An attempt was made to set the DebugPort or ExceptionPort of a process, but a port already exists in the process, or an attempt was made to set the CompletionPort of a file but a port was already set in the file, or an attempt was made to set the associated completion port of an ALPC port but it is already set. |
| 845 | 581 | PORT_ALREADY_SET = 0xC0000048, |
| 846 | ||
| 847 | 582 | /// An attempt was made to query image information on a section that does not map an image. |
| 848 | 583 | SECTION_NOT_IMAGE = 0xC0000049, |
| 849 | ||
| 850 | 584 | /// An attempt was made to suspend a thread whose suspend count was at its maximum. |
| 851 | 585 | SUSPEND_COUNT_EXCEEDED = 0xC000004A, |
| 852 | ||
| 853 | 586 | /// An attempt was made to suspend a thread that has begun termination. |
| 854 | 587 | THREAD_IS_TERMINATING = 0xC000004B, |
| 855 | ||
| 856 | 588 | /// An attempt was made to set the working set limit to an invalid value (for example, the minimum greater than maximum). |
| 857 | 589 | BAD_WORKING_SET_LIMIT = 0xC000004C, |
| 858 | ||
| 859 | 590 | /// A section was created to map a file that is not compatible with an already existing section that maps the same file. |
| 860 | 591 | INCOMPATIBLE_FILE_MAP = 0xC000004D, |
| 861 | ||
| 862 | 592 | /// A view to a section specifies a protection that is incompatible with the protection of the initial view. |
| 863 | 593 | SECTION_PROTECTION = 0xC000004E, |
| 864 | ||
| 865 | 594 | /// An operation involving EAs failed because the file system does not support EAs. |
| 866 | 595 | EAS_NOT_SUPPORTED = 0xC000004F, |
| 867 | ||
| 868 | 596 | /// An EA operation failed because the EA set is too large. |
| 869 | 597 | EA_TOO_LARGE = 0xC0000050, |
| 870 | ||
| 871 | 598 | /// An EA operation failed because the name or EA index is invalid. |
| 872 | 599 | NONEXISTENT_EA_ENTRY = 0xC0000051, |
| 873 | ||
| 874 | 600 | /// The file for which EAs were requested has no EAs. |
| 875 | 601 | NO_EAS_ON_FILE = 0xC0000052, |
| 876 | ||
| 877 | 602 | /// The EA is corrupt and cannot be read. |
| 878 | 603 | EA_CORRUPT_ERROR = 0xC0000053, |
| 879 | ||
| 880 | 604 | /// A requested read/write cannot be granted due to a conflicting file lock. |
| 881 | 605 | FILE_LOCK_CONFLICT = 0xC0000054, |
| 882 | ||
| 883 | 606 | /// A requested file lock cannot be granted due to other existing locks. |
| 884 | 607 | LOCK_NOT_GRANTED = 0xC0000055, |
| 885 | ||
| 886 | 608 | /// A non-close operation has been requested of a file object that has a delete pending. |
| 887 | 609 | DELETE_PENDING = 0xC0000056, |
| 888 | ||
| 889 | 610 | /// An attempt was made to set the control attribute on a file. |
| 890 | 611 | /// This attribute is not supported in the destination file system. |
| 891 | 612 | CTL_FILE_NOT_SUPPORTED = 0xC0000057, |
| 892 | ||
| 893 | 613 | /// Indicates a revision number that was encountered or specified is not one that is known by the service. |
| 894 | 614 | /// It might be a more recent revision than the service is aware of. |
| 895 | 615 | UNKNOWN_REVISION = 0xC0000058, |
| 896 | ||
| 897 | 616 | /// Indicates that two revision levels are incompatible. |
| 898 | 617 | REVISION_MISMATCH = 0xC0000059, |
| 899 | ||
| 900 | 618 | /// Indicates a particular security ID cannot be assigned as the owner of an object. |
| 901 | 619 | INVALID_OWNER = 0xC000005A, |
| 902 | ||
| 903 | 620 | /// Indicates a particular security ID cannot be assigned as the primary group of an object. |
| 904 | 621 | INVALID_PRIMARY_GROUP = 0xC000005B, |
| 905 | ||
| 906 | 622 | /// An attempt has been made to operate on an impersonation token by a thread that is not currently impersonating a client. |
| 907 | 623 | NO_IMPERSONATION_TOKEN = 0xC000005C, |
| 908 | ||
| 909 | 624 | /// A mandatory group cannot be disabled. |
| 910 | 625 | CANT_DISABLE_MANDATORY = 0xC000005D, |
| 911 | ||
| 912 | 626 | /// No logon servers are currently available to service the logon request. |
| 913 | 627 | NO_LOGON_SERVERS = 0xC000005E, |
| 914 | ||
| 915 | 628 | /// A specified logon session does not exist. It might already have been terminated. |
| 916 | 629 | NO_SUCH_LOGON_SESSION = 0xC000005F, |
| 917 | ||
| 918 | 630 | /// A specified privilege does not exist. |
| 919 | 631 | NO_SUCH_PRIVILEGE = 0xC0000060, |
| 920 | ||
| 921 | 632 | /// A required privilege is not held by the client. |
| 922 | 633 | PRIVILEGE_NOT_HELD = 0xC0000061, |
| 923 | ||
| 924 | 634 | /// The name provided is not a properly formed account name. |
| 925 | 635 | INVALID_ACCOUNT_NAME = 0xC0000062, |
| 926 | ||
| 927 | 636 | /// The specified account already exists. |
| 928 | 637 | USER_EXISTS = 0xC0000063, |
| 929 | ||
| 930 | 638 | /// The specified account does not exist. |
| 931 | 639 | NO_SUCH_USER = 0xC0000064, |
| 932 | ||
| 933 | 640 | /// The specified group already exists. |
| 934 | 641 | GROUP_EXISTS = 0xC0000065, |
| 935 | ||
| 936 | 642 | /// The specified group does not exist. |
| 937 | 643 | NO_SUCH_GROUP = 0xC0000066, |
| 938 | ||
| 939 | 644 | /// The specified user account is already in the specified group account. |
| 940 | 645 | /// Also used to indicate a group cannot be deleted because it contains a member. |
| 941 | 646 | MEMBER_IN_GROUP = 0xC0000067, |
| 942 | ||
| 943 | 647 | /// The specified user account is not a member of the specified group account. |
| 944 | 648 | MEMBER_NOT_IN_GROUP = 0xC0000068, |
| 945 | ||
| 946 | 649 | /// Indicates the requested operation would disable or delete the last remaining administration account. |
| 947 | 650 | /// This is not allowed to prevent creating a situation in which the system cannot be administrated. |
| 948 | 651 | LAST_ADMIN = 0xC0000069, |
| 949 | ||
| 950 | 652 | /// When trying to update a password, this return status indicates that the value provided as the current password is not correct. |
| 951 | 653 | WRONG_PASSWORD = 0xC000006A, |
| 952 | ||
| 953 | 654 | /// When trying to update a password, this return status indicates that the value provided for the new password contains values that are not allowed in passwords. |
| 954 | 655 | ILL_FORMED_PASSWORD = 0xC000006B, |
| 955 | ||
| 956 | 656 | /// When trying to update a password, this status indicates that some password update rule has been violated. |
| 957 | 657 | /// For example, the password might not meet length criteria. |
| 958 | 658 | PASSWORD_RESTRICTION = 0xC000006C, |
| 959 | ||
| 960 | 659 | /// The attempted logon is invalid. |
| 961 | 660 | /// This is either due to a bad username or authentication information. |
| 962 | 661 | LOGON_FAILURE = 0xC000006D, |
| 963 | ||
| 964 | 662 | /// Indicates a referenced user name and authentication information are valid, but some user account restriction has prevented successful authentication (such as time-of-day restrictions). |
| 965 | 663 | ACCOUNT_RESTRICTION = 0xC000006E, |
| 966 | ||
| 967 | 664 | /// The user account has time restrictions and cannot be logged onto at this time. |
| 968 | 665 | INVALID_LOGON_HOURS = 0xC000006F, |
| 969 | ||
| 970 | 666 | /// The user account is restricted so that it cannot be used to log on from the source workstation. |
| 971 | 667 | INVALID_WORKSTATION = 0xC0000070, |
| 972 | ||
| 973 | 668 | /// The user account password has expired. |
| 974 | 669 | PASSWORD_EXPIRED = 0xC0000071, |
| 975 | ||
| 976 | 670 | /// The referenced account is currently disabled and cannot be logged on to. |
| 977 | 671 | ACCOUNT_DISABLED = 0xC0000072, |
| 978 | ||
| 979 | 672 | /// None of the information to be translated has been translated. |
| 980 | 673 | NONE_MAPPED = 0xC0000073, |
| 981 | ||
| 982 | 674 | /// The number of LUIDs requested cannot be allocated with a single allocation. |
| 983 | 675 | TOO_MANY_LUIDS_REQUESTED = 0xC0000074, |
| 984 | ||
| 985 | 676 | /// Indicates there are no more LUIDs to allocate. |
| 986 | 677 | LUIDS_EXHAUSTED = 0xC0000075, |
| 987 | ||
| 988 | 678 | /// Indicates the sub-authority value is invalid for the particular use. |
| 989 | 679 | INVALID_SUB_AUTHORITY = 0xC0000076, |
| 990 | ||
| 991 | 680 | /// Indicates the ACL structure is not valid. |
| 992 | 681 | INVALID_ACL = 0xC0000077, |
| 993 | ||
| 994 | 682 | /// Indicates the SID structure is not valid. |
| 995 | 683 | INVALID_SID = 0xC0000078, |
| 996 | ||
| 997 | 684 | /// Indicates the SECURITY_DESCRIPTOR structure is not valid. |
| 998 | 685 | INVALID_SECURITY_DESCR = 0xC0000079, |
| 999 | ||
| 1000 | 686 | /// Indicates the specified procedure address cannot be found in the DLL. |
| 1001 | 687 | PROCEDURE_NOT_FOUND = 0xC000007A, |
| 1002 | ||
| 1003 | 688 | /// {Bad Image} %hs is either not designed to run on Windows or it contains an error. |
| 1004 | 689 | /// Try installing the program again using the original installation media or contact your system administrator or the software vendor for support. |
| 1005 | 690 | INVALID_IMAGE_FORMAT = 0xC000007B, |
| 1006 | ||
| 1007 | 691 | /// An attempt was made to reference a token that does not exist. |
| 1008 | 692 | /// This is typically done by referencing the token that is associated with a thread when the thread is not impersonating a client. |
| 1009 | 693 | NO_TOKEN = 0xC000007C, |
| 1010 | ||
| 1011 | 694 | /// Indicates that an attempt to build either an inherited ACL or ACE was not successful. This can be caused by a number of things. |
| 1012 | 695 | /// One of the more probable causes is the replacement of a CreatorId with a SID that did not fit into the ACE or ACL. |
| 1013 | 696 | BAD_INHERITANCE_ACL = 0xC000007D, |
| 1014 | ||
| 1015 | 697 | /// The range specified in NtUnlockFile was not locked. |
| 1016 | 698 | RANGE_NOT_LOCKED = 0xC000007E, |
| 1017 | ||
| 1018 | 699 | /// An operation failed because the disk was full. |
| 1019 | 700 | DISK_FULL = 0xC000007F, |
| 1020 | ||
| 1021 | 701 | /// The GUID allocation server is disabled at the moment. |
| 1022 | 702 | SERVER_DISABLED = 0xC0000080, |
| 1023 | ||
| 1024 | 703 | /// The GUID allocation server is enabled at the moment. |
| 1025 | 704 | SERVER_NOT_DISABLED = 0xC0000081, |
| 1026 | ||
| 1027 | 705 | /// Too many GUIDs were requested from the allocation server at once. |
| 1028 | 706 | TOO_MANY_GUIDS_REQUESTED = 0xC0000082, |
| 1029 | ||
| 1030 | 707 | /// The GUIDs could not be allocated because the Authority Agent was exhausted. |
| 1031 | 708 | GUIDS_EXHAUSTED = 0xC0000083, |
| 1032 | ||
| 1033 | 709 | /// The value provided was an invalid value for an identifier authority. |
| 1034 | 710 | INVALID_ID_AUTHORITY = 0xC0000084, |
| 1035 | ||
| 1036 | 711 | /// No more authority agent values are available for the particular identifier authority value. |
| 1037 | 712 | AGENTS_EXHAUSTED = 0xC0000085, |
| 1038 | ||
| 1039 | 713 | /// An invalid volume label has been specified. |
| 1040 | 714 | INVALID_VOLUME_LABEL = 0xC0000086, |
| 1041 | ||
| 1042 | 715 | /// A mapped section could not be extended. |
| 1043 | 716 | SECTION_NOT_EXTENDED = 0xC0000087, |
| 1044 | ||
| 1045 | 717 | /// Specified section to flush does not map a data file. |
| 1046 | 718 | NOT_MAPPED_DATA = 0xC0000088, |
| 1047 | ||
| 1048 | 719 | /// Indicates the specified image file did not contain a resource section. |
| 1049 | 720 | RESOURCE_DATA_NOT_FOUND = 0xC0000089, |
| 1050 | ||
| 1051 | 721 | /// Indicates the specified resource type cannot be found in the image file. |
| 1052 | 722 | RESOURCE_TYPE_NOT_FOUND = 0xC000008A, |
| 1053 | ||
| 1054 | 723 | /// Indicates the specified resource name cannot be found in the image file. |
| 1055 | 724 | RESOURCE_NAME_NOT_FOUND = 0xC000008B, |
| 1056 | ||
| 1057 | 725 | /// {EXCEPTION} Array bounds exceeded. |
| 1058 | 726 | ARRAY_BOUNDS_EXCEEDED = 0xC000008C, |
| 1059 | ||
| 1060 | 727 | /// {EXCEPTION} Floating-point denormal operand. |
| 1061 | 728 | FLOAT_DENORMAL_OPERAND = 0xC000008D, |
| 1062 | ||
| 1063 | 729 | /// {EXCEPTION} Floating-point division by zero. |
| 1064 | 730 | FLOAT_DIVIDE_BY_ZERO = 0xC000008E, |
| 1065 | ||
| 1066 | 731 | /// {EXCEPTION} Floating-point inexact result. |
| 1067 | 732 | FLOAT_INEXACT_RESULT = 0xC000008F, |
| 1068 | ||
| 1069 | 733 | /// {EXCEPTION} Floating-point invalid operation. |
| 1070 | 734 | FLOAT_INVALID_OPERATION = 0xC0000090, |
| 1071 | ||
| 1072 | 735 | /// {EXCEPTION} Floating-point overflow. |
| 1073 | 736 | FLOAT_OVERFLOW = 0xC0000091, |
| 1074 | ||
| 1075 | 737 | /// {EXCEPTION} Floating-point stack check. |
| 1076 | 738 | FLOAT_STACK_CHECK = 0xC0000092, |
| 1077 | ||
| 1078 | 739 | /// {EXCEPTION} Floating-point underflow. |
| 1079 | 740 | FLOAT_UNDERFLOW = 0xC0000093, |
| 1080 | ||
| 1081 | 741 | /// {EXCEPTION} Integer division by zero. |
| 1082 | 742 | INTEGER_DIVIDE_BY_ZERO = 0xC0000094, |
| 1083 | ||
| 1084 | 743 | /// {EXCEPTION} Integer overflow. |
| 1085 | 744 | INTEGER_OVERFLOW = 0xC0000095, |
| 1086 | ||
| 1087 | 745 | /// {EXCEPTION} Privileged instruction. |
| 1088 | 746 | PRIVILEGED_INSTRUCTION = 0xC0000096, |
| 1089 | ||
| 1090 | 747 | /// An attempt was made to install more paging files than the system supports. |
| 1091 | 748 | TOO_MANY_PAGING_FILES = 0xC0000097, |
| 1092 | ||
| 1093 | 749 | /// The volume for a file has been externally altered such that the opened file is no longer valid. |
| 1094 | 750 | FILE_INVALID = 0xC0000098, |
| 1095 | ||
| 1096 | 751 | /// When a block of memory is allotted for future updates, such as the memory allocated to hold discretionary access control and primary group information, successive updates might exceed the amount of memory originally allotted. |
| 1097 | 752 | /// Because a quota might already have been charged to several processes that have handles to the object, it is not reasonable to alter the size of the allocated memory. |
| 1098 | 753 | /// Instead, a request that requires more memory than has been allotted must fail and the STATUS_ALLOTTED_SPACE_EXCEEDED error returned. |
| 1099 | 754 | ALLOTTED_SPACE_EXCEEDED = 0xC0000099, |
| 1100 | ||
| 1101 | 755 | /// Insufficient system resources exist to complete the API. |
| 1102 | 756 | INSUFFICIENT_RESOURCES = 0xC000009A, |
| 1103 | ||
| 1104 | 757 | /// An attempt has been made to open a DFS exit path control file. |
| 1105 | 758 | DFS_EXIT_PATH_FOUND = 0xC000009B, |
| 1106 | ||
| 1107 | 759 | /// There are bad blocks (sectors) on the hard disk. |
| 1108 | 760 | DEVICE_DATA_ERROR = 0xC000009C, |
| 1109 | ||
| 1110 | 761 | /// There is bad cabling, non-termination, or the controller is not able to obtain access to the hard disk. |
| 1111 | 762 | DEVICE_NOT_CONNECTED = 0xC000009D, |
| 1112 | ||
| 1113 | 763 | /// Virtual memory cannot be freed because the base address is not the base of the region and a region size of zero was specified. |
| 1114 | 764 | FREE_VM_NOT_AT_BASE = 0xC000009F, |
| 1115 | ||
| 1116 | 765 | /// An attempt was made to free virtual memory that is not allocated. |
| 1117 | 766 | MEMORY_NOT_ALLOCATED = 0xC00000A0, |
| 1118 | ||
| 1119 | 767 | /// The working set is not big enough to allow the requested pages to be locked. |
| 1120 | 768 | WORKING_SET_QUOTA = 0xC00000A1, |
| 1121 | ||
| 1122 | 769 | /// {Write Protect Error} The disk cannot be written to because it is write-protected. |
| 1123 | 770 | /// Remove the write protection from the volume %hs in drive %hs. |
| 1124 | 771 | MEDIA_WRITE_PROTECTED = 0xC00000A2, |
| 1125 | ||
| 1126 | 772 | /// {Drive Not Ready} The drive is not ready for use; its door might be open. |
| 1127 | 773 | /// Check drive %hs and make sure that a disk is inserted and that the drive door is closed. |
| 1128 | 774 | DEVICE_NOT_READY = 0xC00000A3, |
| 1129 | ||
| 1130 | 775 | /// The specified attributes are invalid or are incompatible with the attributes for the group as a whole. |
| 1131 | 776 | INVALID_GROUP_ATTRIBUTES = 0xC00000A4, |
| 1132 | ||
| 1133 | 777 | /// A specified impersonation level is invalid. |
| 1134 | 778 | /// Also used to indicate that a required impersonation level was not provided. |
| 1135 | 779 | BAD_IMPERSONATION_LEVEL = 0xC00000A5, |
| 1136 | ||
| 1137 | 780 | /// An attempt was made to open an anonymous-level token. Anonymous tokens cannot be opened. |
| 1138 | 781 | CANT_OPEN_ANONYMOUS = 0xC00000A6, |
| 1139 | ||
| 1140 | 782 | /// The validation information class requested was invalid. |
| 1141 | 783 | BAD_VALIDATION_CLASS = 0xC00000A7, |
| 1142 | ||
| 1143 | 784 | /// The type of a token object is inappropriate for its attempted use. |
| 1144 | 785 | BAD_TOKEN_TYPE = 0xC00000A8, |
| 1145 | ||
| 1146 | 786 | /// The type of a token object is inappropriate for its attempted use. |
| 1147 | 787 | BAD_MASTER_BOOT_RECORD = 0xC00000A9, |
| 1148 | ||
| 1149 | 788 | /// An attempt was made to execute an instruction at an unaligned address and the host system does not support unaligned instruction references. |
| 1150 | 789 | INSTRUCTION_MISALIGNMENT = 0xC00000AA, |
| 1151 | ||
| 1152 | 790 | /// The maximum named pipe instance count has been reached. |
| 1153 | 791 | INSTANCE_NOT_AVAILABLE = 0xC00000AB, |
| 1154 | ||
| 1155 | 792 | /// An instance of a named pipe cannot be found in the listening state. |
| 1156 | 793 | PIPE_NOT_AVAILABLE = 0xC00000AC, |
| 1157 | ||
| 1158 | 794 | /// The named pipe is not in the connected or closing state. |
| 1159 | 795 | INVALID_PIPE_STATE = 0xC00000AD, |
| 1160 | ||
| 1161 | 796 | /// The specified pipe is set to complete operations and there are current I/O operations queued so that it cannot be changed to queue operations. |
| 1162 | 797 | PIPE_BUSY = 0xC00000AE, |
| 1163 | ||
| 1164 | 798 | /// The specified handle is not open to the server end of the named pipe. |
| 1165 | 799 | ILLEGAL_FUNCTION = 0xC00000AF, |
| 1166 | ||
| 1167 | 800 | /// The specified named pipe is in the disconnected state. |
| 1168 | 801 | PIPE_DISCONNECTED = 0xC00000B0, |
| 1169 | ||
| 1170 | 802 | /// The specified named pipe is in the closing state. |
| 1171 | 803 | PIPE_CLOSING = 0xC00000B1, |
| 1172 | ||
| 1173 | 804 | /// The specified named pipe is in the connected state. |
| 1174 | 805 | PIPE_CONNECTED = 0xC00000B2, |
| 1175 | ||
| 1176 | 806 | /// The specified named pipe is in the listening state. |
| 1177 | 807 | PIPE_LISTENING = 0xC00000B3, |
| 1178 | ||
| 1179 | 808 | /// The specified named pipe is not in message mode. |
| 1180 | 809 | INVALID_READ_MODE = 0xC00000B4, |
| 1181 | ||
| 1182 | 810 | /// {Device Timeout} The specified I/O operation on %hs was not completed before the time-out period expired. |
| 1183 | 811 | IO_TIMEOUT = 0xC00000B5, |
| 1184 | ||
| 1185 | 812 | /// The specified file has been closed by another process. |
| 1186 | 813 | FILE_FORCED_CLOSED = 0xC00000B6, |
| 1187 | ||
| 1188 | 814 | /// Profiling is not started. |
| 1189 | 815 | PROFILING_NOT_STARTED = 0xC00000B7, |
| 1190 | ||
| 1191 | 816 | /// Profiling is not stopped. |
| 1192 | 817 | PROFILING_NOT_STOPPED = 0xC00000B8, |
| 1193 | ||
| 1194 | 818 | /// The passed ACL did not contain the minimum required information. |
| 1195 | 819 | COULD_NOT_INTERPRET = 0xC00000B9, |
| 1196 | ||
| 1197 | 820 | /// The file that was specified as a target is a directory, and the caller specified that it could be anything but a directory. |
| 1198 | 821 | FILE_IS_A_DIRECTORY = 0xC00000BA, |
| 1199 | ||
| 1200 | 822 | /// The request is not supported. |
| 1201 | 823 | NOT_SUPPORTED = 0xC00000BB, |
| 1202 | ||
| 1203 | 824 | /// This remote computer is not listening. |
| 1204 | 825 | REMOTE_NOT_LISTENING = 0xC00000BC, |
| 1205 | ||
| 1206 | 826 | /// A duplicate name exists on the network. |
| 1207 | 827 | DUPLICATE_NAME = 0xC00000BD, |
| 1208 | ||
| 1209 | 828 | /// The network path cannot be located. |
| 1210 | 829 | BAD_NETWORK_PATH = 0xC00000BE, |
| 1211 | ||
| 1212 | 830 | /// The network is busy. |
| 1213 | 831 | NETWORK_BUSY = 0xC00000BF, |
| 1214 | ||
| 1215 | 832 | /// This device does not exist. |
| 1216 | 833 | DEVICE_DOES_NOT_EXIST = 0xC00000C0, |
| 1217 | ||
| 1218 | 834 | /// The network BIOS command limit has been reached. |
| 1219 | 835 | TOO_MANY_COMMANDS = 0xC00000C1, |
| 1220 | ||
| 1221 | 836 | /// An I/O adapter hardware error has occurred. |
| 1222 | 837 | ADAPTER_HARDWARE_ERROR = 0xC00000C2, |
| 1223 | ||
| 1224 | 838 | /// The network responded incorrectly. |
| 1225 | 839 | INVALID_NETWORK_RESPONSE = 0xC00000C3, |
| 1226 | ||
| 1227 | 840 | /// An unexpected network error occurred. |
| 1228 | 841 | UNEXPECTED_NETWORK_ERROR = 0xC00000C4, |
| 1229 | ||
| 1230 | 842 | /// The remote adapter is not compatible. |
| 1231 | 843 | BAD_REMOTE_ADAPTER = 0xC00000C5, |
| 1232 | ||
| 1233 | 844 | /// The print queue is full. |
| 1234 | 845 | PRINT_QUEUE_FULL = 0xC00000C6, |
| 1235 | ||
| 1236 | 846 | /// Space to store the file that is waiting to be printed is not available on the server. |
| 1237 | 847 | NO_SPOOL_SPACE = 0xC00000C7, |
| 1238 | ||
| 1239 | 848 | /// The requested print file has been canceled. |
| 1240 | 849 | PRINT_CANCELLED = 0xC00000C8, |
| 1241 | ||
| 1242 | 850 | /// The network name was deleted. |
| 1243 | 851 | NETWORK_NAME_DELETED = 0xC00000C9, |
| 1244 | ||
| 1245 | 852 | /// Network access is denied. |
| 1246 | 853 | NETWORK_ACCESS_DENIED = 0xC00000CA, |
| 1247 | ||
| 1248 | 854 | /// {Incorrect Network Resource Type} The specified device type (LPT, for example) conflicts with the actual device type on the remote resource. |
| 1249 | 855 | BAD_DEVICE_TYPE = 0xC00000CB, |
| 1250 | ||
| 1251 | 856 | /// {Network Name Not Found} The specified share name cannot be found on the remote server. |
| 1252 | 857 | BAD_NETWORK_NAME = 0xC00000CC, |
| 1253 | ||
| 1254 | 858 | /// The name limit for the network adapter card of the local computer was exceeded. |
| 1255 | 859 | TOO_MANY_NAMES = 0xC00000CD, |
| 1256 | ||
| 1257 | 860 | /// The network BIOS session limit was exceeded. |
| 1258 | 861 | TOO_MANY_SESSIONS = 0xC00000CE, |
| 1259 | ||
| 1260 | 862 | /// File sharing has been temporarily paused. |
| 1261 | 863 | SHARING_PAUSED = 0xC00000CF, |
| 1262 | ||
| 1263 | 864 | /// No more connections can be made to this remote computer at this time because the computer has already accepted the maximum number of connections. |
| 1264 | 865 | REQUEST_NOT_ACCEPTED = 0xC00000D0, |
| 1265 | ||
| 1266 | 866 | /// Print or disk redirection is temporarily paused. |
| 1267 | 867 | REDIRECTOR_PAUSED = 0xC00000D1, |
| 1268 | ||
| 1269 | 868 | /// A network data fault occurred. |
| 1270 | 869 | NET_WRITE_FAULT = 0xC00000D2, |
| 1271 | ||
| 1272 | 870 | /// The number of active profiling objects is at the maximum and no more can be started. |
| 1273 | 871 | PROFILING_AT_LIMIT = 0xC00000D3, |
| 1274 | ||
| 1275 | 872 | /// {Incorrect Volume} The destination file of a rename request is located on a different device than the source of the rename request. |
| 1276 | 873 | NOT_SAME_DEVICE = 0xC00000D4, |
| 1277 | ||
| 1278 | 874 | /// The specified file has been renamed and thus cannot be modified. |
| 1279 | 875 | FILE_RENAMED = 0xC00000D5, |
| 1280 | ||
| 1281 | 876 | /// {Network Request Timeout} The session with a remote server has been disconnected because the time-out interval for a request has expired. |
| 1282 | 877 | VIRTUAL_CIRCUIT_CLOSED = 0xC00000D6, |
| 1283 | ||
| 1284 | 878 | /// Indicates an attempt was made to operate on the security of an object that does not have security associated with it. |
| 1285 | 879 | NO_SECURITY_ON_OBJECT = 0xC00000D7, |
| 1286 | ||
| 1287 | 880 | /// Used to indicate that an operation cannot continue without blocking for I/O. |
| 1288 | 881 | CANT_WAIT = 0xC00000D8, |
| 1289 | ||
| 1290 | 882 | /// Used to indicate that a read operation was done on an empty pipe. |
| 1291 | 883 | PIPE_EMPTY = 0xC00000D9, |
| 1292 | ||
| 1293 | 884 | /// Configuration information could not be read from the domain controller, either because the machine is unavailable or access has been denied. |
| 1294 | 885 | CANT_ACCESS_DOMAIN_INFO = 0xC00000DA, |
| 1295 | ||
| 1296 | 886 | /// Indicates that a thread attempted to terminate itself by default (called NtTerminateThread with NULL) and it was the last thread in the current process. |
| 1297 | 887 | CANT_TERMINATE_SELF = 0xC00000DB, |
| 1298 | ||
| 1299 | 888 | /// Indicates the Sam Server was in the wrong state to perform the desired operation. |
| 1300 | 889 | INVALID_SERVER_STATE = 0xC00000DC, |
| 1301 | ||
| 1302 | 890 | /// Indicates the domain was in the wrong state to perform the desired operation. |
| 1303 | 891 | INVALID_DOMAIN_STATE = 0xC00000DD, |
| 1304 | ||
| 1305 | 892 | /// This operation is only allowed for the primary domain controller of the domain. |
| 1306 | 893 | INVALID_DOMAIN_ROLE = 0xC00000DE, |
| 1307 | ||
| 1308 | 894 | /// The specified domain did not exist. |
| 1309 | 895 | NO_SUCH_DOMAIN = 0xC00000DF, |
| 1310 | ||
| 1311 | 896 | /// The specified domain already exists. |
| 1312 | 897 | DOMAIN_EXISTS = 0xC00000E0, |
| 1313 | ||
| 1314 | 898 | /// An attempt was made to exceed the limit on the number of domains per server for this release. |
| 1315 | 899 | DOMAIN_LIMIT_EXCEEDED = 0xC00000E1, |
| 1316 | ||
| 1317 | 900 | /// An error status returned when the opportunistic lock (oplock) request is denied. |
| 1318 | 901 | OPLOCK_NOT_GRANTED = 0xC00000E2, |
| 1319 | ||
| 1320 | 902 | /// An error status returned when an invalid opportunistic lock (oplock) acknowledgment is received by a file system. |
| 1321 | 903 | INVALID_OPLOCK_PROTOCOL = 0xC00000E3, |
| 1322 | ||
| 1323 | 904 | /// This error indicates that the requested operation cannot be completed due to a catastrophic media failure or an on-disk data structure corruption. |
| 1324 | 905 | INTERNAL_DB_CORRUPTION = 0xC00000E4, |
| 1325 | ||
| 1326 | 906 | /// An internal error occurred. |
| 1327 | 907 | INTERNAL_ERROR = 0xC00000E5, |
| 1328 | ||
| 1329 | 908 | /// Indicates generic access types were contained in an access mask which should already be mapped to non-generic access types. |
| 1330 | 909 | GENERIC_NOT_MAPPED = 0xC00000E6, |
| 1331 | ||
| 1332 | 910 | /// Indicates a security descriptor is not in the necessary format (absolute or self-relative). |
| 1333 | 911 | BAD_DESCRIPTOR_FORMAT = 0xC00000E7, |
| 1334 | ||
| 1335 | 912 | /// An access to a user buffer failed at an expected point in time. |
| 1336 | 913 | /// This code is defined because the caller does not want to accept STATUS_ACCESS_VIOLATION in its filter. |
| 1337 | 914 | INVALID_USER_BUFFER = 0xC00000E8, |
| 1338 | ||
| 1339 | 915 | /// If an I/O error that is not defined in the standard FsRtl filter is returned, it is converted to the following error, which is guaranteed to be in the filter. |
| 1340 | 916 | /// In this case, information is lost; however, the filter correctly handles the exception. |
| 1341 | 917 | UNEXPECTED_IO_ERROR = 0xC00000E9, |
| 1342 | ||
| 1343 | 918 | /// If an MM error that is not defined in the standard FsRtl filter is returned, it is converted to one of the following errors, which are guaranteed to be in the filter. |
| 1344 | 919 | /// In this case, information is lost; however, the filter correctly handles the exception. |
| 1345 | 920 | UNEXPECTED_MM_CREATE_ERR = 0xC00000EA, |
| 1346 | ||
| 1347 | 921 | /// If an MM error that is not defined in the standard FsRtl filter is returned, it is converted to one of the following errors, which are guaranteed to be in the filter. |
| 1348 | 922 | /// In this case, information is lost; however, the filter correctly handles the exception. |
| 1349 | 923 | UNEXPECTED_MM_MAP_ERROR = 0xC00000EB, |
| 1350 | ||
| 1351 | 924 | /// If an MM error that is not defined in the standard FsRtl filter is returned, it is converted to one of the following errors, which are guaranteed to be in the filter. |
| 1352 | 925 | /// In this case, information is lost; however, the filter correctly handles the exception. |
| 1353 | 926 | UNEXPECTED_MM_EXTEND_ERR = 0xC00000EC, |
| 1354 | ||
| 1355 | 927 | /// The requested action is restricted for use by logon processes only. |
| 1356 | 928 | /// The calling process has not registered as a logon process. |
| 1357 | 929 | NOT_LOGON_PROCESS = 0xC00000ED, |
| 1358 | ||
| 1359 | 930 | /// An attempt has been made to start a new session manager or LSA logon session by using an ID that is already in use. |
| 1360 | 931 | LOGON_SESSION_EXISTS = 0xC00000EE, |
| 1361 | ||
| 1362 | 932 | /// An invalid parameter was passed to a service or function as the first argument. |
| 1363 | 933 | INVALID_PARAMETER_1 = 0xC00000EF, |
| 1364 | ||
| 1365 | 934 | /// An invalid parameter was passed to a service or function as the second argument. |
| 1366 | 935 | INVALID_PARAMETER_2 = 0xC00000F0, |
| 1367 | ||
| 1368 | 936 | /// An invalid parameter was passed to a service or function as the third argument. |
| 1369 | 937 | INVALID_PARAMETER_3 = 0xC00000F1, |
| 1370 | ||
| 1371 | 938 | /// An invalid parameter was passed to a service or function as the fourth argument. |
| 1372 | 939 | INVALID_PARAMETER_4 = 0xC00000F2, |
| 1373 | ||
| 1374 | 940 | /// An invalid parameter was passed to a service or function as the fifth argument. |
| 1375 | 941 | INVALID_PARAMETER_5 = 0xC00000F3, |
| 1376 | ||
| 1377 | 942 | /// An invalid parameter was passed to a service or function as the sixth argument. |
| 1378 | 943 | INVALID_PARAMETER_6 = 0xC00000F4, |
| 1379 | ||
| 1380 | 944 | /// An invalid parameter was passed to a service or function as the seventh argument. |
| 1381 | 945 | INVALID_PARAMETER_7 = 0xC00000F5, |
| 1382 | ||
| 1383 | 946 | /// An invalid parameter was passed to a service or function as the eighth argument. |
| 1384 | 947 | INVALID_PARAMETER_8 = 0xC00000F6, |
| 1385 | ||
| 1386 | 948 | /// An invalid parameter was passed to a service or function as the ninth argument. |
| 1387 | 949 | INVALID_PARAMETER_9 = 0xC00000F7, |
| 1388 | ||
| 1389 | 950 | /// An invalid parameter was passed to a service or function as the tenth argument. |
| 1390 | 951 | INVALID_PARAMETER_10 = 0xC00000F8, |
| 1391 | ||
| 1392 | 952 | /// An invalid parameter was passed to a service or function as the eleventh argument. |
| 1393 | 953 | INVALID_PARAMETER_11 = 0xC00000F9, |
| 1394 | ||
| 1395 | 954 | /// An invalid parameter was passed to a service or function as the twelfth argument. |
| 1396 | 955 | INVALID_PARAMETER_12 = 0xC00000FA, |
| 1397 | ||
| 1398 | 956 | /// An attempt was made to access a network file, but the network software was not yet started. |
| 1399 | 957 | REDIRECTOR_NOT_STARTED = 0xC00000FB, |
| 1400 | ||
| 1401 | 958 | /// An attempt was made to start the redirector, but the redirector has already been started. |
| 1402 | 959 | REDIRECTOR_STARTED = 0xC00000FC, |
| 1403 | ||
| 1404 | 960 | /// A new guard page for the stack cannot be created. |
| 1405 | 961 | STACK_OVERFLOW = 0xC00000FD, |
| 1406 | ||
| 1407 | 962 | /// A specified authentication package is unknown. |
| 1408 | 963 | NO_SUCH_PACKAGE = 0xC00000FE, |
| 1409 | ||
| 1410 | 964 | /// A malformed function table was encountered during an unwind operation. |
| 1411 | 965 | BAD_FUNCTION_TABLE = 0xC00000FF, |
| 1412 | ||
| 1413 | 966 | /// Indicates the specified environment variable name was not found in the specified environment block. |
| 1414 | 967 | VARIABLE_NOT_FOUND = 0xC0000100, |
| 1415 | ||
| 1416 | 968 | /// Indicates that the directory trying to be deleted is not empty. |
| 1417 | 969 | DIRECTORY_NOT_EMPTY = 0xC0000101, |
| 1418 | ||
| 1419 | 970 | /// {Corrupt File} The file or directory %hs is corrupt and unreadable. Run the Chkdsk utility. |
| 1420 | 971 | FILE_CORRUPT_ERROR = 0xC0000102, |
| 1421 | ||
| 1422 | 972 | /// A requested opened file is not a directory. |
| 1423 | 973 | NOT_A_DIRECTORY = 0xC0000103, |
| 1424 | ||
| 1425 | 974 | /// The logon session is not in a state that is consistent with the requested operation. |
| 1426 | 975 | BAD_LOGON_SESSION_STATE = 0xC0000104, |
| 1427 | ||
| 1428 | 976 | /// An internal LSA error has occurred. |
| 1429 | 977 | /// An authentication package has requested the creation of a logon session but the ID of an already existing logon session has been specified. |
| 1430 | 978 | LOGON_SESSION_COLLISION = 0xC0000105, |
| 1431 | ||
| 1432 | 979 | /// A specified name string is too long for its intended use. |
| 1433 | 980 | NAME_TOO_LONG = 0xC0000106, |
| 1434 | ||
| 1435 | 981 | /// The user attempted to force close the files on a redirected drive, but there were opened files on the drive, and the user did not specify a sufficient level of force. |
| 1436 | 982 | FILES_OPEN = 0xC0000107, |
| 1437 | ||
| 1438 | 983 | /// The user attempted to force close the files on a redirected drive, but there were opened directories on the drive, and the user did not specify a sufficient level of force. |
| 1439 | 984 | CONNECTION_IN_USE = 0xC0000108, |
| 1440 | ||
| 1441 | 985 | /// RtlFindMessage could not locate the requested message ID in the message table resource. |
| 1442 | 986 | MESSAGE_NOT_FOUND = 0xC0000109, |
| 1443 | ||
| 1444 | 987 | /// An attempt was made to duplicate an object handle into or out of an exiting process. |
| 1445 | 988 | PROCESS_IS_TERMINATING = 0xC000010A, |
| 1446 | ||
| 1447 | 989 | /// Indicates an invalid value has been provided for the LogonType requested. |
| 1448 | 990 | INVALID_LOGON_TYPE = 0xC000010B, |
| 1449 | ||
| 1450 | 991 | /// Indicates that an attempt was made to assign protection to a file system file or directory and one of the SIDs in the security descriptor could not be translated into a GUID that could be stored by the file system. |
| 1451 | 992 | /// This causes the protection attempt to fail, which might cause a file creation attempt to fail. |
| 1452 | 993 | NO_GUID_TRANSLATION = 0xC000010C, |
| 1453 | ||
| 1454 | 994 | /// Indicates that an attempt has been made to impersonate via a named pipe that has not yet been read from. |
| 1455 | 995 | CANNOT_IMPERSONATE = 0xC000010D, |
| 1456 | ||
| 1457 | 996 | /// Indicates that the specified image is already loaded. |
| 1458 | 997 | IMAGE_ALREADY_LOADED = 0xC000010E, |
| 1459 | ||
| 1460 | 998 | /// Indicates that an attempt was made to change the size of the LDT for a process that has no LDT. |
| 1461 | 999 | NO_LDT = 0xC0000117, |
| 1462 | ||
| 1463 | 1000 | /// Indicates that an attempt was made to grow an LDT by setting its size, or that the size was not an even number of selectors. |
| 1464 | 1001 | INVALID_LDT_SIZE = 0xC0000118, |
| 1465 | ||
| 1466 | 1002 | /// Indicates that the starting value for the LDT information was not an integral multiple of the selector size. |
| 1467 | 1003 | INVALID_LDT_OFFSET = 0xC0000119, |
| 1468 | ||
| 1469 | 1004 | /// Indicates that the user supplied an invalid descriptor when trying to set up LDT descriptors. |
| 1470 | 1005 | INVALID_LDT_DESCRIPTOR = 0xC000011A, |
| 1471 | ||
| 1472 | 1006 | /// The specified image file did not have the correct format. It appears to be NE format. |
| 1473 | 1007 | INVALID_IMAGE_NE_FORMAT = 0xC000011B, |
| 1474 | ||
| 1475 | 1008 | /// Indicates that the transaction state of a registry subtree is incompatible with the requested operation. |
| 1476 | 1009 | /// For example, a request has been made to start a new transaction with one already in progress, or a request has been made to apply a transaction when one is not currently in progress. |
| 1477 | 1010 | RXACT_INVALID_STATE = 0xC000011C, |
| 1478 | ||
| 1479 | 1011 | /// Indicates an error has occurred during a registry transaction commit. |
| 1480 | 1012 | /// The database has been left in an unknown, but probably inconsistent, state. |
| 1481 | 1013 | /// The state of the registry transaction is left as COMMITTING. |
| 1482 | 1014 | RXACT_COMMIT_FAILURE = 0xC000011D, |
| 1483 | ||
| 1484 | 1015 | /// An attempt was made to map a file of size zero with the maximum size specified as zero. |
| 1485 | 1016 | MAPPED_FILE_SIZE_ZERO = 0xC000011E, |
| 1486 | ||
| 1487 | 1017 | /// Too many files are opened on a remote server. |
| 1488 | 1018 | /// This error should only be returned by the Windows redirector on a remote drive. |
| 1489 | 1019 | TOO_MANY_OPENED_FILES = 0xC000011F, |
| 1490 | ||
| 1491 | 1020 | /// The I/O request was canceled. |
| 1492 | 1021 | CANCELLED = 0xC0000120, |
| 1493 | ||
| 1494 | 1022 | /// An attempt has been made to remove a file or directory that cannot be deleted. |
| 1495 | 1023 | CANNOT_DELETE = 0xC0000121, |
| 1496 | ||
| 1497 | 1024 | /// Indicates a name that was specified as a remote computer name is syntactically invalid. |
| 1498 | 1025 | INVALID_COMPUTER_NAME = 0xC0000122, |
| 1499 | ||
| 1500 | 1026 | /// An I/O request other than close was performed on a file after it was deleted, which can only happen to a request that did not complete before the last handle was closed via NtClose. |
| 1501 | 1027 | FILE_DELETED = 0xC0000123, |
| 1502 | ||
| 1503 | 1028 | /// Indicates an operation that is incompatible with built-in accounts has been attempted on a built-in (special) SAM account. For example, built-in accounts cannot be deleted. |
| 1504 | 1029 | SPECIAL_ACCOUNT = 0xC0000124, |
| 1505 | ||
| 1506 | 1030 | /// The operation requested cannot be performed on the specified group because it is a built-in special group. |
| 1507 | 1031 | SPECIAL_GROUP = 0xC0000125, |
| 1508 | ||
| 1509 | 1032 | /// The operation requested cannot be performed on the specified user because it is a built-in special user. |
| 1510 | 1033 | SPECIAL_USER = 0xC0000126, |
| 1511 | ||
| 1512 | 1034 | /// Indicates a member cannot be removed from a group because the group is currently the member's primary group. |
| 1513 | 1035 | MEMBERS_PRIMARY_GROUP = 0xC0000127, |
| 1514 | ||
| 1515 | 1036 | /// An I/O request other than close and several other special case operations was attempted using a file object that had already been closed. |
| 1516 | 1037 | FILE_CLOSED = 0xC0000128, |
| 1517 | ||
| 1518 | 1038 | /// Indicates a process has too many threads to perform the requested action. |
| 1519 | 1039 | /// For example, assignment of a primary token can be performed only when a process has zero or one threads. |
| 1520 | 1040 | TOO_MANY_THREADS = 0xC0000129, |
| 1521 | ||
| 1522 | 1041 | /// An attempt was made to operate on a thread within a specific process, but the specified thread is not in the specified process. |
| 1523 | 1042 | THREAD_NOT_IN_PROCESS = 0xC000012A, |
| 1524 | ||
| 1525 | 1043 | /// An attempt was made to establish a token for use as a primary token but the token is already in use. |
| 1526 | 1044 | /// A token can only be the primary token of one process at a time. |
| 1527 | 1045 | TOKEN_ALREADY_IN_USE = 0xC000012B, |
| 1528 | ||
| 1529 | 1046 | /// The page file quota was exceeded. |
| 1530 | 1047 | PAGEFILE_QUOTA_EXCEEDED = 0xC000012C, |
| 1531 | ||
| 1532 | 1048 | /// {Out of Virtual Memory} Your system is low on virtual memory. |
| 1533 | 1049 | /// To ensure that Windows runs correctly, increase the size of your virtual memory paging file. For more information, see Help. |
| 1534 | 1050 | COMMITMENT_LIMIT = 0xC000012D, |
| 1535 | ||
| 1536 | 1051 | /// The specified image file did not have the correct format: it appears to be LE format. |
| 1537 | 1052 | INVALID_IMAGE_LE_FORMAT = 0xC000012E, |
| 1538 | ||
| 1539 | 1053 | /// The specified image file did not have the correct format: it did not have an initial MZ. |
| 1540 | 1054 | INVALID_IMAGE_NOT_MZ = 0xC000012F, |
| 1541 | ||
| 1542 | 1055 | /// The specified image file did not have the correct format: it did not have a proper e_lfarlc in the MZ header. |
| 1543 | 1056 | INVALID_IMAGE_PROTECT = 0xC0000130, |
| 1544 | ||
| 1545 | 1057 | /// The specified image file did not have the correct format: it appears to be a 16-bit Windows image. |
| 1546 | 1058 | INVALID_IMAGE_WIN_16 = 0xC0000131, |
| 1547 | ||
| 1548 | 1059 | /// The Netlogon service cannot start because another Netlogon service running in the domain conflicts with the specified role. |
| 1549 | 1060 | LOGON_SERVER_CONFLICT = 0xC0000132, |
| 1550 | ||
| 1551 | 1061 | /// The time at the primary domain controller is different from the time at the backup domain controller or member server by too large an amount. |
| 1552 | 1062 | TIME_DIFFERENCE_AT_DC = 0xC0000133, |
| 1553 | ||
| 1554 | 1063 | /// On applicable Windows Server releases, the SAM database is significantly out of synchronization with the copy on the domain controller. A complete synchronization is required. |
| 1555 | 1064 | SYNCHRONIZATION_REQUIRED = 0xC0000134, |
| 1556 | ||
| 1557 | 1065 | /// {Unable To Locate Component} This application has failed to start because %hs was not found. |
| 1558 | 1066 | /// Reinstalling the application might fix this problem. |
| 1559 | 1067 | DLL_NOT_FOUND = 0xC0000135, |
| 1560 | ||
| 1561 | 1068 | /// The NtCreateFile API failed. This error should never be returned to an application; it is a place holder for the Windows LAN Manager Redirector to use in its internal error-mapping routines. |
| 1562 | 1069 | OPEN_FAILED = 0xC0000136, |
| 1563 | ||
| 1564 | 1070 | /// {Privilege Failed} The I/O permissions for the process could not be changed. |
| 1565 | 1071 | IO_PRIVILEGE_FAILED = 0xC0000137, |
| 1566 | ||
| 1567 | 1072 | /// {Ordinal Not Found} The ordinal %ld could not be located in the dynamic link library %hs. |
| 1568 | 1073 | ORDINAL_NOT_FOUND = 0xC0000138, |
| 1569 | ||
| 1570 | 1074 | /// {Entry Point Not Found} The procedure entry point %hs could not be located in the dynamic link library %hs. |
| 1571 | 1075 | ENTRYPOINT_NOT_FOUND = 0xC0000139, |
| 1572 | ||
| 1573 | 1076 | /// {Application Exit by CTRL+C} The application terminated as a result of a CTRL+C. |
| 1574 | 1077 | CONTROL_C_EXIT = 0xC000013A, |
| 1575 | ||
| 1576 | 1078 | /// {Virtual Circuit Closed} The network transport on your computer has closed a network connection. |
| 1577 | 1079 | /// There might or might not be I/O requests outstanding. |
| 1578 | 1080 | LOCAL_DISCONNECT = 0xC000013B, |
| 1579 | ||
| 1580 | 1081 | /// {Virtual Circuit Closed} The network transport on a remote computer has closed a network connection. |
| 1581 | 1082 | /// There might or might not be I/O requests outstanding. |
| 1582 | 1083 | REMOTE_DISCONNECT = 0xC000013C, |
| 1583 | ||
| 1584 | 1084 | /// {Insufficient Resources on Remote Computer} The remote computer has insufficient resources to complete the network request. |
| 1585 | 1085 | /// For example, the remote computer might not have enough available memory to carry out the request at this time. |
| 1586 | 1086 | REMOTE_RESOURCES = 0xC000013D, |
| 1587 | ||
| 1588 | 1087 | /// {Virtual Circuit Closed} An existing connection (virtual circuit) has been broken at the remote computer. |
| 1589 | 1088 | /// There is probably something wrong with the network software protocol or the network hardware on the remote computer. |
| 1590 | 1089 | LINK_FAILED = 0xC000013E, |
| 1591 | ||
| 1592 | 1090 | /// {Virtual Circuit Closed} The network transport on your computer has closed a network connection because it had to wait too long for a response from the remote computer. |
| 1593 | 1091 | LINK_TIMEOUT = 0xC000013F, |
| 1594 | ||
| 1595 | 1092 | /// The connection handle that was given to the transport was invalid. |
| 1596 | 1093 | INVALID_CONNECTION = 0xC0000140, |
| 1597 | ||
| 1598 | 1094 | /// The address handle that was given to the transport was invalid. |
| 1599 | 1095 | INVALID_ADDRESS = 0xC0000141, |
| 1600 | ||
| 1601 | 1096 | /// {DLL Initialization Failed} Initialization of the dynamic link library %hs failed. The process is terminating abnormally. |
| 1602 | 1097 | DLL_INIT_FAILED = 0xC0000142, |
| 1603 | ||
| 1604 | 1098 | /// {Missing System File} The required system file %hs is bad or missing. |
| 1605 | 1099 | MISSING_SYSTEMFILE = 0xC0000143, |
| 1606 | ||
| 1607 | 1100 | /// {Application Error} The exception %s (0x%08lx) occurred in the application at location 0x%08lx. |
| 1608 | 1101 | UNHANDLED_EXCEPTION = 0xC0000144, |
| 1609 | ||
| 1610 | 1102 | /// {Application Error} The application failed to initialize properly (0x%lx). Click OK to terminate the application. |
| 1611 | 1103 | APP_INIT_FAILURE = 0xC0000145, |
| 1612 | ||
| 1613 | 1104 | /// {Unable to Create Paging File} The creation of the paging file %hs failed (%lx). The requested size was %ld. |
| 1614 | 1105 | PAGEFILE_CREATE_FAILED = 0xC0000146, |
| 1615 | ||
| 1616 | 1106 | /// {No Paging File Specified} No paging file was specified in the system configuration. |
| 1617 | 1107 | NO_PAGEFILE = 0xC0000147, |
| 1618 | ||
| 1619 | 1108 | /// {Incorrect System Call Level} An invalid level was passed into the specified system call. |
| 1620 | 1109 | INVALID_LEVEL = 0xC0000148, |
| 1621 | ||
| 1622 | 1110 | /// {Incorrect Password to LAN Manager Server} You specified an incorrect password to a LAN Manager 2.x or MS-NET server. |
| 1623 | 1111 | WRONG_PASSWORD_CORE = 0xC0000149, |
| 1624 | ||
| 1625 | 1112 | /// {EXCEPTION} A real-mode application issued a floating-point instruction and floating-point hardware is not present. |
| 1626 | 1113 | ILLEGAL_FLOAT_CONTEXT = 0xC000014A, |
| 1627 | ||
| 1628 | 1114 | /// The pipe operation has failed because the other end of the pipe has been closed. |
| 1629 | 1115 | PIPE_BROKEN = 0xC000014B, |
| 1630 | ||
| 1631 | 1116 | /// {The Registry Is Corrupt} The structure of one of the files that contains registry data is corrupt; the image of the file in memory is corrupt; or the file could not be recovered because the alternate copy or log was absent or corrupt. |
| 1632 | 1117 | REGISTRY_CORRUPT = 0xC000014C, |
| 1633 | ||
| 1634 | 1118 | /// An I/O operation initiated by the Registry failed and cannot be recovered. |
| 1635 | 1119 | /// The registry could not read in, write out, or flush one of the files that contain the system's image of the registry. |
| 1636 | 1120 | REGISTRY_IO_FAILED = 0xC000014D, |
| 1637 | ||
| 1638 | 1121 | /// An event pair synchronization operation was performed using the thread-specific client/server event pair object, but no event pair object was associated with the thread. |
| 1639 | 1122 | NO_EVENT_PAIR = 0xC000014E, |
| 1640 | ||
| 1641 | 1123 | /// The volume does not contain a recognized file system. |
| 1642 | 1124 | /// Be sure that all required file system drivers are loaded and that the volume is not corrupt. |
| 1643 | 1125 | UNRECOGNIZED_VOLUME = 0xC000014F, |
| 1644 | ||
| 1645 | 1126 | /// No serial device was successfully initialized. The serial driver will unload. |
| 1646 | 1127 | SERIAL_NO_DEVICE_INITED = 0xC0000150, |
| 1647 | ||
| 1648 | 1128 | /// The specified local group does not exist. |
| 1649 | 1129 | NO_SUCH_ALIAS = 0xC0000151, |
| 1650 | ||
| 1651 | 1130 | /// The specified account name is not a member of the group. |
| 1652 | 1131 | MEMBER_NOT_IN_ALIAS = 0xC0000152, |
| 1653 | ||
| 1654 | 1132 | /// The specified account name is already a member of the group. |
| 1655 | 1133 | MEMBER_IN_ALIAS = 0xC0000153, |
| 1656 | ||
| 1657 | 1134 | /// The specified local group already exists. |
| 1658 | 1135 | ALIAS_EXISTS = 0xC0000154, |
| 1659 | ||
| 1660 | 1136 | /// A requested type of logon (for example, interactive, network, and service) is not granted by the local security policy of the target system. |
| 1661 | 1137 | /// Ask the system administrator to grant the necessary form of logon. |
| 1662 | 1138 | LOGON_NOT_GRANTED = 0xC0000155, |
| 1663 | ||
| 1664 | 1139 | /// The maximum number of secrets that can be stored in a single system was exceeded. |
| 1665 | 1140 | /// The length and number of secrets is limited to satisfy U.S. State Department export restrictions. |
| 1666 | 1141 | TOO_MANY_SECRETS = 0xC0000156, |
| 1667 | ||
| 1668 | 1142 | /// The length of a secret exceeds the maximum allowable length. |
| 1669 | 1143 | /// The length and number of secrets is limited to satisfy U.S. State Department export restrictions. |
| 1670 | 1144 | SECRET_TOO_LONG = 0xC0000157, |
| 1671 | ||
| 1672 | 1145 | /// The local security authority (LSA) database contains an internal inconsistency. |
| 1673 | 1146 | INTERNAL_DB_ERROR = 0xC0000158, |
| 1674 | ||
| 1675 | 1147 | /// The requested operation cannot be performed in full-screen mode. |
| 1676 | 1148 | FULLSCREEN_MODE = 0xC0000159, |
| 1677 | ||
| 1678 | 1149 | /// During a logon attempt, the user's security context accumulated too many security IDs. This is a very unusual situation. |
| 1679 | 1150 | /// Remove the user from some global or local groups to reduce the number of security IDs to incorporate into the security context. |
| 1680 | 1151 | TOO_MANY_CONTEXT_IDS = 0xC000015A, |
| 1681 | ||
| 1682 | 1152 | /// A user has requested a type of logon (for example, interactive or network) that has not been granted. |
| 1683 | 1153 | /// An administrator has control over who can logon interactively and through the network. |
| 1684 | 1154 | LOGON_TYPE_NOT_GRANTED = 0xC000015B, |
| 1685 | ||
| 1686 | 1155 | /// The system has attempted to load or restore a file into the registry, and the specified file is not in the format of a registry file. |
| 1687 | 1156 | NOT_REGISTRY_FILE = 0xC000015C, |
| 1688 | ||
| 1689 | 1157 | /// An attempt was made to change a user password in the security account manager without providing the necessary Windows cross-encrypted password. |
| 1690 | 1158 | NT_CROSS_ENCRYPTION_REQUIRED = 0xC000015D, |
| 1691 | ||
| 1692 | 1159 | /// A domain server has an incorrect configuration. |
| 1693 | 1160 | DOMAIN_CTRLR_CONFIG_ERROR = 0xC000015E, |
| 1694 | ||
| 1695 | 1161 | /// An attempt was made to explicitly access the secondary copy of information via a device control to the fault tolerance driver and the secondary copy is not present in the system. |
| 1696 | 1162 | FT_MISSING_MEMBER = 0xC000015F, |
| 1697 | ||
| 1698 | 1163 | /// A configuration registry node that represents a driver service entry was ill-formed and did not contain the required value entries. |
| 1699 | 1164 | ILL_FORMED_SERVICE_ENTRY = 0xC0000160, |
| 1700 | ||
| 1701 | 1165 | /// An illegal character was encountered. |
| 1702 | 1166 | /// For a multibyte character set, this includes a lead byte without a succeeding trail byte. |
| 1703 | 1167 | /// For the Unicode character set this includes the characters 0xFFFF and 0xFFFE. |
| 1704 | 1168 | ILLEGAL_CHARACTER = 0xC0000161, |
| 1705 | ||
| 1706 | 1169 | /// No mapping for the Unicode character exists in the target multibyte code page. |
| 1707 | 1170 | UNMAPPABLE_CHARACTER = 0xC0000162, |
| 1708 | ||
| 1709 | 1171 | /// The Unicode character is not defined in the Unicode character set that is installed on the system. |
| 1710 | 1172 | UNDEFINED_CHARACTER = 0xC0000163, |
| 1711 | ||
| 1712 | 1173 | /// The paging file cannot be created on a floppy disk. |
| 1713 | 1174 | FLOPPY_VOLUME = 0xC0000164, |
| 1714 | ||
| 1715 | 1175 | /// {Floppy Disk Error} While accessing a floppy disk, an ID address mark was not found. |
| 1716 | 1176 | FLOPPY_ID_MARK_NOT_FOUND = 0xC0000165, |
| 1717 | ||
| 1718 | 1177 | /// {Floppy Disk Error} While accessing a floppy disk, the track address from the sector ID field was found to be different from the track address that is maintained by the controller. |
| 1719 | 1178 | FLOPPY_WRONG_CYLINDER = 0xC0000166, |
| 1720 | ||
| 1721 | 1179 | /// {Floppy Disk Error} The floppy disk controller reported an error that is not recognized by the floppy disk driver. |
| 1722 | 1180 | FLOPPY_UNKNOWN_ERROR = 0xC0000167, |
| 1723 | ||
| 1724 | 1181 | /// {Floppy Disk Error} While accessing a floppy-disk, the controller returned inconsistent results via its registers. |
| 1725 | 1182 | FLOPPY_BAD_REGISTERS = 0xC0000168, |
| 1726 | ||
| 1727 | 1183 | /// {Hard Disk Error} While accessing the hard disk, a recalibrate operation failed, even after retries. |
| 1728 | 1184 | DISK_RECALIBRATE_FAILED = 0xC0000169, |
| 1729 | ||
| 1730 | 1185 | /// {Hard Disk Error} While accessing the hard disk, a disk operation failed even after retries. |
| 1731 | 1186 | DISK_OPERATION_FAILED = 0xC000016A, |
| 1732 | ||
| 1733 | 1187 | /// {Hard Disk Error} While accessing the hard disk, a disk controller reset was needed, but even that failed. |
| 1734 | 1188 | DISK_RESET_FAILED = 0xC000016B, |
| 1735 | ||
| 1736 | 1189 | /// An attempt was made to open a device that was sharing an interrupt request (IRQ) with other devices. |
| 1737 | 1190 | /// At least one other device that uses that IRQ was already opened. |
| 1738 | 1191 | /// Two concurrent opens of devices that share an IRQ and only work via interrupts is not supported for the particular bus type that the devices use. |
| 1739 | 1192 | SHARED_IRQ_BUSY = 0xC000016C, |
| 1740 | ||
| 1741 | 1193 | /// {FT Orphaning} A disk that is part of a fault-tolerant volume can no longer be accessed. |
| 1742 | 1194 | FT_ORPHANING = 0xC000016D, |
| 1743 | ||
| 1744 | 1195 | /// The basic input/output system (BIOS) failed to connect a system interrupt to the device or bus for which the device is connected. |
| 1745 | 1196 | BIOS_FAILED_TO_CONNECT_INTERRUPT = 0xC000016E, |
| 1746 | ||
| 1747 | 1197 | /// The tape could not be partitioned. |
| 1748 | 1198 | PARTITION_FAILURE = 0xC0000172, |
| 1749 | ||
| 1750 | 1199 | /// When accessing a new tape of a multi-volume partition, the current blocksize is incorrect. |
| 1751 | 1200 | INVALID_BLOCK_LENGTH = 0xC0000173, |
| 1752 | ||
| 1753 | 1201 | /// The tape partition information could not be found when loading a tape. |
| 1754 | 1202 | DEVICE_NOT_PARTITIONED = 0xC0000174, |
| 1755 | ||
| 1756 | 1203 | /// An attempt to lock the eject media mechanism failed. |
| 1757 | 1204 | UNABLE_TO_LOCK_MEDIA = 0xC0000175, |
| 1758 | ||
| 1759 | 1205 | /// An attempt to unload media failed. |
| 1760 | 1206 | UNABLE_TO_UNLOAD_MEDIA = 0xC0000176, |
| 1761 | ||
| 1762 | 1207 | /// The physical end of tape was detected. |
| 1763 | 1208 | EOM_OVERFLOW = 0xC0000177, |
| 1764 | ||
| 1765 | 1209 | /// {No Media} There is no media in the drive. Insert media into drive %hs. |
| 1766 | 1210 | NO_MEDIA = 0xC0000178, |
| 1767 | ||
| 1768 | 1211 | /// A member could not be added to or removed from the local group because the member does not exist. |
| 1769 | 1212 | NO_SUCH_MEMBER = 0xC000017A, |
| 1770 | ||
| 1771 | 1213 | /// A new member could not be added to a local group because the member has the wrong account type. |
| 1772 | 1214 | INVALID_MEMBER = 0xC000017B, |
| 1773 | ||
| 1774 | 1215 | /// An illegal operation was attempted on a registry key that has been marked for deletion. |
| 1775 | 1216 | KEY_DELETED = 0xC000017C, |
| 1776 | ||
| 1777 | 1217 | /// The system could not allocate the required space in a registry log. |
| 1778 | 1218 | NO_LOG_SPACE = 0xC000017D, |
| 1779 | ||
| 1780 | 1219 | /// Too many SIDs have been specified. |
| 1781 | 1220 | TOO_MANY_SIDS = 0xC000017E, |
| 1782 | ||
| 1783 | 1221 | /// An attempt was made to change a user password in the security account manager without providing the necessary LM cross-encrypted password. |
| 1784 | 1222 | LM_CROSS_ENCRYPTION_REQUIRED = 0xC000017F, |
| 1785 | ||
| 1786 | 1223 | /// An attempt was made to create a symbolic link in a registry key that already has subkeys or values. |
| 1787 | 1224 | KEY_HAS_CHILDREN = 0xC0000180, |
| 1788 | ||
| 1789 | 1225 | /// An attempt was made to create a stable subkey under a volatile parent key. |
| 1790 | 1226 | CHILD_MUST_BE_VOLATILE = 0xC0000181, |
| 1791 | ||
| 1792 | 1227 | /// The I/O device is configured incorrectly or the configuration parameters to the driver are incorrect. |
| 1793 | 1228 | DEVICE_CONFIGURATION_ERROR = 0xC0000182, |
| 1794 | ||
| 1795 | 1229 | /// An error was detected between two drivers or within an I/O driver. |
| 1796 | 1230 | DRIVER_INTERNAL_ERROR = 0xC0000183, |
| 1797 | ||
| 1798 | 1231 | /// The device is not in a valid state to perform this request. |
| 1799 | 1232 | INVALID_DEVICE_STATE = 0xC0000184, |
| 1800 | ||
| 1801 | 1233 | /// The I/O device reported an I/O error. |
| 1802 | 1234 | IO_DEVICE_ERROR = 0xC0000185, |
| 1803 | ||
| 1804 | 1235 | /// A protocol error was detected between the driver and the device. |
| 1805 | 1236 | DEVICE_PROTOCOL_ERROR = 0xC0000186, |
| 1806 | ||
| 1807 | 1237 | /// This operation is only allowed for the primary domain controller of the domain. |
| 1808 | 1238 | BACKUP_CONTROLLER = 0xC0000187, |
| 1809 | ||
| 1810 | 1239 | /// The log file space is insufficient to support this operation. |
| 1811 | 1240 | LOG_FILE_FULL = 0xC0000188, |
| 1812 | ||
| 1813 | 1241 | /// A write operation was attempted to a volume after it was dismounted. |
| 1814 | 1242 | TOO_LATE = 0xC0000189, |
| 1815 | ||
| 1816 | 1243 | /// The workstation does not have a trust secret for the primary domain in the local LSA database. |
| 1817 | 1244 | NO_TRUST_LSA_SECRET = 0xC000018A, |
| 1818 | ||
| 1819 | 1245 | /// On applicable Windows Server releases, the SAM database does not have a computer account for this workstation trust relationship. |
| 1820 | 1246 | NO_TRUST_SAM_ACCOUNT = 0xC000018B, |
| 1821 | ||
| 1822 | 1247 | /// The logon request failed because the trust relationship between the primary domain and the trusted domain failed. |
| 1823 | 1248 | TRUSTED_DOMAIN_FAILURE = 0xC000018C, |
| 1824 | ||
| 1825 | 1249 | /// The logon request failed because the trust relationship between this workstation and the primary domain failed. |
| 1826 | 1250 | TRUSTED_RELATIONSHIP_FAILURE = 0xC000018D, |
| 1827 | ||
| 1828 | 1251 | /// The Eventlog log file is corrupt. |
| 1829 | 1252 | EVENTLOG_FILE_CORRUPT = 0xC000018E, |
| 1830 | ||
| 1831 | 1253 | /// No Eventlog log file could be opened. The Eventlog service did not start. |
| 1832 | 1254 | EVENTLOG_CANT_START = 0xC000018F, |
| 1833 | ||
| 1834 | 1255 | /// The network logon failed. This might be because the validation authority cannot be reached. |
| 1835 | 1256 | TRUST_FAILURE = 0xC0000190, |
| 1836 | ||
| 1837 | 1257 | /// An attempt was made to acquire a mutant such that its maximum count would have been exceeded. |
| 1838 | 1258 | MUTANT_LIMIT_EXCEEDED = 0xC0000191, |
| 1839 | ||
| 1840 | 1259 | /// An attempt was made to logon, but the NetLogon service was not started. |
| 1841 | 1260 | NETLOGON_NOT_STARTED = 0xC0000192, |
| 1842 | ||
| 1843 | 1261 | /// The user account has expired. |
| 1844 | 1262 | ACCOUNT_EXPIRED = 0xC0000193, |
| 1845 | ||
| 1846 | 1263 | /// {EXCEPTION} Possible deadlock condition. |
| 1847 | 1264 | POSSIBLE_DEADLOCK = 0xC0000194, |
| 1848 | ||
| 1849 | 1265 | /// Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. |
| 1850 | 1266 | /// Disconnect all previous connections to the server or shared resource and try again. |
| 1851 | 1267 | NETWORK_CREDENTIAL_CONFLICT = 0xC0000195, |
| 1852 | ||
| 1853 | 1268 | /// An attempt was made to establish a session to a network server, but there are already too many sessions established to that server. |
| 1854 | 1269 | REMOTE_SESSION_LIMIT = 0xC0000196, |
| 1855 | ||
| 1856 | 1270 | /// The log file has changed between reads. |
| 1857 | 1271 | EVENTLOG_FILE_CHANGED = 0xC0000197, |
| 1858 | ||
| 1859 | 1272 | /// The account used is an interdomain trust account. |
| 1860 | 1273 | /// Use your global user account or local user account to access this server. |
| 1861 | 1274 | NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 0xC0000198, |
| 1862 | ||
| 1863 | 1275 | /// The account used is a computer account. |
| 1864 | 1276 | /// Use your global user account or local user account to access this server. |
| 1865 | 1277 | NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xC0000199, |
| 1866 | ||
| 1867 | 1278 | /// The account used is a server trust account. |
| 1868 | 1279 | /// Use your global user account or local user account to access this server. |
| 1869 | 1280 | NOLOGON_SERVER_TRUST_ACCOUNT = 0xC000019A, |
| 1870 | ||
| 1871 | 1281 | /// The name or SID of the specified domain is inconsistent with the trust information for that domain. |
| 1872 | 1282 | DOMAIN_TRUST_INCONSISTENT = 0xC000019B, |
| 1873 | ||
| 1874 | 1283 | /// A volume has been accessed for which a file system driver is required that has not yet been loaded. |
| 1875 | 1284 | FS_DRIVER_REQUIRED = 0xC000019C, |
| 1876 | ||
| 1877 | 1285 | /// Indicates that the specified image is already loaded as a DLL. |
| 1878 | 1286 | IMAGE_ALREADY_LOADED_AS_DLL = 0xC000019D, |
| 1879 | ||
| 1880 | 1287 | /// Short name settings cannot be changed on this volume due to the global registry setting. |
| 1881 | 1288 | INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 0xC000019E, |
| 1882 | ||
| 1883 | 1289 | /// Short names are not enabled on this volume. |
| 1884 | 1290 | SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 0xC000019F, |
| 1885 | ||
| 1886 | 1291 | /// The security stream for the given volume is in an inconsistent state. Please run CHKDSK on the volume. |
| 1887 | 1292 | SECURITY_STREAM_IS_INCONSISTENT = 0xC00001A0, |
| 1888 | ||
| 1889 | 1293 | /// A requested file lock operation cannot be processed due to an invalid byte range. |
| 1890 | 1294 | INVALID_LOCK_RANGE = 0xC00001A1, |
| 1891 | ||
| 1892 | 1295 | /// The specified access control entry (ACE) contains an invalid condition. |
| 1893 | 1296 | INVALID_ACE_CONDITION = 0xC00001A2, |
| 1894 | ||
| 1895 | 1297 | /// The subsystem needed to support the image type is not present. |
| 1896 | 1298 | IMAGE_SUBSYSTEM_NOT_PRESENT = 0xC00001A3, |
| 1897 | ||
| 1898 | 1299 | /// The specified file already has a notification GUID associated with it. |
| 1899 | 1300 | NOTIFICATION_GUID_ALREADY_DEFINED = 0xC00001A4, |
| 1900 | ||
| 1901 | 1301 | /// A remote open failed because the network open restrictions were not satisfied. |
| 1902 | 1302 | NETWORK_OPEN_RESTRICTION = 0xC0000201, |
| 1903 | ||
| 1904 | 1303 | /// There is no user session key for the specified logon session. |
| 1905 | 1304 | NO_USER_SESSION_KEY = 0xC0000202, |
| 1906 | ||
| 1907 | 1305 | /// The remote user session has been deleted. |
| 1908 | 1306 | USER_SESSION_DELETED = 0xC0000203, |
| 1909 | ||
| 1910 | 1307 | /// Indicates the specified resource language ID cannot be found in the image file. |
| 1911 | 1308 | RESOURCE_LANG_NOT_FOUND = 0xC0000204, |
| 1912 | ||
| 1913 | 1309 | /// Insufficient server resources exist to complete the request. |
| 1914 | 1310 | INSUFF_SERVER_RESOURCES = 0xC0000205, |
| 1915 | ||
| 1916 | 1311 | /// The size of the buffer is invalid for the specified operation. |
| 1917 | 1312 | INVALID_BUFFER_SIZE = 0xC0000206, |
| 1918 | ||
| 1919 | 1313 | /// The transport rejected the specified network address as invalid. |
| 1920 | 1314 | INVALID_ADDRESS_COMPONENT = 0xC0000207, |
| 1921 | ||
| 1922 | 1315 | /// The transport rejected the specified network address due to invalid use of a wildcard. |
| 1923 | 1316 | INVALID_ADDRESS_WILDCARD = 0xC0000208, |
| 1924 | ||
| 1925 | 1317 | /// The transport address could not be opened because all the available addresses are in use. |
| 1926 | 1318 | TOO_MANY_ADDRESSES = 0xC0000209, |
| 1927 | ||
| 1928 | 1319 | /// The transport address could not be opened because it already exists. |
| 1929 | 1320 | ADDRESS_ALREADY_EXISTS = 0xC000020A, |
| 1930 | ||
| 1931 | 1321 | /// The transport address is now closed. |
| 1932 | 1322 | ADDRESS_CLOSED = 0xC000020B, |
| 1933 | ||
| 1934 | 1323 | /// The transport connection is now disconnected. |
| 1935 | 1324 | CONNECTION_DISCONNECTED = 0xC000020C, |
| 1936 | ||
| 1937 | 1325 | /// The transport connection has been reset. |
| 1938 | 1326 | CONNECTION_RESET = 0xC000020D, |
| 1939 | ||
| 1940 | 1327 | /// The transport cannot dynamically acquire any more nodes. |
| 1941 | 1328 | TOO_MANY_NODES = 0xC000020E, |
| 1942 | ||
| 1943 | 1329 | /// The transport aborted a pending transaction. |
| 1944 | 1330 | TRANSACTION_ABORTED = 0xC000020F, |
| 1945 | ||
| 1946 | 1331 | /// The transport timed out a request that is waiting for a response. |
| 1947 | 1332 | TRANSACTION_TIMED_OUT = 0xC0000210, |
| 1948 | ||
| 1949 | 1333 | /// The transport did not receive a release for a pending response. |
| 1950 | 1334 | TRANSACTION_NO_RELEASE = 0xC0000211, |
| 1951 | ||
| 1952 | 1335 | /// The transport did not find a transaction that matches the specific token. |
| 1953 | 1336 | TRANSACTION_NO_MATCH = 0xC0000212, |
| 1954 | ||
| 1955 | 1337 | /// The transport had previously responded to a transaction request. |
| 1956 | 1338 | TRANSACTION_RESPONDED = 0xC0000213, |
| 1957 | ||
| 1958 | 1339 | /// The transport does not recognize the specified transaction request ID. |
| 1959 | 1340 | TRANSACTION_INVALID_ID = 0xC0000214, |
| 1960 | ||
| 1961 | 1341 | /// The transport does not recognize the specified transaction request type. |
| 1962 | 1342 | TRANSACTION_INVALID_TYPE = 0xC0000215, |
| 1963 | ||
| 1964 | 1343 | /// The transport can only process the specified request on the server side of a session. |
| 1965 | 1344 | NOT_SERVER_SESSION = 0xC0000216, |
| 1966 | ||
| 1967 | 1345 | /// The transport can only process the specified request on the client side of a session. |
| 1968 | 1346 | NOT_CLIENT_SESSION = 0xC0000217, |
| 1969 | ||
| 1970 | 1347 | /// {Registry File Failure} The registry cannot load the hive (file): %hs or its log or alternate. It is corrupt, absent, or not writable. |
| 1971 | 1348 | CANNOT_LOAD_REGISTRY_FILE = 0xC0000218, |
| 1972 | ||
| 1973 | 1349 | /// {Unexpected Failure in DebugActiveProcess} An unexpected failure occurred while processing a DebugActiveProcess API request. |
| 1974 | 1350 | /// Choosing OK will terminate the process, and choosing Cancel will ignore the error. |
| 1975 | 1351 | DEBUG_ATTACH_FAILED = 0xC0000219, |
| 1976 | ||
| 1977 | 1352 | /// {Fatal System Error} The %hs system process terminated unexpectedly with a status of 0x%08x (0x%08x 0x%08x). The system has been shut down. |
| 1978 | 1353 | SYSTEM_PROCESS_TERMINATED = 0xC000021A, |
| 1979 | ||
| 1980 | 1354 | /// {Data Not Accepted} The TDI client could not handle the data received during an indication. |
| 1981 | 1355 | DATA_NOT_ACCEPTED = 0xC000021B, |
| 1982 | ||
| 1983 | 1356 | /// {Unable to Retrieve Browser Server List} The list of servers for this workgroup is not currently available. |
| 1984 | 1357 | NO_BROWSER_SERVERS_FOUND = 0xC000021C, |
| 1985 | ||
| 1986 | 1358 | /// NTVDM encountered a hard error. |
| 1987 | 1359 | VDM_HARD_ERROR = 0xC000021D, |
| 1988 | ||
| 1989 | 1360 | /// {Cancel Timeout} The driver %hs failed to complete a canceled I/O request in the allotted time. |
| 1990 | 1361 | DRIVER_CANCEL_TIMEOUT = 0xC000021E, |
| 1991 | ||
| 1992 | 1362 | /// {Reply Message Mismatch} An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message. |
| 1993 | 1363 | REPLY_MESSAGE_MISMATCH = 0xC000021F, |
| 1994 | ||
| 1995 | 1364 | /// {Mapped View Alignment Incorrect} An attempt was made to map a view of a file, but either the specified base address or the offset into the file were not aligned on the proper allocation granularity. |
| 1996 | 1365 | MAPPED_ALIGNMENT = 0xC0000220, |
| 1997 | ||
| 1998 | 1366 | /// {Bad Image Checksum} The image %hs is possibly corrupt. |
| 1999 | 1367 | /// The header checksum does not match the computed checksum. |
| 2000 | 1368 | IMAGE_CHECKSUM_MISMATCH = 0xC0000221, |
| 2001 | ||
| 2002 | 1369 | /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs. The data has been lost. |
| 2003 | 1370 | /// This error might be caused by a failure of your computer hardware or network connection. Try to save this file elsewhere. |
| 2004 | 1371 | LOST_WRITEBEHIND_DATA = 0xC0000222, |
| 2005 | ||
| 2006 | 1372 | /// The parameters passed to the server in the client/server shared memory window were invalid. |
| 2007 | 1373 | /// Too much data might have been put in the shared memory window. |
| 2008 | 1374 | CLIENT_SERVER_PARAMETERS_INVALID = 0xC0000223, |
| 2009 | ||
| 2010 | 1375 | /// The user password must be changed before logging on the first time. |
| 2011 | 1376 | PASSWORD_MUST_CHANGE = 0xC0000224, |
| 2012 | ||
| 2013 | 1377 | /// The object was not found. |
| 2014 | 1378 | NOT_FOUND = 0xC0000225, |
| 2015 | ||
| 2016 | 1379 | /// The stream is not a tiny stream. |
| 2017 | 1380 | NOT_TINY_STREAM = 0xC0000226, |
| 2018 | ||
| 2019 | 1381 | /// A transaction recovery failed. |
| 2020 | 1382 | RECOVERY_FAILURE = 0xC0000227, |
| 2021 | ||
| 2022 | 1383 | /// The request must be handled by the stack overflow code. |
| 2023 | 1384 | STACK_OVERFLOW_READ = 0xC0000228, |
| 2024 | ||
| 2025 | 1385 | /// A consistency check failed. |
| 2026 | 1386 | FAIL_CHECK = 0xC0000229, |
| 2027 | ||
| 2028 | 1387 | /// The attempt to insert the ID in the index failed because the ID is already in the index. |
| 2029 | 1388 | DUPLICATE_OBJECTID = 0xC000022A, |
| 2030 | ||
| 2031 | 1389 | /// The attempt to set the object ID failed because the object already has an ID. |
| 2032 | 1390 | OBJECTID_EXISTS = 0xC000022B, |
| 2033 | ||
| 2034 | 1391 | /// Internal OFS status codes indicating how an allocation operation is handled. |
| 2035 | 1392 | /// Either it is retried after the containing oNode is moved or the extent stream is converted to a large stream. |
| 2036 | 1393 | CONVERT_TO_LARGE = 0xC000022C, |
| 2037 | ||
| 2038 | 1394 | /// The request needs to be retried. |
| 2039 | 1395 | RETRY = 0xC000022D, |
| 2040 | ||
| 2041 | 1396 | /// The attempt to find the object found an object on the volume that matches by ID; however, it is out of the scope of the handle that is used for the operation. |
| 2042 | 1397 | FOUND_OUT_OF_SCOPE = 0xC000022E, |
| 2043 | ||
| 2044 | 1398 | /// The bucket array must be grown. Retry the transaction after doing so. |
| 2045 | 1399 | ALLOCATE_BUCKET = 0xC000022F, |
| 2046 | ||
| 2047 | 1400 | /// The specified property set does not exist on the object. |
| 2048 | 1401 | PROPSET_NOT_FOUND = 0xC0000230, |
| 2049 | ||
| 2050 | 1402 | /// The user/kernel marshaling buffer has overflowed. |
| 2051 | 1403 | MARSHALL_OVERFLOW = 0xC0000231, |
| 2052 | ||
| 2053 | 1404 | /// The supplied variant structure contains invalid data. |
| 2054 | 1405 | INVALID_VARIANT = 0xC0000232, |
| 2055 | ||
| 2056 | 1406 | /// A domain controller for this domain was not found. |
| 2057 | 1407 | DOMAIN_CONTROLLER_NOT_FOUND = 0xC0000233, |
| 2058 | ||
| 2059 | 1408 | /// The user account has been automatically locked because too many invalid logon attempts or password change attempts have been requested. |
| 2060 | 1409 | ACCOUNT_LOCKED_OUT = 0xC0000234, |
| 2061 | ||
| 2062 | 1410 | /// NtClose was called on a handle that was protected from close via NtSetInformationObject. |
| 2063 | 1411 | HANDLE_NOT_CLOSABLE = 0xC0000235, |
| 2064 | ||
| 2065 | 1412 | /// The transport-connection attempt was refused by the remote system. |
| 2066 | 1413 | CONNECTION_REFUSED = 0xC0000236, |
| 2067 | ||
| 2068 | 1414 | /// The transport connection was gracefully closed. |
| 2069 | 1415 | GRACEFUL_DISCONNECT = 0xC0000237, |
| 2070 | ||
| 2071 | 1416 | /// The transport endpoint already has an address associated with it. |
| 2072 | 1417 | ADDRESS_ALREADY_ASSOCIATED = 0xC0000238, |
| 2073 | ||
| 2074 | 1418 | /// An address has not yet been associated with the transport endpoint. |
| 2075 | 1419 | ADDRESS_NOT_ASSOCIATED = 0xC0000239, |
| 2076 | ||
| 2077 | 1420 | /// An operation was attempted on a nonexistent transport connection. |
| 2078 | 1421 | CONNECTION_INVALID = 0xC000023A, |
| 2079 | ||
| 2080 | 1422 | /// An invalid operation was attempted on an active transport connection. |
| 2081 | 1423 | CONNECTION_ACTIVE = 0xC000023B, |
| 2082 | ||
| 2083 | 1424 | /// The remote network is not reachable by the transport. |
| 2084 | 1425 | NETWORK_UNREACHABLE = 0xC000023C, |
| 2085 | ||
| 2086 | 1426 | /// The remote system is not reachable by the transport. |
| 2087 | 1427 | HOST_UNREACHABLE = 0xC000023D, |
| 2088 | ||
| 2089 | 1428 | /// The remote system does not support the transport protocol. |
| 2090 | 1429 | PROTOCOL_UNREACHABLE = 0xC000023E, |
| 2091 | ||
| 2092 | 1430 | /// No service is operating at the destination port of the transport on the remote system. |
| 2093 | 1431 | PORT_UNREACHABLE = 0xC000023F, |
| 2094 | ||
| 2095 | 1432 | /// The request was aborted. |
| 2096 | 1433 | REQUEST_ABORTED = 0xC0000240, |
| 2097 | ||
| 2098 | 1434 | /// The transport connection was aborted by the local system. |
| 2099 | 1435 | CONNECTION_ABORTED = 0xC0000241, |
| 2100 | ||
| 2101 | 1436 | /// The specified buffer contains ill-formed data. |
| 2102 | 1437 | BAD_COMPRESSION_BUFFER = 0xC0000242, |
| 2103 | ||
| 2104 | 1438 | /// The requested operation cannot be performed on a file with a user mapped section open. |
| 2105 | 1439 | USER_MAPPED_FILE = 0xC0000243, |
| 2106 | ||
| 2107 | 1440 | /// {Audit Failed} An attempt to generate a security audit failed. |
| 2108 | 1441 | AUDIT_FAILED = 0xC0000244, |
| 2109 | ||
| 2110 | 1442 | /// The timer resolution was not previously set by the current process. |
| 2111 | 1443 | TIMER_RESOLUTION_NOT_SET = 0xC0000245, |
| 2112 | ||
| 2113 | 1444 | /// A connection to the server could not be made because the limit on the number of concurrent connections for this account has been reached. |
| 2114 | 1445 | CONNECTION_COUNT_LIMIT = 0xC0000246, |
| 2115 | ||
| 2116 | 1446 | /// Attempting to log on during an unauthorized time of day for this account. |
| 2117 | 1447 | LOGIN_TIME_RESTRICTION = 0xC0000247, |
| 2118 | ||
| 2119 | 1448 | /// The account is not authorized to log on from this station. |
| 2120 | 1449 | LOGIN_WKSTA_RESTRICTION = 0xC0000248, |
| 2121 | ||
| 2122 | 1450 | /// {UP/MP Image Mismatch} The image %hs has been modified for use on a uniprocessor system, but you are running it on a multiprocessor machine. Reinstall the image file. |
| 2123 | 1451 | IMAGE_MP_UP_MISMATCH = 0xC0000249, |
| 2124 | ||
| 2125 | 1452 | /// There is insufficient account information to log you on. |
| 2126 | 1453 | INSUFFICIENT_LOGON_INFO = 0xC0000250, |
| 2127 | ||
| 2128 | 1454 | /// {Invalid DLL Entrypoint} The dynamic link library %hs is not written correctly. |
| 2129 | 1455 | /// The stack pointer has been left in an inconsistent state. |
| 2130 | 1456 | /// The entry point should be declared as WINAPI or STDCALL. |
| 2131 | 1457 | /// Select YES to fail the DLL load. Select NO to continue execution. |
| 2132 | 1458 | /// Selecting NO might cause the application to operate incorrectly. |
| 2133 | 1459 | BAD_DLL_ENTRYPOINT = 0xC0000251, |
| 2134 | ||
| 2135 | 1460 | /// {Invalid Service Callback Entrypoint} The %hs service is not written correctly. |
| 2136 | 1461 | /// The stack pointer has been left in an inconsistent state. |
| 2137 | 1462 | /// The callback entry point should be declared as WINAPI or STDCALL. |
| 2138 | 1463 | /// Selecting OK will cause the service to continue operation. |
| 2139 | 1464 | /// However, the service process might operate incorrectly. |
| 2140 | 1465 | BAD_SERVICE_ENTRYPOINT = 0xC0000252, |
| 2141 | ||
| 2142 | 1466 | /// The server received the messages but did not send a reply. |
| 2143 | 1467 | LPC_REPLY_LOST = 0xC0000253, |
| 2144 | ||
| 2145 | 1468 | /// There is an IP address conflict with another system on the network. |
| 2146 | 1469 | IP_ADDRESS_CONFLICT1 = 0xC0000254, |
| 2147 | ||
| 2148 | 1470 | /// There is an IP address conflict with another system on the network. |
| 2149 | 1471 | IP_ADDRESS_CONFLICT2 = 0xC0000255, |
| 2150 | ||
| 2151 | 1472 | /// {Low On Registry Space} The system has reached the maximum size that is allowed for the system part of the registry. Additional storage requests will be ignored. |
| 2152 | 1473 | REGISTRY_QUOTA_LIMIT = 0xC0000256, |
| 2153 | ||
| 2154 | 1474 | /// The contacted server does not support the indicated part of the DFS namespace. |
| 2155 | 1475 | PATH_NOT_COVERED = 0xC0000257, |
| 2156 | ||
| 2157 | 1476 | /// A callback return system service cannot be executed when no callback is active. |
| 2158 | 1477 | NO_CALLBACK_ACTIVE = 0xC0000258, |
| 2159 | ||
| 2160 | 1478 | /// The service being accessed is licensed for a particular number of connections. |
| 2161 | 1479 | /// No more connections can be made to the service at this time because the service has already accepted the maximum number of connections. |
| 2162 | 1480 | LICENSE_QUOTA_EXCEEDED = 0xC0000259, |
| 2163 | ||
| 2164 | 1481 | /// The password provided is too short to meet the policy of your user account. Choose a longer password. |
| 2165 | 1482 | PWD_TOO_SHORT = 0xC000025A, |
| 2166 | ||
| 2167 | 1483 | /// The policy of your user account does not allow you to change passwords too frequently. |
| 2168 | 1484 | /// This is done to prevent users from changing back to a familiar, but potentially discovered, password. |
| 2169 | 1485 | /// If you feel your password has been compromised, contact your administrator immediately to have a new one assigned. |
| 2170 | 1486 | PWD_TOO_RECENT = 0xC000025B, |
| 2171 | ||
| 2172 | 1487 | /// You have attempted to change your password to one that you have used in the past. |
| 2173 | 1488 | /// The policy of your user account does not allow this. |
| 2174 | 1489 | /// Select a password that you have not previously used. |
| 2175 | 1490 | PWD_HISTORY_CONFLICT = 0xC000025C, |
| 2176 | ||
| 2177 | 1491 | /// You have attempted to load a legacy device driver while its device instance had been disabled. |
| 2178 | 1492 | PLUGPLAY_NO_DEVICE = 0xC000025E, |
| 2179 | ||
| 2180 | 1493 | /// The specified compression format is unsupported. |
| 2181 | 1494 | UNSUPPORTED_COMPRESSION = 0xC000025F, |
| 2182 | ||
| 2183 | 1495 | /// The specified hardware profile configuration is invalid. |
| 2184 | 1496 | INVALID_HW_PROFILE = 0xC0000260, |
| 2185 | ||
| 2186 | 1497 | /// The specified Plug and Play registry device path is invalid. |
| 2187 | 1498 | INVALID_PLUGPLAY_DEVICE_PATH = 0xC0000261, |
| 2188 | ||
| 2189 | 1499 | /// {Driver Entry Point Not Found} The %hs device driver could not locate the ordinal %ld in driver %hs. |
| 2190 | 1500 | DRIVER_ORDINAL_NOT_FOUND = 0xC0000262, |
| 2191 | ||
| 2192 | 1501 | /// {Driver Entry Point Not Found} The %hs device driver could not locate the entry point %hs in driver %hs. |
| 2193 | 1502 | DRIVER_ENTRYPOINT_NOT_FOUND = 0xC0000263, |
| 2194 | ||
| 2195 | 1503 | /// {Application Error} The application attempted to release a resource it did not own. Click OK to terminate the application. |
| 2196 | 1504 | RESOURCE_NOT_OWNED = 0xC0000264, |
| 2197 | ||
| 2198 | 1505 | /// An attempt was made to create more links on a file than the file system supports. |
| 2199 | 1506 | TOO_MANY_LINKS = 0xC0000265, |
| 2200 | ||
| 2201 | 1507 | /// The specified quota list is internally inconsistent with its descriptor. |
| 2202 | 1508 | QUOTA_LIST_INCONSISTENT = 0xC0000266, |
| 2203 | ||
| 2204 | 1509 | /// The specified file has been relocated to offline storage. |
| 2205 | 1510 | FILE_IS_OFFLINE = 0xC0000267, |
| 2206 | ||
| 2207 | 1511 | /// {Windows Evaluation Notification} The evaluation period for this installation of Windows has expired. This system will shutdown in 1 hour. |
| 2208 | 1512 | /// To restore access to this installation of Windows, upgrade this installation by using a licensed distribution of this product. |
| 2209 | 1513 | EVALUATION_EXPIRATION = 0xC0000268, |
| 2210 | ||
| 2211 | 1514 | /// {Illegal System DLL Relocation} The system DLL %hs was relocated in memory. The application will not run properly. |
| 2212 | 1515 | /// The relocation occurred because the DLL %hs occupied an address range that is reserved for Windows system DLLs. |
| 2213 | 1516 | /// The vendor supplying the DLL should be contacted for a new DLL. |
| 2214 | 1517 | ILLEGAL_DLL_RELOCATION = 0xC0000269, |
| 2215 | ||
| 2216 | 1518 | /// {License Violation} The system has detected tampering with your registered product type. |
| 2217 | 1519 | /// This is a violation of your software license. Tampering with the product type is not permitted. |
| 2218 | 1520 | LICENSE_VIOLATION = 0xC000026A, |
| 2219 | ||
| 2220 | 1521 | /// {DLL Initialization Failed} The application failed to initialize because the window station is shutting down. |
| 2221 | 1522 | DLL_INIT_FAILED_LOGOFF = 0xC000026B, |
| 2222 | ||
| 2223 | 1523 | /// {Unable to Load Device Driver} %hs device driver could not be loaded. Error Status was 0x%x. |
| 2224 | 1524 | DRIVER_UNABLE_TO_LOAD = 0xC000026C, |
| 2225 | ||
| 2226 | 1525 | /// DFS is unavailable on the contacted server. |
| 2227 | 1526 | DFS_UNAVAILABLE = 0xC000026D, |
| 2228 | ||
| 2229 | 1527 | /// An operation was attempted to a volume after it was dismounted. |
| 2230 | 1528 | VOLUME_DISMOUNTED = 0xC000026E, |
| 2231 | ||
| 2232 | 1529 | /// An internal error occurred in the Win32 x86 emulation subsystem. |
| 2233 | 1530 | WX86_INTERNAL_ERROR = 0xC000026F, |
| 2234 | ||
| 2235 | 1531 | /// Win32 x86 emulation subsystem floating-point stack check. |
| 2236 | 1532 | WX86_FLOAT_STACK_CHECK = 0xC0000270, |
| 2237 | ||
| 2238 | 1533 | /// The validation process needs to continue on to the next step. |
| 2239 | 1534 | VALIDATE_CONTINUE = 0xC0000271, |
| 2240 | ||
| 2241 | 1535 | /// There was no match for the specified key in the index. |
| 2242 | 1536 | NO_MATCH = 0xC0000272, |
| 2243 | ||
| 2244 | 1537 | /// There are no more matches for the current index enumeration. |
| 2245 | 1538 | NO_MORE_MATCHES = 0xC0000273, |
| 2246 | ||
| 2247 | 1539 | /// The NTFS file or directory is not a reparse point. |
| 2248 | 1540 | NOT_A_REPARSE_POINT = 0xC0000275, |
| 2249 | ||
| 2250 | 1541 | /// The Windows I/O reparse tag passed for the NTFS reparse point is invalid. |
| 2251 | 1542 | IO_REPARSE_TAG_INVALID = 0xC0000276, |
| 2252 | ||
| 2253 | 1543 | /// The Windows I/O reparse tag does not match the one that is in the NTFS reparse point. |
| 2254 | 1544 | IO_REPARSE_TAG_MISMATCH = 0xC0000277, |
| 2255 | ||
| 2256 | 1545 | /// The user data passed for the NTFS reparse point is invalid. |
| 2257 | 1546 | IO_REPARSE_DATA_INVALID = 0xC0000278, |
| 2258 | ||
| 2259 | 1547 | /// The layered file system driver for this I/O tag did not handle it when needed. |
| 2260 | 1548 | IO_REPARSE_TAG_NOT_HANDLED = 0xC0000279, |
| 2261 | ||
| 2262 | 1549 | /// The NTFS symbolic link could not be resolved even though the initial file name is valid. |
| 2263 | 1550 | REPARSE_POINT_NOT_RESOLVED = 0xC0000280, |
| 2264 | ||
| 2265 | 1551 | /// The NTFS directory is a reparse point. |
| 2266 | 1552 | DIRECTORY_IS_A_REPARSE_POINT = 0xC0000281, |
| 2267 | ||
| 2268 | 1553 | /// The range could not be added to the range list because of a conflict. |
| 2269 | 1554 | RANGE_LIST_CONFLICT = 0xC0000282, |
| 2270 | ||
| 2271 | 1555 | /// The specified medium changer source element contains no media. |
| 2272 | 1556 | SOURCE_ELEMENT_EMPTY = 0xC0000283, |
| 2273 | ||
| 2274 | 1557 | /// The specified medium changer destination element already contains media. |
| 2275 | 1558 | DESTINATION_ELEMENT_FULL = 0xC0000284, |
| 2276 | ||
| 2277 | 1559 | /// The specified medium changer element does not exist. |
| 2278 | 1560 | ILLEGAL_ELEMENT_ADDRESS = 0xC0000285, |
| 2279 | ||
| 2280 | 1561 | /// The specified element is contained in a magazine that is no longer present. |
| 2281 | 1562 | MAGAZINE_NOT_PRESENT = 0xC0000286, |
| 2282 | ||
| 2283 | 1563 | /// The device requires re-initialization due to hardware errors. |
| 2284 | 1564 | REINITIALIZATION_NEEDED = 0xC0000287, |
| 2285 | ||
| 2286 | 1565 | /// The file encryption attempt failed. |
| 2287 | 1566 | ENCRYPTION_FAILED = 0xC000028A, |
| 2288 | ||
| 2289 | 1567 | /// The file decryption attempt failed. |
| 2290 | 1568 | DECRYPTION_FAILED = 0xC000028B, |
| 2291 | ||
| 2292 | 1569 | /// The specified range could not be found in the range list. |
| 2293 | 1570 | RANGE_NOT_FOUND = 0xC000028C, |
| 2294 | ||
| 2295 | 1571 | /// There is no encryption recovery policy configured for this system. |
| 2296 | 1572 | NO_RECOVERY_POLICY = 0xC000028D, |
| 2297 | ||
| 2298 | 1573 | /// The required encryption driver is not loaded for this system. |
| 2299 | 1574 | NO_EFS = 0xC000028E, |
| 2300 | ||
| 2301 | 1575 | /// The file was encrypted with a different encryption driver than is currently loaded. |
| 2302 | 1576 | WRONG_EFS = 0xC000028F, |
| 2303 | ||
| 2304 | 1577 | /// There are no EFS keys defined for the user. |
| 2305 | 1578 | NO_USER_KEYS = 0xC0000290, |
| 2306 | ||
| 2307 | 1579 | /// The specified file is not encrypted. |
| 2308 | 1580 | FILE_NOT_ENCRYPTED = 0xC0000291, |
| 2309 | ||
| 2310 | 1581 | /// The specified file is not in the defined EFS export format. |
| 2311 | 1582 | NOT_EXPORT_FORMAT = 0xC0000292, |
| 2312 | ||
| 2313 | 1583 | /// The specified file is encrypted and the user does not have the ability to decrypt it. |
| 2314 | 1584 | FILE_ENCRYPTED = 0xC0000293, |
| 2315 | ||
| 2316 | 1585 | /// The GUID passed was not recognized as valid by a WMI data provider. |
| 2317 | 1586 | WMI_GUID_NOT_FOUND = 0xC0000295, |
| 2318 | ||
| 2319 | 1587 | /// The instance name passed was not recognized as valid by a WMI data provider. |
| 2320 | 1588 | WMI_INSTANCE_NOT_FOUND = 0xC0000296, |
| 2321 | ||
| 2322 | 1589 | /// The data item ID passed was not recognized as valid by a WMI data provider. |
| 2323 | 1590 | WMI_ITEMID_NOT_FOUND = 0xC0000297, |
| 2324 | ||
| 2325 | 1591 | /// The WMI request could not be completed and should be retried. |
| 2326 | 1592 | WMI_TRY_AGAIN = 0xC0000298, |
| 2327 | ||
| 2328 | 1593 | /// The policy object is shared and can only be modified at the root. |
| 2329 | 1594 | SHARED_POLICY = 0xC0000299, |
| 2330 | ||
| 2331 | 1595 | /// The policy object does not exist when it should. |
| 2332 | 1596 | POLICY_OBJECT_NOT_FOUND = 0xC000029A, |
| 2333 | ||
| 2334 | 1597 | /// The requested policy information only lives in the Ds. |
| 2335 | 1598 | POLICY_ONLY_IN_DS = 0xC000029B, |
| 2336 | ||
| 2337 | 1599 | /// The volume must be upgraded to enable this feature. |
| 2338 | 1600 | VOLUME_NOT_UPGRADED = 0xC000029C, |
| 2339 | ||
| 2340 | 1601 | /// The remote storage service is not operational at this time. |
| 2341 | 1602 | REMOTE_STORAGE_NOT_ACTIVE = 0xC000029D, |
| 2342 | ||
| 2343 | 1603 | /// The remote storage service encountered a media error. |
| 2344 | 1604 | REMOTE_STORAGE_MEDIA_ERROR = 0xC000029E, |
| 2345 | ||
| 2346 | 1605 | /// The tracking (workstation) service is not running. |
| 2347 | 1606 | NO_TRACKING_SERVICE = 0xC000029F, |
| 2348 | ||
| 2349 | 1607 | /// The server process is running under a SID that is different from the SID that is required by client. |
| 2350 | 1608 | SERVER_SID_MISMATCH = 0xC00002A0, |
| 2351 | ||
| 2352 | 1609 | /// The specified directory service attribute or value does not exist. |
| 2353 | 1610 | DS_NO_ATTRIBUTE_OR_VALUE = 0xC00002A1, |
| 2354 | ||
| 2355 | 1611 | /// The attribute syntax specified to the directory service is invalid. |
| 2356 | 1612 | DS_INVALID_ATTRIBUTE_SYNTAX = 0xC00002A2, |
| 2357 | ||
| 2358 | 1613 | /// The attribute type specified to the directory service is not defined. |
| 2359 | 1614 | DS_ATTRIBUTE_TYPE_UNDEFINED = 0xC00002A3, |
| 2360 | ||
| 2361 | 1615 | /// The specified directory service attribute or value already exists. |
| 2362 | 1616 | DS_ATTRIBUTE_OR_VALUE_EXISTS = 0xC00002A4, |
| 2363 | ||
| 2364 | 1617 | /// The directory service is busy. |
| 2365 | 1618 | DS_BUSY = 0xC00002A5, |
| 2366 | ||
| 2367 | 1619 | /// The directory service is unavailable. |
| 2368 | 1620 | DS_UNAVAILABLE = 0xC00002A6, |
| 2369 | ||
| 2370 | 1621 | /// The directory service was unable to allocate a relative identifier. |
| 2371 | 1622 | DS_NO_RIDS_ALLOCATED = 0xC00002A7, |
| 2372 | ||
| 2373 | 1623 | /// The directory service has exhausted the pool of relative identifiers. |
| 2374 | 1624 | DS_NO_MORE_RIDS = 0xC00002A8, |
| 2375 | ||
| 2376 | 1625 | /// The requested operation could not be performed because the directory service is not the master for that type of operation. |
| 2377 | 1626 | DS_INCORRECT_ROLE_OWNER = 0xC00002A9, |
| 2378 | ||
| 2379 | 1627 | /// The directory service was unable to initialize the subsystem that allocates relative identifiers. |
| 2380 | 1628 | DS_RIDMGR_INIT_ERROR = 0xC00002AA, |
| 2381 | ||
| 2382 | 1629 | /// The requested operation did not satisfy one or more constraints that are associated with the class of the object. |
| 2383 | 1630 | DS_OBJ_CLASS_VIOLATION = 0xC00002AB, |
| 2384 | ||
| 2385 | 1631 | /// The directory service can perform the requested operation only on a leaf object. |
| 2386 | 1632 | DS_CANT_ON_NON_LEAF = 0xC00002AC, |
| 2387 | ||
| 2388 | 1633 | /// The directory service cannot perform the requested operation on the Relatively Defined Name (RDN) attribute of an object. |
| 2389 | 1634 | DS_CANT_ON_RDN = 0xC00002AD, |
| 2390 | ||
| 2391 | 1635 | /// The directory service detected an attempt to modify the object class of an object. |
| 2392 | 1636 | DS_CANT_MOD_OBJ_CLASS = 0xC00002AE, |
| 2393 | ||
| 2394 | 1637 | /// An error occurred while performing a cross domain move operation. |
| 2395 | 1638 | DS_CROSS_DOM_MOVE_FAILED = 0xC00002AF, |
| 2396 | ||
| 2397 | 1639 | /// Unable to contact the global catalog server. |
| 2398 | 1640 | DS_GC_NOT_AVAILABLE = 0xC00002B0, |
| 2399 | ||
| 2400 | 1641 | /// The requested operation requires a directory service, and none was available. |
| 2401 | 1642 | DIRECTORY_SERVICE_REQUIRED = 0xC00002B1, |
| 2402 | ||
| 2403 | 1643 | /// The reparse attribute cannot be set because it is incompatible with an existing attribute. |
| 2404 | 1644 | REPARSE_ATTRIBUTE_CONFLICT = 0xC00002B2, |
| 2405 | ||
| 2406 | 1645 | /// A group marked "use for deny only" cannot be enabled. |
| 2407 | 1646 | CANT_ENABLE_DENY_ONLY = 0xC00002B3, |
| 2408 | ||
| 2409 | 1647 | /// {EXCEPTION} Multiple floating-point faults. |
| 2410 | 1648 | FLOAT_MULTIPLE_FAULTS = 0xC00002B4, |
| 2411 | ||
| 2412 | 1649 | /// {EXCEPTION} Multiple floating-point traps. |
| 2413 | 1650 | FLOAT_MULTIPLE_TRAPS = 0xC00002B5, |
| 2414 | ||
| 2415 | 1651 | /// The device has been removed. |
| 2416 | 1652 | DEVICE_REMOVED = 0xC00002B6, |
| 2417 | ||
| 2418 | 1653 | /// The volume change journal is being deleted. |
| 2419 | 1654 | JOURNAL_DELETE_IN_PROGRESS = 0xC00002B7, |
| 2420 | ||
| 2421 | 1655 | /// The volume change journal is not active. |
| 2422 | 1656 | JOURNAL_NOT_ACTIVE = 0xC00002B8, |
| 2423 | ||
| 2424 | 1657 | /// The requested interface is not supported. |
| 2425 | 1658 | NOINTERFACE = 0xC00002B9, |
| 2426 | ||
| 2427 | 1659 | /// A directory service resource limit has been exceeded. |
| 2428 | 1660 | DS_ADMIN_LIMIT_EXCEEDED = 0xC00002C1, |
| 2429 | ||
| 2430 | 1661 | /// {System Standby Failed} The driver %hs does not support standby mode. |
| 2431 | 1662 | /// Updating this driver allows the system to go to standby mode. |
| 2432 | 1663 | DRIVER_FAILED_SLEEP = 0xC00002C2, |
| 2433 | ||
| 2434 | 1664 | /// Mutual Authentication failed. The server password is out of date at the domain controller. |
| 2435 | 1665 | MUTUAL_AUTHENTICATION_FAILED = 0xC00002C3, |
| 2436 | ||
| 2437 | 1666 | /// The system file %1 has become corrupt and has been replaced. |
| 2438 | 1667 | CORRUPT_SYSTEM_FILE = 0xC00002C4, |
| 2439 | ||
| 2440 | 1668 | /// {EXCEPTION} Alignment Error A data type misalignment error was detected in a load or store instruction. |
| 2441 | 1669 | DATATYPE_MISALIGNMENT_ERROR = 0xC00002C5, |
| 2442 | ||
| 2443 | 1670 | /// The WMI data item or data block is read-only. |
| 2444 | 1671 | WMI_READ_ONLY = 0xC00002C6, |
| 2445 | ||
| 2446 | 1672 | /// The WMI data item or data block could not be changed. |
| 2447 | 1673 | WMI_SET_FAILURE = 0xC00002C7, |
| 2448 | ||
| 2449 | 1674 | /// {Virtual Memory Minimum Too Low} Your system is low on virtual memory. |
| 2450 | 1675 | /// Windows is increasing the size of your virtual memory paging file. |
| 2451 | 1676 | /// During this process, memory requests for some applications might be denied. For more information, see Help. |
| 2452 | 1677 | COMMITMENT_MINIMUM = 0xC00002C8, |
| 2453 | ||
| 2454 | 1678 | /// {EXCEPTION} Register NaT consumption faults. |
| 2455 | 1679 | /// A NaT value is consumed on a non-speculative instruction. |
| 2456 | 1680 | REG_NAT_CONSUMPTION = 0xC00002C9, |
| 2457 | ||
| 2458 | 1681 | /// The transport element of the medium changer contains media, which is causing the operation to fail. |
| 2459 | 1682 | TRANSPORT_FULL = 0xC00002CA, |
| 2460 | ||
| 2461 | 1683 | /// Security Accounts Manager initialization failed because of the following error: %hs Error Status: 0x%x. |
| 2462 | 1684 | /// Click OK to shut down this system and restart in Directory Services Restore Mode. |
| 2463 | 1685 | /// Check the event log for more detailed information. |
| 2464 | 1686 | DS_SAM_INIT_FAILURE = 0xC00002CB, |
| 2465 | ||
| 2466 | 1687 | /// This operation is supported only when you are connected to the server. |
| 2467 | 1688 | ONLY_IF_CONNECTED = 0xC00002CC, |
| 2468 | ||
| 2469 | 1689 | /// Only an administrator can modify the membership list of an administrative group. |
| 2470 | 1690 | DS_SENSITIVE_GROUP_VIOLATION = 0xC00002CD, |
| 2471 | ||
| 2472 | 1691 | /// A device was removed so enumeration must be restarted. |
| 2473 | 1692 | PNP_RESTART_ENUMERATION = 0xC00002CE, |
| 2474 | ||
| 2475 | 1693 | /// The journal entry has been deleted from the journal. |
| 2476 | 1694 | JOURNAL_ENTRY_DELETED = 0xC00002CF, |
| 2477 | ||
| 2478 | 1695 | /// Cannot change the primary group ID of a domain controller account. |
| 2479 | 1696 | DS_CANT_MOD_PRIMARYGROUPID = 0xC00002D0, |
| 2480 | ||
| 2481 | 1697 | /// {Fatal System Error} The system image %s is not properly signed. |
| 2482 | 1698 | /// The file has been replaced with the signed file. The system has been shut down. |
| 2483 | 1699 | SYSTEM_IMAGE_BAD_SIGNATURE = 0xC00002D1, |
| 2484 | ||
| 2485 | 1700 | /// The device will not start without a reboot. |
| 2486 | 1701 | PNP_REBOOT_REQUIRED = 0xC00002D2, |
| 2487 | ||
| 2488 | 1702 | /// The power state of the current device cannot support this request. |
| 2489 | 1703 | POWER_STATE_INVALID = 0xC00002D3, |
| 2490 | ||
| 2491 | 1704 | /// The specified group type is invalid. |
| 2492 | 1705 | DS_INVALID_GROUP_TYPE = 0xC00002D4, |
| 2493 | ||
| 2494 | 1706 | /// In a mixed domain, no nesting of a global group if the group is security enabled. |
| 2495 | 1707 | DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 0xC00002D5, |
| 2496 | ||
| 2497 | 1708 | /// In a mixed domain, cannot nest local groups with other local groups, if the group is security enabled. |
| 2498 | 1709 | DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 0xC00002D6, |
| 2499 | ||
| 2500 | 1710 | /// A global group cannot have a local group as a member. |
| 2501 | 1711 | DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D7, |
| 2502 | ||
| 2503 | 1712 | /// A global group cannot have a universal group as a member. |
| 2504 | 1713 | DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 0xC00002D8, |
| 2505 | ||
| 2506 | 1714 | /// A universal group cannot have a local group as a member. |
| 2507 | 1715 | DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D9, |
| 2508 | ||
| 2509 | 1716 | /// A global group cannot have a cross-domain member. |
| 2510 | 1717 | DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 0xC00002DA, |
| 2511 | ||
| 2512 | 1718 | /// A local group cannot have another cross-domain local group as a member. |
| 2513 | 1719 | DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 0xC00002DB, |
| 2514 | ||
| 2515 | 1720 | /// Cannot change to a security-disabled group because primary members are in this group. |
| 2516 | 1721 | DS_HAVE_PRIMARY_MEMBERS = 0xC00002DC, |
| 2517 | ||
| 2518 | 1722 | /// The WMI operation is not supported by the data block or method. |
| 2519 | 1723 | WMI_NOT_SUPPORTED = 0xC00002DD, |
| 2520 | ||
| 2521 | 1724 | /// There is not enough power to complete the requested operation. |
| 2522 | 1725 | INSUFFICIENT_POWER = 0xC00002DE, |
| 2523 | ||
| 2524 | 1726 | /// The Security Accounts Manager needs to get the boot password. |
| 2525 | 1727 | SAM_NEED_BOOTKEY_PASSWORD = 0xC00002DF, |
| 2526 | ||
| 2527 | 1728 | /// The Security Accounts Manager needs to get the boot key from the floppy disk. |
| 2528 | 1729 | SAM_NEED_BOOTKEY_FLOPPY = 0xC00002E0, |
| 2529 | ||
| 2530 | 1730 | /// The directory service cannot start. |
| 2531 | 1731 | DS_CANT_START = 0xC00002E1, |
| 2532 | ||
| 2533 | 1732 | /// The directory service could not start because of the following error: %hs Error Status: 0x%x. |
| 2534 | 1733 | /// Click OK to shut down this system and restart in Directory Services Restore Mode. |
| 2535 | 1734 | /// Check the event log for more detailed information. |
| 2536 | 1735 | DS_INIT_FAILURE = 0xC00002E2, |
| 2537 | ||
| 2538 | 1736 | /// The Security Accounts Manager initialization failed because of the following error: %hs Error Status: 0x%x. |
| 2539 | 1737 | /// Click OK to shut down this system and restart in Safe Mode. |
| 2540 | 1738 | /// Check the event log for more detailed information. |
| 2541 | 1739 | SAM_INIT_FAILURE = 0xC00002E3, |
| 2542 | ||
| 2543 | 1740 | /// The requested operation can be performed only on a global catalog server. |
| 2544 | 1741 | DS_GC_REQUIRED = 0xC00002E4, |
| 2545 | ||
| 2546 | 1742 | /// A local group can only be a member of other local groups in the same domain. |
| 2547 | 1743 | DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 0xC00002E5, |
| 2548 | ||
| 2549 | 1744 | /// Foreign security principals cannot be members of universal groups. |
| 2550 | 1745 | DS_NO_FPO_IN_UNIVERSAL_GROUPS = 0xC00002E6, |
| 2551 | ||
| 2552 | 1746 | /// Your computer could not be joined to the domain. |
| 2553 | 1747 | /// You have exceeded the maximum number of computer accounts you are allowed to create in this domain. |
| 2554 | 1748 | /// Contact your system administrator to have this limit reset or increased. |
| 2555 | 1749 | DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 0xC00002E7, |
| 2556 | ||
| 2557 | 1750 | /// This operation cannot be performed on the current domain. |
| 2558 | 1751 | CURRENT_DOMAIN_NOT_ALLOWED = 0xC00002E9, |
| 2559 | ||
| 2560 | 1752 | /// The directory or file cannot be created. |
| 2561 | 1753 | CANNOT_MAKE = 0xC00002EA, |
| 2562 | ||
| 2563 | 1754 | /// The system is in the process of shutting down. |
| 2564 | 1755 | SYSTEM_SHUTDOWN = 0xC00002EB, |
| 2565 | ||
| 2566 | 1756 | /// Directory Services could not start because of the following error: %hs Error Status: 0x%x. Click OK to shut down the system. |
| 2567 | 1757 | /// You can use the recovery console to diagnose the system further. |
| 2568 | 1758 | DS_INIT_FAILURE_CONSOLE = 0xC00002EC, |
| 2569 | ||
| 2570 | 1759 | /// Security Accounts Manager initialization failed because of the following error: %hs Error Status: 0x%x. Click OK to shut down the system. |
| 2571 | 1760 | /// You can use the recovery console to diagnose the system further. |
| 2572 | 1761 | DS_SAM_INIT_FAILURE_CONSOLE = 0xC00002ED, |
| 2573 | ||
| 2574 | 1762 | /// A security context was deleted before the context was completed. This is considered a logon failure. |
| 2575 | 1763 | UNFINISHED_CONTEXT_DELETED = 0xC00002EE, |
| 2576 | ||
| 2577 | 1764 | /// The client is trying to negotiate a context and the server requires user-to-user but did not send a TGT reply. |
| 2578 | 1765 | NO_TGT_REPLY = 0xC00002EF, |
| 2579 | ||
| 2580 | 1766 | /// An object ID was not found in the file. |
| 2581 | 1767 | OBJECTID_NOT_FOUND = 0xC00002F0, |
| 2582 | ||
| 2583 | 1768 | /// Unable to accomplish the requested task because the local machine does not have any IP addresses. |
| 2584 | 1769 | NO_IP_ADDRESSES = 0xC00002F1, |
| 2585 | ||
| 2586 | 1770 | /// The supplied credential handle does not match the credential that is associated with the security context. |
| 2587 | 1771 | WRONG_CREDENTIAL_HANDLE = 0xC00002F2, |
| 2588 | ||
| 2589 | 1772 | /// The crypto system or checksum function is invalid because a required function is unavailable. |
| 2590 | 1773 | CRYPTO_SYSTEM_INVALID = 0xC00002F3, |
| 2591 | ||
| 2592 | 1774 | /// The number of maximum ticket referrals has been exceeded. |
| 2593 | 1775 | MAX_REFERRALS_EXCEEDED = 0xC00002F4, |
| 2594 | ||
| 2595 | 1776 | /// The local machine must be a Kerberos KDC (domain controller) and it is not. |
| 2596 | 1777 | MUST_BE_KDC = 0xC00002F5, |
| 2597 | ||
| 2598 | 1778 | /// The other end of the security negotiation requires strong crypto but it is not supported on the local machine. |
| 2599 | 1779 | STRONG_CRYPTO_NOT_SUPPORTED = 0xC00002F6, |
| 2600 | ||
| 2601 | 1780 | /// The KDC reply contained more than one principal name. |
| 2602 | 1781 | TOO_MANY_PRINCIPALS = 0xC00002F7, |
| 2603 | ||
| 2604 | 1782 | /// Expected to find PA data for a hint of what etype to use, but it was not found. |
| 2605 | 1783 | NO_PA_DATA = 0xC00002F8, |
| 2606 | ||
| 2607 | 1784 | /// The client certificate does not contain a valid UPN, or does not match the client name in the logon request. Contact your administrator. |
| 2608 | 1785 | PKINIT_NAME_MISMATCH = 0xC00002F9, |
| 2609 | ||
| 2610 | 1786 | /// Smart card logon is required and was not used. |
| 2611 | 1787 | SMARTCARD_LOGON_REQUIRED = 0xC00002FA, |
| 2612 | ||
| 2613 | 1788 | /// An invalid request was sent to the KDC. |
| 2614 | 1789 | KDC_INVALID_REQUEST = 0xC00002FB, |
| 2615 | ||
| 2616 | 1790 | /// The KDC was unable to generate a referral for the service requested. |
| 2617 | 1791 | KDC_UNABLE_TO_REFER = 0xC00002FC, |
| 2618 | ||
| 2619 | 1792 | /// The encryption type requested is not supported by the KDC. |
| 2620 | 1793 | KDC_UNKNOWN_ETYPE = 0xC00002FD, |
| 2621 | ||
| 2622 | 1794 | /// A system shutdown is in progress. |
| 2623 | 1795 | SHUTDOWN_IN_PROGRESS = 0xC00002FE, |
| 2624 | ||
| 2625 | 1796 | /// The server machine is shutting down. |
| 2626 | 1797 | SERVER_SHUTDOWN_IN_PROGRESS = 0xC00002FF, |
| 2627 | ||
| 2628 | 1798 | /// This operation is not supported on a computer running Windows Server 2003 operating system for Small Business Server. |
| 2629 | 1799 | NOT_SUPPORTED_ON_SBS = 0xC0000300, |
| 2630 | ||
| 2631 | 1800 | /// The WMI GUID is no longer available. |
| 2632 | 1801 | WMI_GUID_DISCONNECTED = 0xC0000301, |
| 2633 | ||
| 2634 | 1802 | /// Collection or events for the WMI GUID is already disabled. |
| 2635 | 1803 | WMI_ALREADY_DISABLED = 0xC0000302, |
| 2636 | ||
| 2637 | 1804 | /// Collection or events for the WMI GUID is already enabled. |
| 2638 | 1805 | WMI_ALREADY_ENABLED = 0xC0000303, |
| 2639 | ||
| 2640 | 1806 | /// The master file table on the volume is too fragmented to complete this operation. |
| 2641 | 1807 | MFT_TOO_FRAGMENTED = 0xC0000304, |
| 2642 | ||
| 2643 | 1808 | /// Copy protection failure. |
| 2644 | 1809 | COPY_PROTECTION_FAILURE = 0xC0000305, |
| 2645 | ||
| 2646 | 1810 | /// Copy protection error—DVD CSS Authentication failed. |
| 2647 | 1811 | CSS_AUTHENTICATION_FAILURE = 0xC0000306, |
| 2648 | ||
| 2649 | 1812 | /// Copy protection error—The specified sector does not contain a valid key. |
| 2650 | 1813 | CSS_KEY_NOT_PRESENT = 0xC0000307, |
| 2651 | ||
| 2652 | 1814 | /// Copy protection error—DVD session key not established. |
| 2653 | 1815 | CSS_KEY_NOT_ESTABLISHED = 0xC0000308, |
| 2654 | ||
| 2655 | 1816 | /// Copy protection error—The read failed because the sector is encrypted. |
| 2656 | 1817 | CSS_SCRAMBLED_SECTOR = 0xC0000309, |
| 2657 | ||
| 2658 | 1818 | /// Copy protection error—The region of the specified DVD does not correspond to the region setting of the drive. |
| 2659 | 1819 | CSS_REGION_MISMATCH = 0xC000030A, |
| 2660 | ||
| 2661 | 1820 | /// Copy protection error—The region setting of the drive might be permanent. |
| 2662 | 1821 | CSS_RESETS_EXHAUSTED = 0xC000030B, |
| 2663 | ||
| 2664 | 1822 | /// The Kerberos protocol encountered an error while validating the KDC certificate during smart card logon. |
| 2665 | 1823 | /// There is more information in the system event log. |
| 2666 | 1824 | PKINIT_FAILURE = 0xC0000320, |
| 2667 | ||
| 2668 | 1825 | /// The Kerberos protocol encountered an error while attempting to use the smart card subsystem. |
| 2669 | 1826 | SMARTCARD_SUBSYSTEM_FAILURE = 0xC0000321, |
| 2670 | ||
| 2671 | 1827 | /// The target server does not have acceptable Kerberos credentials. |
| 2672 | 1828 | NO_KERB_KEY = 0xC0000322, |
| 2673 | ||
| 2674 | 1829 | /// The transport determined that the remote system is down. |
| 2675 | 1830 | HOST_DOWN = 0xC0000350, |
| 2676 | ||
| 2677 | 1831 | /// An unsupported pre-authentication mechanism was presented to the Kerberos package. |
| 2678 | 1832 | UNSUPPORTED_PREAUTH = 0xC0000351, |
| 2679 | ||
| 2680 | 1833 | /// The encryption algorithm that is used on the source file needs a bigger key buffer than the one that is used on the destination file. |
| 2681 | 1834 | EFS_ALG_BLOB_TOO_BIG = 0xC0000352, |
| 2682 | ||
| 2683 | 1835 | /// An attempt to remove a processes DebugPort was made, but a port was not already associated with the process. |
| 2684 | 1836 | PORT_NOT_SET = 0xC0000353, |
| 2685 | ||
| 2686 | 1837 | /// An attempt to do an operation on a debug port failed because the port is in the process of being deleted. |
| 2687 | 1838 | DEBUGGER_INACTIVE = 0xC0000354, |
| 2688 | ||
| 2689 | 1839 | /// This version of Windows is not compatible with the behavior version of the directory forest, domain, or domain controller. |
| 2690 | 1840 | DS_VERSION_CHECK_FAILURE = 0xC0000355, |
| 2691 | ||
| 2692 | 1841 | /// The specified event is currently not being audited. |
| 2693 | 1842 | AUDITING_DISABLED = 0xC0000356, |
| 2694 | ||
| 2695 | 1843 | /// The machine account was created prior to Windows NT 4.0 operating system. The account needs to be recreated. |
| 2696 | 1844 | PRENT4_MACHINE_ACCOUNT = 0xC0000357, |
| 2697 | ||
| 2698 | 1845 | /// An account group cannot have a universal group as a member. |
| 2699 | 1846 | DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 0xC0000358, |
| 2700 | ||
| 2701 | 1847 | /// The specified image file did not have the correct format; it appears to be a 32-bit Windows image. |
| 2702 | 1848 | INVALID_IMAGE_WIN_32 = 0xC0000359, |
| 2703 | ||
| 2704 | 1849 | /// The specified image file did not have the correct format; it appears to be a 64-bit Windows image. |
| 2705 | 1850 | INVALID_IMAGE_WIN_64 = 0xC000035A, |
| 2706 | ||
| 2707 | 1851 | /// The client's supplied SSPI channel bindings were incorrect. |
| 2708 | 1852 | BAD_BINDINGS = 0xC000035B, |
| 2709 | ||
| 2710 | 1853 | /// The client session has expired; so the client must re-authenticate to continue accessing the remote resources. |
| 2711 | 1854 | NETWORK_SESSION_EXPIRED = 0xC000035C, |
| 2712 | ||
| 2713 | 1855 | /// The AppHelp dialog box canceled; thus preventing the application from starting. |
| 2714 | 1856 | APPHELP_BLOCK = 0xC000035D, |
| 2715 | ||
| 2716 | 1857 | /// The SID filtering operation removed all SIDs. |
| 2717 | 1858 | ALL_SIDS_FILTERED = 0xC000035E, |
| 2718 | ||
| 2719 | 1859 | /// The driver was not loaded because the system is starting in safe mode. |
| 2720 | 1860 | NOT_SAFE_MODE_DRIVER = 0xC000035F, |
| 2721 | ||
| 2722 | 1861 | /// Access to %1 has been restricted by your Administrator by the default software restriction policy level. |
| 2723 | 1862 | ACCESS_DISABLED_BY_POLICY_DEFAULT = 0xC0000361, |
| 2724 | ||
| 2725 | 1863 | /// Access to %1 has been restricted by your Administrator by location with policy rule %2 placed on path %3. |
| 2726 | 1864 | ACCESS_DISABLED_BY_POLICY_PATH = 0xC0000362, |
| 2727 | ||
| 2728 | 1865 | /// Access to %1 has been restricted by your Administrator by software publisher policy. |
| 2729 | 1866 | ACCESS_DISABLED_BY_POLICY_PUBLISHER = 0xC0000363, |
| 2730 | ||
| 2731 | 1867 | /// Access to %1 has been restricted by your Administrator by policy rule %2. |
| 2732 | 1868 | ACCESS_DISABLED_BY_POLICY_OTHER = 0xC0000364, |
| 2733 | ||
| 2734 | 1869 | /// The driver was not loaded because it failed its initialization call. |
| 2735 | 1870 | FAILED_DRIVER_ENTRY = 0xC0000365, |
| 2736 | ||
| 2737 | 1871 | /// The device encountered an error while applying power or reading the device configuration. |
| 2738 | 1872 | /// This might be caused by a failure of your hardware or by a poor connection. |
| 2739 | 1873 | DEVICE_ENUMERATION_ERROR = 0xC0000366, |
| 2740 | ||
| 2741 | 1874 | /// The create operation failed because the name contained at least one mount point that resolves to a volume to which the specified device object is not attached. |
| 2742 | 1875 | MOUNT_POINT_NOT_RESOLVED = 0xC0000368, |
| 2743 | ||
| 2744 | 1876 | /// The device object parameter is either not a valid device object or is not attached to the volume that is specified by the file name. |
| 2745 | 1877 | INVALID_DEVICE_OBJECT_PARAMETER = 0xC0000369, |
| 2746 | ||
| 2747 | 1878 | /// A machine check error has occurred. |
| 2748 | 1879 | /// Check the system event log for additional information. |
| 2749 | 1880 | MCA_OCCURED = 0xC000036A, |
| 2750 | ||
| 2751 | 1881 | /// Driver %2 has been blocked from loading. |
| 2752 | 1882 | DRIVER_BLOCKED_CRITICAL = 0xC000036B, |
| 2753 | ||
| 2754 | 1883 | /// Driver %2 has been blocked from loading. |
| 2755 | 1884 | DRIVER_BLOCKED = 0xC000036C, |
| 2756 | ||
| 2757 | 1885 | /// There was error [%2] processing the driver database. |
| 2758 | 1886 | DRIVER_DATABASE_ERROR = 0xC000036D, |
| 2759 | ||
| 2760 | 1887 | /// System hive size has exceeded its limit. |
| 2761 | 1888 | SYSTEM_HIVE_TOO_LARGE = 0xC000036E, |
| 2762 | ||
| 2763 | 1889 | /// A dynamic link library (DLL) referenced a module that was neither a DLL nor the process's executable image. |
| 2764 | 1890 | INVALID_IMPORT_OF_NON_DLL = 0xC000036F, |
| 2765 | ||
| 2766 | 1891 | /// The local account store does not contain secret material for the specified account. |
| 2767 | 1892 | NO_SECRETS = 0xC0000371, |
| 2768 | ||
| 2769 | 1893 | /// Access to %1 has been restricted by your Administrator by policy rule %2. |
| 2770 | 1894 | ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 0xC0000372, |
| 2771 | ||
| 2772 | 1895 | /// The system was not able to allocate enough memory to perform a stack switch. |
| 2773 | 1896 | FAILED_STACK_SWITCH = 0xC0000373, |
| 2774 | ||
| 2775 | 1897 | /// A heap has been corrupted. |
| 2776 | 1898 | HEAP_CORRUPTION = 0xC0000374, |
| 2777 | ||
| 2778 | 1899 | /// An incorrect PIN was presented to the smart card. |
| 2779 | 1900 | SMARTCARD_WRONG_PIN = 0xC0000380, |
| 2780 | ||
| 2781 | 1901 | /// The smart card is blocked. |
| 2782 | 1902 | SMARTCARD_CARD_BLOCKED = 0xC0000381, |
| 2783 | ||
| 2784 | 1903 | /// No PIN was presented to the smart card. |
| 2785 | 1904 | SMARTCARD_CARD_NOT_AUTHENTICATED = 0xC0000382, |
| 2786 | ||
| 2787 | 1905 | /// No smart card is available. |
| 2788 | 1906 | SMARTCARD_NO_CARD = 0xC0000383, |
| 2789 | ||
| 2790 | 1907 | /// The requested key container does not exist on the smart card. |
| 2791 | 1908 | SMARTCARD_NO_KEY_CONTAINER = 0xC0000384, |
| 2792 | ||
| 2793 | 1909 | /// The requested certificate does not exist on the smart card. |
| 2794 | 1910 | SMARTCARD_NO_CERTIFICATE = 0xC0000385, |
| 2795 | ||
| 2796 | 1911 | /// The requested keyset does not exist. |
| 2797 | 1912 | SMARTCARD_NO_KEYSET = 0xC0000386, |
| 2798 | ||
| 2799 | 1913 | /// A communication error with the smart card has been detected. |
| 2800 | 1914 | SMARTCARD_IO_ERROR = 0xC0000387, |
| 2801 | ||
| 2802 | 1915 | /// The system detected a possible attempt to compromise security. |
| 2803 | 1916 | /// Ensure that you can contact the server that authenticated you. |
| 2804 | 1917 | DOWNGRADE_DETECTED = 0xC0000388, |
| 2805 | ||
| 2806 | 1918 | /// The smart card certificate used for authentication has been revoked. Contact your system administrator. |
| 2807 | 1919 | /// There might be additional information in the event log. |
| 2808 | 1920 | SMARTCARD_CERT_REVOKED = 0xC0000389, |
| 2809 | ||
| 2810 | 1921 | /// An untrusted certificate authority was detected while processing the smart card certificate that is used for authentication. Contact your system administrator. |
| 2811 | 1922 | ISSUING_CA_UNTRUSTED = 0xC000038A, |
| 2812 | ||
| 2813 | 1923 | /// The revocation status of the smart card certificate that is used for authentication could not be determined. Contact your system administrator. |
| 2814 | 1924 | REVOCATION_OFFLINE_C = 0xC000038B, |
| 2815 | ||
| 2816 | 1925 | /// The smart card certificate used for authentication was not trusted. Contact your system administrator. |
| 2817 | 1926 | PKINIT_CLIENT_FAILURE = 0xC000038C, |
| 2818 | ||
| 2819 | 1927 | /// The smart card certificate used for authentication has expired. Contact your system administrator. |
| 2820 | 1928 | SMARTCARD_CERT_EXPIRED = 0xC000038D, |
| 2821 | ||
| 2822 | 1929 | /// The driver could not be loaded because a previous version of the driver is still in memory. |
| 2823 | 1930 | DRIVER_FAILED_PRIOR_UNLOAD = 0xC000038E, |
| 2824 | ||
| 2825 | 1931 | /// The smart card provider could not perform the action because the context was acquired as silent. |
| 2826 | 1932 | SMARTCARD_SILENT_CONTEXT = 0xC000038F, |
| 2827 | ||
| 2828 | 1933 | /// The delegated trust creation quota of the current user has been exceeded. |
| 2829 | 1934 | PER_USER_TRUST_QUOTA_EXCEEDED = 0xC0000401, |
| 2830 | ||
| 2831 | 1935 | /// The total delegated trust creation quota has been exceeded. |
| 2832 | 1936 | ALL_USER_TRUST_QUOTA_EXCEEDED = 0xC0000402, |
| 2833 | ||
| 2834 | 1937 | /// The delegated trust deletion quota of the current user has been exceeded. |
| 2835 | 1938 | USER_DELETE_TRUST_QUOTA_EXCEEDED = 0xC0000403, |
| 2836 | ||
| 2837 | 1939 | /// The requested name already exists as a unique identifier. |
| 2838 | 1940 | DS_NAME_NOT_UNIQUE = 0xC0000404, |
| 2839 | ||
| 2840 | 1941 | /// The requested object has a non-unique identifier and cannot be retrieved. |
| 2841 | 1942 | DS_DUPLICATE_ID_FOUND = 0xC0000405, |
| 2842 | ||
| 2843 | 1943 | /// The group cannot be converted due to attribute restrictions on the requested group type. |
| 2844 | 1944 | DS_GROUP_CONVERSION_ERROR = 0xC0000406, |
| 2845 | ||
| 2846 | 1945 | /// {Volume Shadow Copy Service} Wait while the Volume Shadow Copy Service prepares volume %hs for hibernation. |
| 2847 | 1946 | VOLSNAP_PREPARE_HIBERNATE = 0xC0000407, |
| 2848 | ||
| 2849 | 1947 | /// Kerberos sub-protocol User2User is required. |
| 2850 | 1948 | USER2USER_REQUIRED = 0xC0000408, |
| 2851 | ||
| 2852 | 1949 | /// The system detected an overrun of a stack-based buffer in this application. |
| 2853 | 1950 | /// This overrun could potentially allow a malicious user to gain control of this application. |
| 2854 | 1951 | STACK_BUFFER_OVERRUN = 0xC0000409, |
| 2855 | ||
| 2856 | 1952 | /// The Kerberos subsystem encountered an error. |
| 2857 | 1953 | /// A service for user protocol request was made against a domain controller which does not support service for user. |
| 2858 | 1954 | NO_S4U_PROT_SUPPORT = 0xC000040A, |
| 2859 | ||
| 2860 | 1955 | /// An attempt was made by this server to make a Kerberos constrained delegation request for a target that is outside the server realm. |
| 2861 | 1956 | /// This action is not supported and the resulting error indicates a misconfiguration on the allowed-to-delegate-to list for this server. Contact your administrator. |
| 2862 | 1957 | CROSSREALM_DELEGATION_FAILURE = 0xC000040B, |
| 2863 | ||
| 2864 | 1958 | /// The revocation status of the domain controller certificate used for smart card authentication could not be determined. |
| 2865 | 1959 | /// There is additional information in the system event log. Contact your system administrator. |
| 2866 | 1960 | REVOCATION_OFFLINE_KDC = 0xC000040C, |
| 2867 | ||
| 2868 | 1961 | /// An untrusted certificate authority was detected while processing the domain controller certificate used for authentication. |
| 2869 | 1962 | /// There is additional information in the system event log. Contact your system administrator. |
| 2870 | 1963 | ISSUING_CA_UNTRUSTED_KDC = 0xC000040D, |
| 2871 | ||
| 2872 | 1964 | /// The domain controller certificate used for smart card logon has expired. |
| 2873 | 1965 | /// Contact your system administrator with the contents of your system event log. |
| 2874 | 1966 | KDC_CERT_EXPIRED = 0xC000040E, |
| 2875 | ||
| 2876 | 1967 | /// The domain controller certificate used for smart card logon has been revoked. |
| 2877 | 1968 | /// Contact your system administrator with the contents of your system event log. |
| 2878 | 1969 | KDC_CERT_REVOKED = 0xC000040F, |
| 2879 | ||
| 2880 | 1970 | /// Data present in one of the parameters is more than the function can operate on. |
| 2881 | 1971 | PARAMETER_QUOTA_EXCEEDED = 0xC0000410, |
| 2882 | ||
| 2883 | 1972 | /// The system has failed to hibernate (The error code is %hs). |
| 2884 | 1973 | /// Hibernation will be disabled until the system is restarted. |
| 2885 | 1974 | HIBERNATION_FAILURE = 0xC0000411, |
| 2886 | ||
| 2887 | 1975 | /// An attempt to delay-load a .dll or get a function address in a delay-loaded .dll failed. |
| 2888 | 1976 | DELAY_LOAD_FAILED = 0xC0000412, |
| 2889 | ||
| 2890 | 1977 | /// Logon Failure: The machine you are logging onto is protected by an authentication firewall. |
| 2891 | 1978 | /// The specified account is not allowed to authenticate to the machine. |
| 2892 | 1979 | AUTHENTICATION_FIREWALL_FAILED = 0xC0000413, |
| 2893 | ||
| 2894 | 1980 | /// %hs is a 16-bit application. You do not have permissions to execute 16-bit applications. |
| 2895 | 1981 | /// Check your permissions with your system administrator. |
| 2896 | 1982 | VDM_DISALLOWED = 0xC0000414, |
| 2897 | ||
| 2898 | 1983 | /// {Display Driver Stopped Responding} The %hs display driver has stopped working normally. |
| 2899 | 1984 | /// Save your work and reboot the system to restore full display functionality. |
| 2900 | 1985 | /// The next time you reboot the machine a dialog will be displayed giving you a chance to report this failure to Microsoft. |
| 2901 | 1986 | HUNG_DISPLAY_DRIVER_THREAD = 0xC0000415, |
| 2902 | ||
| 2903 | 1987 | /// The Desktop heap encountered an error while allocating session memory. |
| 2904 | 1988 | /// There is more information in the system event log. |
| 2905 | 1989 | INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 0xC0000416, |
| 2906 | ||
| 2907 | 1990 | /// An invalid parameter was passed to a C runtime function. |
| 2908 | 1991 | INVALID_CRUNTIME_PARAMETER = 0xC0000417, |
| 2909 | ||
| 2910 | 1992 | /// The authentication failed because NTLM was blocked. |
| 2911 | 1993 | NTLM_BLOCKED = 0xC0000418, |
| 2912 | ||
| 2913 | 1994 | /// The source object's SID already exists in destination forest. |
| 2914 | 1995 | DS_SRC_SID_EXISTS_IN_FOREST = 0xC0000419, |
| 2915 | ||
| 2916 | 1996 | /// The domain name of the trusted domain already exists in the forest. |
| 2917 | 1997 | DS_DOMAIN_NAME_EXISTS_IN_FOREST = 0xC000041A, |
| 2918 | ||
| 2919 | 1998 | /// The flat name of the trusted domain already exists in the forest. |
| 2920 | 1999 | DS_FLAT_NAME_EXISTS_IN_FOREST = 0xC000041B, |
| 2921 | ||
| 2922 | 2000 | /// The User Principal Name (UPN) is invalid. |
| 2923 | 2001 | INVALID_USER_PRINCIPAL_NAME = 0xC000041C, |
| 2924 | ||
| 2925 | 2002 | /// There has been an assertion failure. |
| 2926 | 2003 | ASSERTION_FAILURE = 0xC0000420, |
| 2927 | ||
| 2928 | 2004 | /// Application verifier has found an error in the current process. |
| 2929 | 2005 | VERIFIER_STOP = 0xC0000421, |
| 2930 | ||
| 2931 | 2006 | /// A user mode unwind is in progress. |
| 2932 | 2007 | CALLBACK_POP_STACK = 0xC0000423, |
| 2933 | ||
| 2934 | 2008 | /// %2 has been blocked from loading due to incompatibility with this system. |
| 2935 | 2009 | /// Contact your software vendor for a compatible version of the driver. |
| 2936 | 2010 | INCOMPATIBLE_DRIVER_BLOCKED = 0xC0000424, |
| 2937 | ||
| 2938 | 2011 | /// Illegal operation attempted on a registry key which has already been unloaded. |
| 2939 | 2012 | HIVE_UNLOADED = 0xC0000425, |
| 2940 | ||
| 2941 | 2013 | /// Compression is disabled for this volume. |
| 2942 | 2014 | COMPRESSION_DISABLED = 0xC0000426, |
| 2943 | ||
| 2944 | 2015 | /// The requested operation could not be completed due to a file system limitation. |
| 2945 | 2016 | FILE_SYSTEM_LIMITATION = 0xC0000427, |
| 2946 | ||
| 2947 | 2017 | /// The hash for image %hs cannot be found in the system catalogs. |
| 2948 | 2018 | /// The image is likely corrupt or the victim of tampering. |
| 2949 | 2019 | INVALID_IMAGE_HASH = 0xC0000428, |
| 2950 | ||
| 2951 | 2020 | /// The implementation is not capable of performing the request. |
| 2952 | 2021 | NOT_CAPABLE = 0xC0000429, |
| 2953 | ||
| 2954 | 2022 | /// The requested operation is out of order with respect to other operations. |
| 2955 | 2023 | REQUEST_OUT_OF_SEQUENCE = 0xC000042A, |
| 2956 | ||
| 2957 | 2024 | /// An operation attempted to exceed an implementation-defined limit. |
| 2958 | 2025 | IMPLEMENTATION_LIMIT = 0xC000042B, |
| 2959 | ||
| 2960 | 2026 | /// The requested operation requires elevation. |
| 2961 | 2027 | ELEVATION_REQUIRED = 0xC000042C, |
| 2962 | ||
| 2963 | 2028 | /// The required security context does not exist. |
| 2964 | 2029 | NO_SECURITY_CONTEXT = 0xC000042D, |
| 2965 | ||
| 2966 | 2030 | /// The PKU2U protocol encountered an error while attempting to utilize the associated certificates. |
| 2967 | 2031 | PKU2U_CERT_FAILURE = 0xC000042E, |
| 2968 | ||
| 2969 | 2032 | /// The operation was attempted beyond the valid data length of the file. |
| 2970 | 2033 | BEYOND_VDL = 0xC0000432, |
| 2971 | ||
| 2972 | 2034 | /// The attempted write operation encountered a write already in progress for some portion of the range. |
| 2973 | 2035 | ENCOUNTERED_WRITE_IN_PROGRESS = 0xC0000433, |
| 2974 | ||
| 2975 | 2036 | /// The page fault mappings changed in the middle of processing a fault so the operation must be retried. |
| 2976 | 2037 | PTE_CHANGED = 0xC0000434, |
| 2977 | ||
| 2978 | 2038 | /// The attempt to purge this file from memory failed to purge some or all the data from memory. |
| 2979 | 2039 | PURGE_FAILED = 0xC0000435, |
| 2980 | ||
| 2981 | 2040 | /// The requested credential requires confirmation. |
| 2982 | 2041 | CRED_REQUIRES_CONFIRMATION = 0xC0000440, |
| 2983 | ||
| 2984 | 2042 | /// The remote server sent an invalid response for a file being opened with Client Side Encryption. |
| 2985 | 2043 | CS_ENCRYPTION_INVALID_SERVER_RESPONSE = 0xC0000441, |
| 2986 | ||
| 2987 | 2044 | /// Client Side Encryption is not supported by the remote server even though it claims to support it. |
| 2988 | 2045 | CS_ENCRYPTION_UNSUPPORTED_SERVER = 0xC0000442, |
| 2989 | ||
| 2990 | 2046 | /// File is encrypted and should be opened in Client Side Encryption mode. |
| 2991 | 2047 | CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE = 0xC0000443, |
| 2992 | ||
| 2993 | 2048 | /// A new encrypted file is being created and a $EFS needs to be provided. |
| 2994 | 2049 | CS_ENCRYPTION_NEW_ENCRYPTED_FILE = 0xC0000444, |
| 2995 | ||
| 2996 | 2050 | /// The SMB client requested a CSE FSCTL on a non-CSE file. |
| 2997 | 2051 | CS_ENCRYPTION_FILE_NOT_CSE = 0xC0000445, |
| 2998 | ||
| 2999 | 2052 | /// Indicates a particular Security ID cannot be assigned as the label of an object. |
| 3000 | 2053 | INVALID_LABEL = 0xC0000446, |
| 3001 | ||
| 3002 | 2054 | /// The process hosting the driver for this device has terminated. |
| 3003 | 2055 | DRIVER_PROCESS_TERMINATED = 0xC0000450, |
| 3004 | ||
| 3005 | 2056 | /// The requested system device cannot be identified due to multiple indistinguishable devices potentially matching the identification criteria. |
| 3006 | 2057 | AMBIGUOUS_SYSTEM_DEVICE = 0xC0000451, |
| 3007 | ||
| 3008 | 2058 | /// The requested system device cannot be found. |
| 3009 | 2059 | SYSTEM_DEVICE_NOT_FOUND = 0xC0000452, |
| 3010 | ||
| 3011 | 2060 | /// This boot application must be restarted. |
| 3012 | 2061 | RESTART_BOOT_APPLICATION = 0xC0000453, |
| 3013 | ||
| 3014 | 2062 | /// Insufficient NVRAM resources exist to complete the API. A reboot might be required. |
| 3015 | 2063 | INSUFFICIENT_NVRAM_RESOURCES = 0xC0000454, |
| 3016 | ||
| 3017 | 2064 | /// No ranges for the specified operation were able to be processed. |
| 3018 | 2065 | NO_RANGES_PROCESSED = 0xC0000460, |
| 3019 | ||
| 3020 | 2066 | /// The storage device does not support Offload Write. |
| 3021 | 2067 | DEVICE_FEATURE_NOT_SUPPORTED = 0xC0000463, |
| 3022 | ||
| 3023 | 2068 | /// Data cannot be moved because the source device cannot communicate with the destination device. |
| 3024 | 2069 | DEVICE_UNREACHABLE = 0xC0000464, |
| 3025 | ||
| 3026 | 2070 | /// The token representing the data is invalid or expired. |
| 3027 | 2071 | INVALID_TOKEN = 0xC0000465, |
| 3028 | ||
| 3029 | 2072 | /// The file server is temporarily unavailable. |
| 3030 | 2073 | SERVER_UNAVAILABLE = 0xC0000466, |
| 3031 | ||
| 3032 | 2074 | /// The specified task name is invalid. |
| 3033 | 2075 | INVALID_TASK_NAME = 0xC0000500, |
| 3034 | ||
| 3035 | 2076 | /// The specified task index is invalid. |
| 3036 | 2077 | INVALID_TASK_INDEX = 0xC0000501, |
| 3037 | ||
| 3038 | 2078 | /// The specified thread is already joining a task. |
| 3039 | 2079 | THREAD_ALREADY_IN_TASK = 0xC0000502, |
| 3040 | ||
| 3041 | 2080 | /// A callback has requested to bypass native code. |
| 3042 | 2081 | CALLBACK_BYPASS = 0xC0000503, |
| 3043 | ||
| 3044 | 2082 | /// A fail fast exception occurred. |
| 3045 | 2083 | /// Exception handlers will not be invoked and the process will be terminated immediately. |
| 3046 | 2084 | FAIL_FAST_EXCEPTION = 0xC0000602, |
| 3047 | ||
| 3048 | 2085 | /// Windows cannot verify the digital signature for this file. |
| 3049 | 2086 | /// The signing certificate for this file has been revoked. |
| 3050 | 2087 | IMAGE_CERT_REVOKED = 0xC0000603, |
| 3051 | ||
| 3052 | 2088 | /// The ALPC port is closed. |
| 3053 | 2089 | PORT_CLOSED = 0xC0000700, |
| 3054 | ||
| 3055 | 2090 | /// The ALPC message requested is no longer available. |
| 3056 | 2091 | MESSAGE_LOST = 0xC0000701, |
| 3057 | ||
| 3058 | 2092 | /// The ALPC message supplied is invalid. |
| 3059 | 2093 | INVALID_MESSAGE = 0xC0000702, |
| 3060 | ||
| 3061 | 2094 | /// The ALPC message has been canceled. |
| 3062 | 2095 | REQUEST_CANCELED = 0xC0000703, |
| 3063 | ||
| 3064 | 2096 | /// Invalid recursive dispatch attempt. |
| 3065 | 2097 | RECURSIVE_DISPATCH = 0xC0000704, |
| 3066 | ||
| 3067 | 2098 | /// No receive buffer has been supplied in a synchronous request. |
| 3068 | 2099 | LPC_RECEIVE_BUFFER_EXPECTED = 0xC0000705, |
| 3069 | ||
| 3070 | 2100 | /// The connection port is used in an invalid context. |
| 3071 | 2101 | LPC_INVALID_CONNECTION_USAGE = 0xC0000706, |
| 3072 | ||
| 3073 | 2102 | /// The ALPC port does not accept new request messages. |
| 3074 | 2103 | LPC_REQUESTS_NOT_ALLOWED = 0xC0000707, |
| 3075 | ||
| 3076 | 2104 | /// The resource requested is already in use. |
| 3077 | 2105 | RESOURCE_IN_USE = 0xC0000708, |
| 3078 | ||
| 3079 | 2106 | /// The hardware has reported an uncorrectable memory error. |
| 3080 | 2107 | HARDWARE_MEMORY_ERROR = 0xC0000709, |
| 3081 | ||
| 3082 | 2108 | /// Status 0x%08x was returned, waiting on handle 0x%x for wait 0x%p, in waiter 0x%p. |
| 3083 | 2109 | THREADPOOL_HANDLE_EXCEPTION = 0xC000070A, |
| 3084 | ||
| 3085 | 2110 | /// After a callback to 0x%p(0x%p), a completion call to Set event(0x%p) failed with status 0x%08x. |
| 3086 | 2111 | THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED = 0xC000070B, |
| 3087 | ||
| 3088 | 2112 | /// After a callback to 0x%p(0x%p), a completion call to ReleaseSemaphore(0x%p, %d) failed with status 0x%08x. |
| 3089 | 2113 | THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED = 0xC000070C, |
| 3090 | ||
| 3091 | 2114 | /// After a callback to 0x%p(0x%p), a completion call to ReleaseMutex(%p) failed with status 0x%08x. |
| 3092 | 2115 | THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED = 0xC000070D, |
| 3093 | ||
| 3094 | 2116 | /// After a callback to 0x%p(0x%p), a completion call to FreeLibrary(%p) failed with status 0x%08x. |
| 3095 | 2117 | THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED = 0xC000070E, |
| 3096 | ||
| 3097 | 2118 | /// The thread pool 0x%p was released while a thread was posting a callback to 0x%p(0x%p) to it. |
| 3098 | 2119 | THREADPOOL_RELEASED_DURING_OPERATION = 0xC000070F, |
| 3099 | ||
| 3100 | 2120 | /// A thread pool worker thread is impersonating a client, after a callback to 0x%p(0x%p). |
| 3101 | 2121 | /// This is unexpected, indicating that the callback is missing a call to revert the impersonation. |
| 3102 | 2122 | CALLBACK_RETURNED_WHILE_IMPERSONATING = 0xC0000710, |
| 3103 | ||
| 3104 | 2123 | /// A thread pool worker thread is impersonating a client, after executing an APC. |
| 3105 | 2124 | /// This is unexpected, indicating that the APC is missing a call to revert the impersonation. |
| 3106 | 2125 | APC_RETURNED_WHILE_IMPERSONATING = 0xC0000711, |
| 3107 | ||
| 3108 | 2126 | /// Either the target process, or the target thread's containing process, is a protected process. |
| 3109 | 2127 | PROCESS_IS_PROTECTED = 0xC0000712, |
| 3110 | ||
| 3111 | 2128 | /// A thread is getting dispatched with MCA EXCEPTION because of MCA. |
| 3112 | 2129 | MCA_EXCEPTION = 0xC0000713, |
| 3113 | ||
| 3114 | 2130 | /// The client certificate account mapping is not unique. |
| 3115 | 2131 | CERTIFICATE_MAPPING_NOT_UNIQUE = 0xC0000714, |
| 3116 | ||
| 3117 | 2132 | /// The symbolic link cannot be followed because its type is disabled. |
| 3118 | 2133 | SYMLINK_CLASS_DISABLED = 0xC0000715, |
| 3119 | ||
| 3120 | 2134 | /// Indicates that the specified string is not valid for IDN normalization. |
| 3121 | 2135 | INVALID_IDN_NORMALIZATION = 0xC0000716, |
| 3122 | ||
| 3123 | 2136 | /// No mapping for the Unicode character exists in the target multi-byte code page. |
| 3124 | 2137 | NO_UNICODE_TRANSLATION = 0xC0000717, |
| 3125 | ||
| 3126 | 2138 | /// The provided callback is already registered. |
| 3127 | 2139 | ALREADY_REGISTERED = 0xC0000718, |
| 3128 | ||
| 3129 | 2140 | /// The provided context did not match the target. |
| 3130 | 2141 | CONTEXT_MISMATCH = 0xC0000719, |
| 3131 | ||
| 3132 | 2142 | /// The specified port already has a completion list. |
| 3133 | 2143 | PORT_ALREADY_HAS_COMPLETION_LIST = 0xC000071A, |
| 3134 | ||
| 3135 | 2144 | /// A threadpool worker thread entered a callback at thread base priority 0x%x and exited at priority 0x%x. |
| 3136 | 2145 | /// This is unexpected, indicating that the callback missed restoring the priority. |
| 3137 | 2146 | CALLBACK_RETURNED_THREAD_PRIORITY = 0xC000071B, |
| 3138 | ||
| 3139 | 2147 | /// An invalid thread, handle %p, is specified for this operation. |
| 3140 | 2148 | /// Possibly, a threadpool worker thread was specified. |
| 3141 | 2149 | INVALID_THREAD = 0xC000071C, |
| 3142 | ||
| 3143 | 2150 | /// A threadpool worker thread entered a callback, which left transaction state. |
| 3144 | 2151 | /// This is unexpected, indicating that the callback missed clearing the transaction. |
| 3145 | 2152 | CALLBACK_RETURNED_TRANSACTION = 0xC000071D, |
| 3146 | ||
| 3147 | 2153 | /// A threadpool worker thread entered a callback, which left the loader lock held. |
| 3148 | 2154 | /// This is unexpected, indicating that the callback missed releasing the lock. |
| 3149 | 2155 | CALLBACK_RETURNED_LDR_LOCK = 0xC000071E, |
| 3150 | ||
| 3151 | 2156 | /// A threadpool worker thread entered a callback, which left with preferred languages set. |
| 3152 | 2157 | /// This is unexpected, indicating that the callback missed clearing them. |
| 3153 | 2158 | CALLBACK_RETURNED_LANG = 0xC000071F, |
| 3154 | ||
| 3155 | 2159 | /// A threadpool worker thread entered a callback, which left with background priorities set. |
| 3156 | 2160 | /// This is unexpected, indicating that the callback missed restoring the original priorities. |
| 3157 | 2161 | CALLBACK_RETURNED_PRI_BACK = 0xC0000720, |
| 3158 | ||
| 3159 | 2162 | /// The attempted operation required self healing to be enabled. |
| 3160 | 2163 | DISK_REPAIR_DISABLED = 0xC0000800, |
| 3161 | ||
| 3162 | 2164 | /// The directory service cannot perform the requested operation because a domain rename operation is in progress. |
| 3163 | 2165 | DS_DOMAIN_RENAME_IN_PROGRESS = 0xC0000801, |
| 3164 | ||
| 3165 | 2166 | /// An operation failed because the storage quota was exceeded. |
| 3166 | 2167 | DISK_QUOTA_EXCEEDED = 0xC0000802, |
| 3167 | ||
| 3168 | 2168 | /// An operation failed because the content was blocked. |
| 3169 | 2169 | CONTENT_BLOCKED = 0xC0000804, |
| 3170 | ||
| 3171 | 2170 | /// The operation could not be completed due to bad clusters on disk. |
| 3172 | 2171 | BAD_CLUSTERS = 0xC0000805, |
| 3173 | ||
| 3174 | 2172 | /// The operation could not be completed because the volume is dirty. Please run the Chkdsk utility and try again. |
| 3175 | 2173 | VOLUME_DIRTY = 0xC0000806, |
| 3176 | ||
| 3177 | 2174 | /// This file is checked out or locked for editing by another user. |
| 3178 | 2175 | FILE_CHECKED_OUT = 0xC0000901, |
| 3179 | ||
| 3180 | 2176 | /// The file must be checked out before saving changes. |
| 3181 | 2177 | CHECKOUT_REQUIRED = 0xC0000902, |
| 3182 | ||
| 3183 | 2178 | /// The file type being saved or retrieved has been blocked. |
| 3184 | 2179 | BAD_FILE_TYPE = 0xC0000903, |
| 3185 | ||
| 3186 | 2180 | /// The file size exceeds the limit allowed and cannot be saved. |
| 3187 | 2181 | FILE_TOO_LARGE = 0xC0000904, |
| 3188 | ||
| 3189 | 2182 | /// Access Denied. Before opening files in this location, you must first browse to the e.g. |
| 3190 | 2183 | /// site and select the option to log on automatically. |
| 3191 | 2184 | FORMS_AUTH_REQUIRED = 0xC0000905, |
| 3192 | ||
| 3193 | 2185 | /// The operation did not complete successfully because the file contains a virus. |
| 3194 | 2186 | VIRUS_INFECTED = 0xC0000906, |
| 3195 | ||
| 3196 | 2187 | /// This file contains a virus and cannot be opened. |
| 3197 | 2188 | /// Due to the nature of this virus, the file has been removed from this location. |
| 3198 | 2189 | VIRUS_DELETED = 0xC0000907, |
| 3199 | ||
| 3200 | 2190 | /// The resources required for this device conflict with the MCFG table. |
| 3201 | 2191 | BAD_MCFG_TABLE = 0xC0000908, |
| 3202 | ||
| 3203 | 2192 | /// The operation did not complete successfully because it would cause an oplock to be broken. |
| 3204 | 2193 | /// The caller has requested that existing oplocks not be broken. |
| 3205 | 2194 | CANNOT_BREAK_OPLOCK = 0xC0000909, |
| 3206 | ||
| 3207 | 2195 | /// WOW Assertion Error. |
| 3208 | 2196 | WOW_ASSERTION = 0xC0009898, |
| 3209 | ||
| 3210 | 2197 | /// The cryptographic signature is invalid. |
| 3211 | 2198 | INVALID_SIGNATURE = 0xC000A000, |
| 3212 | ||
| 3213 | 2199 | /// The cryptographic provider does not support HMAC. |
| 3214 | 2200 | HMAC_NOT_SUPPORTED = 0xC000A001, |
| 3215 | ||
| 3216 | 2201 | /// The IPsec queue overflowed. |
| 3217 | 2202 | IPSEC_QUEUE_OVERFLOW = 0xC000A010, |
| 3218 | ||
| 3219 | 2203 | /// The neighbor discovery queue overflowed. |
| 3220 | 2204 | ND_QUEUE_OVERFLOW = 0xC000A011, |
| 3221 | ||
| 3222 | 2205 | /// An Internet Control Message Protocol (ICMP) hop limit exceeded error was received. |
| 3223 | 2206 | HOPLIMIT_EXCEEDED = 0xC000A012, |
| 3224 | ||
| 3225 | 2207 | /// The protocol is not installed on the local machine. |
| 3226 | 2208 | PROTOCOL_NOT_SUPPORTED = 0xC000A013, |
| 3227 | ||
| 3228 | 2209 | /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. |
| 3229 | 2210 | /// This error might be caused by network connectivity issues. Try to save this file elsewhere. |
| 3230 | 2211 | LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 0xC000A080, |
| 3231 | ||
| 3232 | 2212 | /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. |
| 3233 | 2213 | /// This error was returned by the server on which the file exists. Try to save this file elsewhere. |
| 3234 | 2214 | LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 0xC000A081, |
| 3235 | ||
| 3236 | 2215 | /// {Delayed Write Failed} Windows was unable to save all the data for the file %hs; the data has been lost. |
| 3237 | 2216 | /// This error might be caused if the device has been removed or the media is write-protected. |
| 3238 | 2217 | LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 0xC000A082, |
| 3239 | ||
| 3240 | 2218 | /// Windows was unable to parse the requested XML data. |
| 3241 | 2219 | XML_PARSE_ERROR = 0xC000A083, |
| 3242 | ||
| 3243 | 2220 | /// An error was encountered while processing an XML digital signature. |
| 3244 | 2221 | XMLDSIG_ERROR = 0xC000A084, |
| 3245 | ||
| 3246 | 2222 | /// This indicates that the caller made the connection request in the wrong routing compartment. |
| 3247 | 2223 | WRONG_COMPARTMENT = 0xC000A085, |
| 3248 | ||
| 3249 | 2224 | /// This indicates that there was an AuthIP failure when attempting to connect to the remote host. |
| 3250 | 2225 | AUTHIP_FAILURE = 0xC000A086, |
| 3251 | ||
| 3252 | 2226 | /// OID mapped groups cannot have members. |
| 3253 | 2227 | DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS = 0xC000A087, |
| 3254 | ||
| 3255 | 2228 | /// The specified OID cannot be found. |
| 3256 | 2229 | DS_OID_NOT_FOUND = 0xC000A088, |
| 3257 | ||
| 3258 | 2230 | /// Hash generation for the specified version and hash type is not enabled on server. |
| 3259 | 2231 | HASH_NOT_SUPPORTED = 0xC000A100, |
| 3260 | ||
| 3261 | 2232 | /// The hash requests is not present or not up to date with the current file contents. |
| 3262 | 2233 | HASH_NOT_PRESENT = 0xC000A101, |
| 3263 | ||
| 3264 | 2234 | /// A file system filter on the server has not opted in for Offload Read support. |
| 3265 | 2235 | OFFLOAD_READ_FLT_NOT_SUPPORTED = 0xC000A2A1, |
| 3266 | ||
| 3267 | 2236 | /// A file system filter on the server has not opted in for Offload Write support. |
| 3268 | 2237 | OFFLOAD_WRITE_FLT_NOT_SUPPORTED = 0xC000A2A2, |
| 3269 | ||
| 3270 | 2238 | /// Offload read operations cannot be performed on: |
| 3271 | 2239 | /// - Compressed files |
| 3272 | 2240 | /// - Sparse files |
| 3273 | 2241 | /// - Encrypted files |
| 3274 | 2242 | /// - File system metadata files |
| 3275 | 2243 | OFFLOAD_READ_FILE_NOT_SUPPORTED = 0xC000A2A3, |
| 3276 | ||
| 3277 | 2244 | /// Offload write operations cannot be performed on: |
| 3278 | 2245 | /// - Compressed files |
| 3279 | 2246 | /// - Sparse files |
| 3280 | 2247 | /// - Encrypted files |
| 3281 | 2248 | /// - File system metadata files |
| 3282 | 2249 | OFFLOAD_WRITE_FILE_NOT_SUPPORTED = 0xC000A2A4, |
| 3283 | ||
| 3284 | 2250 | /// The debugger did not perform a state change. |
| 3285 | 2251 | DBG_NO_STATE_CHANGE = 0xC0010001, |
| 3286 | ||
| 3287 | 2252 | /// The debugger found that the application is not idle. |
| 3288 | 2253 | DBG_APP_NOT_IDLE = 0xC0010002, |
| 3289 | ||
| 3290 | 2254 | /// The string binding is invalid. |
| 3291 | 2255 | RPC_NT_INVALID_STRING_BINDING = 0xC0020001, |
| 3292 | ||
| 3293 | 2256 | /// The binding handle is not the correct type. |
| 3294 | 2257 | RPC_NT_WRONG_KIND_OF_BINDING = 0xC0020002, |
| 3295 | ||
| 3296 | 2258 | /// The binding handle is invalid. |
| 3297 | 2259 | RPC_NT_INVALID_BINDING = 0xC0020003, |
| 3298 | ||
| 3299 | 2260 | /// The RPC protocol sequence is not supported. |
| 3300 | 2261 | RPC_NT_PROTSEQ_NOT_SUPPORTED = 0xC0020004, |
| 3301 | ||
| 3302 | 2262 | /// The RPC protocol sequence is invalid. |
| 3303 | 2263 | RPC_NT_INVALID_RPC_PROTSEQ = 0xC0020005, |
| 3304 | ||
| 3305 | 2264 | /// The string UUID is invalid. |
| 3306 | 2265 | RPC_NT_INVALID_STRING_UUID = 0xC0020006, |
| 3307 | ||
| 3308 | 2266 | /// The endpoint format is invalid. |
| 3309 | 2267 | RPC_NT_INVALID_ENDPOINT_FORMAT = 0xC0020007, |
| 3310 | ||
| 3311 | 2268 | /// The network address is invalid. |
| 3312 | 2269 | RPC_NT_INVALID_NET_ADDR = 0xC0020008, |
| 3313 | ||
| 3314 | 2270 | /// No endpoint was found. |
| 3315 | 2271 | RPC_NT_NO_ENDPOINT_FOUND = 0xC0020009, |
| 3316 | ||
| 3317 | 2272 | /// The time-out value is invalid. |
| 3318 | 2273 | RPC_NT_INVALID_TIMEOUT = 0xC002000A, |
| 3319 | ||
| 3320 | 2274 | /// The object UUID was not found. |
| 3321 | 2275 | RPC_NT_OBJECT_NOT_FOUND = 0xC002000B, |
| 3322 | ||
| 3323 | 2276 | /// The object UUID has already been registered. |
| 3324 | 2277 | RPC_NT_ALREADY_REGISTERED = 0xC002000C, |
| 3325 | ||
| 3326 | 2278 | /// The type UUID has already been registered. |
| 3327 | 2279 | RPC_NT_TYPE_ALREADY_REGISTERED = 0xC002000D, |
| 3328 | ||
| 3329 | 2280 | /// The RPC server is already listening. |
| 3330 | 2281 | RPC_NT_ALREADY_LISTENING = 0xC002000E, |
| 3331 | ||
| 3332 | 2282 | /// No protocol sequences have been registered. |
| 3333 | 2283 | RPC_NT_NO_PROTSEQS_REGISTERED = 0xC002000F, |
| 3334 | ||
| 3335 | 2284 | /// The RPC server is not listening. |
| 3336 | 2285 | RPC_NT_NOT_LISTENING = 0xC0020010, |
| 3337 | ||
| 3338 | 2286 | /// The manager type is unknown. |
| 3339 | 2287 | RPC_NT_UNKNOWN_MGR_TYPE = 0xC0020011, |
| 3340 | ||
| 3341 | 2288 | /// The interface is unknown. |
| 3342 | 2289 | RPC_NT_UNKNOWN_IF = 0xC0020012, |
| 3343 | ||
| 3344 | 2290 | /// There are no bindings. |
| 3345 | 2291 | RPC_NT_NO_BINDINGS = 0xC0020013, |
| 3346 | ||
| 3347 | 2292 | /// There are no protocol sequences. |
| 3348 | 2293 | RPC_NT_NO_PROTSEQS = 0xC0020014, |
| 3349 | ||
| 3350 | 2294 | /// The endpoint cannot be created. |
| 3351 | 2295 | RPC_NT_CANT_CREATE_ENDPOINT = 0xC0020015, |
| 3352 | ||
| 3353 | 2296 | /// Insufficient resources are available to complete this operation. |
| 3354 | 2297 | RPC_NT_OUT_OF_RESOURCES = 0xC0020016, |
| 3355 | ||
| 3356 | 2298 | /// The RPC server is unavailable. |
| 3357 | 2299 | RPC_NT_SERVER_UNAVAILABLE = 0xC0020017, |
| 3358 | ||
| 3359 | 2300 | /// The RPC server is too busy to complete this operation. |
| 3360 | 2301 | RPC_NT_SERVER_TOO_BUSY = 0xC0020018, |
| 3361 | ||
| 3362 | 2302 | /// The network options are invalid. |
| 3363 | 2303 | RPC_NT_INVALID_NETWORK_OPTIONS = 0xC0020019, |
| 3364 | ||
| 3365 | 2304 | /// No RPCs are active on this thread. |
| 3366 | 2305 | RPC_NT_NO_CALL_ACTIVE = 0xC002001A, |
| 3367 | ||
| 3368 | 2306 | /// The RPC failed. |
| 3369 | 2307 | RPC_NT_CALL_FAILED = 0xC002001B, |
| 3370 | ||
| 3371 | 2308 | /// The RPC failed and did not execute. |
| 3372 | 2309 | RPC_NT_CALL_FAILED_DNE = 0xC002001C, |
| 3373 | ||
| 3374 | 2310 | /// An RPC protocol error occurred. |
| 3375 | 2311 | RPC_NT_PROTOCOL_ERROR = 0xC002001D, |
| 3376 | ||
| 3377 | 2312 | /// The RPC server does not support the transfer syntax. |
| 3378 | 2313 | RPC_NT_UNSUPPORTED_TRANS_SYN = 0xC002001F, |
| 3379 | ||
| 3380 | 2314 | /// The type UUID is not supported. |
| 3381 | 2315 | RPC_NT_UNSUPPORTED_TYPE = 0xC0020021, |
| 3382 | ||
| 3383 | 2316 | /// The tag is invalid. |
| 3384 | 2317 | RPC_NT_INVALID_TAG = 0xC0020022, |
| 3385 | ||
| 3386 | 2318 | /// The array bounds are invalid. |
| 3387 | 2319 | RPC_NT_INVALID_BOUND = 0xC0020023, |
| 3388 | ||
| 3389 | 2320 | /// The binding does not contain an entry name. |
| 3390 | 2321 | RPC_NT_NO_ENTRY_NAME = 0xC0020024, |
| 3391 | ||
| 3392 | 2322 | /// The name syntax is invalid. |
| 3393 | 2323 | RPC_NT_INVALID_NAME_SYNTAX = 0xC0020025, |
| 3394 | ||
| 3395 | 2324 | /// The name syntax is not supported. |
| 3396 | 2325 | RPC_NT_UNSUPPORTED_NAME_SYNTAX = 0xC0020026, |
| 3397 | ||
| 3398 | 2326 | /// No network address is available to construct a UUID. |
| 3399 | 2327 | RPC_NT_UUID_NO_ADDRESS = 0xC0020028, |
| 3400 | ||
| 3401 | 2328 | /// The endpoint is a duplicate. |
| 3402 | 2329 | RPC_NT_DUPLICATE_ENDPOINT = 0xC0020029, |
| 3403 | ||
| 3404 | 2330 | /// The authentication type is unknown. |
| 3405 | 2331 | RPC_NT_UNKNOWN_AUTHN_TYPE = 0xC002002A, |
| 3406 | ||
| 3407 | 2332 | /// The maximum number of calls is too small. |
| 3408 | 2333 | RPC_NT_MAX_CALLS_TOO_SMALL = 0xC002002B, |
| 3409 | ||
| 3410 | 2334 | /// The string is too long. |
| 3411 | 2335 | RPC_NT_STRING_TOO_LONG = 0xC002002C, |
| 3412 | ||
| 3413 | 2336 | /// The RPC protocol sequence was not found. |
| 3414 | 2337 | RPC_NT_PROTSEQ_NOT_FOUND = 0xC002002D, |
| 3415 | ||
| 3416 | 2338 | /// The procedure number is out of range. |
| 3417 | 2339 | RPC_NT_PROCNUM_OUT_OF_RANGE = 0xC002002E, |
| 3418 | ||
| 3419 | 2340 | /// The binding does not contain any authentication information. |
| 3420 | 2341 | RPC_NT_BINDING_HAS_NO_AUTH = 0xC002002F, |
| 3421 | ||
| 3422 | 2342 | /// The authentication service is unknown. |
| 3423 | 2343 | RPC_NT_UNKNOWN_AUTHN_SERVICE = 0xC0020030, |
| 3424 | ||
| 3425 | 2344 | /// The authentication level is unknown. |
| 3426 | 2345 | RPC_NT_UNKNOWN_AUTHN_LEVEL = 0xC0020031, |
| 3427 | ||
| 3428 | 2346 | /// The security context is invalid. |
| 3429 | 2347 | RPC_NT_INVALID_AUTH_IDENTITY = 0xC0020032, |
| 3430 | ||
| 3431 | 2348 | /// The authorization service is unknown. |
| 3432 | 2349 | RPC_NT_UNKNOWN_AUTHZ_SERVICE = 0xC0020033, |
| 3433 | ||
| 3434 | 2350 | /// The entry is invalid. |
| 3435 | 2351 | EPT_NT_INVALID_ENTRY = 0xC0020034, |
| 3436 | ||
| 3437 | 2352 | /// The operation cannot be performed. |
| 3438 | 2353 | EPT_NT_CANT_PERFORM_OP = 0xC0020035, |
| 3439 | ||
| 3440 | 2354 | /// No more endpoints are available from the endpoint mapper. |
| 3441 | 2355 | EPT_NT_NOT_REGISTERED = 0xC0020036, |
| 3442 | ||
| 3443 | 2356 | /// No interfaces have been exported. |
| 3444 | 2357 | RPC_NT_NOTHING_TO_EXPORT = 0xC0020037, |
| 3445 | ||
| 3446 | 2358 | /// The entry name is incomplete. |
| 3447 | 2359 | RPC_NT_INCOMPLETE_NAME = 0xC0020038, |
| 3448 | ||
| 3449 | 2360 | /// The version option is invalid. |
| 3450 | 2361 | RPC_NT_INVALID_VERS_OPTION = 0xC0020039, |
| 3451 | ||
| 3452 | 2362 | /// There are no more members. |
| 3453 | 2363 | RPC_NT_NO_MORE_MEMBERS = 0xC002003A, |
| 3454 | ||
| 3455 | 2364 | /// There is nothing to unexport. |
| 3456 | 2365 | RPC_NT_NOT_ALL_OBJS_UNEXPORTED = 0xC002003B, |
| 3457 | ||
| 3458 | 2366 | /// The interface was not found. |
| 3459 | 2367 | RPC_NT_INTERFACE_NOT_FOUND = 0xC002003C, |
| 3460 | ||
| 3461 | 2368 | /// The entry already exists. |
| 3462 | 2369 | RPC_NT_ENTRY_ALREADY_EXISTS = 0xC002003D, |
| 3463 | ||
| 3464 | 2370 | /// The entry was not found. |
| 3465 | 2371 | RPC_NT_ENTRY_NOT_FOUND = 0xC002003E, |
| 3466 | ||
| 3467 | 2372 | /// The name service is unavailable. |
| 3468 | 2373 | RPC_NT_NAME_SERVICE_UNAVAILABLE = 0xC002003F, |
| 3469 | ||
| 3470 | 2374 | /// The network address family is invalid. |
| 3471 | 2375 | RPC_NT_INVALID_NAF_ID = 0xC0020040, |
| 3472 | ||
| 3473 | 2376 | /// The requested operation is not supported. |
| 3474 | 2377 | RPC_NT_CANNOT_SUPPORT = 0xC0020041, |
| 3475 | ||
| 3476 | 2378 | /// No security context is available to allow impersonation. |
| 3477 | 2379 | RPC_NT_NO_CONTEXT_AVAILABLE = 0xC0020042, |
| 3478 | ||
| 3479 | 2380 | /// An internal error occurred in the RPC. |
| 3480 | 2381 | RPC_NT_INTERNAL_ERROR = 0xC0020043, |
| 3481 | ||
| 3482 | 2382 | /// The RPC server attempted to divide an integer by zero. |
| 3483 | 2383 | RPC_NT_ZERO_DIVIDE = 0xC0020044, |
| 3484 | ||
| 3485 | 2384 | /// An addressing error occurred in the RPC server. |
| 3486 | 2385 | RPC_NT_ADDRESS_ERROR = 0xC0020045, |
| 3487 | ||
| 3488 | 2386 | /// A floating point operation at the RPC server caused a divide by zero. |
| 3489 | 2387 | RPC_NT_FP_DIV_ZERO = 0xC0020046, |
| 3490 | ||
| 3491 | 2388 | /// A floating point underflow occurred at the RPC server. |
| 3492 | 2389 | RPC_NT_FP_UNDERFLOW = 0xC0020047, |
| 3493 | ||
| 3494 | 2390 | /// A floating point overflow occurred at the RPC server. |
| 3495 | 2391 | RPC_NT_FP_OVERFLOW = 0xC0020048, |
| 3496 | ||
| 3497 | 2392 | /// An RPC is already in progress for this thread. |
| 3498 | 2393 | RPC_NT_CALL_IN_PROGRESS = 0xC0020049, |
| 3499 | ||
| 3500 | 2394 | /// There are no more bindings. |
| 3501 | 2395 | RPC_NT_NO_MORE_BINDINGS = 0xC002004A, |
| 3502 | ||
| 3503 | 2396 | /// The group member was not found. |
| 3504 | 2397 | RPC_NT_GROUP_MEMBER_NOT_FOUND = 0xC002004B, |
| 3505 | ||
| 3506 | 2398 | /// The endpoint mapper database entry could not be created. |
| 3507 | 2399 | EPT_NT_CANT_CREATE = 0xC002004C, |
| 3508 | ||
| 3509 | 2400 | /// The object UUID is the nil UUID. |
| 3510 | 2401 | RPC_NT_INVALID_OBJECT = 0xC002004D, |
| 3511 | ||
| 3512 | 2402 | /// No interfaces have been registered. |
| 3513 | 2403 | RPC_NT_NO_INTERFACES = 0xC002004F, |
| 3514 | ||
| 3515 | 2404 | /// The RPC was canceled. |
| 3516 | 2405 | RPC_NT_CALL_CANCELLED = 0xC0020050, |
| 3517 | ||
| 3518 | 2406 | /// The binding handle does not contain all the required information. |
| 3519 | 2407 | RPC_NT_BINDING_INCOMPLETE = 0xC0020051, |
| 3520 | ||
| 3521 | 2408 | /// A communications failure occurred during an RPC. |
| 3522 | 2409 | RPC_NT_COMM_FAILURE = 0xC0020052, |
| 3523 | ||
| 3524 | 2410 | /// The requested authentication level is not supported. |
| 3525 | 2411 | RPC_NT_UNSUPPORTED_AUTHN_LEVEL = 0xC0020053, |
| 3526 | ||
| 3527 | 2412 | /// No principal name was registered. |
| 3528 | 2413 | RPC_NT_NO_PRINC_NAME = 0xC0020054, |
| 3529 | ||
| 3530 | 2414 | /// The error specified is not a valid Windows RPC error code. |
| 3531 | 2415 | RPC_NT_NOT_RPC_ERROR = 0xC0020055, |
| 3532 | ||
| 3533 | 2416 | /// A security package-specific error occurred. |
| 3534 | 2417 | RPC_NT_SEC_PKG_ERROR = 0xC0020057, |
| 3535 | ||
| 3536 | 2418 | /// The thread was not canceled. |
| 3537 | 2419 | RPC_NT_NOT_CANCELLED = 0xC0020058, |
| 3538 | ||
| 3539 | 2420 | /// Invalid asynchronous RPC handle. |
| 3540 | 2421 | RPC_NT_INVALID_ASYNC_HANDLE = 0xC0020062, |
| 3541 | ||
| 3542 | 2422 | /// Invalid asynchronous RPC call handle for this operation. |
| 3543 | 2423 | RPC_NT_INVALID_ASYNC_CALL = 0xC0020063, |
| 3544 | ||
| 3545 | 2424 | /// Access to the HTTP proxy is denied. |
| 3546 | 2425 | RPC_NT_PROXY_ACCESS_DENIED = 0xC0020064, |
| 3547 | ||
| 3548 | 2426 | /// The list of RPC servers available for auto-handle binding has been exhausted. |
| 3549 | 2427 | RPC_NT_NO_MORE_ENTRIES = 0xC0030001, |
| 3550 | ||
| 3551 | 2428 | /// The file designated by DCERPCCHARTRANS cannot be opened. |
| 3552 | 2429 | RPC_NT_SS_CHAR_TRANS_OPEN_FAIL = 0xC0030002, |
| 3553 | ||
| 3554 | 2430 | /// The file containing the character translation table has fewer than 512 bytes. |
| 3555 | 2431 | RPC_NT_SS_CHAR_TRANS_SHORT_FILE = 0xC0030003, |
| 3556 | ||
| 3557 | 2432 | /// A null context handle is passed as an [in] parameter. |
| 3558 | 2433 | RPC_NT_SS_IN_NULL_CONTEXT = 0xC0030004, |
| 3559 | ||
| 3560 | 2434 | /// The context handle does not match any known context handles. |
| 3561 | 2435 | RPC_NT_SS_CONTEXT_MISMATCH = 0xC0030005, |
| 3562 | ||
| 3563 | 2436 | /// The context handle changed during a call. |
| 3564 | 2437 | RPC_NT_SS_CONTEXT_DAMAGED = 0xC0030006, |
| 3565 | ||
| 3566 | 2438 | /// The binding handles passed to an RPC do not match. |
| 3567 | 2439 | RPC_NT_SS_HANDLES_MISMATCH = 0xC0030007, |
| 3568 | ||
| 3569 | 2440 | /// The stub is unable to get the call handle. |
| 3570 | 2441 | RPC_NT_SS_CANNOT_GET_CALL_HANDLE = 0xC0030008, |
| 3571 | ||
| 3572 | 2442 | /// A null reference pointer was passed to the stub. |
| 3573 | 2443 | RPC_NT_NULL_REF_POINTER = 0xC0030009, |
| 3574 | ||
| 3575 | 2444 | /// The enumeration value is out of range. |
| 3576 | 2445 | RPC_NT_ENUM_VALUE_OUT_OF_RANGE = 0xC003000A, |
| 3577 | ||
| 3578 | 2446 | /// The byte count is too small. |
| 3579 | 2447 | RPC_NT_BYTE_COUNT_TOO_SMALL = 0xC003000B, |
| 3580 | ||
| 3581 | 2448 | /// The stub received bad data. |
| 3582 | 2449 | RPC_NT_BAD_STUB_DATA = 0xC003000C, |
| 3583 | ||
| 3584 | 2450 | /// Invalid operation on the encoding/decoding handle. |
| 3585 | 2451 | RPC_NT_INVALID_ES_ACTION = 0xC0030059, |
| 3586 | ||
| 3587 | 2452 | /// Incompatible version of the serializing package. |
| 3588 | 2453 | RPC_NT_WRONG_ES_VERSION = 0xC003005A, |
| 3589 | ||
| 3590 | 2454 | /// Incompatible version of the RPC stub. |
| 3591 | 2455 | RPC_NT_WRONG_STUB_VERSION = 0xC003005B, |
| 3592 | ||
| 3593 | 2456 | /// The RPC pipe object is invalid or corrupt. |
| 3594 | 2457 | RPC_NT_INVALID_PIPE_OBJECT = 0xC003005C, |
| 3595 | ||
| 3596 | 2458 | /// An invalid operation was attempted on an RPC pipe object. |
| 3597 | 2459 | RPC_NT_INVALID_PIPE_OPERATION = 0xC003005D, |
| 3598 | ||
| 3599 | 2460 | /// Unsupported RPC pipe version. |
| 3600 | 2461 | RPC_NT_WRONG_PIPE_VERSION = 0xC003005E, |
| 3601 | ||
| 3602 | 2462 | /// The RPC pipe object has already been closed. |
| 3603 | 2463 | RPC_NT_PIPE_CLOSED = 0xC003005F, |
| 3604 | ||
| 3605 | 2464 | /// The RPC call completed before all pipes were processed. |
| 3606 | 2465 | RPC_NT_PIPE_DISCIPLINE_ERROR = 0xC0030060, |
| 3607 | ||
| 3608 | 2466 | /// No more data is available from the RPC pipe. |
| 3609 | 2467 | RPC_NT_PIPE_EMPTY = 0xC0030061, |
| 3610 | ||
| 3611 | 2468 | /// A device is missing in the system BIOS MPS table. This device will not be used. |
| 3612 | 2469 | /// Contact your system vendor for a system BIOS update. |
| 3613 | 2470 | PNP_BAD_MPS_TABLE = 0xC0040035, |
| 3614 | ||
| 3615 | 2471 | /// A translator failed to translate resources. |
| 3616 | 2472 | PNP_TRANSLATION_FAILED = 0xC0040036, |
| 3617 | ||
| 3618 | 2473 | /// An IRQ translator failed to translate resources. |
| 3619 | 2474 | PNP_IRQ_TRANSLATION_FAILED = 0xC0040037, |
| 3620 | ||
| 3621 | 2475 | /// Driver %2 returned an invalid ID for a child device (%3). |
| 3622 | 2476 | PNP_INVALID_ID = 0xC0040038, |
| 3623 | ||
| 3624 | 2477 | /// Reissue the given operation as a cached I/O operation |
| 3625 | 2478 | IO_REISSUE_AS_CACHED = 0xC0040039, |
| 3626 | ||
| 3627 | 2479 | /// Session name %1 is invalid. |
| 3628 | 2480 | CTX_WINSTATION_NAME_INVALID = 0xC00A0001, |
| 3629 | ||
| 3630 | 2481 | /// The protocol driver %1 is invalid. |
| 3631 | 2482 | CTX_INVALID_PD = 0xC00A0002, |
| 3632 | ||
| 3633 | 2483 | /// The protocol driver %1 was not found in the system path. |
| 3634 | 2484 | CTX_PD_NOT_FOUND = 0xC00A0003, |
| 3635 | ||
| 3636 | 2485 | /// A close operation is pending on the terminal connection. |
| 3637 | 2486 | CTX_CLOSE_PENDING = 0xC00A0006, |
| 3638 | ||
| 3639 | 2487 | /// No free output buffers are available. |
| 3640 | 2488 | CTX_NO_OUTBUF = 0xC00A0007, |
| 3641 | ||
| 3642 | 2489 | /// The MODEM.INF file was not found. |
| 3643 | 2490 | CTX_MODEM_INF_NOT_FOUND = 0xC00A0008, |
| 3644 | ||
| 3645 | 2491 | /// The modem (%1) was not found in the MODEM.INF file. |
| 3646 | 2492 | CTX_INVALID_MODEMNAME = 0xC00A0009, |
| 3647 | ||
| 3648 | 2493 | /// The modem did not accept the command sent to it. |
| 3649 | 2494 | /// Verify that the configured modem name matches the attached modem. |
| 3650 | 2495 | CTX_RESPONSE_ERROR = 0xC00A000A, |
| 3651 | ||
| 3652 | 2496 | /// The modem did not respond to the command sent to it. |
| 3653 | 2497 | /// Verify that the modem cable is properly attached and the modem is turned on. |
| 3654 | 2498 | CTX_MODEM_RESPONSE_TIMEOUT = 0xC00A000B, |
| 3655 | ||
| 3656 | 2499 | /// Carrier detection has failed or the carrier has been dropped due to disconnection. |
| 3657 | 2500 | CTX_MODEM_RESPONSE_NO_CARRIER = 0xC00A000C, |
| 3658 | ||
| 3659 | 2501 | /// A dial tone was not detected within the required time. |
| 3660 | 2502 | /// Verify that the phone cable is properly attached and functional. |
| 3661 | 2503 | CTX_MODEM_RESPONSE_NO_DIALTONE = 0xC00A000D, |
| 3662 | ||
| 3663 | 2504 | /// A busy signal was detected at a remote site on callback. |
| 3664 | 2505 | CTX_MODEM_RESPONSE_BUSY = 0xC00A000E, |
| 3665 | ||
| 3666 | 2506 | /// A voice was detected at a remote site on callback. |
| 3667 | 2507 | CTX_MODEM_RESPONSE_VOICE = 0xC00A000F, |
| 3668 | ||
| 3669 | 2508 | /// Transport driver error. |
| 3670 | 2509 | CTX_TD_ERROR = 0xC00A0010, |
| 3671 | ||
| 3672 | 2510 | /// The client you are using is not licensed to use this system. Your logon request is denied. |
| 3673 | 2511 | CTX_LICENSE_CLIENT_INVALID = 0xC00A0012, |
| 3674 | ||
| 3675 | 2512 | /// The system has reached its licensed logon limit. Try again later. |
| 3676 | 2513 | CTX_LICENSE_NOT_AVAILABLE = 0xC00A0013, |
| 3677 | ||
| 3678 | 2514 | /// The system license has expired. Your logon request is denied. |
| 3679 | 2515 | CTX_LICENSE_EXPIRED = 0xC00A0014, |
| 3680 | ||
| 3681 | 2516 | /// The specified session cannot be found. |
| 3682 | 2517 | CTX_WINSTATION_NOT_FOUND = 0xC00A0015, |
| 3683 | ||
| 3684 | 2518 | /// The specified session name is already in use. |
| 3685 | 2519 | CTX_WINSTATION_NAME_COLLISION = 0xC00A0016, |
| 3686 | ||
| 3687 | 2520 | /// The requested operation cannot be completed because the terminal connection is currently processing a connect, disconnect, reset, or delete operation. |
| 3688 | 2521 | CTX_WINSTATION_BUSY = 0xC00A0017, |
| 3689 | ||
| 3690 | 2522 | /// An attempt has been made to connect to a session whose video mode is not supported by the current client. |
| 3691 | 2523 | CTX_BAD_VIDEO_MODE = 0xC00A0018, |
| 3692 | ||
| 3693 | 2524 | /// The application attempted to enable DOS graphics mode. DOS graphics mode is not supported. |
| 3694 | 2525 | CTX_GRAPHICS_INVALID = 0xC00A0022, |
| 3695 | ||
| 3696 | 2526 | /// The requested operation can be performed only on the system console. |
| 3697 | 2527 | /// This is most often the result of a driver or system DLL requiring direct console access. |
| 3698 | 2528 | CTX_NOT_CONSOLE = 0xC00A0024, |
| 3699 | ||
| 3700 | 2529 | /// The client failed to respond to the server connect message. |
| 3701 | 2530 | CTX_CLIENT_QUERY_TIMEOUT = 0xC00A0026, |
| 3702 | ||
| 3703 | 2531 | /// Disconnecting the console session is not supported. |
| 3704 | 2532 | CTX_CONSOLE_DISCONNECT = 0xC00A0027, |
| 3705 | ||
| 3706 | 2533 | /// Reconnecting a disconnected session to the console is not supported. |
| 3707 | 2534 | CTX_CONSOLE_CONNECT = 0xC00A0028, |
| 3708 | ||
| 3709 | 2535 | /// The request to control another session remotely was denied. |
| 3710 | 2536 | CTX_SHADOW_DENIED = 0xC00A002A, |
| 3711 | ||
| 3712 | 2537 | /// A process has requested access to a session, but has not been granted those access rights. |
| 3713 | 2538 | CTX_WINSTATION_ACCESS_DENIED = 0xC00A002B, |
| 3714 | ||
| 3715 | 2539 | /// The terminal connection driver %1 is invalid. |
| 3716 | 2540 | CTX_INVALID_WD = 0xC00A002E, |
| 3717 | ||
| 3718 | 2541 | /// The terminal connection driver %1 was not found in the system path. |
| 3719 | 2542 | CTX_WD_NOT_FOUND = 0xC00A002F, |
| 3720 | ||
| 3721 | 2543 | /// The requested session cannot be controlled remotely. |
| 3722 | 2544 | /// You cannot control your own session, a session that is trying to control your session, a session that has no user logged on, or other sessions from the console. |
| 3723 | 2545 | CTX_SHADOW_INVALID = 0xC00A0030, |
| 3724 | ||
| 3725 | 2546 | /// The requested session is not configured to allow remote control. |
| 3726 | 2547 | CTX_SHADOW_DISABLED = 0xC00A0031, |
| 3727 | ||
| 3728 | 2548 | /// The RDP protocol component %2 detected an error in the protocol stream and has disconnected the client. |
| 3729 | 2549 | RDP_PROTOCOL_ERROR = 0xC00A0032, |
| 3730 | ||
| 3731 | 2550 | /// Your request to connect to this terminal server has been rejected. |
| 3732 | 2551 | /// Your terminal server client license number has not been entered for this copy of the terminal client. |
| 3733 | 2552 | /// Contact your system administrator for help in entering a valid, unique license number for this terminal server client. Click OK to continue. |
| 3734 | 2553 | CTX_CLIENT_LICENSE_NOT_SET = 0xC00A0033, |
| 3735 | ||
| 3736 | 2554 | /// Your request to connect to this terminal server has been rejected. |
| 3737 | 2555 | /// Your terminal server client license number is currently being used by another user. |
| 3738 | 2556 | /// Contact your system administrator to obtain a new copy of the terminal server client with a valid, unique license number. Click OK to continue. |
| 3739 | 2557 | CTX_CLIENT_LICENSE_IN_USE = 0xC00A0034, |
| 3740 | ||
| 3741 | 2558 | /// The remote control of the console was terminated because the display mode was changed. |
| 3742 | 2559 | /// Changing the display mode in a remote control session is not supported. |
| 3743 | 2560 | CTX_SHADOW_ENDED_BY_MODE_CHANGE = 0xC00A0035, |
| 3744 | ||
| 3745 | 2561 | /// Remote control could not be terminated because the specified session is not currently being remotely controlled. |
| 3746 | 2562 | CTX_SHADOW_NOT_RUNNING = 0xC00A0036, |
| 3747 | ||
| 3748 | 2563 | /// Your interactive logon privilege has been disabled. Contact your system administrator. |
| 3749 | 2564 | CTX_LOGON_DISABLED = 0xC00A0037, |
| 3750 | ||
| 3751 | 2565 | /// The terminal server security layer detected an error in the protocol stream and has disconnected the client. |
| 3752 | 2566 | CTX_SECURITY_LAYER_ERROR = 0xC00A0038, |
| 3753 | ||
| 3754 | 2567 | /// The target session is incompatible with the current session. |
| 3755 | 2568 | TS_INCOMPATIBLE_SESSIONS = 0xC00A0039, |
| 3756 | ||
| 3757 | 2569 | /// The resource loader failed to find an MUI file. |
| 3758 | 2570 | MUI_FILE_NOT_FOUND = 0xC00B0001, |
| 3759 | ||
| 3760 | 2571 | /// The resource loader failed to load an MUI file because the file failed to pass validation. |
| 3761 | 2572 | MUI_INVALID_FILE = 0xC00B0002, |
| 3762 | ||
| 3763 | 2573 | /// The RC manifest is corrupted with garbage data, is an unsupported version, or is missing a required item. |
| 3764 | 2574 | MUI_INVALID_RC_CONFIG = 0xC00B0003, |
| 3765 | ||
| 3766 | 2575 | /// The RC manifest has an invalid culture name. |
| 3767 | 2576 | MUI_INVALID_LOCALE_NAME = 0xC00B0004, |
| 3768 | ||
| 3769 | 2577 | /// The RC manifest has and invalid ultimate fallback name. |
| 3770 | 2578 | MUI_INVALID_ULTIMATEFALLBACK_NAME = 0xC00B0005, |
| 3771 | ||
| 3772 | 2579 | /// The resource loader cache does not have a loaded MUI entry. |
| 3773 | 2580 | MUI_FILE_NOT_LOADED = 0xC00B0006, |
| 3774 | ||
| 3775 | 2581 | /// The user stopped resource enumeration. |
| 3776 | 2582 | RESOURCE_ENUM_USER_STOP = 0xC00B0007, |
| 3777 | ||
| 3778 | 2583 | /// The cluster node is not valid. |
| 3779 | 2584 | CLUSTER_INVALID_NODE = 0xC0130001, |
| 3780 | ||
| 3781 | 2585 | /// The cluster node already exists. |
| 3782 | 2586 | CLUSTER_NODE_EXISTS = 0xC0130002, |
| 3783 | ||
| 3784 | 2587 | /// A node is in the process of joining the cluster. |
| 3785 | 2588 | CLUSTER_JOIN_IN_PROGRESS = 0xC0130003, |
| 3786 | ||
| 3787 | 2589 | /// The cluster node was not found. |
| 3788 | 2590 | CLUSTER_NODE_NOT_FOUND = 0xC0130004, |
| 3789 | ||
| 3790 | 2591 | /// The cluster local node information was not found. |
| 3791 | 2592 | CLUSTER_LOCAL_NODE_NOT_FOUND = 0xC0130005, |
| 3792 | ||
| 3793 | 2593 | /// The cluster network already exists. |
| 3794 | 2594 | CLUSTER_NETWORK_EXISTS = 0xC0130006, |
| 3795 | ||
| 3796 | 2595 | /// The cluster network was not found. |
| 3797 | 2596 | CLUSTER_NETWORK_NOT_FOUND = 0xC0130007, |
| 3798 | ||
| 3799 | 2597 | /// The cluster network interface already exists. |
| 3800 | 2598 | CLUSTER_NETINTERFACE_EXISTS = 0xC0130008, |
| 3801 | ||
| 3802 | 2599 | /// The cluster network interface was not found. |
| 3803 | 2600 | CLUSTER_NETINTERFACE_NOT_FOUND = 0xC0130009, |
| 3804 | ||
| 3805 | 2601 | /// The cluster request is not valid for this object. |
| 3806 | 2602 | CLUSTER_INVALID_REQUEST = 0xC013000A, |
| 3807 | ||
| 3808 | 2603 | /// The cluster network provider is not valid. |
| 3809 | 2604 | CLUSTER_INVALID_NETWORK_PROVIDER = 0xC013000B, |
| 3810 | ||
| 3811 | 2605 | /// The cluster node is down. |
| 3812 | 2606 | CLUSTER_NODE_DOWN = 0xC013000C, |
| 3813 | ||
| 3814 | 2607 | /// The cluster node is not reachable. |
| 3815 | 2608 | CLUSTER_NODE_UNREACHABLE = 0xC013000D, |
| 3816 | ||
| 3817 | 2609 | /// The cluster node is not a member of the cluster. |
| 3818 | 2610 | CLUSTER_NODE_NOT_MEMBER = 0xC013000E, |
| 3819 | ||
| 3820 | 2611 | /// A cluster join operation is not in progress. |
| 3821 | 2612 | CLUSTER_JOIN_NOT_IN_PROGRESS = 0xC013000F, |
| 3822 | ||
| 3823 | 2613 | /// The cluster network is not valid. |
| 3824 | 2614 | CLUSTER_INVALID_NETWORK = 0xC0130010, |
| 3825 | ||
| 3826 | 2615 | /// No network adapters are available. |
| 3827 | 2616 | CLUSTER_NO_NET_ADAPTERS = 0xC0130011, |
| 3828 | ||
| 3829 | 2617 | /// The cluster node is up. |
| 3830 | 2618 | CLUSTER_NODE_UP = 0xC0130012, |
| 3831 | ||
| 3832 | 2619 | /// The cluster node is paused. |
| 3833 | 2620 | CLUSTER_NODE_PAUSED = 0xC0130013, |
| 3834 | ||
| 3835 | 2621 | /// The cluster node is not paused. |
| 3836 | 2622 | CLUSTER_NODE_NOT_PAUSED = 0xC0130014, |
| 3837 | ||
| 3838 | 2623 | /// No cluster security context is available. |
| 3839 | 2624 | CLUSTER_NO_SECURITY_CONTEXT = 0xC0130015, |
| 3840 | ||
| 3841 | 2625 | /// The cluster network is not configured for internal cluster communication. |
| 3842 | 2626 | CLUSTER_NETWORK_NOT_INTERNAL = 0xC0130016, |
| 3843 | ||
| 3844 | 2627 | /// The cluster node has been poisoned. |
| 3845 | 2628 | CLUSTER_POISONED = 0xC0130017, |
| 3846 | ||
| 3847 | 2629 | /// An attempt was made to run an invalid AML opcode. |
| 3848 | 2630 | ACPI_INVALID_OPCODE = 0xC0140001, |
| 3849 | ||
| 3850 | 2631 | /// The AML interpreter stack has overflowed. |
| 3851 | 2632 | ACPI_STACK_OVERFLOW = 0xC0140002, |
| 3852 | ||
| 3853 | 2633 | /// An inconsistent state has occurred. |
| 3854 | 2634 | ACPI_ASSERT_FAILED = 0xC0140003, |
| 3855 | ||
| 3856 | 2635 | /// An attempt was made to access an array outside its bounds. |
| 3857 | 2636 | ACPI_INVALID_INDEX = 0xC0140004, |
| 3858 | ||
| 3859 | 2637 | /// A required argument was not specified. |
| 3860 | 2638 | ACPI_INVALID_ARGUMENT = 0xC0140005, |
| 3861 | ||
| 3862 | 2639 | /// A fatal error has occurred. |
| 3863 | 2640 | ACPI_FATAL = 0xC0140006, |
| 3864 | ||
| 3865 | 2641 | /// An invalid SuperName was specified. |
| 3866 | 2642 | ACPI_INVALID_SUPERNAME = 0xC0140007, |
| 3867 | ||
| 3868 | 2643 | /// An argument with an incorrect type was specified. |
| 3869 | 2644 | ACPI_INVALID_ARGTYPE = 0xC0140008, |
| 3870 | ||
| 3871 | 2645 | /// An object with an incorrect type was specified. |
| 3872 | 2646 | ACPI_INVALID_OBJTYPE = 0xC0140009, |
| 3873 | ||
| 3874 | 2647 | /// A target with an incorrect type was specified. |
| 3875 | 2648 | ACPI_INVALID_TARGETTYPE = 0xC014000A, |
| 3876 | ||
| 3877 | 2649 | /// An incorrect number of arguments was specified. |
| 3878 | 2650 | ACPI_INCORRECT_ARGUMENT_COUNT = 0xC014000B, |
| 3879 | ||
| 3880 | 2651 | /// An address failed to translate. |
| 3881 | 2652 | ACPI_ADDRESS_NOT_MAPPED = 0xC014000C, |
| 3882 | ||
| 3883 | 2653 | /// An incorrect event type was specified. |
| 3884 | 2654 | ACPI_INVALID_EVENTTYPE = 0xC014000D, |
| 3885 | ||
| 3886 | 2655 | /// A handler for the target already exists. |
| 3887 | 2656 | ACPI_HANDLER_COLLISION = 0xC014000E, |
| 3888 | ||
| 3889 | 2657 | /// Invalid data for the target was specified. |
| 3890 | 2658 | ACPI_INVALID_DATA = 0xC014000F, |
| 3891 | ||
| 3892 | 2659 | /// An invalid region for the target was specified. |
| 3893 | 2660 | ACPI_INVALID_REGION = 0xC0140010, |
| 3894 | ||
| 3895 | 2661 | /// An attempt was made to access a field outside the defined range. |
| 3896 | 2662 | ACPI_INVALID_ACCESS_SIZE = 0xC0140011, |
| 3897 | ||
| 3898 | 2663 | /// The global system lock could not be acquired. |
| 3899 | 2664 | ACPI_ACQUIRE_GLOBAL_LOCK = 0xC0140012, |
| 3900 | ||
| 3901 | 2665 | /// An attempt was made to reinitialize the ACPI subsystem. |
| 3902 | 2666 | ACPI_ALREADY_INITIALIZED = 0xC0140013, |
| 3903 | ||
| 3904 | 2667 | /// The ACPI subsystem has not been initialized. |
| 3905 | 2668 | ACPI_NOT_INITIALIZED = 0xC0140014, |
| 3906 | ||
| 3907 | 2669 | /// An incorrect mutex was specified. |
| 3908 | 2670 | ACPI_INVALID_MUTEX_LEVEL = 0xC0140015, |
| 3909 | ||
| 3910 | 2671 | /// The mutex is not currently owned. |
| 3911 | 2672 | ACPI_MUTEX_NOT_OWNED = 0xC0140016, |
| 3912 | ||
| 3913 | 2673 | /// An attempt was made to access the mutex by a process that was not the owner. |
| 3914 | 2674 | ACPI_MUTEX_NOT_OWNER = 0xC0140017, |
| 3915 | ||
| 3916 | 2675 | /// An error occurred during an access to region space. |
| 3917 | 2676 | ACPI_RS_ACCESS = 0xC0140018, |
| 3918 | ||
| 3919 | 2677 | /// An attempt was made to use an incorrect table. |
| 3920 | 2678 | ACPI_INVALID_TABLE = 0xC0140019, |
| 3921 | ||
| 3922 | 2679 | /// The registration of an ACPI event failed. |
| 3923 | 2680 | ACPI_REG_HANDLER_FAILED = 0xC0140020, |
| 3924 | ||
| 3925 | 2681 | /// An ACPI power object failed to transition state. |
| 3926 | 2682 | ACPI_POWER_REQUEST_FAILED = 0xC0140021, |
| 3927 | ||
| 3928 | 2683 | /// The requested section is not present in the activation context. |
| 3929 | 2684 | SXS_SECTION_NOT_FOUND = 0xC0150001, |
| 3930 | ||
| 3931 | 2685 | /// Windows was unble to process the application binding information. |
| 3932 | 2686 | /// Refer to the system event log for further information. |
| 3933 | 2687 | SXS_CANT_GEN_ACTCTX = 0xC0150002, |
| 3934 | ||
| 3935 | 2688 | /// The application binding data format is invalid. |
| 3936 | 2689 | SXS_INVALID_ACTCTXDATA_FORMAT = 0xC0150003, |
| 3937 | ||
| 3938 | 2690 | /// The referenced assembly is not installed on the system. |
| 3939 | 2691 | SXS_ASSEMBLY_NOT_FOUND = 0xC0150004, |
| 3940 | ||
| 3941 | 2692 | /// The manifest file does not begin with the required tag and format information. |
| 3942 | 2693 | SXS_MANIFEST_FORMAT_ERROR = 0xC0150005, |
| 3943 | ||
| 3944 | 2694 | /// The manifest file contains one or more syntax errors. |
| 3945 | 2695 | SXS_MANIFEST_PARSE_ERROR = 0xC0150006, |
| 3946 | ||
| 3947 | 2696 | /// The application attempted to activate a disabled activation context. |
| 3948 | 2697 | SXS_ACTIVATION_CONTEXT_DISABLED = 0xC0150007, |
| 3949 | ||
| 3950 | 2698 | /// The requested lookup key was not found in any active activation context. |
| 3951 | 2699 | SXS_KEY_NOT_FOUND = 0xC0150008, |
| 3952 | ||
| 3953 | 2700 | /// A component version required by the application conflicts with another component version that is already active. |
| 3954 | 2701 | SXS_VERSION_CONFLICT = 0xC0150009, |
| 3955 | ||
| 3956 | 2702 | /// The type requested activation context section does not match the query API used. |
| 3957 | 2703 | SXS_WRONG_SECTION_TYPE = 0xC015000A, |
| 3958 | ||
| 3959 | 2704 | /// Lack of system resources has required isolated activation to be disabled for the current thread of execution. |
| 3960 | 2705 | SXS_THREAD_QUERIES_DISABLED = 0xC015000B, |
| 3961 | ||
| 3962 | 2706 | /// The referenced assembly could not be found. |
| 3963 | 2707 | SXS_ASSEMBLY_MISSING = 0xC015000C, |
| 3964 | ||
| 3965 | 2708 | /// An attempt to set the process default activation context failed because the process default activation context was already set. |
| 3966 | 2709 | SXS_PROCESS_DEFAULT_ALREADY_SET = 0xC015000E, |
| 3967 | ||
| 3968 | 2710 | /// The activation context being deactivated is not the most recently activated one. |
| 3969 | 2711 | SXS_EARLY_DEACTIVATION = 0xC015000F, |
| 3970 | ||
| 3971 | 2712 | /// The activation context being deactivated is not active for the current thread of execution. |
| 3972 | 2713 | SXS_INVALID_DEACTIVATION = 0xC0150010, |
| 3973 | ||
| 3974 | 2714 | /// The activation context being deactivated has already been deactivated. |
| 3975 | 2715 | SXS_MULTIPLE_DEACTIVATION = 0xC0150011, |
| 3976 | ||
| 3977 | 2716 | /// The activation context of the system default assembly could not be generated. |
| 3978 | 2717 | SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY = 0xC0150012, |
| 3979 | ||
| 3980 | 2718 | /// A component used by the isolation facility has requested that the process be terminated. |
| 3981 | 2719 | SXS_PROCESS_TERMINATION_REQUESTED = 0xC0150013, |
| 3982 | ||
| 3983 | 2720 | /// The activation context activation stack for the running thread of execution is corrupt. |
| 3984 | 2721 | SXS_CORRUPT_ACTIVATION_STACK = 0xC0150014, |
| 3985 | ||
| 3986 | 2722 | /// The application isolation metadata for this process or thread has become corrupt. |
| 3987 | 2723 | SXS_CORRUPTION = 0xC0150015, |
| 3988 | ||
| 3989 | 2724 | /// The value of an attribute in an identity is not within the legal range. |
| 3990 | 2725 | SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE = 0xC0150016, |
| 3991 | ||
| 3992 | 2726 | /// The name of an attribute in an identity is not within the legal range. |
| 3993 | 2727 | SXS_INVALID_IDENTITY_ATTRIBUTE_NAME = 0xC0150017, |
| 3994 | ||
| 3995 | 2728 | /// An identity contains two definitions for the same attribute. |
| 3996 | 2729 | SXS_IDENTITY_DUPLICATE_ATTRIBUTE = 0xC0150018, |
| 3997 | ||
| 3998 | 2730 | /// The identity string is malformed. |
| 3999 | 2731 | /// This might be due to a trailing comma, more than two unnamed attributes, a missing attribute name, or a missing attribute value. |
| 4000 | 2732 | SXS_IDENTITY_PARSE_ERROR = 0xC0150019, |
| 4001 | ||
| 4002 | 2733 | /// The component store has become corrupted. |
| 4003 | 2734 | SXS_COMPONENT_STORE_CORRUPT = 0xC015001A, |
| 4004 | ||
| 4005 | 2735 | /// A component's file does not match the verification information present in the component manifest. |
| 4006 | 2736 | SXS_FILE_HASH_MISMATCH = 0xC015001B, |
| 4007 | ||
| 4008 | 2737 | /// The identities of the manifests are identical, but their contents are different. |
| 4009 | 2738 | SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT = 0xC015001C, |
| 4010 | ||
| 4011 | 2739 | /// The component identities are different. |
| 4012 | 2740 | SXS_IDENTITIES_DIFFERENT = 0xC015001D, |
| 4013 | ||
| 4014 | 2741 | /// The assembly is not a deployment. |
| 4015 | 2742 | SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT = 0xC015001E, |
| 4016 | ||
| 4017 | 2743 | /// The file is not a part of the assembly. |
| 4018 | 2744 | SXS_FILE_NOT_PART_OF_ASSEMBLY = 0xC015001F, |
| 4019 | ||
| 4020 | 2745 | /// An advanced installer failed during setup or servicing. |
| 4021 | 2746 | ADVANCED_INSTALLER_FAILED = 0xC0150020, |
| 4022 | ||
| 4023 | 2747 | /// The character encoding in the XML declaration did not match the encoding used in the document. |
| 4024 | 2748 | XML_ENCODING_MISMATCH = 0xC0150021, |
| 4025 | ||
| 4026 | 2749 | /// The size of the manifest exceeds the maximum allowed. |
| 4027 | 2750 | SXS_MANIFEST_TOO_BIG = 0xC0150022, |
| 4028 | ||
| 4029 | 2751 | /// The setting is not registered. |
| 4030 | 2752 | SXS_SETTING_NOT_REGISTERED = 0xC0150023, |
| 4031 | ||
| 4032 | 2753 | /// One or more required transaction members are not present. |
| 4033 | 2754 | SXS_TRANSACTION_CLOSURE_INCOMPLETE = 0xC0150024, |
| 4034 | ||
| 4035 | 2755 | /// The SMI primitive installer failed during setup or servicing. |
| 4036 | 2756 | SMI_PRIMITIVE_INSTALLER_FAILED = 0xC0150025, |
| 4037 | ||
| 4038 | 2757 | /// A generic command executable returned a result that indicates failure. |
| 4039 | 2758 | GENERIC_COMMAND_FAILED = 0xC0150026, |
| 4040 | ||
| 4041 | 2759 | /// A component is missing file verification information in its manifest. |
| 4042 | 2760 | SXS_FILE_HASH_MISSING = 0xC0150027, |
| 4043 | ||
| 4044 | 2761 | /// The function attempted to use a name that is reserved for use by another transaction. |
| 4045 | 2762 | TRANSACTIONAL_CONFLICT = 0xC0190001, |
| 4046 | ||
| 4047 | 2763 | /// The transaction handle associated with this operation is invalid. |
| 4048 | 2764 | INVALID_TRANSACTION = 0xC0190002, |
| 4049 | ||
| 4050 | 2765 | /// The requested operation was made in the context of a transaction that is no longer active. |
| 4051 | 2766 | TRANSACTION_NOT_ACTIVE = 0xC0190003, |
| 4052 | ||
| 4053 | 2767 | /// The transaction manager was unable to be successfully initialized. Transacted operations are not supported. |
| 4054 | 2768 | TM_INITIALIZATION_FAILED = 0xC0190004, |
| 4055 | ||
| 4056 | 2769 | /// Transaction support within the specified file system resource manager was not started or was shut down due to an error. |
| 4057 | 2770 | RM_NOT_ACTIVE = 0xC0190005, |
| 4058 | ||
| 4059 | 2771 | /// The metadata of the resource manager has been corrupted. The resource manager will not function. |
| 4060 | 2772 | RM_METADATA_CORRUPT = 0xC0190006, |
| 4061 | ||
| 4062 | 2773 | /// The resource manager attempted to prepare a transaction that it has not successfully joined. |
| 4063 | 2774 | TRANSACTION_NOT_JOINED = 0xC0190007, |
| 4064 | ||
| 4065 | 2775 | /// The specified directory does not contain a file system resource manager. |
| 4066 | 2776 | DIRECTORY_NOT_RM = 0xC0190008, |
| 4067 | ||
| 4068 | 2777 | /// The remote server or share does not support transacted file operations. |
| 4069 | 2778 | TRANSACTIONS_UNSUPPORTED_REMOTE = 0xC019000A, |
| 4070 | ||
| 4071 | 2779 | /// The requested log size for the file system resource manager is invalid. |
| 4072 | 2780 | LOG_RESIZE_INVALID_SIZE = 0xC019000B, |
| 4073 | ||
| 4074 | 2781 | /// The remote server sent mismatching version number or Fid for a file opened with transactions. |
| 4075 | 2782 | REMOTE_FILE_VERSION_MISMATCH = 0xC019000C, |
| 4076 | ||
| 4077 | 2783 | /// The resource manager tried to register a protocol that already exists. |
| 4078 | 2784 | CRM_PROTOCOL_ALREADY_EXISTS = 0xC019000F, |
| 4079 | ||
| 4080 | 2785 | /// The attempt to propagate the transaction failed. |
| 4081 | 2786 | TRANSACTION_PROPAGATION_FAILED = 0xC0190010, |
| 4082 | ||
| 4083 | 2787 | /// The requested propagation protocol was not registered as a CRM. |
| 4084 | 2788 | CRM_PROTOCOL_NOT_FOUND = 0xC0190011, |
| 4085 | ||
| 4086 | 2789 | /// The transaction object already has a superior enlistment, and the caller attempted an operation that would have created a new superior. Only a single superior enlistment is allowed. |
| 4087 | 2790 | TRANSACTION_SUPERIOR_EXISTS = 0xC0190012, |
| 4088 | ||
| 4089 | 2791 | /// The requested operation is not valid on the transaction object in its current state. |
| 4090 | 2792 | TRANSACTION_REQUEST_NOT_VALID = 0xC0190013, |
| 4091 | ||
| 4092 | 2793 | /// The caller has called a response API, but the response is not expected because the transaction manager did not issue the corresponding request to the caller. |
| 4093 | 2794 | TRANSACTION_NOT_REQUESTED = 0xC0190014, |
| 4094 | ||
| 4095 | 2795 | /// It is too late to perform the requested operation, because the transaction has already been aborted. |
| 4096 | 2796 | TRANSACTION_ALREADY_ABORTED = 0xC0190015, |
| 4097 | ||
| 4098 | 2797 | /// It is too late to perform the requested operation, because the transaction has already been committed. |
| 4099 | 2798 | TRANSACTION_ALREADY_COMMITTED = 0xC0190016, |
| 4100 | ||
| 4101 | 2799 | /// The buffer passed in to NtPushTransaction or NtPullTransaction is not in a valid format. |
| 4102 | 2800 | TRANSACTION_INVALID_MARSHALL_BUFFER = 0xC0190017, |
| 4103 | ||
| 4104 | 2801 | /// The current transaction context associated with the thread is not a valid handle to a transaction object. |
| 4105 | 2802 | CURRENT_TRANSACTION_NOT_VALID = 0xC0190018, |
| 4106 | ||
| 4107 | 2803 | /// An attempt to create space in the transactional resource manager's log failed. |
| 4108 | 2804 | /// The failure status has been recorded in the event log. |
| 4109 | 2805 | LOG_GROWTH_FAILED = 0xC0190019, |
| 4110 | ||
| 4111 | 2806 | /// The object (file, stream, or link) that corresponds to the handle has been deleted by a transaction savepoint rollback. |
| 4112 | 2807 | OBJECT_NO_LONGER_EXISTS = 0xC0190021, |
| 4113 | ||
| 4114 | 2808 | /// The specified file miniversion was not found for this transacted file open. |
| 4115 | 2809 | STREAM_MINIVERSION_NOT_FOUND = 0xC0190022, |
| 4116 | ||
| 4117 | 2810 | /// The specified file miniversion was found but has been invalidated. |
| 4118 | 2811 | /// The most likely cause is a transaction savepoint rollback. |
| 4119 | 2812 | STREAM_MINIVERSION_NOT_VALID = 0xC0190023, |
| 4120 | ||
| 4121 | 2813 | /// A miniversion can be opened only in the context of the transaction that created it. |
| 4122 | 2814 | MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION = 0xC0190024, |
| 4123 | ||
| 4124 | 2815 | /// It is not possible to open a miniversion with modify access. |
| 4125 | 2816 | CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT = 0xC0190025, |
| 4126 | ||
| 4127 | 2817 | /// It is not possible to create any more miniversions for this stream. |
| 4128 | 2818 | CANT_CREATE_MORE_STREAM_MINIVERSIONS = 0xC0190026, |
| 4129 | ||
| 4130 | 2819 | /// The handle has been invalidated by a transaction. |
| 4131 | 2820 | /// The most likely cause is the presence of memory mapping on a file or an open handle when the transaction ended or rolled back to savepoint. |
| 4132 | 2821 | HANDLE_NO_LONGER_VALID = 0xC0190028, |
| 4133 | ||
| 4134 | 2822 | /// The log data is corrupt. |
| 4135 | 2823 | LOG_CORRUPTION_DETECTED = 0xC0190030, |
| 4136 | ||
| 4137 | 2824 | /// The transaction outcome is unavailable because the resource manager responsible for it is disconnected. |
| 4138 | 2825 | RM_DISCONNECTED = 0xC0190032, |
| 4139 | ||
| 4140 | 2826 | /// The request was rejected because the enlistment in question is not a superior enlistment. |
| 4141 | 2827 | ENLISTMENT_NOT_SUPERIOR = 0xC0190033, |
| 4142 | ||
| 4143 | 2828 | /// The file cannot be opened in a transaction because its identity depends on the outcome of an unresolved transaction. |
| 4144 | 2829 | FILE_IDENTITY_NOT_PERSISTENT = 0xC0190036, |
| 4145 | ||
| 4146 | 2830 | /// The operation cannot be performed because another transaction is depending on this property not changing. |
| 4147 | 2831 | CANT_BREAK_TRANSACTIONAL_DEPENDENCY = 0xC0190037, |
| 4148 | ||
| 4149 | 2832 | /// The operation would involve a single file with two transactional resource managers and is, therefore, not allowed. |
| 4150 | 2833 | CANT_CROSS_RM_BOUNDARY = 0xC0190038, |
| 4151 | ||
| 4152 | 2834 | /// The $Txf directory must be empty for this operation to succeed. |
| 4153 | 2835 | TXF_DIR_NOT_EMPTY = 0xC0190039, |
| 4154 | ||
| 4155 | 2836 | /// The operation would leave a transactional resource manager in an inconsistent state and is therefore not allowed. |
| 4156 | 2837 | INDOUBT_TRANSACTIONS_EXIST = 0xC019003A, |
| 4157 | ||
| 4158 | 2838 | /// The operation could not be completed because the transaction manager does not have a log. |
| 4159 | 2839 | TM_VOLATILE = 0xC019003B, |
| 4160 | ||
| 4161 | 2840 | /// A rollback could not be scheduled because a previously scheduled rollback has already executed or been queued for execution. |
| 4162 | 2841 | ROLLBACK_TIMER_EXPIRED = 0xC019003C, |
| 4163 | ||
| 4164 | 2842 | /// The transactional metadata attribute on the file or directory %hs is corrupt and unreadable. |
| 4165 | 2843 | TXF_ATTRIBUTE_CORRUPT = 0xC019003D, |
| 4166 | ||
| 4167 | 2844 | /// The encryption operation could not be completed because a transaction is active. |
| 4168 | 2845 | EFS_NOT_ALLOWED_IN_TRANSACTION = 0xC019003E, |
| 4169 | ||
| 4170 | 2846 | /// This object is not allowed to be opened in a transaction. |
| 4171 | 2847 | TRANSACTIONAL_OPEN_NOT_ALLOWED = 0xC019003F, |
| 4172 | ||
| 4173 | 2848 | /// Memory mapping (creating a mapped section) a remote file under a transaction is not supported. |
| 4174 | 2849 | TRANSACTED_MAPPING_UNSUPPORTED_REMOTE = 0xC0190040, |
| 4175 | ||
| 4176 | 2850 | /// Promotion was required to allow the resource manager to enlist, but the transaction was set to disallow it. |
| 4177 | 2851 | TRANSACTION_REQUIRED_PROMOTION = 0xC0190043, |
| 4178 | ||
| 4179 | 2852 | /// This file is open for modification in an unresolved transaction and can be opened for execute only by a transacted reader. |
| 4180 | 2853 | CANNOT_EXECUTE_FILE_IN_TRANSACTION = 0xC0190044, |
| 4181 | ||
| 4182 | 2854 | /// The request to thaw frozen transactions was ignored because transactions were not previously frozen. |
| 4183 | 2855 | TRANSACTIONS_NOT_FROZEN = 0xC0190045, |
| 4184 | ||
| 4185 | 2856 | /// Transactions cannot be frozen because a freeze is already in progress. |
| 4186 | 2857 | TRANSACTION_FREEZE_IN_PROGRESS = 0xC0190046, |
| 4187 | ||
| 4188 | 2858 | /// The target volume is not a snapshot volume. |
| 4189 | 2859 | /// This operation is valid only on a volume mounted as a snapshot. |
| 4190 | 2860 | NOT_SNAPSHOT_VOLUME = 0xC0190047, |
| 4191 | ||
| 4192 | 2861 | /// The savepoint operation failed because files are open on the transaction, which is not permitted. |
| 4193 | 2862 | NO_SAVEPOINT_WITH_OPEN_FILES = 0xC0190048, |
| 4194 | ||
| 4195 | 2863 | /// The sparse operation could not be completed because a transaction is active on the file. |
| 4196 | 2864 | SPARSE_NOT_ALLOWED_IN_TRANSACTION = 0xC0190049, |
| 4197 | ||
| 4198 | 2865 | /// The call to create a transaction manager object failed because the Tm Identity that is stored in the log file does not match the Tm Identity that was passed in as an argument. |
| 4199 | 2866 | TM_IDENTITY_MISMATCH = 0xC019004A, |
| 4200 | ||
| 4201 | 2867 | /// I/O was attempted on a section object that has been floated as a result of a transaction ending. There is no valid data. |
| 4202 | 2868 | FLOATED_SECTION = 0xC019004B, |
| 4203 | ||
| 4204 | 2869 | /// The transactional resource manager cannot currently accept transacted work due to a transient condition, such as low resources. |
| 4205 | 2870 | CANNOT_ACCEPT_TRANSACTED_WORK = 0xC019004C, |
| 4206 | ||
| 4207 | 2871 | /// The transactional resource manager had too many transactions outstanding that could not be aborted. |
| 4208 | 2872 | /// The transactional resource manager has been shut down. |
| 4209 | 2873 | CANNOT_ABORT_TRANSACTIONS = 0xC019004D, |
| 4210 | ||
| 4211 | 2874 | /// The specified transaction was unable to be opened because it was not found. |
| 4212 | 2875 | TRANSACTION_NOT_FOUND = 0xC019004E, |
| 4213 | ||
| 4214 | 2876 | /// The specified resource manager was unable to be opened because it was not found. |
| 4215 | 2877 | RESOURCEMANAGER_NOT_FOUND = 0xC019004F, |
| 4216 | ||
| 4217 | 2878 | /// The specified enlistment was unable to be opened because it was not found. |
| 4218 | 2879 | ENLISTMENT_NOT_FOUND = 0xC0190050, |
| 4219 | ||
| 4220 | 2880 | /// The specified transaction manager was unable to be opened because it was not found. |
| 4221 | 2881 | TRANSACTIONMANAGER_NOT_FOUND = 0xC0190051, |
| 4222 | ||
| 4223 | 2882 | /// The specified resource manager was unable to create an enlistment because its associated transaction manager is not online. |
| 4224 | 2883 | TRANSACTIONMANAGER_NOT_ONLINE = 0xC0190052, |
| 4225 | ||
| 4226 | 2884 | /// The specified transaction manager was unable to create the objects contained in its log file in the Ob namespace. |
| 4227 | 2885 | /// Therefore, the transaction manager was unable to recover. |
| 4228 | 2886 | TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION = 0xC0190053, |
| 4229 | ||
| 4230 | 2887 | /// The call to create a superior enlistment on this transaction object could not be completed because the transaction object specified for the enlistment is a subordinate branch of the transaction. |
| 4231 | 2888 | /// Only the root of the transaction can be enlisted as a superior. |
| 4232 | 2889 | TRANSACTION_NOT_ROOT = 0xC0190054, |
| 4233 | ||
| 4234 | 2890 | /// Because the associated transaction manager or resource manager has been closed, the handle is no longer valid. |
| 4235 | 2891 | TRANSACTION_OBJECT_EXPIRED = 0xC0190055, |
| 4236 | ||
| 4237 | 2892 | /// The compression operation could not be completed because a transaction is active on the file. |
| 4238 | 2893 | COMPRESSION_NOT_ALLOWED_IN_TRANSACTION = 0xC0190056, |
| 4239 | ||
| 4240 | 2894 | /// The specified operation could not be performed on this superior enlistment because the enlistment was not created with the corresponding completion response in the NotificationMask. |
| 4241 | 2895 | TRANSACTION_RESPONSE_NOT_ENLISTED = 0xC0190057, |
| 4242 | ||
| 4243 | 2896 | /// The specified operation could not be performed because the record to be logged was too long. |
| 4244 | 2897 | /// This can occur because either there are too many enlistments on this transaction or the combined RecoveryInformation being logged on behalf of those enlistments is too long. |
| 4245 | 2898 | TRANSACTION_RECORD_TOO_LONG = 0xC0190058, |
| 4246 | ||
| 4247 | 2899 | /// The link-tracking operation could not be completed because a transaction is active. |
| 4248 | 2900 | NO_LINK_TRACKING_IN_TRANSACTION = 0xC0190059, |
| 4249 | ||
| 4250 | 2901 | /// This operation cannot be performed in a transaction. |
| 4251 | 2902 | OPERATION_NOT_SUPPORTED_IN_TRANSACTION = 0xC019005A, |
| 4252 | ||
| 4253 | 2903 | /// The kernel transaction manager had to abort or forget the transaction because it blocked forward progress. |
| 4254 | 2904 | TRANSACTION_INTEGRITY_VIOLATED = 0xC019005B, |
| 4255 | ||
| 4256 | 2905 | /// The handle is no longer properly associated with its transaction. |
| 4257 | 2906 | /// It might have been opened in a transactional resource manager that was subsequently forced to restart. Please close the handle and open a new one. |
| 4258 | 2907 | EXPIRED_HANDLE = 0xC0190060, |
| 4259 | ||
| 4260 | 2908 | /// The specified operation could not be performed because the resource manager is not enlisted in the transaction. |
| 4261 | 2909 | TRANSACTION_NOT_ENLISTED = 0xC0190061, |
| 4262 | ||
| 4263 | 2910 | /// The log service found an invalid log sector. |
| 4264 | 2911 | LOG_SECTOR_INVALID = 0xC01A0001, |
| 4265 | ||
| 4266 | 2912 | /// The log service encountered a log sector with invalid block parity. |
| 4267 | 2913 | LOG_SECTOR_PARITY_INVALID = 0xC01A0002, |
| 4268 | ||
| 4269 | 2914 | /// The log service encountered a remapped log sector. |
| 4270 | 2915 | LOG_SECTOR_REMAPPED = 0xC01A0003, |
| 4271 | ||
| 4272 | 2916 | /// The log service encountered a partial or incomplete log block. |
| 4273 | 2917 | LOG_BLOCK_INCOMPLETE = 0xC01A0004, |
| 4274 | ||
| 4275 | 2918 | /// The log service encountered an attempt to access data outside the active log range. |
| 4276 | 2919 | LOG_INVALID_RANGE = 0xC01A0005, |
| 4277 | ||
| 4278 | 2920 | /// The log service user-log marshaling buffers are exhausted. |
| 4279 | 2921 | LOG_BLOCKS_EXHAUSTED = 0xC01A0006, |
| 4280 | ||
| 4281 | 2922 | /// The log service encountered an attempt to read from a marshaling area with an invalid read context. |
| 4282 | 2923 | LOG_READ_CONTEXT_INVALID = 0xC01A0007, |
| 4283 | ||
| 4284 | 2924 | /// The log service encountered an invalid log restart area. |
| 4285 | 2925 | LOG_RESTART_INVALID = 0xC01A0008, |
| 4286 | ||
| 4287 | 2926 | /// The log service encountered an invalid log block version. |
| 4288 | 2927 | LOG_BLOCK_VERSION = 0xC01A0009, |
| 4289 | ||
| 4290 | 2928 | /// The log service encountered an invalid log block. |
| 4291 | 2929 | LOG_BLOCK_INVALID = 0xC01A000A, |
| 4292 | ||
| 4293 | 2930 | /// The log service encountered an attempt to read the log with an invalid read mode. |
| 4294 | 2931 | LOG_READ_MODE_INVALID = 0xC01A000B, |
| 4295 | ||
| 4296 | 2932 | /// The log service encountered a corrupted metadata file. |
| 4297 | 2933 | LOG_METADATA_CORRUPT = 0xC01A000D, |
| 4298 | ||
| 4299 | 2934 | /// The log service encountered a metadata file that could not be created by the log file system. |
| 4300 | 2935 | LOG_METADATA_INVALID = 0xC01A000E, |
| 4301 | ||
| 4302 | 2936 | /// The log service encountered a metadata file with inconsistent data. |
| 4303 | 2937 | LOG_METADATA_INCONSISTENT = 0xC01A000F, |
| 4304 | ||
| 4305 | 2938 | /// The log service encountered an attempt to erroneously allocate or dispose reservation space. |
| 4306 | 2939 | LOG_RESERVATION_INVALID = 0xC01A0010, |
| 4307 | ||
| 4308 | 2940 | /// The log service cannot delete the log file or the file system container. |
| 4309 | 2941 | LOG_CANT_DELETE = 0xC01A0011, |
| 4310 | ||
| 4311 | 2942 | /// The log service has reached the maximum allowable containers allocated to a log file. |
| 4312 | 2943 | LOG_CONTAINER_LIMIT_EXCEEDED = 0xC01A0012, |
| 4313 | ||
| 4314 | 2944 | /// The log service has attempted to read or write backward past the start of the log. |
| 4315 | 2945 | LOG_START_OF_LOG = 0xC01A0013, |
| 4316 | ||
| 4317 | 2946 | /// The log policy could not be installed because a policy of the same type is already present. |
| 4318 | 2947 | LOG_POLICY_ALREADY_INSTALLED = 0xC01A0014, |
| 4319 | ||
| 4320 | 2948 | /// The log policy in question was not installed at the time of the request. |
| 4321 | 2949 | LOG_POLICY_NOT_INSTALLED = 0xC01A0015, |
| 4322 | ||
| 4323 | 2950 | /// The installed set of policies on the log is invalid. |
| 4324 | 2951 | LOG_POLICY_INVALID = 0xC01A0016, |
| 4325 | ||
| 4326 | 2952 | /// A policy on the log in question prevented the operation from completing. |
| 4327 | 2953 | LOG_POLICY_CONFLICT = 0xC01A0017, |
| 4328 | ||
| 4329 | 2954 | /// The log space cannot be reclaimed because the log is pinned by the archive tail. |
| 4330 | 2955 | LOG_PINNED_ARCHIVE_TAIL = 0xC01A0018, |
| 4331 | ||
| 4332 | 2956 | /// The log record is not a record in the log file. |
| 4333 | 2957 | LOG_RECORD_NONEXISTENT = 0xC01A0019, |
| 4334 | ||
| 4335 | 2958 | /// The number of reserved log records or the adjustment of the number of reserved log records is invalid. |
| 4336 | 2959 | LOG_RECORDS_RESERVED_INVALID = 0xC01A001A, |
| 4337 | ||
| 4338 | 2960 | /// The reserved log space or the adjustment of the log space is invalid. |
| 4339 | 2961 | LOG_SPACE_RESERVED_INVALID = 0xC01A001B, |
| 4340 | ||
| 4341 | 2962 | /// A new or existing archive tail or the base of the active log is invalid. |
| 4342 | 2963 | LOG_TAIL_INVALID = 0xC01A001C, |
| 4343 | ||
| 4344 | 2964 | /// The log space is exhausted. |
| 4345 | 2965 | LOG_FULL = 0xC01A001D, |
| 4346 | ||
| 4347 | 2966 | /// The log is multiplexed; no direct writes to the physical log are allowed. |
| 4348 | 2967 | LOG_MULTIPLEXED = 0xC01A001E, |
| 4349 | ||
| 4350 | 2968 | /// The operation failed because the log is dedicated. |
| 4351 | 2969 | LOG_DEDICATED = 0xC01A001F, |
| 4352 | ||
| 4353 | 2970 | /// The operation requires an archive context. |
| 4354 | 2971 | LOG_ARCHIVE_NOT_IN_PROGRESS = 0xC01A0020, |
| 4355 | ||
| 4356 | 2972 | /// Log archival is in progress. |
| 4357 | 2973 | LOG_ARCHIVE_IN_PROGRESS = 0xC01A0021, |
| 4358 | ||
| 4359 | 2974 | /// The operation requires a nonephemeral log, but the log is ephemeral. |
| 4360 | 2975 | LOG_EPHEMERAL = 0xC01A0022, |
| 4361 | ||
| 4362 | 2976 | /// The log must have at least two containers before it can be read from or written to. |
| 4363 | 2977 | LOG_NOT_ENOUGH_CONTAINERS = 0xC01A0023, |
| 4364 | ||
| 4365 | 2978 | /// A log client has already registered on the stream. |
| 4366 | 2979 | LOG_CLIENT_ALREADY_REGISTERED = 0xC01A0024, |
| 4367 | ||
| 4368 | 2980 | /// A log client has not been registered on the stream. |
| 4369 | 2981 | LOG_CLIENT_NOT_REGISTERED = 0xC01A0025, |
| 4370 | ||
| 4371 | 2982 | /// A request has already been made to handle the log full condition. |
| 4372 | 2983 | LOG_FULL_HANDLER_IN_PROGRESS = 0xC01A0026, |
| 4373 | ||
| 4374 | 2984 | /// The log service encountered an error when attempting to read from a log container. |
| 4375 | 2985 | LOG_CONTAINER_READ_FAILED = 0xC01A0027, |
| 4376 | ||
| 4377 | 2986 | /// The log service encountered an error when attempting to write to a log container. |
| 4378 | 2987 | LOG_CONTAINER_WRITE_FAILED = 0xC01A0028, |
| 4379 | ||
| 4380 | 2988 | /// The log service encountered an error when attempting to open a log container. |
| 4381 | 2989 | LOG_CONTAINER_OPEN_FAILED = 0xC01A0029, |
| 4382 | ||
| 4383 | 2990 | /// The log service encountered an invalid container state when attempting a requested action. |
| 4384 | 2991 | LOG_CONTAINER_STATE_INVALID = 0xC01A002A, |
| 4385 | ||
| 4386 | 2992 | /// The log service is not in the correct state to perform a requested action. |
| 4387 | 2993 | LOG_STATE_INVALID = 0xC01A002B, |
| 4388 | ||
| 4389 | 2994 | /// The log space cannot be reclaimed because the log is pinned. |
| 4390 | 2995 | LOG_PINNED = 0xC01A002C, |
| 4391 | ||
| 4392 | 2996 | /// The log metadata flush failed. |
| 4393 | 2997 | LOG_METADATA_FLUSH_FAILED = 0xC01A002D, |
| 4394 | ||
| 4395 | 2998 | /// Security on the log and its containers is inconsistent. |
| 4396 | 2999 | LOG_INCONSISTENT_SECURITY = 0xC01A002E, |
| 4397 | ||
| 4398 | 3000 | /// Records were appended to the log or reservation changes were made, but the log could not be flushed. |
| 4399 | 3001 | LOG_APPENDED_FLUSH_FAILED = 0xC01A002F, |
| 4400 | ||
| 4401 | 3002 | /// The log is pinned due to reservation consuming most of the log space. |
| 4402 | 3003 | /// Free some reserved records to make space available. |
| 4403 | 3004 | LOG_PINNED_RESERVATION = 0xC01A0030, |
| 4404 | ||
| 4405 | 3005 | /// {Display Driver Stopped Responding} The %hs display driver has stopped working normally. |
| 4406 | 3006 | /// Save your work and reboot the system to restore full display functionality. |
| 4407 | 3007 | /// The next time you reboot the computer, a dialog box will allow you to upload data about this failure to Microsoft. |
| 4408 | 3008 | VIDEO_HUNG_DISPLAY_DRIVER_THREAD = 0xC01B00EA, |
| 4409 | ||
| 4410 | 3009 | /// A handler was not defined by the filter for this operation. |
| 4411 | 3010 | FLT_NO_HANDLER_DEFINED = 0xC01C0001, |
| 4412 | ||
| 4413 | 3011 | /// A context is already defined for this object. |
| 4414 | 3012 | FLT_CONTEXT_ALREADY_DEFINED = 0xC01C0002, |
| 4415 | ||
| 4416 | 3013 | /// Asynchronous requests are not valid for this operation. |
| 4417 | 3014 | FLT_INVALID_ASYNCHRONOUS_REQUEST = 0xC01C0003, |
| 4418 | ||
| 4419 | 3015 | /// This is an internal error code used by the filter manager to determine if a fast I/O operation should be forced down the input/output request packet (IRP) path. Minifilters should never return this value. |
| 4420 | 3016 | FLT_DISALLOW_FAST_IO = 0xC01C0004, |
| 4421 | ||
| 4422 | 3017 | /// An invalid name request was made. |
| 4423 | 3018 | /// The name requested cannot be retrieved at this time. |
| 4424 | 3019 | FLT_INVALID_NAME_REQUEST = 0xC01C0005, |
| 4425 | ||
| 4426 | 3020 | /// Posting this operation to a worker thread for further processing is not safe at this time because it could lead to a system deadlock. |
| 4427 | 3021 | FLT_NOT_SAFE_TO_POST_OPERATION = 0xC01C0006, |
| 4428 | ||
| 4429 | 3022 | /// The Filter Manager was not initialized when a filter tried to register. |
| 4430 | 3023 | /// Make sure that the Filter Manager is loaded as a driver. |
| 4431 | 3024 | FLT_NOT_INITIALIZED = 0xC01C0007, |
| 4432 | ||
| 4433 | 3025 | /// The filter is not ready for attachment to volumes because it has not finished initializing (FltStartFiltering has not been called). |
| 4434 | 3026 | FLT_FILTER_NOT_READY = 0xC01C0008, |
| 4435 | ||
| 4436 | 3027 | /// The filter must clean up any operation-specific context at this time because it is being removed from the system before the operation is completed by the lower drivers. |
| 4437 | 3028 | FLT_POST_OPERATION_CLEANUP = 0xC01C0009, |
| 4438 | ||
| 4439 | 3029 | /// The Filter Manager had an internal error from which it cannot recover; therefore, the operation has failed. |
| 4440 | 3030 | /// This is usually the result of a filter returning an invalid value from a pre-operation callback. |
| 4441 | 3031 | FLT_INTERNAL_ERROR = 0xC01C000A, |
| 4442 | ||
| 4443 | 3032 | /// The object specified for this action is in the process of being deleted; therefore, the action requested cannot be completed at this time. |
| 4444 | 3033 | FLT_DELETING_OBJECT = 0xC01C000B, |
| 4445 | ||
| 4446 | 3034 | /// A nonpaged pool must be used for this type of context. |
| 4447 | 3035 | FLT_MUST_BE_NONPAGED_POOL = 0xC01C000C, |
| 4448 | ||
| 4449 | 3036 | /// A duplicate handler definition has been provided for an operation. |
| 4450 | 3037 | FLT_DUPLICATE_ENTRY = 0xC01C000D, |
| 4451 | ||
| 4452 | 3038 | /// The callback data queue has been disabled. |
| 4453 | 3039 | FLT_CBDQ_DISABLED = 0xC01C000E, |
| 4454 | ||
| 4455 | 3040 | /// Do not attach the filter to the volume at this time. |
| 4456 | 3041 | FLT_DO_NOT_ATTACH = 0xC01C000F, |
| 4457 | ||
| 4458 | 3042 | /// Do not detach the filter from the volume at this time. |
| 4459 | 3043 | FLT_DO_NOT_DETACH = 0xC01C0010, |
| 4460 | ||
| 4461 | 3044 | /// An instance already exists at this altitude on the volume specified. |
| 4462 | 3045 | FLT_INSTANCE_ALTITUDE_COLLISION = 0xC01C0011, |
| 4463 | ||
| 4464 | 3046 | /// An instance already exists with this name on the volume specified. |
| 4465 | 3047 | FLT_INSTANCE_NAME_COLLISION = 0xC01C0012, |
| 4466 | ||
| 4467 | 3048 | /// The system could not find the filter specified. |
| 4468 | 3049 | FLT_FILTER_NOT_FOUND = 0xC01C0013, |
| 4469 | ||
| 4470 | 3050 | /// The system could not find the volume specified. |
| 4471 | 3051 | FLT_VOLUME_NOT_FOUND = 0xC01C0014, |
| 4472 | ||
| 4473 | 3052 | /// The system could not find the instance specified. |
| 4474 | 3053 | FLT_INSTANCE_NOT_FOUND = 0xC01C0015, |
| 4475 | ||
| 4476 | 3054 | /// No registered context allocation definition was found for the given request. |
| 4477 | 3055 | FLT_CONTEXT_ALLOCATION_NOT_FOUND = 0xC01C0016, |
| 4478 | ||
| 4479 | 3056 | /// An invalid parameter was specified during context registration. |
| 4480 | 3057 | FLT_INVALID_CONTEXT_REGISTRATION = 0xC01C0017, |
| 4481 | ||
| 4482 | 3058 | /// The name requested was not found in the Filter Manager name cache and could not be retrieved from the file system. |
| 4483 | 3059 | FLT_NAME_CACHE_MISS = 0xC01C0018, |
| 4484 | ||
| 4485 | 3060 | /// The requested device object does not exist for the given volume. |
| 4486 | 3061 | FLT_NO_DEVICE_OBJECT = 0xC01C0019, |
| 4487 | ||
| 4488 | 3062 | /// The specified volume is already mounted. |
| 4489 | 3063 | FLT_VOLUME_ALREADY_MOUNTED = 0xC01C001A, |
| 4490 | ||
| 4491 | 3064 | /// The specified transaction context is already enlisted in a transaction. |
| 4492 | 3065 | FLT_ALREADY_ENLISTED = 0xC01C001B, |
| 4493 | ||
| 4494 | 3066 | /// The specified context is already attached to another object. |
| 4495 | 3067 | FLT_CONTEXT_ALREADY_LINKED = 0xC01C001C, |
| 4496 | ||
| 4497 | 3068 | /// No waiter is present for the filter's reply to this message. |
| 4498 | 3069 | FLT_NO_WAITER_FOR_REPLY = 0xC01C0020, |
| 4499 | ||
| 4500 | 3070 | /// A monitor descriptor could not be obtained. |
| 4501 | 3071 | MONITOR_NO_DESCRIPTOR = 0xC01D0001, |
| 4502 | ||
| 4503 | 3072 | /// This release does not support the format of the obtained monitor descriptor. |
| 4504 | 3073 | MONITOR_UNKNOWN_DESCRIPTOR_FORMAT = 0xC01D0002, |
| 4505 | ||
| 4506 | 3074 | /// The checksum of the obtained monitor descriptor is invalid. |
| 4507 | 3075 | MONITOR_INVALID_DESCRIPTOR_CHECKSUM = 0xC01D0003, |
| 4508 | ||
| 4509 | 3076 | /// The monitor descriptor contains an invalid standard timing block. |
| 4510 | 3077 | MONITOR_INVALID_STANDARD_TIMING_BLOCK = 0xC01D0004, |
| 4511 | ||
| 4512 | 3078 | /// WMI data-block registration failed for one of the MSMonitorClass WMI subclasses. |
| 4513 | 3079 | MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED = 0xC01D0005, |
| 4514 | ||
| 4515 | 3080 | /// The provided monitor descriptor block is either corrupted or does not contain the monitor's detailed serial number. |
| 4516 | 3081 | MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK = 0xC01D0006, |
| 4517 | ||
| 4518 | 3082 | /// The provided monitor descriptor block is either corrupted or does not contain the monitor's user-friendly name. |
| 4519 | 3083 | MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK = 0xC01D0007, |
| 4520 | ||
| 4521 | 3084 | /// There is no monitor descriptor data at the specified (offset or size) region. |
| 4522 | 3085 | MONITOR_NO_MORE_DESCRIPTOR_DATA = 0xC01D0008, |
| 4523 | ||
| 4524 | 3086 | /// The monitor descriptor contains an invalid detailed timing block. |
| 4525 | 3087 | MONITOR_INVALID_DETAILED_TIMING_BLOCK = 0xC01D0009, |
| 4526 | ||
| 4527 | 3088 | /// Monitor descriptor contains invalid manufacture date. |
| 4528 | 3089 | MONITOR_INVALID_MANUFACTURE_DATE = 0xC01D000A, |
| 4529 | ||
| 4530 | 3090 | /// Exclusive mode ownership is needed to create an unmanaged primary allocation. |
| 4531 | 3091 | GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER = 0xC01E0000, |
| 4532 | ||
| 4533 | 3092 | /// The driver needs more DMA buffer space to complete the requested operation. |
| 4534 | 3093 | GRAPHICS_INSUFFICIENT_DMA_BUFFER = 0xC01E0001, |
| 4535 | ||
| 4536 | 3094 | /// The specified display adapter handle is invalid. |
| 4537 | 3095 | GRAPHICS_INVALID_DISPLAY_ADAPTER = 0xC01E0002, |
| 4538 | ||
| 4539 | 3096 | /// The specified display adapter and all of its state have been reset. |
| 4540 | 3097 | GRAPHICS_ADAPTER_WAS_RESET = 0xC01E0003, |
| 4541 | ||
| 4542 | 3098 | /// The driver stack does not match the expected driver model. |
| 4543 | 3099 | GRAPHICS_INVALID_DRIVER_MODEL = 0xC01E0004, |
| 4544 | ||
| 4545 | 3100 | /// Present happened but ended up into the changed desktop mode. |
| 4546 | 3101 | GRAPHICS_PRESENT_MODE_CHANGED = 0xC01E0005, |
| 4547 | ||
| 4548 | 3102 | /// Nothing to present due to desktop occlusion. |
| 4549 | 3103 | GRAPHICS_PRESENT_OCCLUDED = 0xC01E0006, |
| 4550 | ||
| 4551 | 3104 | /// Not able to present due to denial of desktop access. |
| 4552 | 3105 | GRAPHICS_PRESENT_DENIED = 0xC01E0007, |
| 4553 | ||
| 4554 | 3106 | /// Not able to present with color conversion. |
| 4555 | 3107 | GRAPHICS_CANNOTCOLORCONVERT = 0xC01E0008, |
| 4556 | ||
| 4557 | 3108 | /// Present redirection is disabled (desktop windowing management subsystem is off). |
| 4558 | 3109 | GRAPHICS_PRESENT_REDIRECTION_DISABLED = 0xC01E000B, |
| 4559 | ||
| 4560 | 3110 | /// Previous exclusive VidPn source owner has released its ownership |
| 4561 | 3111 | GRAPHICS_PRESENT_UNOCCLUDED = 0xC01E000C, |
| 4562 | ||
| 4563 | 3112 | /// Not enough video memory is available to complete the operation. |
| 4564 | 3113 | GRAPHICS_NO_VIDEO_MEMORY = 0xC01E0100, |
| 4565 | ||
| 4566 | 3114 | /// Could not probe and lock the underlying memory of an allocation. |
| 4567 | 3115 | GRAPHICS_CANT_LOCK_MEMORY = 0xC01E0101, |
| 4568 | ||
| 4569 | 3116 | /// The allocation is currently busy. |
| 4570 | 3117 | GRAPHICS_ALLOCATION_BUSY = 0xC01E0102, |
| 4571 | ||
| 4572 | 3118 | /// An object being referenced has already reached the maximum reference count and cannot be referenced further. |
| 4573 | 3119 | GRAPHICS_TOO_MANY_REFERENCES = 0xC01E0103, |
| 4574 | ||
| 4575 | 3120 | /// A problem could not be solved due to an existing condition. Try again later. |
| 4576 | 3121 | GRAPHICS_TRY_AGAIN_LATER = 0xC01E0104, |
| 4577 | ||
| 4578 | 3122 | /// A problem could not be solved due to an existing condition. Try again now. |
| 4579 | 3123 | GRAPHICS_TRY_AGAIN_NOW = 0xC01E0105, |
| 4580 | ||
| 4581 | 3124 | /// The allocation is invalid. |
| 4582 | 3125 | GRAPHICS_ALLOCATION_INVALID = 0xC01E0106, |
| 4583 | ||
| 4584 | 3126 | /// No more unswizzling apertures are currently available. |
| 4585 | 3127 | GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE = 0xC01E0107, |
| 4586 | ||
| 4587 | 3128 | /// The current allocation cannot be unswizzled by an aperture. |
| 4588 | 3129 | GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED = 0xC01E0108, |
| 4589 | ||
| 4590 | 3130 | /// The request failed because a pinned allocation cannot be evicted. |
| 4591 | 3131 | GRAPHICS_CANT_EVICT_PINNED_ALLOCATION = 0xC01E0109, |
| 4592 | ||
| 4593 | 3132 | /// The allocation cannot be used from its current segment location for the specified operation. |
| 4594 | 3133 | GRAPHICS_INVALID_ALLOCATION_USAGE = 0xC01E0110, |
| 4595 | ||
| 4596 | 3134 | /// A locked allocation cannot be used in the current command buffer. |
| 4597 | 3135 | GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION = 0xC01E0111, |
| 4598 | ||
| 4599 | 3136 | /// The allocation being referenced has been closed permanently. |
| 4600 | 3137 | GRAPHICS_ALLOCATION_CLOSED = 0xC01E0112, |
| 4601 | ||
| 4602 | 3138 | /// An invalid allocation instance is being referenced. |
| 4603 | 3139 | GRAPHICS_INVALID_ALLOCATION_INSTANCE = 0xC01E0113, |
| 4604 | ||
| 4605 | 3140 | /// An invalid allocation handle is being referenced. |
| 4606 | 3141 | GRAPHICS_INVALID_ALLOCATION_HANDLE = 0xC01E0114, |
| 4607 | ||
| 4608 | 3142 | /// The allocation being referenced does not belong to the current device. |
| 4609 | 3143 | GRAPHICS_WRONG_ALLOCATION_DEVICE = 0xC01E0115, |
| 4610 | ||
| 4611 | 3144 | /// The specified allocation lost its content. |
| 4612 | 3145 | GRAPHICS_ALLOCATION_CONTENT_LOST = 0xC01E0116, |
| 4613 | ||
| 4614 | 3146 | /// A GPU exception was detected on the given device. The device cannot be scheduled. |
| 4615 | 3147 | GRAPHICS_GPU_EXCEPTION_ON_DEVICE = 0xC01E0200, |
| 4616 | ||
| 4617 | 3148 | /// The specified VidPN topology is invalid. |
| 4618 | 3149 | GRAPHICS_INVALID_VIDPN_TOPOLOGY = 0xC01E0300, |
| 4619 | ||
| 4620 | 3150 | /// The specified VidPN topology is valid but is not supported by this model of the display adapter. |
| 4621 | 3151 | GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED = 0xC01E0301, |
| 4622 | ||
| 4623 | 3152 | /// The specified VidPN topology is valid but is not currently supported by the display adapter due to allocation of its resources. |
| 4624 | 3153 | GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED = 0xC01E0302, |
| 4625 | ||
| 4626 | 3154 | /// The specified VidPN handle is invalid. |
| 4627 | 3155 | GRAPHICS_INVALID_VIDPN = 0xC01E0303, |
| 4628 | ||
| 4629 | 3156 | /// The specified video present source is invalid. |
| 4630 | 3157 | GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE = 0xC01E0304, |
| 4631 | ||
| 4632 | 3158 | /// The specified video present target is invalid. |
| 4633 | 3159 | GRAPHICS_INVALID_VIDEO_PRESENT_TARGET = 0xC01E0305, |
| 4634 | ||
| 4635 | 3160 | /// The specified VidPN modality is not supported (for example, at least two of the pinned modes are not co-functional). |
| 4636 | 3161 | GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED = 0xC01E0306, |
| 4637 | ||
| 4638 | 3162 | /// The specified VidPN source mode set is invalid. |
| 4639 | 3163 | GRAPHICS_INVALID_VIDPN_SOURCEMODESET = 0xC01E0308, |
| 4640 | ||
| 4641 | 3164 | /// The specified VidPN target mode set is invalid. |
| 4642 | 3165 | GRAPHICS_INVALID_VIDPN_TARGETMODESET = 0xC01E0309, |
| 4643 | ||
| 4644 | 3166 | /// The specified video signal frequency is invalid. |
| 4645 | 3167 | GRAPHICS_INVALID_FREQUENCY = 0xC01E030A, |
| 4646 | ||
| 4647 | 3168 | /// The specified video signal active region is invalid. |
| 4648 | 3169 | GRAPHICS_INVALID_ACTIVE_REGION = 0xC01E030B, |
| 4649 | ||
| 4650 | 3170 | /// The specified video signal total region is invalid. |
| 4651 | 3171 | GRAPHICS_INVALID_TOTAL_REGION = 0xC01E030C, |
| 4652 | ||
| 4653 | 3172 | /// The specified video present source mode is invalid. |
| 4654 | 3173 | GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE = 0xC01E0310, |
| 4655 | ||
| 4656 | 3174 | /// The specified video present target mode is invalid. |
| 4657 | 3175 | GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE = 0xC01E0311, |
| 4658 | ||
| 4659 | 3176 | /// The pinned mode must remain in the set on the VidPN's co-functional modality enumeration. |
| 4660 | 3177 | GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET = 0xC01E0312, |
| 4661 | ||
| 4662 | 3178 | /// The specified video present path is already in the VidPN's topology. |
| 4663 | 3179 | GRAPHICS_PATH_ALREADY_IN_TOPOLOGY = 0xC01E0313, |
| 4664 | ||
| 4665 | 3180 | /// The specified mode is already in the mode set. |
| 4666 | 3181 | GRAPHICS_MODE_ALREADY_IN_MODESET = 0xC01E0314, |
| 4667 | ||
| 4668 | 3182 | /// The specified video present source set is invalid. |
| 4669 | 3183 | GRAPHICS_INVALID_VIDEOPRESENTSOURCESET = 0xC01E0315, |
| 4670 | ||
| 4671 | 3184 | /// The specified video present target set is invalid. |
| 4672 | 3185 | GRAPHICS_INVALID_VIDEOPRESENTTARGETSET = 0xC01E0316, |
| 4673 | ||
| 4674 | 3186 | /// The specified video present source is already in the video present source set. |
| 4675 | 3187 | GRAPHICS_SOURCE_ALREADY_IN_SET = 0xC01E0317, |
| 4676 | ||
| 4677 | 3188 | /// The specified video present target is already in the video present target set. |
| 4678 | 3189 | GRAPHICS_TARGET_ALREADY_IN_SET = 0xC01E0318, |
| 4679 | ||
| 4680 | 3190 | /// The specified VidPN present path is invalid. |
| 4681 | 3191 | GRAPHICS_INVALID_VIDPN_PRESENT_PATH = 0xC01E0319, |
| 4682 | ||
| 4683 | 3192 | /// The miniport has no recommendation for augmenting the specified VidPN's topology. |
| 4684 | 3193 | GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY = 0xC01E031A, |
| 4685 | ||
| 4686 | 3194 | /// The specified monitor frequency range set is invalid. |
| 4687 | 3195 | GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET = 0xC01E031B, |
| 4688 | ||
| 4689 | 3196 | /// The specified monitor frequency range is invalid. |
| 4690 | 3197 | GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE = 0xC01E031C, |
| 4691 | ||
| 4692 | 3198 | /// The specified frequency range is not in the specified monitor frequency range set. |
| 4693 | 3199 | GRAPHICS_FREQUENCYRANGE_NOT_IN_SET = 0xC01E031D, |
| 4694 | ||
| 4695 | 3200 | /// The specified frequency range is already in the specified monitor frequency range set. |
| 4696 | 3201 | GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET = 0xC01E031F, |
| 4697 | ||
| 4698 | 3202 | /// The specified mode set is stale. Reacquire the new mode set. |
| 4699 | 3203 | GRAPHICS_STALE_MODESET = 0xC01E0320, |
| 4700 | ||
| 4701 | 3204 | /// The specified monitor source mode set is invalid. |
| 4702 | 3205 | GRAPHICS_INVALID_MONITOR_SOURCEMODESET = 0xC01E0321, |
| 4703 | ||
| 4704 | 3206 | /// The specified monitor source mode is invalid. |
| 4705 | 3207 | GRAPHICS_INVALID_MONITOR_SOURCE_MODE = 0xC01E0322, |
| 4706 | ||
| 4707 | 3208 | /// The miniport does not have a recommendation regarding the request to provide a functional VidPN given the current display adapter configuration. |
| 4708 | 3209 | GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN = 0xC01E0323, |
| 4709 | ||
| 4710 | 3210 | /// The ID of the specified mode is being used by another mode in the set. |
| 4711 | 3211 | GRAPHICS_MODE_ID_MUST_BE_UNIQUE = 0xC01E0324, |
| 4712 | ||
| 4713 | 3212 | /// The system failed to determine a mode that is supported by both the display adapter and the monitor connected to it. |
| 4714 | 3213 | GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION = 0xC01E0325, |
| 4715 | ||
| 4716 | 3214 | /// The number of video present targets must be greater than or equal to the number of video present sources. |
| 4717 | 3215 | GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES = 0xC01E0326, |
| 4718 | ||
| 4719 | 3216 | /// The specified present path is not in the VidPN's topology. |
| 4720 | 3217 | GRAPHICS_PATH_NOT_IN_TOPOLOGY = 0xC01E0327, |
| 4721 | ||
| 4722 | 3218 | /// The display adapter must have at least one video present source. |
| 4723 | 3219 | GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE = 0xC01E0328, |
| 4724 | ||
| 4725 | 3220 | /// The display adapter must have at least one video present target. |
| 4726 | 3221 | GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET = 0xC01E0329, |
| 4727 | ||
| 4728 | 3222 | /// The specified monitor descriptor set is invalid. |
| 4729 | 3223 | GRAPHICS_INVALID_MONITORDESCRIPTORSET = 0xC01E032A, |
| 4730 | ||
| 4731 | 3224 | /// The specified monitor descriptor is invalid. |
| 4732 | 3225 | GRAPHICS_INVALID_MONITORDESCRIPTOR = 0xC01E032B, |
| 4733 | ||
| 4734 | 3226 | /// The specified descriptor is not in the specified monitor descriptor set. |
| 4735 | 3227 | GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET = 0xC01E032C, |
| 4736 | ||
| 4737 | 3228 | /// The specified descriptor is already in the specified monitor descriptor set. |
| 4738 | 3229 | GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET = 0xC01E032D, |
| 4739 | ||
| 4740 | 3230 | /// The ID of the specified monitor descriptor is being used by another descriptor in the set. |
| 4741 | 3231 | GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE = 0xC01E032E, |
| 4742 | ||
| 4743 | 3232 | /// The specified video present target subset type is invalid. |
| 4744 | 3233 | GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE = 0xC01E032F, |
| 4745 | ||
| 4746 | 3234 | /// Two or more of the specified resources are not related to each other, as defined by the interface semantics. |
| 4747 | 3235 | GRAPHICS_RESOURCES_NOT_RELATED = 0xC01E0330, |
| 4748 | ||
| 4749 | 3236 | /// The ID of the specified video present source is being used by another source in the set. |
| 4750 | 3237 | GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE = 0xC01E0331, |
| 4751 | ||
| 4752 | 3238 | /// The ID of the specified video present target is being used by another target in the set. |
| 4753 | 3239 | GRAPHICS_TARGET_ID_MUST_BE_UNIQUE = 0xC01E0332, |
| 4754 | ||
| 4755 | 3240 | /// The specified VidPN source cannot be used because there is no available VidPN target to connect it to. |
| 4756 | 3241 | GRAPHICS_NO_AVAILABLE_VIDPN_TARGET = 0xC01E0333, |
| 4757 | ||
| 4758 | 3242 | /// The newly arrived monitor could not be associated with a display adapter. |
| 4759 | 3243 | GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER = 0xC01E0334, |
| 4760 | ||
| 4761 | 3244 | /// The particular display adapter does not have an associated VidPN manager. |
| 4762 | 3245 | GRAPHICS_NO_VIDPNMGR = 0xC01E0335, |
| 4763 | ||
| 4764 | 3246 | /// The VidPN manager of the particular display adapter does not have an active VidPN. |
| 4765 | 3247 | GRAPHICS_NO_ACTIVE_VIDPN = 0xC01E0336, |
| 4766 | ||
| 4767 | 3248 | /// The specified VidPN topology is stale; obtain the new topology. |
| 4768 | 3249 | GRAPHICS_STALE_VIDPN_TOPOLOGY = 0xC01E0337, |
| 4769 | ||
| 4770 | 3250 | /// No monitor is connected on the specified video present target. |
| 4771 | 3251 | GRAPHICS_MONITOR_NOT_CONNECTED = 0xC01E0338, |
| 4772 | ||
| 4773 | 3252 | /// The specified source is not part of the specified VidPN's topology. |
| 4774 | 3253 | GRAPHICS_SOURCE_NOT_IN_TOPOLOGY = 0xC01E0339, |
| 4775 | ||
| 4776 | 3254 | /// The specified primary surface size is invalid. |
| 4777 | 3255 | GRAPHICS_INVALID_PRIMARYSURFACE_SIZE = 0xC01E033A, |
| 4778 | ||
| 4779 | 3256 | /// The specified visible region size is invalid. |
| 4780 | 3257 | GRAPHICS_INVALID_VISIBLEREGION_SIZE = 0xC01E033B, |
| 4781 | ||
| 4782 | 3258 | /// The specified stride is invalid. |
| 4783 | 3259 | GRAPHICS_INVALID_STRIDE = 0xC01E033C, |
| 4784 | ||
| 4785 | 3260 | /// The specified pixel format is invalid. |
| 4786 | 3261 | GRAPHICS_INVALID_PIXELFORMAT = 0xC01E033D, |
| 4787 | ||
| 4788 | 3262 | /// The specified color basis is invalid. |
| 4789 | 3263 | GRAPHICS_INVALID_COLORBASIS = 0xC01E033E, |
| 4790 | ||
| 4791 | 3264 | /// The specified pixel value access mode is invalid. |
| 4792 | 3265 | GRAPHICS_INVALID_PIXELVALUEACCESSMODE = 0xC01E033F, |
| 4793 | ||
| 4794 | 3266 | /// The specified target is not part of the specified VidPN's topology. |
| 4795 | 3267 | GRAPHICS_TARGET_NOT_IN_TOPOLOGY = 0xC01E0340, |
| 4796 | ||
| 4797 | 3268 | /// Failed to acquire the display mode management interface. |
| 4798 | 3269 | GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT = 0xC01E0341, |
| 4799 | ||
| 4800 | 3270 | /// The specified VidPN source is already owned by a DMM client and cannot be used until that client releases it. |
| 4801 | 3271 | GRAPHICS_VIDPN_SOURCE_IN_USE = 0xC01E0342, |
| 4802 | ||
| 4803 | 3272 | /// The specified VidPN is active and cannot be accessed. |
| 4804 | 3273 | GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN = 0xC01E0343, |
| 4805 | ||
| 4806 | 3274 | /// The specified VidPN's present path importance ordinal is invalid. |
| 4807 | 3275 | GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL = 0xC01E0344, |
| 4808 | ||
| 4809 | 3276 | /// The specified VidPN's present path content geometry transformation is invalid. |
| 4810 | 3277 | GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION = 0xC01E0345, |
| 4811 | ||
| 4812 | 3278 | /// The specified content geometry transformation is not supported on the respective VidPN present path. |
| 4813 | 3279 | GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED = 0xC01E0346, |
| 4814 | ||
| 4815 | 3280 | /// The specified gamma ramp is invalid. |
| 4816 | 3281 | GRAPHICS_INVALID_GAMMA_RAMP = 0xC01E0347, |
| 4817 | ||
| 4818 | 3282 | /// The specified gamma ramp is not supported on the respective VidPN present path. |
| 4819 | 3283 | GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED = 0xC01E0348, |
| 4820 | ||
| 4821 | 3284 | /// Multisampling is not supported on the respective VidPN present path. |
| 4822 | 3285 | GRAPHICS_MULTISAMPLING_NOT_SUPPORTED = 0xC01E0349, |
| 4823 | ||
| 4824 | 3286 | /// The specified mode is not in the specified mode set. |
| 4825 | 3287 | GRAPHICS_MODE_NOT_IN_MODESET = 0xC01E034A, |
| 4826 | ||
| 4827 | 3288 | /// The specified VidPN topology recommendation reason is invalid. |
| 4828 | 3289 | GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON = 0xC01E034D, |
| 4829 | ||
| 4830 | 3290 | /// The specified VidPN present path content type is invalid. |
| 4831 | 3291 | GRAPHICS_INVALID_PATH_CONTENT_TYPE = 0xC01E034E, |
| 4832 | ||
| 4833 | 3292 | /// The specified VidPN present path copy protection type is invalid. |
| 4834 | 3293 | GRAPHICS_INVALID_COPYPROTECTION_TYPE = 0xC01E034F, |
| 4835 | ||
| 4836 | 3294 | /// Only one unassigned mode set can exist at any one time for a particular VidPN source or target. |
| 4837 | 3295 | GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS = 0xC01E0350, |
| 4838 | ||
| 4839 | 3296 | /// The specified scan line ordering type is invalid. |
| 4840 | 3297 | GRAPHICS_INVALID_SCANLINE_ORDERING = 0xC01E0352, |
| 4841 | ||
| 4842 | 3298 | /// The topology changes are not allowed for the specified VidPN. |
| 4843 | 3299 | GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED = 0xC01E0353, |
| 4844 | ||
| 4845 | 3300 | /// All available importance ordinals are being used in the specified topology. |
| 4846 | 3301 | GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS = 0xC01E0354, |
| 4847 | ||
| 4848 | 3302 | /// The specified primary surface has a different private-format attribute than the current primary surface. |
| 4849 | 3303 | GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT = 0xC01E0355, |
| 4850 | ||
| 4851 | 3304 | /// The specified mode-pruning algorithm is invalid. |
| 4852 | 3305 | GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM = 0xC01E0356, |
| 4853 | ||
| 4854 | 3306 | /// The specified monitor-capability origin is invalid. |
| 4855 | 3307 | GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN = 0xC01E0357, |
| 4856 | ||
| 4857 | 3308 | /// The specified monitor-frequency range constraint is invalid. |
| 4858 | 3309 | GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT = 0xC01E0358, |
| 4859 | ||
| 4860 | 3310 | /// The maximum supported number of present paths has been reached. |
| 4861 | 3311 | GRAPHICS_MAX_NUM_PATHS_REACHED = 0xC01E0359, |
| 4862 | ||
| 4863 | 3312 | /// The miniport requested that augmentation be canceled for the specified source of the specified VidPN's topology. |
| 4864 | 3313 | GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION = 0xC01E035A, |
| 4865 | ||
| 4866 | 3314 | /// The specified client type was not recognized. |
| 4867 | 3315 | GRAPHICS_INVALID_CLIENT_TYPE = 0xC01E035B, |
| 4868 | ||
| 4869 | 3316 | /// The client VidPN is not set on this adapter (for example, no user mode-initiated mode changes have taken place on this adapter). |
| 4870 | 3317 | GRAPHICS_CLIENTVIDPN_NOT_SET = 0xC01E035C, |
| 4871 | ||
| 4872 | 3318 | /// The specified display adapter child device already has an external device connected to it. |
| 4873 | 3319 | GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED = 0xC01E0400, |
| 4874 | ||
| 4875 | 3320 | /// The display adapter child device does not support reporting a descriptor. |
| 4876 | 3321 | GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED = 0xC01E0401, |
| 4877 | ||
| 4878 | 3322 | /// The display adapter is not linked to any other adapters. |
| 4879 | 3323 | GRAPHICS_NOT_A_LINKED_ADAPTER = 0xC01E0430, |
| 4880 | ||
| 4881 | 3324 | /// The lead adapter in a linked configuration was not enumerated yet. |
| 4882 | 3325 | GRAPHICS_LEADLINK_NOT_ENUMERATED = 0xC01E0431, |
| 4883 | ||
| 4884 | 3326 | /// Some chain adapters in a linked configuration have not yet been enumerated. |
| 4885 | 3327 | GRAPHICS_CHAINLINKS_NOT_ENUMERATED = 0xC01E0432, |
| 4886 | ||
| 4887 | 3328 | /// The chain of linked adapters is not ready to start because of an unknown failure. |
| 4888 | 3329 | GRAPHICS_ADAPTER_CHAIN_NOT_READY = 0xC01E0433, |
| 4889 | ||
| 4890 | 3330 | /// An attempt was made to start a lead link display adapter when the chain links had not yet started. |
| 4891 | 3331 | GRAPHICS_CHAINLINKS_NOT_STARTED = 0xC01E0434, |
| 4892 | ||
| 4893 | 3332 | /// An attempt was made to turn on a lead link display adapter when the chain links were turned off. |
| 4894 | 3333 | GRAPHICS_CHAINLINKS_NOT_POWERED_ON = 0xC01E0435, |
| 4895 | ||
| 4896 | 3334 | /// The adapter link was found in an inconsistent state. |
| 4897 | 3335 | /// Not all adapters are in an expected PNP/power state. |
| 4898 | 3336 | GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE = 0xC01E0436, |
| 4899 | ||
| 4900 | 3337 | /// The driver trying to start is not the same as the driver for the posted display adapter. |
| 4901 | 3338 | GRAPHICS_NOT_POST_DEVICE_DRIVER = 0xC01E0438, |
| 4902 | ||
| 4903 | 3339 | /// An operation is being attempted that requires the display adapter to be in a quiescent state. |
| 4904 | 3340 | GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED = 0xC01E043B, |
| 4905 | ||
| 4906 | 3341 | /// The driver does not support OPM. |
| 4907 | 3342 | GRAPHICS_OPM_NOT_SUPPORTED = 0xC01E0500, |
| 4908 | ||
| 4909 | 3343 | /// The driver does not support COPP. |
| 4910 | 3344 | GRAPHICS_COPP_NOT_SUPPORTED = 0xC01E0501, |
| 4911 | ||
| 4912 | 3345 | /// The driver does not support UAB. |
| 4913 | 3346 | GRAPHICS_UAB_NOT_SUPPORTED = 0xC01E0502, |
| 4914 | ||
| 4915 | 3347 | /// The specified encrypted parameters are invalid. |
| 4916 | 3348 | GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS = 0xC01E0503, |
| 4917 | ||
| 4918 | 3349 | /// An array passed to a function cannot hold all of the data that the function wants to put in it. |
| 4919 | 3350 | GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL = 0xC01E0504, |
| 4920 | ||
| 4921 | 3351 | /// The GDI display device passed to this function does not have any active protected outputs. |
| 4922 | 3352 | GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST = 0xC01E0505, |
| 4923 | ||
| 4924 | 3353 | /// The PVP cannot find an actual GDI display device that corresponds to the passed-in GDI display device name. |
| 4925 | 3354 | GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME = 0xC01E0506, |
| 4926 | ||
| 4927 | 3355 | /// This function failed because the GDI display device passed to it was not attached to the Windows desktop. |
| 4928 | 3356 | GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP = 0xC01E0507, |
| 4929 | ||
| 4930 | 3357 | /// The PVP does not support mirroring display devices because they do not have any protected outputs. |
| 4931 | 3358 | GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED = 0xC01E0508, |
| 4932 | ||
| 4933 | 3359 | /// The function failed because an invalid pointer parameter was passed to it. |
| 4934 | 3360 | /// A pointer parameter is invalid if it is null, is not correctly aligned, or it points to an invalid address or a kernel mode address. |
| 4935 | 3361 | GRAPHICS_OPM_INVALID_POINTER = 0xC01E050A, |
| 4936 | ||
| 4937 | 3362 | /// An internal error caused an operation to fail. |
| 4938 | 3363 | GRAPHICS_OPM_INTERNAL_ERROR = 0xC01E050B, |
| 4939 | ||
| 4940 | 3364 | /// The function failed because the caller passed in an invalid OPM user-mode handle. |
| 4941 | 3365 | GRAPHICS_OPM_INVALID_HANDLE = 0xC01E050C, |
| 4942 | ||
| 4943 | 3366 | /// This function failed because the GDI device passed to it did not have any monitors associated with it. |
| 4944 | 3367 | GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE = 0xC01E050D, |
| 4945 | ||
| 4946 | 3368 | /// A certificate could not be returned because the certificate buffer passed to the function was too small. |
| 4947 | 3369 | GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH = 0xC01E050E, |
| 4948 | ||
| 4949 | 3370 | /// DxgkDdiOpmCreateProtectedOutput() could not create a protected output because the video present yarget is in spanning mode. |
| 4950 | 3371 | GRAPHICS_OPM_SPANNING_MODE_ENABLED = 0xC01E050F, |
| 4951 | ||
| 4952 | 3372 | /// DxgkDdiOpmCreateProtectedOutput() could not create a protected output because the video present target is in theater mode. |
| 4953 | 3373 | GRAPHICS_OPM_THEATER_MODE_ENABLED = 0xC01E0510, |
| 4954 | ||
| 4955 | 3374 | /// The function call failed because the display adapter's hardware functionality scan (HFS) failed to validate the graphics hardware. |
| 4956 | 3375 | GRAPHICS_PVP_HFS_FAILED = 0xC01E0511, |
| 4957 | ||
| 4958 | 3376 | /// The HDCP SRM passed to this function did not comply with section 5 of the HDCP 1.1 specification. |
| 4959 | 3377 | GRAPHICS_OPM_INVALID_SRM = 0xC01E0512, |
| 4960 | ||
| 4961 | 3378 | /// The protected output cannot enable the HDCP system because it does not support it. |
| 4962 | 3379 | GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP = 0xC01E0513, |
| 4963 | ||
| 4964 | 3380 | /// The protected output cannot enable analog copy protection because it does not support it. |
| 4965 | 3381 | GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP = 0xC01E0514, |
| 4966 | ||
| 4967 | 3382 | /// The protected output cannot enable the CGMS-A protection technology because it does not support it. |
| 4968 | 3383 | GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA = 0xC01E0515, |
| 4969 | ||
| 4970 | 3384 | /// DxgkDdiOPMGetInformation() cannot return the version of the SRM being used because the application never successfully passed an SRM to the protected output. |
| 4971 | 3385 | GRAPHICS_OPM_HDCP_SRM_NEVER_SET = 0xC01E0516, |
| 4972 | ||
| 4973 | 3386 | /// DxgkDdiOPMConfigureProtectedOutput() cannot enable the specified output protection technology because the output's screen resolution is too high. |
| 4974 | 3387 | GRAPHICS_OPM_RESOLUTION_TOO_HIGH = 0xC01E0517, |
| 4975 | ||
| 4976 | 3388 | /// DxgkDdiOPMConfigureProtectedOutput() cannot enable HDCP because other physical outputs are using the display adapter's HDCP hardware. |
| 4977 | 3389 | GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE = 0xC01E0518, |
| 4978 | ||
| 4979 | 3390 | /// The operating system asynchronously destroyed this OPM-protected output because the operating system state changed. |
| 4980 | 3391 | /// This error typically occurs because the monitor PDO associated with this protected output was removed or stopped, the protected output's session became a nonconsole session, or the protected output's desktop became inactive. |
| 4981 | 3392 | GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS = 0xC01E051A, |
| 4982 | ||
| 4983 | 3393 | /// OPM functions cannot be called when a session is changing its type. |
| 4984 | 3394 | /// Three types of sessions currently exist: console, disconnected, and remote (RDP or ICA). |
| 4985 | 3395 | GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS = 0xC01E051B, |
| 4986 | ||
| 4987 | 3396 | /// The DxgkDdiOPMGetCOPPCompatibleInformation, DxgkDdiOPMGetInformation, or DxgkDdiOPMConfigureProtectedOutput function failed. |
| 4988 | 3397 | /// This error is returned only if a protected output has OPM semantics. |
| 4989 | 3398 | /// DxgkDdiOPMGetCOPPCompatibleInformation always returns this error if a protected output has OPM semantics. |
| 4990 | 3399 | /// DxgkDdiOPMGetInformation returns this error code if the caller requested COPP-specific information. |
| 4991 | 3400 | /// DxgkDdiOPMConfigureProtectedOutput returns this error when the caller tries to use a COPP-specific command. |
| 4992 | 3401 | GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS = 0xC01E051C, |
| 4993 | ||
| 4994 | 3402 | /// The DxgkDdiOPMGetInformation and DxgkDdiOPMGetCOPPCompatibleInformation functions return this error code if the passed-in sequence number is not the expected sequence number or the passed-in OMAC value is invalid. |
| 4995 | 3403 | GRAPHICS_OPM_INVALID_INFORMATION_REQUEST = 0xC01E051D, |
| 4996 | ||
| 4997 | 3404 | /// The function failed because an unexpected error occurred inside a display driver. |
| 4998 | 3405 | GRAPHICS_OPM_DRIVER_INTERNAL_ERROR = 0xC01E051E, |
| 4999 | ||
| 5000 | 3406 | /// The DxgkDdiOPMGetCOPPCompatibleInformation, DxgkDdiOPMGetInformation, or DxgkDdiOPMConfigureProtectedOutput function failed. |
| 5001 | 3407 | /// This error is returned only if a protected output has COPP semantics. |
| 5002 | 3408 | /// DxgkDdiOPMGetCOPPCompatibleInformation returns this error code if the caller requested OPM-specific information. |
| 5003 | 3409 | /// DxgkDdiOPMGetInformation always returns this error if a protected output has COPP semantics. |
| 5004 | 3410 | /// DxgkDdiOPMConfigureProtectedOutput returns this error when the caller tries to use an OPM-specific command. |
| 5005 | 3411 | GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS = 0xC01E051F, |
| 5006 | ||
| 5007 | 3412 | /// The DxgkDdiOPMGetCOPPCompatibleInformation and DxgkDdiOPMConfigureProtectedOutput functions return this error if the display driver does not support the DXGKMDT_OPM_GET_ACP_AND_CGMSA_SIGNALING and DXGKMDT_OPM_SET_ACP_AND_CGMSA_SIGNALING GUIDs. |
| 5008 | 3413 | GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED = 0xC01E0520, |
| 5009 | ||
| 5010 | 3414 | /// The DxgkDdiOPMConfigureProtectedOutput function returns this error code if the passed-in sequence number is not the expected sequence number or the passed-in OMAC value is invalid. |
| 5011 | 3415 | GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST = 0xC01E0521, |
| 5012 | ||
| 5013 | 3416 | /// The monitor connected to the specified video output does not have an I2C bus. |
| 5014 | 3417 | GRAPHICS_I2C_NOT_SUPPORTED = 0xC01E0580, |
| 5015 | ||
| 5016 | 3418 | /// No device on the I2C bus has the specified address. |
| 5017 | 3419 | GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST = 0xC01E0581, |
| 5018 | ||
| 5019 | 3420 | /// An error occurred while transmitting data to the device on the I2C bus. |
| 5020 | 3421 | GRAPHICS_I2C_ERROR_TRANSMITTING_DATA = 0xC01E0582, |
| 5021 | ||
| 5022 | 3422 | /// An error occurred while receiving data from the device on the I2C bus. |
| 5023 | 3423 | GRAPHICS_I2C_ERROR_RECEIVING_DATA = 0xC01E0583, |
| 5024 | ||
| 5025 | 3424 | /// The monitor does not support the specified VCP code. |
| 5026 | 3425 | GRAPHICS_DDCCI_VCP_NOT_SUPPORTED = 0xC01E0584, |
| 5027 | ||
| 5028 | 3426 | /// The data received from the monitor is invalid. |
| 5029 | 3427 | GRAPHICS_DDCCI_INVALID_DATA = 0xC01E0585, |
| 5030 | ||
| 5031 | 3428 | /// A function call failed because a monitor returned an invalid timing status byte when the operating system used the DDC/CI get timing report and timing message command to get a timing report from a monitor. |
| 5032 | 3429 | GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE = 0xC01E0586, |
| 5033 | ||
| 5034 | 3430 | /// A monitor returned a DDC/CI capabilities string that did not comply with the ACCESS.bus 3.0, DDC/CI 1.1, or MCCS 2 Revision 1 specification. |
| 5035 | 3431 | GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING = 0xC01E0587, |
| 5036 | ||
| 5037 | 3432 | /// An internal error caused an operation to fail. |
| 5038 | 3433 | GRAPHICS_MCA_INTERNAL_ERROR = 0xC01E0588, |
| 5039 | ||
| 5040 | 3434 | /// An operation failed because a DDC/CI message had an invalid value in its command field. |
| 5041 | 3435 | GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND = 0xC01E0589, |
| 5042 | ||
| 5043 | 3436 | /// This error occurred because a DDC/CI message had an invalid value in its length field. |
| 5044 | 3437 | GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH = 0xC01E058A, |
| 5045 | ||
| 5046 | 3438 | /// This error occurred because the value in a DDC/CI message's checksum field did not match the message's computed checksum value. |
| 5047 | 3439 | /// This error implies that the data was corrupted while it was being transmitted from a monitor to a computer. |
| 5048 | 3440 | GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM = 0xC01E058B, |
| 5049 | ||
| 5050 | 3441 | /// This function failed because an invalid monitor handle was passed to it. |
| 5051 | 3442 | GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE = 0xC01E058C, |
| 5052 | ||
| 5053 | 3443 | /// The operating system asynchronously destroyed the monitor that corresponds to this handle because the operating system's state changed. |
| 5054 | 3444 | /// This error typically occurs because the monitor PDO associated with this handle was removed or stopped, or a display mode change occurred. |
| 5055 | 3445 | /// A display mode change occurs when Windows sends a WM_DISPLAYCHANGE message to applications. |
| 5056 | 3446 | GRAPHICS_MONITOR_NO_LONGER_EXISTS = 0xC01E058D, |
| 5057 | ||
| 5058 | 3447 | /// This function can be used only if a program is running in the local console session. |
| 5059 | 3448 | /// It cannot be used if a program is running on a remote desktop session or on a terminal server session. |
| 5060 | 3449 | GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED = 0xC01E05E0, |
| 5061 | ||
| 5062 | 3450 | /// This function cannot find an actual GDI display device that corresponds to the specified GDI display device name. |
| 5063 | 3451 | GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME = 0xC01E05E1, |
| 5064 | ||
| 5065 | 3452 | /// The function failed because the specified GDI display device was not attached to the Windows desktop. |
| 5066 | 3453 | GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP = 0xC01E05E2, |
| 5067 | ||
| 5068 | 3454 | /// This function does not support GDI mirroring display devices because GDI mirroring display devices do not have any physical monitors associated with them. |
| 5069 | 3455 | GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED = 0xC01E05E3, |
| 5070 | ||
| 5071 | 3456 | /// The function failed because an invalid pointer parameter was passed to it. |
| 5072 | 3457 | /// A pointer parameter is invalid if it is null, is not correctly aligned, or points to an invalid address or to a kernel mode address. |
| 5073 | 3458 | GRAPHICS_INVALID_POINTER = 0xC01E05E4, |
| 5074 | ||
| 5075 | 3459 | /// This function failed because the GDI device passed to it did not have a monitor associated with it. |
| 5076 | 3460 | GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE = 0xC01E05E5, |
| 5077 | ||
| 5078 | 3461 | /// An array passed to the function cannot hold all of the data that the function must copy into the array. |
| 5079 | 3462 | GRAPHICS_PARAMETER_ARRAY_TOO_SMALL = 0xC01E05E6, |
| 5080 | ||
| 5081 | 3463 | /// An internal error caused an operation to fail. |
| 5082 | 3464 | GRAPHICS_INTERNAL_ERROR = 0xC01E05E7, |
| 5083 | ||
| 5084 | 3465 | /// The function failed because the current session is changing its type. |
| 5085 | 3466 | /// This function cannot be called when the current session is changing its type. |
| 5086 | 3467 | /// Three types of sessions currently exist: console, disconnected, and remote (RDP or ICA). |
| 5087 | 3468 | GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS = 0xC01E05E8, |
| 5088 | ||
| 5089 | 3469 | /// The volume must be unlocked before it can be used. |
| 5090 | 3470 | FVE_LOCKED_VOLUME = 0xC0210000, |
| 5091 | ||
| 5092 | 3471 | /// The volume is fully decrypted and no key is available. |
| 5093 | 3472 | FVE_NOT_ENCRYPTED = 0xC0210001, |
| 5094 | ||
| 5095 | 3473 | /// The control block for the encrypted volume is not valid. |
| 5096 | 3474 | FVE_BAD_INFORMATION = 0xC0210002, |
| 5097 | ||
| 5098 | 3475 | /// Not enough free space remains on the volume to allow encryption. |
| 5099 | 3476 | FVE_TOO_SMALL = 0xC0210003, |
| 5100 | ||
| 5101 | 3477 | /// The partition cannot be encrypted because the file system is not supported. |
| 5102 | 3478 | FVE_FAILED_WRONG_FS = 0xC0210004, |
| 5103 | ||
| 5104 | 3479 | /// The file system is inconsistent. Run the Check Disk utility. |
| 5105 | 3480 | FVE_FAILED_BAD_FS = 0xC0210005, |
| 5106 | ||
| 5107 | 3481 | /// The file system does not extend to the end of the volume. |
| 5108 | 3482 | FVE_FS_NOT_EXTENDED = 0xC0210006, |
| 5109 | ||
| 5110 | 3483 | /// This operation cannot be performed while a file system is mounted on the volume. |
| 5111 | 3484 | FVE_FS_MOUNTED = 0xC0210007, |
| 5112 | ||
| 5113 | 3485 | /// BitLocker Drive Encryption is not included with this version of Windows. |
| 5114 | 3486 | FVE_NO_LICENSE = 0xC0210008, |
| 5115 | ||
| 5116 | 3487 | /// The requested action was denied by the FVE control engine. |
| 5117 | 3488 | FVE_ACTION_NOT_ALLOWED = 0xC0210009, |
| 5118 | ||
| 5119 | 3489 | /// The data supplied is malformed. |
| 5120 | 3490 | FVE_BAD_DATA = 0xC021000A, |
| 5121 | ||
| 5122 | 3491 | /// The volume is not bound to the system. |
| 5123 | 3492 | FVE_VOLUME_NOT_BOUND = 0xC021000B, |
| 5124 | ||
| 5125 | 3493 | /// The volume specified is not a data volume. |
| 5126 | 3494 | FVE_NOT_DATA_VOLUME = 0xC021000C, |
| 5127 | ||
| 5128 | 3495 | /// A read operation failed while converting the volume. |
| 5129 | 3496 | FVE_CONV_READ_ERROR = 0xC021000D, |
| 5130 | ||
| 5131 | 3497 | /// A write operation failed while converting the volume. |
| 5132 | 3498 | FVE_CONV_WRITE_ERROR = 0xC021000E, |
| 5133 | ||
| 5134 | 3499 | /// The control block for the encrypted volume was updated by another thread. Try again. |
| 5135 | 3500 | FVE_OVERLAPPED_UPDATE = 0xC021000F, |
| 5136 | ||
| 5137 | 3501 | /// The volume encryption algorithm cannot be used on this sector size. |
| 5138 | 3502 | FVE_FAILED_SECTOR_SIZE = 0xC0210010, |
| 5139 | ||
| 5140 | 3503 | /// BitLocker recovery authentication failed. |
| 5141 | 3504 | FVE_FAILED_AUTHENTICATION = 0xC0210011, |
| 5142 | ||
| 5143 | 3505 | /// The volume specified is not the boot operating system volume. |
| 5144 | 3506 | FVE_NOT_OS_VOLUME = 0xC0210012, |
| 5145 | ||
| 5146 | 3507 | /// The BitLocker startup key or recovery password could not be read from external media. |
| 5147 | 3508 | FVE_KEYFILE_NOT_FOUND = 0xC0210013, |
| 5148 | ||
| 5149 | 3509 | /// The BitLocker startup key or recovery password file is corrupt or invalid. |
| 5150 | 3510 | FVE_KEYFILE_INVALID = 0xC0210014, |
| 5151 | ||
| 5152 | 3511 | /// The BitLocker encryption key could not be obtained from the startup key or the recovery password. |
| 5153 | 3512 | FVE_KEYFILE_NO_VMK = 0xC0210015, |
| 5154 | ||
| 5155 | 3513 | /// The TPM is disabled. |
| 5156 | 3514 | FVE_TPM_DISABLED = 0xC0210016, |
| 5157 | ||
| 5158 | 3515 | /// The authorization data for the SRK of the TPM is not zero. |
| 5159 | 3516 | FVE_TPM_SRK_AUTH_NOT_ZERO = 0xC0210017, |
| 5160 | ||
| 5161 | 3517 | /// The system boot information changed or the TPM locked out access to BitLocker encryption keys until the computer is restarted. |
| 5162 | 3518 | FVE_TPM_INVALID_PCR = 0xC0210018, |
| 5163 | ||
| 5164 | 3519 | /// The BitLocker encryption key could not be obtained from the TPM. |
| 5165 | 3520 | FVE_TPM_NO_VMK = 0xC0210019, |
| 5166 | ||
| 5167 | 3521 | /// The BitLocker encryption key could not be obtained from the TPM and PIN. |
| 5168 | 3522 | FVE_PIN_INVALID = 0xC021001A, |
| 5169 | ||
| 5170 | 3523 | /// A boot application hash does not match the hash computed when BitLocker was turned on. |
| 5171 | 3524 | FVE_AUTH_INVALID_APPLICATION = 0xC021001B, |
| 5172 | ||
| 5173 | 3525 | /// The Boot Configuration Data (BCD) settings are not supported or have changed because BitLocker was enabled. |
| 5174 | 3526 | FVE_AUTH_INVALID_CONFIG = 0xC021001C, |
| 5175 | ||
| 5176 | 3527 | /// Boot debugging is enabled. Run Windows Boot Configuration Data Store Editor (bcdedit.exe) to turn it off. |
| 5177 | 3528 | FVE_DEBUGGER_ENABLED = 0xC021001D, |
| 5178 | ||
| 5179 | 3529 | /// The BitLocker encryption key could not be obtained. |
| 5180 | 3530 | FVE_DRY_RUN_FAILED = 0xC021001E, |
| 5181 | ||
| 5182 | 3531 | /// The metadata disk region pointer is incorrect. |
| 5183 | 3532 | FVE_BAD_METADATA_POINTER = 0xC021001F, |
| 5184 | ||
| 5185 | 3533 | /// The backup copy of the metadata is out of date. |
| 5186 | 3534 | FVE_OLD_METADATA_COPY = 0xC0210020, |
| 5187 | ||
| 5188 | 3535 | /// No action was taken because a system restart is required. |
| 5189 | 3536 | FVE_REBOOT_REQUIRED = 0xC0210021, |
| 5190 | ||
| 5191 | 3537 | /// No action was taken because BitLocker Drive Encryption is in RAW access mode. |
| 5192 | 3538 | FVE_RAW_ACCESS = 0xC0210022, |
| 5193 | ||
| 5194 | 3539 | /// BitLocker Drive Encryption cannot enter RAW access mode for this volume. |
| 5195 | 3540 | FVE_RAW_BLOCKED = 0xC0210023, |
| 5196 | ||
| 5197 | 3541 | /// This feature of BitLocker Drive Encryption is not included with this version of Windows. |
| 5198 | 3542 | FVE_NO_FEATURE_LICENSE = 0xC0210026, |
| 5199 | ||
| 5200 | 3543 | /// Group policy does not permit turning off BitLocker Drive Encryption on roaming data volumes. |
| 5201 | 3544 | FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED = 0xC0210027, |
| 5202 | ||
| 5203 | 3545 | /// Bitlocker Drive Encryption failed to recover from aborted conversion. |
| 5204 | 3546 | /// This could be due to either all conversion logs being corrupted or the media being write-protected. |
| 5205 | 3547 | FVE_CONV_RECOVERY_FAILED = 0xC0210028, |
| 5206 | ||
| 5207 | 3548 | /// The requested virtualization size is too big. |
| 5208 | 3549 | FVE_VIRTUALIZED_SPACE_TOO_BIG = 0xC0210029, |
| 5209 | ||
| 5210 | 3550 | /// The drive is too small to be protected using BitLocker Drive Encryption. |
| 5211 | 3551 | FVE_VOLUME_TOO_SMALL = 0xC0210030, |
| 5212 | ||
| 5213 | 3552 | /// The callout does not exist. |
| 5214 | 3553 | FWP_CALLOUT_NOT_FOUND = 0xC0220001, |
| 5215 | ||
| 5216 | 3554 | /// The filter condition does not exist. |
| 5217 | 3555 | FWP_CONDITION_NOT_FOUND = 0xC0220002, |
| 5218 | ||
| 5219 | 3556 | /// The filter does not exist. |
| 5220 | 3557 | FWP_FILTER_NOT_FOUND = 0xC0220003, |
| 5221 | ||
| 5222 | 3558 | /// The layer does not exist. |
| 5223 | 3559 | FWP_LAYER_NOT_FOUND = 0xC0220004, |
| 5224 | ||
| 5225 | 3560 | /// The provider does not exist. |
| 5226 | 3561 | FWP_PROVIDER_NOT_FOUND = 0xC0220005, |
| 5227 | ||
| 5228 | 3562 | /// The provider context does not exist. |
| 5229 | 3563 | FWP_PROVIDER_CONTEXT_NOT_FOUND = 0xC0220006, |
| 5230 | ||
| 5231 | 3564 | /// The sublayer does not exist. |
| 5232 | 3565 | FWP_SUBLAYER_NOT_FOUND = 0xC0220007, |
| 5233 | ||
| 5234 | 3566 | /// The object does not exist. |
| 5235 | 3567 | FWP_NOT_FOUND = 0xC0220008, |
| 5236 | ||
| 5237 | 3568 | /// An object with that GUID or LUID already exists. |
| 5238 | 3569 | FWP_ALREADY_EXISTS = 0xC0220009, |
| 5239 | ||
| 5240 | 3570 | /// The object is referenced by other objects and cannot be deleted. |
| 5241 | 3571 | FWP_IN_USE = 0xC022000A, |
| 5242 | ||
| 5243 | 3572 | /// The call is not allowed from within a dynamic session. |
| 5244 | 3573 | FWP_DYNAMIC_SESSION_IN_PROGRESS = 0xC022000B, |
| 5245 | ||
| 5246 | 3574 | /// The call was made from the wrong session and cannot be completed. |
| 5247 | 3575 | FWP_WRONG_SESSION = 0xC022000C, |
| 5248 | ||
| 5249 | 3576 | /// The call must be made from within an explicit transaction. |
| 5250 | 3577 | FWP_NO_TXN_IN_PROGRESS = 0xC022000D, |
| 5251 | ||
| 5252 | 3578 | /// The call is not allowed from within an explicit transaction. |
| 5253 | 3579 | FWP_TXN_IN_PROGRESS = 0xC022000E, |
| 5254 | ||
| 5255 | 3580 | /// The explicit transaction has been forcibly canceled. |
| 5256 | 3581 | FWP_TXN_ABORTED = 0xC022000F, |
| 5257 | ||
| 5258 | 3582 | /// The session has been canceled. |
| 5259 | 3583 | FWP_SESSION_ABORTED = 0xC0220010, |
| 5260 | ||
| 5261 | 3584 | /// The call is not allowed from within a read-only transaction. |
| 5262 | 3585 | FWP_INCOMPATIBLE_TXN = 0xC0220011, |
| 5263 | ||
| 5264 | 3586 | /// The call timed out while waiting to acquire the transaction lock. |
| 5265 | 3587 | FWP_TIMEOUT = 0xC0220012, |
| 5266 | ||
| 5267 | 3588 | /// The collection of network diagnostic events is disabled. |
| 5268 | 3589 | FWP_NET_EVENTS_DISABLED = 0xC0220013, |
| 5269 | ||
| 5270 | 3590 | /// The operation is not supported by the specified layer. |
| 5271 | 3591 | FWP_INCOMPATIBLE_LAYER = 0xC0220014, |
| 5272 | ||
| 5273 | 3592 | /// The call is allowed for kernel-mode callers only. |
| 5274 | 3593 | FWP_KM_CLIENTS_ONLY = 0xC0220015, |
| 5275 | ||
| 5276 | 3594 | /// The call tried to associate two objects with incompatible lifetimes. |
| 5277 | 3595 | FWP_LIFETIME_MISMATCH = 0xC0220016, |
| 5278 | ||
| 5279 | 3596 | /// The object is built-in and cannot be deleted. |
| 5280 | 3597 | FWP_BUILTIN_OBJECT = 0xC0220017, |
| 5281 | ||
| 5282 | /// The maximum number of boot-time filters has been reached. | |
| 5283 | FWP_TOO_MANY_BOOTTIME_FILTERS = 0xC0220018, | |
| 5284 | ||
| 5285 | 3598 | /// The maximum number of callouts has been reached. |
| 5286 | 3599 | FWP_TOO_MANY_CALLOUTS = 0xC0220018, |
| 5287 | ||
| 5288 | 3600 | /// A notification could not be delivered because a message queue has reached maximum capacity. |
| 5289 | 3601 | FWP_NOTIFICATION_DROPPED = 0xC0220019, |
| 5290 | ||
| 5291 | 3602 | /// The traffic parameters do not match those for the security association context. |
| 5292 | 3603 | FWP_TRAFFIC_MISMATCH = 0xC022001A, |
| 5293 | ||
| 5294 | 3604 | /// The call is not allowed for the current security association state. |
| 5295 | 3605 | FWP_INCOMPATIBLE_SA_STATE = 0xC022001B, |
| 5296 | ||
| 5297 | 3606 | /// A required pointer is null. |
| 5298 | 3607 | FWP_NULL_POINTER = 0xC022001C, |
| 5299 | ||
| 5300 | 3608 | /// An enumerator is not valid. |
| 5301 | 3609 | FWP_INVALID_ENUMERATOR = 0xC022001D, |
| 5302 | ||
| 5303 | 3610 | /// The flags field contains an invalid value. |
| 5304 | 3611 | FWP_INVALID_FLAGS = 0xC022001E, |
| 5305 | ||
| 5306 | 3612 | /// A network mask is not valid. |
| 5307 | 3613 | FWP_INVALID_NET_MASK = 0xC022001F, |
| 5308 | ||
| 5309 | 3614 | /// An FWP_RANGE is not valid. |
| 5310 | 3615 | FWP_INVALID_RANGE = 0xC0220020, |
| 5311 | ||
| 5312 | 3616 | /// The time interval is not valid. |
| 5313 | 3617 | FWP_INVALID_INTERVAL = 0xC0220021, |
| 5314 | ||
| 5315 | 3618 | /// An array that must contain at least one element has a zero length. |
| 5316 | 3619 | FWP_ZERO_LENGTH_ARRAY = 0xC0220022, |
| 5317 | ||
| 5318 | 3620 | /// The displayData.name field cannot be null. |
| 5319 | 3621 | FWP_NULL_DISPLAY_NAME = 0xC0220023, |
| 5320 | ||
| 5321 | 3622 | /// The action type is not one of the allowed action types for a filter. |
| 5322 | 3623 | FWP_INVALID_ACTION_TYPE = 0xC0220024, |
| 5323 | ||
| 5324 | 3624 | /// The filter weight is not valid. |
| 5325 | 3625 | FWP_INVALID_WEIGHT = 0xC0220025, |
| 5326 | ||
| 5327 | 3626 | /// A filter condition contains a match type that is not compatible with the operands. |
| 5328 | 3627 | FWP_MATCH_TYPE_MISMATCH = 0xC0220026, |
| 5329 | ||
| 5330 | 3628 | /// An FWP_VALUE or FWPM_CONDITION_VALUE is of the wrong type. |
| 5331 | 3629 | FWP_TYPE_MISMATCH = 0xC0220027, |
| 5332 | ||
| 5333 | 3630 | /// An integer value is outside the allowed range. |
| 5334 | 3631 | FWP_OUT_OF_BOUNDS = 0xC0220028, |
| 5335 | ||
| 5336 | 3632 | /// A reserved field is nonzero. |
| 5337 | 3633 | FWP_RESERVED = 0xC0220029, |
| 5338 | ||
| 5339 | 3634 | /// A filter cannot contain multiple conditions operating on a single field. |
| 5340 | 3635 | FWP_DUPLICATE_CONDITION = 0xC022002A, |
| 5341 | ||
| 5342 | 3636 | /// A policy cannot contain the same keying module more than once. |
| 5343 | 3637 | FWP_DUPLICATE_KEYMOD = 0xC022002B, |
| 5344 | ||
| 5345 | 3638 | /// The action type is not compatible with the layer. |
| 5346 | 3639 | FWP_ACTION_INCOMPATIBLE_WITH_LAYER = 0xC022002C, |
| 5347 | ||
| 5348 | 3640 | /// The action type is not compatible with the sublayer. |
| 5349 | 3641 | FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER = 0xC022002D, |
| 5350 | ||
| 5351 | 3642 | /// The raw context or the provider context is not compatible with the layer. |
| 5352 | 3643 | FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER = 0xC022002E, |
| 5353 | ||
| 5354 | 3644 | /// The raw context or the provider context is not compatible with the callout. |
| 5355 | 3645 | FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT = 0xC022002F, |
| 5356 | ||
| 5357 | 3646 | /// The authentication method is not compatible with the policy type. |
| 5358 | 3647 | FWP_INCOMPATIBLE_AUTH_METHOD = 0xC0220030, |
| 5359 | ||
| 5360 | 3648 | /// The Diffie-Hellman group is not compatible with the policy type. |
| 5361 | 3649 | FWP_INCOMPATIBLE_DH_GROUP = 0xC0220031, |
| 5362 | ||
| 5363 | 3650 | /// An IKE policy cannot contain an Extended Mode policy. |
| 5364 | 3651 | FWP_EM_NOT_SUPPORTED = 0xC0220032, |
| 5365 | ||
| 5366 | 3652 | /// The enumeration template or subscription will never match any objects. |
| 5367 | 3653 | FWP_NEVER_MATCH = 0xC0220033, |
| 5368 | ||
| 5369 | 3654 | /// The provider context is of the wrong type. |
| 5370 | 3655 | FWP_PROVIDER_CONTEXT_MISMATCH = 0xC0220034, |
| 5371 | ||
| 5372 | 3656 | /// The parameter is incorrect. |
| 5373 | 3657 | FWP_INVALID_PARAMETER = 0xC0220035, |
| 5374 | ||
| 5375 | 3658 | /// The maximum number of sublayers has been reached. |
| 5376 | 3659 | FWP_TOO_MANY_SUBLAYERS = 0xC0220036, |
| 5377 | ||
| 5378 | 3660 | /// The notification function for a callout returned an error. |
| 5379 | 3661 | FWP_CALLOUT_NOTIFICATION_FAILED = 0xC0220037, |
| 5380 | ||
| 5381 | 3662 | /// The IPsec authentication configuration is not compatible with the authentication type. |
| 5382 | 3663 | FWP_INCOMPATIBLE_AUTH_CONFIG = 0xC0220038, |
| 5383 | ||
| 5384 | 3664 | /// The IPsec cipher configuration is not compatible with the cipher type. |
| 5385 | 3665 | FWP_INCOMPATIBLE_CIPHER_CONFIG = 0xC0220039, |
| 5386 | ||
| 5387 | 3666 | /// A policy cannot contain the same auth method more than once. |
| 5388 | 3667 | FWP_DUPLICATE_AUTH_METHOD = 0xC022003C, |
| 5389 | ||
| 5390 | 3668 | /// The TCP/IP stack is not ready. |
| 5391 | 3669 | FWP_TCPIP_NOT_READY = 0xC0220100, |
| 5392 | ||
| 5393 | 3670 | /// The injection handle is being closed by another thread. |
| 5394 | 3671 | FWP_INJECT_HANDLE_CLOSING = 0xC0220101, |
| 5395 | ||
| 5396 | 3672 | /// The injection handle is stale. |
| 5397 | 3673 | FWP_INJECT_HANDLE_STALE = 0xC0220102, |
| 5398 | ||
| 5399 | 3674 | /// The classify cannot be pended. |
| 5400 | 3675 | FWP_CANNOT_PEND = 0xC0220103, |
| 5401 | ||
| 5402 | 3676 | /// The binding to the network interface is being closed. |
| 5403 | 3677 | NDIS_CLOSING = 0xC0230002, |
| 5404 | ||
| 5405 | 3678 | /// An invalid version was specified. |
| 5406 | 3679 | NDIS_BAD_VERSION = 0xC0230004, |
| 5407 | ||
| 5408 | 3680 | /// An invalid characteristics table was used. |
| 5409 | 3681 | NDIS_BAD_CHARACTERISTICS = 0xC0230005, |
| 5410 | ||
| 5411 | 3682 | /// Failed to find the network interface or the network interface is not ready. |
| 5412 | 3683 | NDIS_ADAPTER_NOT_FOUND = 0xC0230006, |
| 5413 | ||
| 5414 | 3684 | /// Failed to open the network interface. |
| 5415 | 3685 | NDIS_OPEN_FAILED = 0xC0230007, |
| 5416 | ||
| 5417 | 3686 | /// The network interface has encountered an internal unrecoverable failure. |
| 5418 | 3687 | NDIS_DEVICE_FAILED = 0xC0230008, |
| 5419 | ||
| 5420 | 3688 | /// The multicast list on the network interface is full. |
| 5421 | 3689 | NDIS_MULTICAST_FULL = 0xC0230009, |
| 5422 | ||
| 5423 | 3690 | /// An attempt was made to add a duplicate multicast address to the list. |
| 5424 | 3691 | NDIS_MULTICAST_EXISTS = 0xC023000A, |
| 5425 | ||
| 5426 | 3692 | /// At attempt was made to remove a multicast address that was never added. |
| 5427 | 3693 | NDIS_MULTICAST_NOT_FOUND = 0xC023000B, |
| 5428 | ||
| 5429 | 3694 | /// The network interface aborted the request. |
| 5430 | 3695 | NDIS_REQUEST_ABORTED = 0xC023000C, |
| 5431 | ||
| 5432 | 3696 | /// The network interface cannot process the request because it is being reset. |
| 5433 | 3697 | NDIS_RESET_IN_PROGRESS = 0xC023000D, |
| 5434 | ||
| 5435 | 3698 | /// An attempt was made to send an invalid packet on a network interface. |
| 5436 | 3699 | NDIS_INVALID_PACKET = 0xC023000F, |
| 5437 | ||
| 5438 | 3700 | /// The specified request is not a valid operation for the target device. |
| 5439 | 3701 | NDIS_INVALID_DEVICE_REQUEST = 0xC0230010, |
| 5440 | ||
| 5441 | 3702 | /// The network interface is not ready to complete this operation. |
| 5442 | 3703 | NDIS_ADAPTER_NOT_READY = 0xC0230011, |
| 5443 | ||
| 5444 | 3704 | /// The length of the buffer submitted for this operation is not valid. |
| 5445 | 3705 | NDIS_INVALID_LENGTH = 0xC0230014, |
| 5446 | ||
| 5447 | 3706 | /// The data used for this operation is not valid. |
| 5448 | 3707 | NDIS_INVALID_DATA = 0xC0230015, |
| 5449 | ||
| 5450 | 3708 | /// The length of the submitted buffer for this operation is too small. |
| 5451 | 3709 | NDIS_BUFFER_TOO_SHORT = 0xC0230016, |
| 5452 | ||
| 5453 | 3710 | /// The network interface does not support this object identifier. |
| 5454 | 3711 | NDIS_INVALID_OID = 0xC0230017, |
| 5455 | ||
| 5456 | 3712 | /// The network interface has been removed. |
| 5457 | 3713 | NDIS_ADAPTER_REMOVED = 0xC0230018, |
| 5458 | ||
| 5459 | 3714 | /// The network interface does not support this media type. |
| 5460 | 3715 | NDIS_UNSUPPORTED_MEDIA = 0xC0230019, |
| 5461 | ||
| 5462 | 3716 | /// An attempt was made to remove a token ring group address that is in use by other components. |
| 5463 | 3717 | NDIS_GROUP_ADDRESS_IN_USE = 0xC023001A, |
| 5464 | ||
| 5465 | 3718 | /// An attempt was made to map a file that cannot be found. |
| 5466 | 3719 | NDIS_FILE_NOT_FOUND = 0xC023001B, |
| 5467 | ||
| 5468 | 3720 | /// An error occurred while NDIS tried to map the file. |
| 5469 | 3721 | NDIS_ERROR_READING_FILE = 0xC023001C, |
| 5470 | ||
| 5471 | 3722 | /// An attempt was made to map a file that is already mapped. |
| 5472 | 3723 | NDIS_ALREADY_MAPPED = 0xC023001D, |
| 5473 | ||
| 5474 | 3724 | /// An attempt to allocate a hardware resource failed because the resource is used by another component. |
| 5475 | 3725 | NDIS_RESOURCE_CONFLICT = 0xC023001E, |
| 5476 | ||
| 5477 | 3726 | /// The I/O operation failed because the network media is disconnected or the wireless access point is out of range. |
| 5478 | 3727 | NDIS_MEDIA_DISCONNECTED = 0xC023001F, |
| 5479 | ||
| 5480 | 3728 | /// The network address used in the request is invalid. |
| 5481 | 3729 | NDIS_INVALID_ADDRESS = 0xC0230022, |
| 5482 | ||
| 5483 | 3730 | /// The offload operation on the network interface has been paused. |
| 5484 | 3731 | NDIS_PAUSED = 0xC023002A, |
| 5485 | ||
| 5486 | 3732 | /// The network interface was not found. |
| 5487 | 3733 | NDIS_INTERFACE_NOT_FOUND = 0xC023002B, |
| 5488 | ||
| 5489 | 3734 | /// The revision number specified in the structure is not supported. |
| 5490 | 3735 | NDIS_UNSUPPORTED_REVISION = 0xC023002C, |
| 5491 | ||
| 5492 | 3736 | /// The specified port does not exist on this network interface. |
| 5493 | 3737 | NDIS_INVALID_PORT = 0xC023002D, |
| 5494 | ||
| 5495 | 3738 | /// The current state of the specified port on this network interface does not support the requested operation. |
| 5496 | 3739 | NDIS_INVALID_PORT_STATE = 0xC023002E, |
| 5497 | ||
| 5498 | 3740 | /// The miniport adapter is in a lower power state. |
| 5499 | 3741 | NDIS_LOW_POWER_STATE = 0xC023002F, |
| 5500 | ||
| 5501 | 3742 | /// The network interface does not support this request. |
| 5502 | 3743 | NDIS_NOT_SUPPORTED = 0xC02300BB, |
| 5503 | ||
| 5504 | 3744 | /// The TCP connection is not offloadable because of a local policy setting. |
| 5505 | 3745 | NDIS_OFFLOAD_POLICY = 0xC023100F, |
| 5506 | ||
| 5507 | 3746 | /// The TCP connection is not offloadable by the Chimney offload target. |
| 5508 | 3747 | NDIS_OFFLOAD_CONNECTION_REJECTED = 0xC0231012, |
| 5509 | ||
| 5510 | 3748 | /// The IP Path object is not in an offloadable state. |
| 5511 | 3749 | NDIS_OFFLOAD_PATH_REJECTED = 0xC0231013, |
| 5512 | ||
| 5513 | 3750 | /// The wireless LAN interface is in auto-configuration mode and does not support the requested parameter change operation. |
| 5514 | 3751 | NDIS_DOT11_AUTO_CONFIG_ENABLED = 0xC0232000, |
| 5515 | ||
| 5516 | 3752 | /// The wireless LAN interface is busy and cannot perform the requested operation. |
| 5517 | 3753 | NDIS_DOT11_MEDIA_IN_USE = 0xC0232001, |
| 5518 | ||
| 5519 | 3754 | /// The wireless LAN interface is power down and does not support the requested operation. |
| 5520 | 3755 | NDIS_DOT11_POWER_STATE_INVALID = 0xC0232002, |
| 5521 | ||
| 5522 | 3756 | /// The list of wake on LAN patterns is full. |
| 5523 | 3757 | NDIS_PM_WOL_PATTERN_LIST_FULL = 0xC0232003, |
| 5524 | ||
| 5525 | 3758 | /// The list of low power protocol offloads is full. |
| 5526 | 3759 | NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL = 0xC0232004, |
| 5527 | ||
| 5528 | 3760 | /// The SPI in the packet does not match a valid IPsec SA. |
| 5529 | 3761 | IPSEC_BAD_SPI = 0xC0360001, |
| 5530 | ||
| 5531 | 3762 | /// The packet was received on an IPsec SA whose lifetime has expired. |
| 5532 | 3763 | IPSEC_SA_LIFETIME_EXPIRED = 0xC0360002, |
| 5533 | ||
| 5534 | 3764 | /// The packet was received on an IPsec SA that does not match the packet characteristics. |
| 5535 | 3765 | IPSEC_WRONG_SA = 0xC0360003, |
| 5536 | ||
| 5537 | 3766 | /// The packet sequence number replay check failed. |
| 5538 | 3767 | IPSEC_REPLAY_CHECK_FAILED = 0xC0360004, |
| 5539 | ||
| 5540 | 3768 | /// The IPsec header and/or trailer in the packet is invalid. |
| 5541 | 3769 | IPSEC_INVALID_PACKET = 0xC0360005, |
| 5542 | ||
| 5543 | 3770 | /// The IPsec integrity check failed. |
| 5544 | 3771 | IPSEC_INTEGRITY_CHECK_FAILED = 0xC0360006, |
| 5545 | ||
| 5546 | 3772 | /// IPsec dropped a clear text packet. |
| 5547 | 3773 | IPSEC_CLEAR_TEXT_DROP = 0xC0360007, |
| 5548 | ||
| 5549 | 3774 | /// IPsec dropped an incoming ESP packet in authenticated firewall mode. This drop is benign. |
| 5550 | 3775 | IPSEC_AUTH_FIREWALL_DROP = 0xC0360008, |
| 5551 | ||
| 5552 | 3776 | /// IPsec dropped a packet due to DOS throttle. |
| 5553 | 3777 | IPSEC_THROTTLE_DROP = 0xC0360009, |
| 5554 | ||
| 5555 | 3778 | /// IPsec Dos Protection matched an explicit block rule. |
| 5556 | 3779 | IPSEC_DOSP_BLOCK = 0xC0368000, |
| 5557 | ||
| 5558 | 3780 | /// IPsec Dos Protection received an IPsec specific multicast packet which is not allowed. |
| 5559 | 3781 | IPSEC_DOSP_RECEIVED_MULTICAST = 0xC0368001, |
| 5560 | ||
| 5561 | 3782 | /// IPsec Dos Protection received an incorrectly formatted packet. |
| 5562 | 3783 | IPSEC_DOSP_INVALID_PACKET = 0xC0368002, |
| 5563 | ||
| 5564 | 3784 | /// IPsec Dos Protection failed to lookup state. |
| 5565 | 3785 | IPSEC_DOSP_STATE_LOOKUP_FAILED = 0xC0368003, |
| 5566 | ||
| 5567 | 3786 | /// IPsec Dos Protection failed to create state because there are already maximum number of entries allowed by policy. |
| 5568 | 3787 | IPSEC_DOSP_MAX_ENTRIES = 0xC0368004, |
| 5569 | ||
| 5570 | 3788 | /// IPsec Dos Protection received an IPsec negotiation packet for a keying module which is not allowed by policy. |
| 5571 | 3789 | IPSEC_DOSP_KEYMOD_NOT_ALLOWED = 0xC0368005, |
| 5572 | ||
| 5573 | 3790 | /// IPsec Dos Protection failed to create per internal IP ratelimit queue because there is already maximum number of queues allowed by policy. |
| 5574 | 3791 | IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES = 0xC0368006, |
| 5575 | ||
| 5576 | 3792 | /// The system does not support mirrored volumes. |
| 5577 | 3793 | VOLMGR_MIRROR_NOT_SUPPORTED = 0xC038005B, |
| 5578 | ||
| 5579 | 3794 | /// The system does not support RAID-5 volumes. |
| 5580 | 3795 | VOLMGR_RAID5_NOT_SUPPORTED = 0xC038005C, |
| 5581 | ||
| 5582 | 3796 | /// A virtual disk support provider for the specified file was not found. |
| 5583 | 3797 | VIRTDISK_PROVIDER_NOT_FOUND = 0xC03A0014, |
| 5584 | ||
| 5585 | 3798 | /// The specified disk is not a virtual disk. |
| 5586 | 3799 | VIRTDISK_NOT_VIRTUAL_DISK = 0xC03A0015, |
| 5587 | ||
| 5588 | 3800 | /// The chain of virtual hard disks is inaccessible. |
| 5589 | 3801 | /// The process has not been granted access rights to the parent virtual hard disk for the differencing disk. |
| 5590 | 3802 | VHD_PARENT_VHD_ACCESS_DENIED = 0xC03A0016, |
| 5591 | ||
| 5592 | 3803 | /// The chain of virtual hard disks is corrupted. |
| 5593 | 3804 | /// There is a mismatch in the virtual sizes of the parent virtual hard disk and differencing disk. |
| 5594 | 3805 | VHD_CHILD_PARENT_SIZE_MISMATCH = 0xC03A0017, |
| 5595 | ||
| 5596 | 3806 | /// The chain of virtual hard disks is corrupted. |
| 5597 | 3807 | /// A differencing disk is indicated in its own parent chain. |
| 5598 | 3808 | VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED = 0xC03A0018, |
| 5599 | ||
| 5600 | 3809 | /// The chain of virtual hard disks is inaccessible. |
| 5601 | 3810 | /// There was an error opening a virtual hard disk further up the chain. |
| 5602 | 3811 | VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT = 0xC03A0019, |
| 5603 | ||
| 5604 | 3812 | _, |
| 5605 | 3813 | }; |
lib/std/packed_int_array.zig+23-21| ... | ... | @@ -4,11 +4,13 @@ |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | 6 | const std = @import("std"); |
| 7 | const builtin = std.builtin; | |
| 7 | const builtin = @import("builtin"); | |
| 8 | 8 | const debug = std.debug; |
| 9 | 9 | const testing = std.testing; |
| 10 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 11 | const Endian = std.builtin.Endian; | |
| 10 | 12 | |
| 11 | pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { | |
| 13 | pub fn PackedIntIo(comptime Int: type, comptime endian: Endian) type { | |
| 12 | 14 | //The general technique employed here is to cast bytes in the array to a container |
| 13 | 15 | // integer (having bits % 8 == 0) large enough to contain the number of bits we want, |
| 14 | 16 | // then we can retrieve or store the new value with a relative minimum of masking |
| ... | ... | @@ -71,7 +73,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 71 | 73 | const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]); |
| 72 | 74 | var value = value_ptr.*; |
| 73 | 75 | |
| 74 | if (endian != builtin.endian) value = @byteSwap(Container, value); | |
| 76 | if (endian != native_endian) value = @byteSwap(Container, value); | |
| 75 | 77 | |
| 76 | 78 | switch (endian) { |
| 77 | 79 | .Big => { |
| ... | ... | @@ -119,7 +121,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 119 | 121 | const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]); |
| 120 | 122 | var target = target_ptr.*; |
| 121 | 123 | |
| 122 | if (endian != builtin.endian) target = @byteSwap(Container, target); | |
| 124 | if (endian != native_endian) target = @byteSwap(Container, target); | |
| 123 | 125 | |
| 124 | 126 | //zero the bits we want to replace in the existing bytes |
| 125 | 127 | const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift; |
| ... | ... | @@ -129,7 +131,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 129 | 131 | //merge the new value |
| 130 | 132 | target |= value; |
| 131 | 133 | |
| 132 | if (endian != builtin.endian) target = @byteSwap(Container, target); | |
| 134 | if (endian != native_endian) target = @byteSwap(Container, target); | |
| 133 | 135 | |
| 134 | 136 | //save it back |
| 135 | 137 | target_ptr.* = target; |
| ... | ... | @@ -151,7 +153,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 151 | 153 | return new_slice; |
| 152 | 154 | } |
| 153 | 155 | |
| 154 | fn sliceCast(bytes: []u8, comptime NewInt: type, comptime new_endian: builtin.Endian, bit_offset: u3, old_len: usize) PackedIntSliceEndian(NewInt, new_endian) { | |
| 156 | fn sliceCast(bytes: []u8, comptime NewInt: type, comptime new_endian: Endian, bit_offset: u3, old_len: usize) PackedIntSliceEndian(NewInt, new_endian) { | |
| 155 | 157 | const new_int_bits = comptime std.meta.bitCount(NewInt); |
| 156 | 158 | const New = PackedIntSliceEndian(NewInt, new_endian); |
| 157 | 159 | |
| ... | ... | @@ -172,13 +174,13 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 172 | 174 | /// are packed using native endianess and without storing any meta |
| 173 | 175 | /// data. PackedIntArray(i3, 8) will occupy exactly 3 bytes of memory. |
| 174 | 176 | pub fn PackedIntArray(comptime Int: type, comptime int_count: usize) type { |
| 175 | return PackedIntArrayEndian(Int, builtin.endian, int_count); | |
| 177 | return PackedIntArrayEndian(Int, native_endian, int_count); | |
| 176 | 178 | } |
| 177 | 179 | |
| 178 | 180 | ///Creates a bit-packed array of integers of type Int. Bits |
| 179 | 181 | /// are packed using specified endianess and without storing any meta |
| 180 | 182 | /// data. |
| 181 | pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, comptime int_count: usize) type { | |
| 183 | pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: Endian, comptime int_count: usize) type { | |
| 182 | 184 | const int_bits = comptime std.meta.bitCount(Int); |
| 183 | 185 | const total_bits = int_bits * int_count; |
| 184 | 186 | const total_bytes = (total_bits + 7) / 8; |
| ... | ... | @@ -247,7 +249,7 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, |
| 247 | 249 | ///Create a PackedIntSlice of the array using NewInt as the bit width integer |
| 248 | 250 | /// and new_endian as the new endianess. NewInt's bit width must fit evenly within |
| 249 | 251 | /// the array's Int's total bits. |
| 250 | pub fn sliceCastEndian(self: *Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) { | |
| 252 | pub fn sliceCastEndian(self: *Self, comptime NewInt: type, comptime new_endian: Endian) PackedIntSliceEndian(NewInt, new_endian) { | |
| 251 | 253 | return Io.sliceCast(&self.bytes, NewInt, new_endian, 0, int_count); |
| 252 | 254 | } |
| 253 | 255 | }; |
| ... | ... | @@ -257,13 +259,13 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian, |
| 257 | 259 | /// Bits are packed using native endianess and without storing any meta |
| 258 | 260 | /// data. |
| 259 | 261 | pub fn PackedIntSlice(comptime Int: type) type { |
| 260 | return PackedIntSliceEndian(Int, builtin.endian); | |
| 262 | return PackedIntSliceEndian(Int, native_endian); | |
| 261 | 263 | } |
| 262 | 264 | |
| 263 | 265 | ///Uses a slice as a bit-packed block of int_count integers of type Int. |
| 264 | 266 | /// Bits are packed using specified endianess and without storing any meta |
| 265 | 267 | /// data. |
| 266 | pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: builtin.Endian) type { | |
| 268 | pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: Endian) type { | |
| 267 | 269 | const int_bits = comptime std.meta.bitCount(Int); |
| 268 | 270 | const Io = PackedIntIo(Int, endian); |
| 269 | 271 | |
| ... | ... | @@ -328,7 +330,7 @@ pub fn PackedIntSliceEndian(comptime Int: type, comptime endian: builtin.Endian) |
| 328 | 330 | ///Create a PackedIntSlice of this slice using NewInt as the bit width integer |
| 329 | 331 | /// and new_endian as the new endianess. NewInt's bit width must fit evenly within |
| 330 | 332 | /// this slice's Int's total bits. |
| 331 | pub fn sliceCastEndian(self: Self, comptime NewInt: type, comptime new_endian: builtin.Endian) PackedIntSliceEndian(NewInt, new_endian) { | |
| 333 | pub fn sliceCastEndian(self: Self, comptime NewInt: type, comptime new_endian: Endian) PackedIntSliceEndian(NewInt, new_endian) { | |
| 332 | 334 | return Io.sliceCast(self.bytes, NewInt, new_endian, self.bit_offset, self.int_count); |
| 333 | 335 | } |
| 334 | 336 | }; |
| ... | ... | @@ -338,7 +340,7 @@ const we_are_testing_this_with_stage1_which_leaks_comptime_memory = true; |
| 338 | 340 | |
| 339 | 341 | test "PackedIntArray" { |
| 340 | 342 | // TODO @setEvalBranchQuota generates panics in wasm32. Investigate. |
| 341 | if (builtin.arch == .wasm32) return error.SkipZigTest; | |
| 343 | if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest; | |
| 342 | 344 | if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; |
| 343 | 345 | |
| 344 | 346 | @setEvalBranchQuota(10000); |
| ... | ... | @@ -348,7 +350,7 @@ test "PackedIntArray" { |
| 348 | 350 | comptime var bits = 0; |
| 349 | 351 | inline while (bits <= max_bits) : (bits += 1) { |
| 350 | 352 | //alternate unsigned and signed |
| 351 | const sign: builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; | |
| 353 | const sign: std.builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; | |
| 352 | 354 | const I = std.meta.Int(sign, bits); |
| 353 | 355 | |
| 354 | 356 | const PackedArray = PackedIntArray(I, int_count); |
| ... | ... | @@ -394,7 +396,7 @@ test "PackedIntArray initAllTo" { |
| 394 | 396 | |
| 395 | 397 | test "PackedIntSlice" { |
| 396 | 398 | // TODO @setEvalBranchQuota generates panics in wasm32. Investigate. |
| 397 | if (builtin.arch == .wasm32) return error.SkipZigTest; | |
| 399 | if (builtin.target.cpu.arch == .wasm32) return error.SkipZigTest; | |
| 398 | 400 | if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; |
| 399 | 401 | |
| 400 | 402 | @setEvalBranchQuota(10000); |
| ... | ... | @@ -408,7 +410,7 @@ test "PackedIntSlice" { |
| 408 | 410 | comptime var bits = 0; |
| 409 | 411 | inline while (bits <= max_bits) : (bits += 1) { |
| 410 | 412 | //alternate unsigned and signed |
| 411 | const sign: builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; | |
| 413 | const sign: std.builtin.Signedness = if (bits % 2 == 0) .signed else .unsigned; | |
| 412 | 414 | const I = std.meta.Int(sign, bits); |
| 413 | 415 | const P = PackedIntSlice(I); |
| 414 | 416 | |
| ... | ... | @@ -539,7 +541,7 @@ test "PackedInt(Array/Slice) sliceCast" { |
| 539 | 541 | |
| 540 | 542 | var i = @as(usize, 0); |
| 541 | 543 | while (i < packed_slice_cast_2.len()) : (i += 1) { |
| 542 | const val = switch (builtin.endian) { | |
| 544 | const val = switch (native_endian) { | |
| 543 | 545 | .Big => 0b01, |
| 544 | 546 | .Little => 0b10, |
| 545 | 547 | }; |
| ... | ... | @@ -547,7 +549,7 @@ test "PackedInt(Array/Slice) sliceCast" { |
| 547 | 549 | } |
| 548 | 550 | i = 0; |
| 549 | 551 | while (i < packed_slice_cast_4.len()) : (i += 1) { |
| 550 | const val = switch (builtin.endian) { | |
| 552 | const val = switch (native_endian) { | |
| 551 | 553 | .Big => 0b0101, |
| 552 | 554 | .Little => 0b1010, |
| 553 | 555 | }; |
| ... | ... | @@ -561,7 +563,7 @@ test "PackedInt(Array/Slice) sliceCast" { |
| 561 | 563 | } |
| 562 | 564 | i = 0; |
| 563 | 565 | while (i < packed_slice_cast_3.len()) : (i += 1) { |
| 564 | const val = switch (builtin.endian) { | |
| 566 | const val = switch (native_endian) { | |
| 565 | 567 | .Big => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000), |
| 566 | 568 | .Little => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000), |
| 567 | 569 | }; |
| ... | ... | @@ -641,7 +643,7 @@ test "PackedInt(Array/Slice)Endian" { |
| 641 | 643 | test "PackedIntArray at end of available memory" { |
| 642 | 644 | if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; |
| 643 | 645 | |
| 644 | switch (builtin.os.tag) { | |
| 646 | switch (builtin.target.os.tag) { | |
| 645 | 647 | .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {}, |
| 646 | 648 | else => return, |
| 647 | 649 | } |
| ... | ... | @@ -662,7 +664,7 @@ test "PackedIntArray at end of available memory" { |
| 662 | 664 | test "PackedIntSlice at end of available memory" { |
| 663 | 665 | if (we_are_testing_this_with_stage1_which_leaks_comptime_memory) return error.SkipZigTest; |
| 664 | 666 | |
| 665 | switch (builtin.os.tag) { | |
| 667 | switch (builtin.target.os.tag) { | |
| 666 | 668 | .linux, .macos, .ios, .freebsd, .netbsd, .openbsd, .windows => {}, |
| 667 | 669 | else => return, |
| 668 | 670 | } |
lib/std/start_windows_tls.zig+2-2| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // The MIT license requires this copyright notice to be included in all copies |
| 5 | 5 | // and substantial portions of the software. |
| 6 | 6 | const std = @import("std"); |
| 7 | const builtin = std.builtin; | |
| 7 | const builtin = @import("builtin"); | |
| 8 | 8 | |
| 9 | 9 | export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES; |
| 10 | 10 | export var _tls_start: u8 linksection(".tls") = 0; |
| ... | ... | @@ -13,7 +13,7 @@ export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = |
| 13 | 13 | export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null; |
| 14 | 14 | |
| 15 | 15 | comptime { |
| 16 | if (builtin.arch == .i386) { | |
| 16 | if (builtin.target.cpu.arch == .i386) { | |
| 17 | 17 | // The __tls_array is the offset of the ThreadLocalStoragePointer field |
| 18 | 18 | // in the TEB block whose base address held in the %fs segment. |
| 19 | 19 | asm ( |
test/behavior.zig created+153| ... | ... | @@ -0,0 +1,153 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | comptime { | |
| 4 | // Tests that pass for both. | |
| 5 | {} | |
| 6 | ||
| 7 | if (builtin.zig_is_stage2) { | |
| 8 | // Tests that only pass for stage2. | |
| 9 | } else { | |
| 10 | // Tests that only pass for stage1. | |
| 11 | _ = @import("behavior/align.zig"); | |
| 12 | _ = @import("behavior/alignof.zig"); | |
| 13 | _ = @import("behavior/array.zig"); | |
| 14 | if (builtin.os.tag != .wasi) { | |
| 15 | _ = @import("behavior/asm.zig"); | |
| 16 | _ = @import("behavior/async_fn.zig"); | |
| 17 | } | |
| 18 | _ = @import("behavior/atomics.zig"); | |
| 19 | _ = @import("behavior/await_struct.zig"); | |
| 20 | _ = @import("behavior/bit_shifting.zig"); | |
| 21 | _ = @import("behavior/bitcast.zig"); | |
| 22 | _ = @import("behavior/bitreverse.zig"); | |
| 23 | _ = @import("behavior/bool.zig"); | |
| 24 | _ = @import("behavior/bugs/1025.zig"); | |
| 25 | _ = @import("behavior/bugs/1076.zig"); | |
| 26 | _ = @import("behavior/bugs/1111.zig"); | |
| 27 | _ = @import("behavior/bugs/1120.zig"); | |
| 28 | _ = @import("behavior/bugs/1277.zig"); | |
| 29 | _ = @import("behavior/bugs/1310.zig"); | |
| 30 | _ = @import("behavior/bugs/1322.zig"); | |
| 31 | _ = @import("behavior/bugs/1381.zig"); | |
| 32 | _ = @import("behavior/bugs/1421.zig"); | |
| 33 | _ = @import("behavior/bugs/1442.zig"); | |
| 34 | _ = @import("behavior/bugs/1486.zig"); | |
| 35 | _ = @import("behavior/bugs/1500.zig"); | |
| 36 | _ = @import("behavior/bugs/1607.zig"); | |
| 37 | _ = @import("behavior/bugs/1735.zig"); | |
| 38 | _ = @import("behavior/bugs/1741.zig"); | |
| 39 | _ = @import("behavior/bugs/1851.zig"); | |
| 40 | _ = @import("behavior/bugs/1914.zig"); | |
| 41 | _ = @import("behavior/bugs/2006.zig"); | |
| 42 | _ = @import("behavior/bugs/2114.zig"); | |
| 43 | _ = @import("behavior/bugs/2346.zig"); | |
| 44 | _ = @import("behavior/bugs/2578.zig"); | |
| 45 | _ = @import("behavior/bugs/2692.zig"); | |
| 46 | _ = @import("behavior/bugs/2889.zig"); | |
| 47 | _ = @import("behavior/bugs/3007.zig"); | |
| 48 | _ = @import("behavior/bugs/3046.zig"); | |
| 49 | _ = @import("behavior/bugs/3112.zig"); | |
| 50 | _ = @import("behavior/bugs/3367.zig"); | |
| 51 | _ = @import("behavior/bugs/3384.zig"); | |
| 52 | _ = @import("behavior/bugs/3586.zig"); | |
| 53 | _ = @import("behavior/bugs/3742.zig"); | |
| 54 | _ = @import("behavior/bugs/4328.zig"); | |
| 55 | _ = @import("behavior/bugs/4560.zig"); | |
| 56 | _ = @import("behavior/bugs/4769_a.zig"); | |
| 57 | _ = @import("behavior/bugs/4769_b.zig"); | |
| 58 | _ = @import("behavior/bugs/4769_c.zig"); | |
| 59 | _ = @import("behavior/bugs/4954.zig"); | |
| 60 | _ = @import("behavior/bugs/5398.zig"); | |
| 61 | _ = @import("behavior/bugs/5413.zig"); | |
| 62 | _ = @import("behavior/bugs/5474.zig"); | |
| 63 | _ = @import("behavior/bugs/5487.zig"); | |
| 64 | _ = @import("behavior/bugs/6456.zig"); | |
| 65 | _ = @import("behavior/bugs/6781.zig"); | |
| 66 | _ = @import("behavior/bugs/6850.zig"); | |
| 67 | _ = @import("behavior/bugs/7027.zig"); | |
| 68 | _ = @import("behavior/bugs/7047.zig"); | |
| 69 | _ = @import("behavior/bugs/7003.zig"); | |
| 70 | _ = @import("behavior/bugs/7250.zig"); | |
| 71 | _ = @import("behavior/bugs/394.zig"); | |
| 72 | _ = @import("behavior/bugs/421.zig"); | |
| 73 | _ = @import("behavior/bugs/529.zig"); | |
| 74 | _ = @import("behavior/bugs/624.zig"); | |
| 75 | _ = @import("behavior/bugs/655.zig"); | |
| 76 | _ = @import("behavior/bugs/656.zig"); | |
| 77 | _ = @import("behavior/bugs/679.zig"); | |
| 78 | _ = @import("behavior/bugs/704.zig"); | |
| 79 | _ = @import("behavior/bugs/718.zig"); | |
| 80 | _ = @import("behavior/bugs/726.zig"); | |
| 81 | _ = @import("behavior/bugs/828.zig"); | |
| 82 | _ = @import("behavior/bugs/920.zig"); | |
| 83 | _ = @import("behavior/byteswap.zig"); | |
| 84 | _ = @import("behavior/byval_arg_var.zig"); | |
| 85 | _ = @import("behavior/call.zig"); | |
| 86 | _ = @import("behavior/cast.zig"); | |
| 87 | _ = @import("behavior/const_slice_child.zig"); | |
| 88 | _ = @import("behavior/defer.zig"); | |
| 89 | _ = @import("behavior/enum.zig"); | |
| 90 | _ = @import("behavior/enum_with_members.zig"); | |
| 91 | _ = @import("behavior/error.zig"); | |
| 92 | _ = @import("behavior/eval.zig"); | |
| 93 | _ = @import("behavior/field_parent_ptr.zig"); | |
| 94 | _ = @import("behavior/floatop.zig"); | |
| 95 | _ = @import("behavior/fn.zig"); | |
| 96 | _ = @import("behavior/fn_in_struct_in_comptime.zig"); | |
| 97 | _ = @import("behavior/fn_delegation.zig"); | |
| 98 | _ = @import("behavior/for.zig"); | |
| 99 | _ = @import("behavior/generics.zig"); | |
| 100 | _ = @import("behavior/hasdecl.zig"); | |
| 101 | _ = @import("behavior/hasfield.zig"); | |
| 102 | _ = @import("behavior/if.zig"); | |
| 103 | _ = @import("behavior/import.zig"); | |
| 104 | _ = @import("behavior/incomplete_struct_param_tld.zig"); | |
| 105 | _ = @import("behavior/inttoptr.zig"); | |
| 106 | _ = @import("behavior/ir_block_deps.zig"); | |
| 107 | _ = @import("behavior/math.zig"); | |
| 108 | _ = @import("behavior/merge_error_sets.zig"); | |
| 109 | _ = @import("behavior/misc.zig"); | |
| 110 | _ = @import("behavior/muladd.zig"); | |
| 111 | _ = @import("behavior/namespace_depends_on_compile_var.zig"); | |
| 112 | _ = @import("behavior/null.zig"); | |
| 113 | _ = @import("behavior/optional.zig"); | |
| 114 | _ = @import("behavior/pointers.zig"); | |
| 115 | _ = @import("behavior/popcount.zig"); | |
| 116 | _ = @import("behavior/ptrcast.zig"); | |
| 117 | _ = @import("behavior/pub_enum.zig"); | |
| 118 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); | |
| 119 | _ = @import("behavior/reflection.zig"); | |
| 120 | _ = @import("behavior/shuffle.zig"); | |
| 121 | _ = @import("behavior/sizeof_and_typeof.zig"); | |
| 122 | _ = @import("behavior/slice.zig"); | |
| 123 | _ = @import("behavior/slice_sentinel_comptime.zig"); | |
| 124 | _ = @import("behavior/struct.zig"); | |
| 125 | _ = @import("behavior/struct_contains_null_ptr_itself.zig"); | |
| 126 | _ = @import("behavior/struct_contains_slice_of_itself.zig"); | |
| 127 | _ = @import("behavior/switch.zig"); | |
| 128 | _ = @import("behavior/switch_prong_err_enum.zig"); | |
| 129 | _ = @import("behavior/switch_prong_implicit_cast.zig"); | |
| 130 | _ = @import("behavior/syntax.zig"); | |
| 131 | _ = @import("behavior/this.zig"); | |
| 132 | _ = @import("behavior/truncate.zig"); | |
| 133 | _ = @import("behavior/try.zig"); | |
| 134 | _ = @import("behavior/tuple.zig"); | |
| 135 | _ = @import("behavior/type.zig"); | |
| 136 | _ = @import("behavior/type_info.zig"); | |
| 137 | _ = @import("behavior/typename.zig"); | |
| 138 | _ = @import("behavior/undefined.zig"); | |
| 139 | _ = @import("behavior/underscore.zig"); | |
| 140 | _ = @import("behavior/union.zig"); | |
| 141 | _ = @import("behavior/usingnamespace.zig"); | |
| 142 | _ = @import("behavior/var_args.zig"); | |
| 143 | _ = @import("behavior/vector.zig"); | |
| 144 | _ = @import("behavior/void.zig"); | |
| 145 | if (builtin.target.cpu.arch == .wasm32) { | |
| 146 | _ = @import("behavior/wasm.zig"); | |
| 147 | } | |
| 148 | _ = @import("behavior/while.zig"); | |
| 149 | _ = @import("behavior/widening.zig"); | |
| 150 | _ = @import("behavior/src.zig"); | |
| 151 | _ = @import("behavior/translate_c_macros.zig"); | |
| 152 | } | |
| 153 | } |
test/behavior/align.zig created+347| ... | ... | @@ -0,0 +1,347 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const builtin = @import("builtin"); | |
| 4 | const native_arch = builtin.target.cpu.arch; | |
| 5 | ||
| 6 | var foo: u8 align(4) = 100; | |
| 7 | ||
| 8 | test "global variable alignment" { | |
| 9 | comptime expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); | |
| 10 | comptime expect(@TypeOf(&foo) == *align(4) u8); | |
| 11 | { | |
| 12 | const slice = @as(*[1]u8, &foo)[0..]; | |
| 13 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 14 | } | |
| 15 | { | |
| 16 | var runtime_zero: usize = 0; | |
| 17 | const slice = @as(*[1]u8, &foo)[runtime_zero..]; | |
| 18 | comptime expect(@TypeOf(slice) == []align(4) u8); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn derp() align(@sizeOf(usize) * 2) i32 { | |
| 23 | return 1234; | |
| 24 | } | |
| 25 | fn noop1() align(1) void {} | |
| 26 | fn noop4() align(4) void {} | |
| 27 | ||
| 28 | test "function alignment" { | |
| 29 | // function alignment is a compile error on wasm32/wasm64 | |
| 30 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 31 | ||
| 32 | expect(derp() == 1234); | |
| 33 | expect(@TypeOf(noop1) == fn () align(1) void); | |
| 34 | expect(@TypeOf(noop4) == fn () align(4) void); | |
| 35 | noop1(); | |
| 36 | noop4(); | |
| 37 | } | |
| 38 | ||
| 39 | var baz: packed struct { | |
| 40 | a: u32, | |
| 41 | b: u32, | |
| 42 | } = undefined; | |
| 43 | ||
| 44 | test "packed struct alignment" { | |
| 45 | expect(@TypeOf(&baz.b) == *align(1) u32); | |
| 46 | } | |
| 47 | ||
| 48 | const blah: packed struct { | |
| 49 | a: u3, | |
| 50 | b: u3, | |
| 51 | c: u2, | |
| 52 | } = undefined; | |
| 53 | ||
| 54 | test "bit field alignment" { | |
| 55 | expect(@TypeOf(&blah.b) == *align(1:3:1) const u3); | |
| 56 | } | |
| 57 | ||
| 58 | test "default alignment allows unspecified in type syntax" { | |
| 59 | expect(*u32 == *align(@alignOf(u32)) u32); | |
| 60 | } | |
| 61 | ||
| 62 | test "implicitly decreasing pointer alignment" { | |
| 63 | const a: u32 align(4) = 3; | |
| 64 | const b: u32 align(8) = 4; | |
| 65 | expect(addUnaligned(&a, &b) == 7); | |
| 66 | } | |
| 67 | ||
| 68 | fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { | |
| 69 | return a.* + b.*; | |
| 70 | } | |
| 71 | ||
| 72 | test "implicitly decreasing slice alignment" { | |
| 73 | const a: u32 align(4) = 3; | |
| 74 | const b: u32 align(8) = 4; | |
| 75 | expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7); | |
| 76 | } | |
| 77 | fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { | |
| 78 | return a[0] + b[0]; | |
| 79 | } | |
| 80 | ||
| 81 | test "specifying alignment allows pointer cast" { | |
| 82 | testBytesAlign(0x33); | |
| 83 | } | |
| 84 | fn testBytesAlign(b: u8) void { | |
| 85 | var bytes align(4) = [_]u8{ | |
| 86 | b, | |
| 87 | b, | |
| 88 | b, | |
| 89 | b, | |
| 90 | }; | |
| 91 | const ptr = @ptrCast(*u32, &bytes[0]); | |
| 92 | expect(ptr.* == 0x33333333); | |
| 93 | } | |
| 94 | ||
| 95 | test "@alignCast pointers" { | |
| 96 | var x: u32 align(4) = 1; | |
| 97 | expectsOnly1(&x); | |
| 98 | expect(x == 2); | |
| 99 | } | |
| 100 | fn expectsOnly1(x: *align(1) u32) void { | |
| 101 | expects4(@alignCast(4, x)); | |
| 102 | } | |
| 103 | fn expects4(x: *align(4) u32) void { | |
| 104 | x.* += 1; | |
| 105 | } | |
| 106 | ||
| 107 | test "@alignCast slices" { | |
| 108 | var array align(4) = [_]u32{ | |
| 109 | 1, | |
| 110 | 1, | |
| 111 | }; | |
| 112 | const slice = array[0..]; | |
| 113 | sliceExpectsOnly1(slice); | |
| 114 | expect(slice[0] == 2); | |
| 115 | } | |
| 116 | fn sliceExpectsOnly1(slice: []align(1) u32) void { | |
| 117 | sliceExpects4(@alignCast(4, slice)); | |
| 118 | } | |
| 119 | fn sliceExpects4(slice: []align(4) u32) void { | |
| 120 | slice[0] += 1; | |
| 121 | } | |
| 122 | ||
| 123 | test "implicitly decreasing fn alignment" { | |
| 124 | // function alignment is a compile error on wasm32/wasm64 | |
| 125 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 126 | ||
| 127 | testImplicitlyDecreaseFnAlign(alignedSmall, 1234); | |
| 128 | testImplicitlyDecreaseFnAlign(alignedBig, 5678); | |
| 129 | } | |
| 130 | ||
| 131 | fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void { | |
| 132 | expect(ptr() == answer); | |
| 133 | } | |
| 134 | ||
| 135 | fn alignedSmall() align(8) i32 { | |
| 136 | return 1234; | |
| 137 | } | |
| 138 | fn alignedBig() align(16) i32 { | |
| 139 | return 5678; | |
| 140 | } | |
| 141 | ||
| 142 | test "@alignCast functions" { | |
| 143 | // function alignment is a compile error on wasm32/wasm64 | |
| 144 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 145 | ||
| 146 | expect(fnExpectsOnly1(simple4) == 0x19); | |
| 147 | } | |
| 148 | fn fnExpectsOnly1(ptr: fn () align(1) i32) i32 { | |
| 149 | return fnExpects4(@alignCast(4, ptr)); | |
| 150 | } | |
| 151 | fn fnExpects4(ptr: fn () align(4) i32) i32 { | |
| 152 | return ptr(); | |
| 153 | } | |
| 154 | fn simple4() align(4) i32 { | |
| 155 | return 0x19; | |
| 156 | } | |
| 157 | ||
| 158 | test "generic function with align param" { | |
| 159 | // function alignment is a compile error on wasm32/wasm64 | |
| 160 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 161 | ||
| 162 | expect(whyWouldYouEverDoThis(1) == 0x1); | |
| 163 | expect(whyWouldYouEverDoThis(4) == 0x1); | |
| 164 | expect(whyWouldYouEverDoThis(8) == 0x1); | |
| 165 | } | |
| 166 | ||
| 167 | fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { | |
| 168 | return 0x1; | |
| 169 | } | |
| 170 | ||
| 171 | test "@ptrCast preserves alignment of bigger source" { | |
| 172 | var x: u32 align(16) = 1234; | |
| 173 | const ptr = @ptrCast(*u8, &x); | |
| 174 | expect(@TypeOf(ptr) == *align(16) u8); | |
| 175 | } | |
| 176 | ||
| 177 | test "runtime known array index has best alignment possible" { | |
| 178 | // take full advantage of over-alignment | |
| 179 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; | |
| 180 | expect(@TypeOf(&array[0]) == *align(4) u8); | |
| 181 | expect(@TypeOf(&array[1]) == *u8); | |
| 182 | expect(@TypeOf(&array[2]) == *align(2) u8); | |
| 183 | expect(@TypeOf(&array[3]) == *u8); | |
| 184 | ||
| 185 | // because align is too small but we still figure out to use 2 | |
| 186 | var bigger align(2) = [_]u64{ 1, 2, 3, 4 }; | |
| 187 | expect(@TypeOf(&bigger[0]) == *align(2) u64); | |
| 188 | expect(@TypeOf(&bigger[1]) == *align(2) u64); | |
| 189 | expect(@TypeOf(&bigger[2]) == *align(2) u64); | |
| 190 | expect(@TypeOf(&bigger[3]) == *align(2) u64); | |
| 191 | ||
| 192 | // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2 | |
| 193 | var smaller align(2) = [_]u32{ 1, 2, 3, 4 }; | |
| 194 | var runtime_zero: usize = 0; | |
| 195 | comptime expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32); | |
| 196 | comptime expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32); | |
| 197 | testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32); | |
| 198 | testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32); | |
| 199 | testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32); | |
| 200 | testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32); | |
| 201 | ||
| 202 | // has to use ABI alignment because index known at runtime only | |
| 203 | testIndex2(array[runtime_zero..].ptr, 0, *u8); | |
| 204 | testIndex2(array[runtime_zero..].ptr, 1, *u8); | |
| 205 | testIndex2(array[runtime_zero..].ptr, 2, *u8); | |
| 206 | testIndex2(array[runtime_zero..].ptr, 3, *u8); | |
| 207 | } | |
| 208 | fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void { | |
| 209 | comptime expect(@TypeOf(&smaller[index]) == T); | |
| 210 | } | |
| 211 | fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) void { | |
| 212 | comptime expect(@TypeOf(&ptr[index]) == T); | |
| 213 | } | |
| 214 | ||
| 215 | test "alignstack" { | |
| 216 | expect(fnWithAlignedStack() == 1234); | |
| 217 | } | |
| 218 | ||
| 219 | fn fnWithAlignedStack() i32 { | |
| 220 | @setAlignStack(256); | |
| 221 | return 1234; | |
| 222 | } | |
| 223 | ||
| 224 | test "alignment of structs" { | |
| 225 | expect(@alignOf(struct { | |
| 226 | a: i32, | |
| 227 | b: *i32, | |
| 228 | }) == @alignOf(usize)); | |
| 229 | } | |
| 230 | ||
| 231 | test "alignment of function with c calling convention" { | |
| 232 | var runtime_nothing = nothing; | |
| 233 | const casted1 = @ptrCast(*const u8, runtime_nothing); | |
| 234 | const casted2 = @ptrCast(fn () callconv(.C) void, casted1); | |
| 235 | casted2(); | |
| 236 | } | |
| 237 | ||
| 238 | fn nothing() callconv(.C) void {} | |
| 239 | ||
| 240 | test "return error union with 128-bit integer" { | |
| 241 | expect(3 == try give()); | |
| 242 | } | |
| 243 | fn give() anyerror!u128 { | |
| 244 | return 3; | |
| 245 | } | |
| 246 | ||
| 247 | test "alignment of >= 128-bit integer type" { | |
| 248 | expect(@alignOf(u128) == 16); | |
| 249 | expect(@alignOf(u129) == 16); | |
| 250 | } | |
| 251 | ||
| 252 | test "alignment of struct with 128-bit field" { | |
| 253 | expect(@alignOf(struct { | |
| 254 | x: u128, | |
| 255 | }) == 16); | |
| 256 | ||
| 257 | comptime { | |
| 258 | expect(@alignOf(struct { | |
| 259 | x: u128, | |
| 260 | }) == 16); | |
| 261 | } | |
| 262 | } | |
| 263 | ||
| 264 | test "size of extern struct with 128-bit field" { | |
| 265 | expect(@sizeOf(extern struct { | |
| 266 | x: u128, | |
| 267 | y: u8, | |
| 268 | }) == 32); | |
| 269 | ||
| 270 | comptime { | |
| 271 | expect(@sizeOf(extern struct { | |
| 272 | x: u128, | |
| 273 | y: u8, | |
| 274 | }) == 32); | |
| 275 | } | |
| 276 | } | |
| 277 | ||
| 278 | const DefaultAligned = struct { | |
| 279 | nevermind: u32, | |
| 280 | badguy: i128, | |
| 281 | }; | |
| 282 | ||
| 283 | test "read 128-bit field from default aligned struct in stack memory" { | |
| 284 | var default_aligned = DefaultAligned{ | |
| 285 | .nevermind = 1, | |
| 286 | .badguy = 12, | |
| 287 | }; | |
| 288 | expect((@ptrToInt(&default_aligned.badguy) % 16) == 0); | |
| 289 | expect(12 == default_aligned.badguy); | |
| 290 | } | |
| 291 | ||
| 292 | var default_aligned_global = DefaultAligned{ | |
| 293 | .nevermind = 1, | |
| 294 | .badguy = 12, | |
| 295 | }; | |
| 296 | ||
| 297 | test "read 128-bit field from default aligned struct in global memory" { | |
| 298 | expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0); | |
| 299 | expect(12 == default_aligned_global.badguy); | |
| 300 | } | |
| 301 | ||
| 302 | test "struct field explicit alignment" { | |
| 303 | const S = struct { | |
| 304 | const Node = struct { | |
| 305 | next: *Node, | |
| 306 | massive_byte: u8 align(64), | |
| 307 | }; | |
| 308 | }; | |
| 309 | ||
| 310 | var node: S.Node = undefined; | |
| 311 | node.massive_byte = 100; | |
| 312 | expect(node.massive_byte == 100); | |
| 313 | comptime expect(@TypeOf(&node.massive_byte) == *align(64) u8); | |
| 314 | expect(@ptrToInt(&node.massive_byte) % 64 == 0); | |
| 315 | } | |
| 316 | ||
| 317 | test "align(@alignOf(T)) T does not force resolution of T" { | |
| 318 | const S = struct { | |
| 319 | const A = struct { | |
| 320 | a: *align(@alignOf(A)) A, | |
| 321 | }; | |
| 322 | fn doTheTest() void { | |
| 323 | suspend { | |
| 324 | resume @frame(); | |
| 325 | } | |
| 326 | _ = bar(@Frame(doTheTest)); | |
| 327 | } | |
| 328 | fn bar(comptime T: type) *align(@alignOf(T)) T { | |
| 329 | ok = true; | |
| 330 | return undefined; | |
| 331 | } | |
| 332 | ||
| 333 | var ok = false; | |
| 334 | }; | |
| 335 | _ = async S.doTheTest(); | |
| 336 | expect(S.ok); | |
| 337 | } | |
| 338 | ||
| 339 | test "align(N) on functions" { | |
| 340 | // function alignment is a compile error on wasm32/wasm64 | |
| 341 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 342 | ||
| 343 | expect((@ptrToInt(overaligned_fn) & (0x1000 - 1)) == 0); | |
| 344 | } | |
| 345 | fn overaligned_fn() align(0x1000) i32 { | |
| 346 | return 42; | |
| 347 | } |
test/behavior/alignof.zig created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const builtin = @import("builtin"); | |
| 4 | const native_arch = builtin.target.cpu.arch; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | ||
| 7 | const Foo = struct { | |
| 8 | x: u32, | |
| 9 | y: u32, | |
| 10 | z: u32, | |
| 11 | }; | |
| 12 | ||
| 13 | test "@alignOf(T) before referencing T" { | |
| 14 | comptime expect(@alignOf(Foo) != maxInt(usize)); | |
| 15 | if (native_arch == .x86_64) { | |
| 16 | comptime expect(@alignOf(Foo) == 4); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | test "comparison of @alignOf(T) against zero" { | |
| 21 | { | |
| 22 | const T = struct { x: u32 }; | |
| 23 | expect(!(@alignOf(T) == 0)); | |
| 24 | expect(@alignOf(T) != 0); | |
| 25 | expect(!(@alignOf(T) < 0)); | |
| 26 | expect(!(@alignOf(T) <= 0)); | |
| 27 | expect(@alignOf(T) > 0); | |
| 28 | expect(@alignOf(T) >= 0); | |
| 29 | } | |
| 30 | { | |
| 31 | const T = struct {}; | |
| 32 | expect(@alignOf(T) == 0); | |
| 33 | expect(!(@alignOf(T) != 0)); | |
| 34 | expect(!(@alignOf(T) < 0)); | |
| 35 | expect(@alignOf(T) <= 0); | |
| 36 | expect(!(@alignOf(T) > 0)); | |
| 37 | expect(@alignOf(T) >= 0); | |
| 38 | } | |
| 39 | } |
test/behavior/array.zig created+489| ... | ... | @@ -0,0 +1,489 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const mem = std.mem; | |
| 4 | const expect = testing.expect; | |
| 5 | const expectEqual = testing.expectEqual; | |
| 6 | ||
| 7 | test "arrays" { | |
| 8 | var array: [5]u32 = undefined; | |
| 9 | ||
| 10 | var i: u32 = 0; | |
| 11 | while (i < 5) { | |
| 12 | array[i] = i + 1; | |
| 13 | i = array[i]; | |
| 14 | } | |
| 15 | ||
| 16 | i = 0; | |
| 17 | var accumulator = @as(u32, 0); | |
| 18 | while (i < 5) { | |
| 19 | accumulator += array[i]; | |
| 20 | ||
| 21 | i += 1; | |
| 22 | } | |
| 23 | ||
| 24 | expect(accumulator == 15); | |
| 25 | expect(getArrayLen(&array) == 5); | |
| 26 | } | |
| 27 | fn getArrayLen(a: []const u32) usize { | |
| 28 | return a.len; | |
| 29 | } | |
| 30 | ||
| 31 | test "array with sentinels" { | |
| 32 | const S = struct { | |
| 33 | fn doTheTest(is_ct: bool) void { | |
| 34 | if (is_ct) { | |
| 35 | var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; | |
| 36 | // Disabled at runtime because of | |
| 37 | // https://github.com/ziglang/zig/issues/4372 | |
| 38 | expectEqual(@as(u8, 0xde), zero_sized[0]); | |
| 39 | var reinterpreted = @ptrCast(*[1]u8, &zero_sized); | |
| 40 | expectEqual(@as(u8, 0xde), reinterpreted[0]); | |
| 41 | } | |
| 42 | var arr: [3:0x55]u8 = undefined; | |
| 43 | // Make sure the sentinel pointer is pointing after the last element | |
| 44 | if (!is_ct) { | |
| 45 | const sentinel_ptr = @ptrToInt(&arr[3]); | |
| 46 | const last_elem_ptr = @ptrToInt(&arr[2]); | |
| 47 | expectEqual(@as(usize, 1), sentinel_ptr - last_elem_ptr); | |
| 48 | } | |
| 49 | // Make sure the sentinel is writeable | |
| 50 | arr[3] = 0x55; | |
| 51 | } | |
| 52 | }; | |
| 53 | ||
| 54 | S.doTheTest(false); | |
| 55 | comptime S.doTheTest(true); | |
| 56 | } | |
| 57 | ||
| 58 | test "void arrays" { | |
| 59 | var array: [4]void = undefined; | |
| 60 | array[0] = void{}; | |
| 61 | array[1] = array[2]; | |
| 62 | expect(@sizeOf(@TypeOf(array)) == 0); | |
| 63 | expect(array.len == 4); | |
| 64 | } | |
| 65 | ||
| 66 | test "array literal" { | |
| 67 | const hex_mult = [_]u16{ | |
| 68 | 4096, | |
| 69 | 256, | |
| 70 | 16, | |
| 71 | 1, | |
| 72 | }; | |
| 73 | ||
| 74 | expect(hex_mult.len == 4); | |
| 75 | expect(hex_mult[1] == 256); | |
| 76 | } | |
| 77 | ||
| 78 | test "array dot len const expr" { | |
| 79 | expect(comptime x: { | |
| 80 | break :x some_array.len == 4; | |
| 81 | }); | |
| 82 | } | |
| 83 | ||
| 84 | const ArrayDotLenConstExpr = struct { | |
| 85 | y: [some_array.len]u8, | |
| 86 | }; | |
| 87 | const some_array = [_]u8{ | |
| 88 | 0, | |
| 89 | 1, | |
| 90 | 2, | |
| 91 | 3, | |
| 92 | }; | |
| 93 | ||
| 94 | test "nested arrays" { | |
| 95 | const array_of_strings = [_][]const u8{ | |
| 96 | "hello", | |
| 97 | "this", | |
| 98 | "is", | |
| 99 | "my", | |
| 100 | "thing", | |
| 101 | }; | |
| 102 | for (array_of_strings) |s, i| { | |
| 103 | if (i == 0) expect(mem.eql(u8, s, "hello")); | |
| 104 | if (i == 1) expect(mem.eql(u8, s, "this")); | |
| 105 | if (i == 2) expect(mem.eql(u8, s, "is")); | |
| 106 | if (i == 3) expect(mem.eql(u8, s, "my")); | |
| 107 | if (i == 4) expect(mem.eql(u8, s, "thing")); | |
| 108 | } | |
| 109 | } | |
| 110 | ||
| 111 | var s_array: [8]Sub = undefined; | |
| 112 | const Sub = struct { | |
| 113 | b: u8, | |
| 114 | }; | |
| 115 | const Str = struct { | |
| 116 | a: []Sub, | |
| 117 | }; | |
| 118 | test "set global var array via slice embedded in struct" { | |
| 119 | var s = Str{ .a = s_array[0..] }; | |
| 120 | ||
| 121 | s.a[0].b = 1; | |
| 122 | s.a[1].b = 2; | |
| 123 | s.a[2].b = 3; | |
| 124 | ||
| 125 | expect(s_array[0].b == 1); | |
| 126 | expect(s_array[1].b == 2); | |
| 127 | expect(s_array[2].b == 3); | |
| 128 | } | |
| 129 | ||
| 130 | test "array literal with specified size" { | |
| 131 | var array = [2]u8{ | |
| 132 | 1, | |
| 133 | 2, | |
| 134 | }; | |
| 135 | expect(array[0] == 1); | |
| 136 | expect(array[1] == 2); | |
| 137 | } | |
| 138 | ||
| 139 | test "array len field" { | |
| 140 | var arr = [4]u8{ 0, 0, 0, 0 }; | |
| 141 | var ptr = &arr; | |
| 142 | expect(arr.len == 4); | |
| 143 | comptime expect(arr.len == 4); | |
| 144 | expect(ptr.len == 4); | |
| 145 | comptime expect(ptr.len == 4); | |
| 146 | } | |
| 147 | ||
| 148 | test "single-item pointer to array indexing and slicing" { | |
| 149 | testSingleItemPtrArrayIndexSlice(); | |
| 150 | comptime testSingleItemPtrArrayIndexSlice(); | |
| 151 | } | |
| 152 | ||
| 153 | fn testSingleItemPtrArrayIndexSlice() void { | |
| 154 | { | |
| 155 | var array: [4]u8 = "aaaa".*; | |
| 156 | doSomeMangling(&array); | |
| 157 | expect(mem.eql(u8, "azya", &array)); | |
| 158 | } | |
| 159 | { | |
| 160 | var array = "aaaa".*; | |
| 161 | doSomeMangling(&array); | |
| 162 | expect(mem.eql(u8, "azya", &array)); | |
| 163 | } | |
| 164 | } | |
| 165 | ||
| 166 | fn doSomeMangling(array: *[4]u8) void { | |
| 167 | array[1] = 'z'; | |
| 168 | array[2..3][0] = 'y'; | |
| 169 | } | |
| 170 | ||
| 171 | test "implicit cast single-item pointer" { | |
| 172 | testImplicitCastSingleItemPtr(); | |
| 173 | comptime testImplicitCastSingleItemPtr(); | |
| 174 | } | |
| 175 | ||
| 176 | fn testImplicitCastSingleItemPtr() void { | |
| 177 | var byte: u8 = 100; | |
| 178 | const slice = @as(*[1]u8, &byte)[0..]; | |
| 179 | slice[0] += 1; | |
| 180 | expect(byte == 101); | |
| 181 | } | |
| 182 | ||
| 183 | fn testArrayByValAtComptime(b: [2]u8) u8 { | |
| 184 | return b[0]; | |
| 185 | } | |
| 186 | ||
| 187 | test "comptime evalutating function that takes array by value" { | |
| 188 | const arr = [_]u8{ 0, 1 }; | |
| 189 | _ = comptime testArrayByValAtComptime(arr); | |
| 190 | _ = comptime testArrayByValAtComptime(arr); | |
| 191 | } | |
| 192 | ||
| 193 | test "implicit comptime in array type size" { | |
| 194 | var arr: [plusOne(10)]bool = undefined; | |
| 195 | expect(arr.len == 11); | |
| 196 | } | |
| 197 | ||
| 198 | fn plusOne(x: u32) u32 { | |
| 199 | return x + 1; | |
| 200 | } | |
| 201 | ||
| 202 | test "runtime initialize array elem and then implicit cast to slice" { | |
| 203 | var two: i32 = 2; | |
| 204 | const x: []const i32 = &[_]i32{two}; | |
| 205 | expect(x[0] == 2); | |
| 206 | } | |
| 207 | ||
| 208 | test "array literal as argument to function" { | |
| 209 | const S = struct { | |
| 210 | fn entry(two: i32) void { | |
| 211 | foo(&[_]i32{ | |
| 212 | 1, | |
| 213 | 2, | |
| 214 | 3, | |
| 215 | }); | |
| 216 | foo(&[_]i32{ | |
| 217 | 1, | |
| 218 | two, | |
| 219 | 3, | |
| 220 | }); | |
| 221 | foo2(true, &[_]i32{ | |
| 222 | 1, | |
| 223 | 2, | |
| 224 | 3, | |
| 225 | }); | |
| 226 | foo2(true, &[_]i32{ | |
| 227 | 1, | |
| 228 | two, | |
| 229 | 3, | |
| 230 | }); | |
| 231 | } | |
| 232 | fn foo(x: []const i32) void { | |
| 233 | expect(x[0] == 1); | |
| 234 | expect(x[1] == 2); | |
| 235 | expect(x[2] == 3); | |
| 236 | } | |
| 237 | fn foo2(trash: bool, x: []const i32) void { | |
| 238 | expect(trash); | |
| 239 | expect(x[0] == 1); | |
| 240 | expect(x[1] == 2); | |
| 241 | expect(x[2] == 3); | |
| 242 | } | |
| 243 | }; | |
| 244 | S.entry(2); | |
| 245 | comptime S.entry(2); | |
| 246 | } | |
| 247 | ||
| 248 | test "double nested array to const slice cast in array literal" { | |
| 249 | const S = struct { | |
| 250 | fn entry(two: i32) void { | |
| 251 | const cases = [_][]const []const i32{ | |
| 252 | &[_][]const i32{&[_]i32{1}}, | |
| 253 | &[_][]const i32{&[_]i32{ 2, 3 }}, | |
| 254 | &[_][]const i32{ | |
| 255 | &[_]i32{4}, | |
| 256 | &[_]i32{ 5, 6, 7 }, | |
| 257 | }, | |
| 258 | }; | |
| 259 | check(&cases); | |
| 260 | ||
| 261 | const cases2 = [_][]const i32{ | |
| 262 | &[_]i32{1}, | |
| 263 | &[_]i32{ two, 3 }, | |
| 264 | }; | |
| 265 | expect(cases2.len == 2); | |
| 266 | expect(cases2[0].len == 1); | |
| 267 | expect(cases2[0][0] == 1); | |
| 268 | expect(cases2[1].len == 2); | |
| 269 | expect(cases2[1][0] == 2); | |
| 270 | expect(cases2[1][1] == 3); | |
| 271 | ||
| 272 | const cases3 = [_][]const []const i32{ | |
| 273 | &[_][]const i32{&[_]i32{1}}, | |
| 274 | &[_][]const i32{&[_]i32{ two, 3 }}, | |
| 275 | &[_][]const i32{ | |
| 276 | &[_]i32{4}, | |
| 277 | &[_]i32{ 5, 6, 7 }, | |
| 278 | }, | |
| 279 | }; | |
| 280 | check(&cases3); | |
| 281 | } | |
| 282 | ||
| 283 | fn check(cases: []const []const []const i32) void { | |
| 284 | expect(cases.len == 3); | |
| 285 | expect(cases[0].len == 1); | |
| 286 | expect(cases[0][0].len == 1); | |
| 287 | expect(cases[0][0][0] == 1); | |
| 288 | expect(cases[1].len == 1); | |
| 289 | expect(cases[1][0].len == 2); | |
| 290 | expect(cases[1][0][0] == 2); | |
| 291 | expect(cases[1][0][1] == 3); | |
| 292 | expect(cases[2].len == 2); | |
| 293 | expect(cases[2][0].len == 1); | |
| 294 | expect(cases[2][0][0] == 4); | |
| 295 | expect(cases[2][1].len == 3); | |
| 296 | expect(cases[2][1][0] == 5); | |
| 297 | expect(cases[2][1][1] == 6); | |
| 298 | expect(cases[2][1][2] == 7); | |
| 299 | } | |
| 300 | }; | |
| 301 | S.entry(2); | |
| 302 | comptime S.entry(2); | |
| 303 | } | |
| 304 | ||
| 305 | test "read/write through global variable array of struct fields initialized via array mult" { | |
| 306 | const S = struct { | |
| 307 | fn doTheTest() void { | |
| 308 | expect(storage[0].term == 1); | |
| 309 | storage[0] = MyStruct{ .term = 123 }; | |
| 310 | expect(storage[0].term == 123); | |
| 311 | } | |
| 312 | ||
| 313 | pub const MyStruct = struct { | |
| 314 | term: usize, | |
| 315 | }; | |
| 316 | ||
| 317 | var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; | |
| 318 | }; | |
| 319 | S.doTheTest(); | |
| 320 | } | |
| 321 | ||
| 322 | test "implicit cast zero sized array ptr to slice" { | |
| 323 | { | |
| 324 | var b = "".*; | |
| 325 | const c: []const u8 = &b; | |
| 326 | expect(c.len == 0); | |
| 327 | } | |
| 328 | { | |
| 329 | var b: [0]u8 = "".*; | |
| 330 | const c: []const u8 = &b; | |
| 331 | expect(c.len == 0); | |
| 332 | } | |
| 333 | } | |
| 334 | ||
| 335 | test "anonymous list literal syntax" { | |
| 336 | const S = struct { | |
| 337 | fn doTheTest() void { | |
| 338 | var array: [4]u8 = .{ 1, 2, 3, 4 }; | |
| 339 | expect(array[0] == 1); | |
| 340 | expect(array[1] == 2); | |
| 341 | expect(array[2] == 3); | |
| 342 | expect(array[3] == 4); | |
| 343 | } | |
| 344 | }; | |
| 345 | S.doTheTest(); | |
| 346 | comptime S.doTheTest(); | |
| 347 | } | |
| 348 | ||
| 349 | test "anonymous literal in array" { | |
| 350 | const S = struct { | |
| 351 | const Foo = struct { | |
| 352 | a: usize = 2, | |
| 353 | b: usize = 4, | |
| 354 | }; | |
| 355 | fn doTheTest() void { | |
| 356 | var array: [2]Foo = .{ | |
| 357 | .{ .a = 3 }, | |
| 358 | .{ .b = 3 }, | |
| 359 | }; | |
| 360 | expect(array[0].a == 3); | |
| 361 | expect(array[0].b == 4); | |
| 362 | expect(array[1].a == 2); | |
| 363 | expect(array[1].b == 3); | |
| 364 | } | |
| 365 | }; | |
| 366 | S.doTheTest(); | |
| 367 | comptime S.doTheTest(); | |
| 368 | } | |
| 369 | ||
| 370 | test "access the null element of a null terminated array" { | |
| 371 | const S = struct { | |
| 372 | fn doTheTest() void { | |
| 373 | var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; | |
| 374 | expect(array[4] == 0); | |
| 375 | var len: usize = 4; | |
| 376 | expect(array[len] == 0); | |
| 377 | } | |
| 378 | }; | |
| 379 | S.doTheTest(); | |
| 380 | comptime S.doTheTest(); | |
| 381 | } | |
| 382 | ||
| 383 | test "type deduction for array subscript expression" { | |
| 384 | const S = struct { | |
| 385 | fn doTheTest() void { | |
| 386 | var array = [_]u8{ 0x55, 0xAA }; | |
| 387 | var v0 = true; | |
| 388 | expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]); | |
| 389 | var v1 = false; | |
| 390 | expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]); | |
| 391 | } | |
| 392 | }; | |
| 393 | S.doTheTest(); | |
| 394 | comptime S.doTheTest(); | |
| 395 | } | |
| 396 | ||
| 397 | test "sentinel element count towards the ABI size calculation" { | |
| 398 | const S = struct { | |
| 399 | fn doTheTest() void { | |
| 400 | const T = packed struct { | |
| 401 | fill_pre: u8 = 0x55, | |
| 402 | data: [0:0]u8 = undefined, | |
| 403 | fill_post: u8 = 0xAA, | |
| 404 | }; | |
| 405 | var x = T{}; | |
| 406 | var as_slice = mem.asBytes(&x); | |
| 407 | expectEqual(@as(usize, 3), as_slice.len); | |
| 408 | expectEqual(@as(u8, 0x55), as_slice[0]); | |
| 409 | expectEqual(@as(u8, 0xAA), as_slice[2]); | |
| 410 | } | |
| 411 | }; | |
| 412 | ||
| 413 | S.doTheTest(); | |
| 414 | comptime S.doTheTest(); | |
| 415 | } | |
| 416 | ||
| 417 | test "zero-sized array with recursive type definition" { | |
| 418 | const U = struct { | |
| 419 | fn foo(comptime T: type, comptime n: usize) type { | |
| 420 | return struct { | |
| 421 | s: [n]T, | |
| 422 | x: usize = n, | |
| 423 | }; | |
| 424 | } | |
| 425 | }; | |
| 426 | ||
| 427 | const S = struct { | |
| 428 | list: U.foo(@This(), 0), | |
| 429 | }; | |
| 430 | ||
| 431 | var t: S = .{ .list = .{ .s = undefined } }; | |
| 432 | expectEqual(@as(usize, 0), t.list.x); | |
| 433 | } | |
| 434 | ||
| 435 | test "type coercion of anon struct literal to array" { | |
| 436 | const S = struct { | |
| 437 | const U = union{ | |
| 438 | a: u32, | |
| 439 | b: bool, | |
| 440 | c: []const u8, | |
| 441 | }; | |
| 442 | ||
| 443 | fn doTheTest() void { | |
| 444 | var x1: u8 = 42; | |
| 445 | const t1 = .{ x1, 56, 54 }; | |
| 446 | var arr1: [3]u8 = t1; | |
| 447 | expect(arr1[0] == 42); | |
| 448 | expect(arr1[1] == 56); | |
| 449 | expect(arr1[2] == 54); | |
| 450 | ||
| 451 | var x2: U = .{ .a = 42 }; | |
| 452 | const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; | |
| 453 | var arr2: [3]U = t2; | |
| 454 | expect(arr2[0].a == 42); | |
| 455 | expect(arr2[1].b == true); | |
| 456 | expect(mem.eql(u8, arr2[2].c, "hello")); | |
| 457 | } | |
| 458 | }; | |
| 459 | S.doTheTest(); | |
| 460 | comptime S.doTheTest(); | |
| 461 | } | |
| 462 | ||
| 463 | test "type coercion of pointer to anon struct literal to pointer to array" { | |
| 464 | const S = struct { | |
| 465 | const U = union{ | |
| 466 | a: u32, | |
| 467 | b: bool, | |
| 468 | c: []const u8, | |
| 469 | }; | |
| 470 | ||
| 471 | fn doTheTest() void { | |
| 472 | var x1: u8 = 42; | |
| 473 | const t1 = &.{ x1, 56, 54 }; | |
| 474 | var arr1: *const[3]u8 = t1; | |
| 475 | expect(arr1[0] == 42); | |
| 476 | expect(arr1[1] == 56); | |
| 477 | expect(arr1[2] == 54); | |
| 478 | ||
| 479 | var x2: U = .{ .a = 42 }; | |
| 480 | const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } }; | |
| 481 | var arr2: *const [3]U = t2; | |
| 482 | expect(arr2[0].a == 42); | |
| 483 | expect(arr2[1].b == true); | |
| 484 | expect(mem.eql(u8, arr2[2].c, "hello")); | |
| 485 | } | |
| 486 | }; | |
| 487 | S.doTheTest(); | |
| 488 | comptime S.doTheTest(); | |
| 489 | } |
test/behavior/asm.zig created+94| ... | ... | @@ -0,0 +1,94 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const is_x86_64_linux = std.Target.current.cpu.arch == .x86_64 and std.Target.current.os.tag == .linux; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (is_x86_64_linux) { | |
| 8 | asm ( | |
| 9 | \\.globl this_is_my_alias; | |
| 10 | \\.type this_is_my_alias, @function; | |
| 11 | \\.set this_is_my_alias, derp; | |
| 12 | ); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | test "module level assembly" { | |
| 17 | if (is_x86_64_linux) { | |
| 18 | expect(this_is_my_alias() == 1234); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | test "output constraint modifiers" { | |
| 23 | // This is only testing compilation. | |
| 24 | var a: u32 = 3; | |
| 25 | asm volatile ("" | |
| 26 | : [_] "=m,r" (a) | |
| 27 | : | |
| 28 | : "" | |
| 29 | ); | |
| 30 | asm volatile ("" | |
| 31 | : [_] "=r,m" (a) | |
| 32 | : | |
| 33 | : "" | |
| 34 | ); | |
| 35 | } | |
| 36 | ||
| 37 | test "alternative constraints" { | |
| 38 | // Make sure we allow commas as a separator for alternative constraints. | |
| 39 | var a: u32 = 3; | |
| 40 | asm volatile ("" | |
| 41 | : [_] "=r,m" (a) | |
| 42 | : [_] "r,m" (a) | |
| 43 | : "" | |
| 44 | ); | |
| 45 | } | |
| 46 | ||
| 47 | test "sized integer/float in asm input" { | |
| 48 | asm volatile ("" | |
| 49 | : | |
| 50 | : [_] "m" (@as(usize, 3)) | |
| 51 | : "" | |
| 52 | ); | |
| 53 | asm volatile ("" | |
| 54 | : | |
| 55 | : [_] "m" (@as(i15, -3)) | |
| 56 | : "" | |
| 57 | ); | |
| 58 | asm volatile ("" | |
| 59 | : | |
| 60 | : [_] "m" (@as(u3, 3)) | |
| 61 | : "" | |
| 62 | ); | |
| 63 | asm volatile ("" | |
| 64 | : | |
| 65 | : [_] "m" (@as(i3, 3)) | |
| 66 | : "" | |
| 67 | ); | |
| 68 | asm volatile ("" | |
| 69 | : | |
| 70 | : [_] "m" (@as(u121, 3)) | |
| 71 | : "" | |
| 72 | ); | |
| 73 | asm volatile ("" | |
| 74 | : | |
| 75 | : [_] "m" (@as(i121, 3)) | |
| 76 | : "" | |
| 77 | ); | |
| 78 | asm volatile ("" | |
| 79 | : | |
| 80 | : [_] "m" (@as(f32, 3.17)) | |
| 81 | : "" | |
| 82 | ); | |
| 83 | asm volatile ("" | |
| 84 | : | |
| 85 | : [_] "m" (@as(f64, 3.17)) | |
| 86 | : "" | |
| 87 | ); | |
| 88 | } | |
| 89 | ||
| 90 | extern fn this_is_my_alias() i32; | |
| 91 | ||
| 92 | export fn derp() i32 { | |
| 93 | return 1234; | |
| 94 | } |
test/behavior/async_fn.zig created+1673| ... | ... | @@ -0,0 +1,1673 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const expectEqualStrings = std.testing.expectEqualStrings; | |
| 6 | const expectError = std.testing.expectError; | |
| 7 | ||
| 8 | var global_x: i32 = 1; | |
| 9 | ||
| 10 | test "simple coroutine suspend and resume" { | |
| 11 | var frame = async simpleAsyncFn(); | |
| 12 | expect(global_x == 2); | |
| 13 | resume frame; | |
| 14 | expect(global_x == 3); | |
| 15 | const af: anyframe->void = &frame; | |
| 16 | resume frame; | |
| 17 | expect(global_x == 4); | |
| 18 | } | |
| 19 | fn simpleAsyncFn() void { | |
| 20 | global_x += 1; | |
| 21 | suspend {} | |
| 22 | global_x += 1; | |
| 23 | suspend {} | |
| 24 | global_x += 1; | |
| 25 | } | |
| 26 | ||
| 27 | var global_y: i32 = 1; | |
| 28 | ||
| 29 | test "pass parameter to coroutine" { | |
| 30 | var p = async simpleAsyncFnWithArg(2); | |
| 31 | expect(global_y == 3); | |
| 32 | resume p; | |
| 33 | expect(global_y == 5); | |
| 34 | } | |
| 35 | fn simpleAsyncFnWithArg(delta: i32) void { | |
| 36 | global_y += delta; | |
| 37 | suspend {} | |
| 38 | global_y += delta; | |
| 39 | } | |
| 40 | ||
| 41 | test "suspend at end of function" { | |
| 42 | const S = struct { | |
| 43 | var x: i32 = 1; | |
| 44 | ||
| 45 | fn doTheTest() void { | |
| 46 | expect(x == 1); | |
| 47 | const p = async suspendAtEnd(); | |
| 48 | expect(x == 2); | |
| 49 | } | |
| 50 | ||
| 51 | fn suspendAtEnd() void { | |
| 52 | x += 1; | |
| 53 | suspend {} | |
| 54 | } | |
| 55 | }; | |
| 56 | S.doTheTest(); | |
| 57 | } | |
| 58 | ||
| 59 | test "local variable in async function" { | |
| 60 | const S = struct { | |
| 61 | var x: i32 = 0; | |
| 62 | ||
| 63 | fn doTheTest() void { | |
| 64 | expect(x == 0); | |
| 65 | var p = async add(1, 2); | |
| 66 | expect(x == 0); | |
| 67 | resume p; | |
| 68 | expect(x == 0); | |
| 69 | resume p; | |
| 70 | expect(x == 0); | |
| 71 | resume p; | |
| 72 | expect(x == 3); | |
| 73 | } | |
| 74 | ||
| 75 | fn add(a: i32, b: i32) void { | |
| 76 | var accum: i32 = 0; | |
| 77 | suspend {} | |
| 78 | accum += a; | |
| 79 | suspend {} | |
| 80 | accum += b; | |
| 81 | suspend {} | |
| 82 | x = accum; | |
| 83 | } | |
| 84 | }; | |
| 85 | S.doTheTest(); | |
| 86 | } | |
| 87 | ||
| 88 | test "calling an inferred async function" { | |
| 89 | const S = struct { | |
| 90 | var x: i32 = 1; | |
| 91 | var other_frame: *@Frame(other) = undefined; | |
| 92 | ||
| 93 | fn doTheTest() void { | |
| 94 | _ = async first(); | |
| 95 | expect(x == 1); | |
| 96 | resume other_frame.*; | |
| 97 | expect(x == 2); | |
| 98 | } | |
| 99 | ||
| 100 | fn first() void { | |
| 101 | other(); | |
| 102 | } | |
| 103 | fn other() void { | |
| 104 | other_frame = @frame(); | |
| 105 | suspend {} | |
| 106 | x += 1; | |
| 107 | } | |
| 108 | }; | |
| 109 | S.doTheTest(); | |
| 110 | } | |
| 111 | ||
| 112 | test "@frameSize" { | |
| 113 | const S = struct { | |
| 114 | fn doTheTest() void { | |
| 115 | { | |
| 116 | var ptr = @ptrCast(fn (i32) callconv(.Async) void, other); | |
| 117 | const size = @frameSize(ptr); | |
| 118 | expect(size == @sizeOf(@Frame(other))); | |
| 119 | } | |
| 120 | { | |
| 121 | var ptr = @ptrCast(fn () callconv(.Async) void, first); | |
| 122 | const size = @frameSize(ptr); | |
| 123 | expect(size == @sizeOf(@Frame(first))); | |
| 124 | } | |
| 125 | } | |
| 126 | ||
| 127 | fn first() void { | |
| 128 | other(1); | |
| 129 | } | |
| 130 | fn other(param: i32) void { | |
| 131 | var local: i32 = undefined; | |
| 132 | suspend {} | |
| 133 | } | |
| 134 | }; | |
| 135 | S.doTheTest(); | |
| 136 | } | |
| 137 | ||
| 138 | test "coroutine suspend, resume" { | |
| 139 | const S = struct { | |
| 140 | var frame: anyframe = undefined; | |
| 141 | ||
| 142 | fn doTheTest() void { | |
| 143 | _ = async amain(); | |
| 144 | seq('d'); | |
| 145 | resume frame; | |
| 146 | seq('h'); | |
| 147 | ||
| 148 | expect(std.mem.eql(u8, &points, "abcdefgh")); | |
| 149 | } | |
| 150 | ||
| 151 | fn amain() void { | |
| 152 | seq('a'); | |
| 153 | var f = async testAsyncSeq(); | |
| 154 | seq('c'); | |
| 155 | await f; | |
| 156 | seq('g'); | |
| 157 | } | |
| 158 | ||
| 159 | fn testAsyncSeq() void { | |
| 160 | defer seq('f'); | |
| 161 | ||
| 162 | seq('b'); | |
| 163 | suspend { | |
| 164 | frame = @frame(); | |
| 165 | } | |
| 166 | seq('e'); | |
| 167 | } | |
| 168 | var points = [_]u8{'x'} ** "abcdefgh".len; | |
| 169 | var index: usize = 0; | |
| 170 | ||
| 171 | fn seq(c: u8) void { | |
| 172 | points[index] = c; | |
| 173 | index += 1; | |
| 174 | } | |
| 175 | }; | |
| 176 | S.doTheTest(); | |
| 177 | } | |
| 178 | ||
| 179 | test "coroutine suspend with block" { | |
| 180 | const p = async testSuspendBlock(); | |
| 181 | expect(!global_result); | |
| 182 | resume a_promise; | |
| 183 | expect(global_result); | |
| 184 | } | |
| 185 | ||
| 186 | var a_promise: anyframe = undefined; | |
| 187 | var global_result = false; | |
| 188 | fn testSuspendBlock() callconv(.Async) void { | |
| 189 | suspend { | |
| 190 | comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock)); | |
| 191 | a_promise = @frame(); | |
| 192 | } | |
| 193 | ||
| 194 | // Test to make sure that @frame() works as advertised (issue #1296) | |
| 195 | // var our_handle: anyframe = @frame(); | |
| 196 | expect(a_promise == @as(anyframe, @frame())); | |
| 197 | ||
| 198 | global_result = true; | |
| 199 | } | |
| 200 | ||
| 201 | var await_a_promise: anyframe = undefined; | |
| 202 | var await_final_result: i32 = 0; | |
| 203 | ||
| 204 | test "coroutine await" { | |
| 205 | await_seq('a'); | |
| 206 | var p = async await_amain(); | |
| 207 | await_seq('f'); | |
| 208 | resume await_a_promise; | |
| 209 | await_seq('i'); | |
| 210 | expect(await_final_result == 1234); | |
| 211 | expect(std.mem.eql(u8, &await_points, "abcdefghi")); | |
| 212 | } | |
| 213 | fn await_amain() callconv(.Async) void { | |
| 214 | await_seq('b'); | |
| 215 | var p = async await_another(); | |
| 216 | await_seq('e'); | |
| 217 | await_final_result = await p; | |
| 218 | await_seq('h'); | |
| 219 | } | |
| 220 | fn await_another() callconv(.Async) i32 { | |
| 221 | await_seq('c'); | |
| 222 | suspend { | |
| 223 | await_seq('d'); | |
| 224 | await_a_promise = @frame(); | |
| 225 | } | |
| 226 | await_seq('g'); | |
| 227 | return 1234; | |
| 228 | } | |
| 229 | ||
| 230 | var await_points = [_]u8{0} ** "abcdefghi".len; | |
| 231 | var await_seq_index: usize = 0; | |
| 232 | ||
| 233 | fn await_seq(c: u8) void { | |
| 234 | await_points[await_seq_index] = c; | |
| 235 | await_seq_index += 1; | |
| 236 | } | |
| 237 | ||
| 238 | var early_final_result: i32 = 0; | |
| 239 | ||
| 240 | test "coroutine await early return" { | |
| 241 | early_seq('a'); | |
| 242 | var p = async early_amain(); | |
| 243 | early_seq('f'); | |
| 244 | expect(early_final_result == 1234); | |
| 245 | expect(std.mem.eql(u8, &early_points, "abcdef")); | |
| 246 | } | |
| 247 | fn early_amain() callconv(.Async) void { | |
| 248 | early_seq('b'); | |
| 249 | var p = async early_another(); | |
| 250 | early_seq('d'); | |
| 251 | early_final_result = await p; | |
| 252 | early_seq('e'); | |
| 253 | } | |
| 254 | fn early_another() callconv(.Async) i32 { | |
| 255 | early_seq('c'); | |
| 256 | return 1234; | |
| 257 | } | |
| 258 | ||
| 259 | var early_points = [_]u8{0} ** "abcdef".len; | |
| 260 | var early_seq_index: usize = 0; | |
| 261 | ||
| 262 | fn early_seq(c: u8) void { | |
| 263 | early_points[early_seq_index] = c; | |
| 264 | early_seq_index += 1; | |
| 265 | } | |
| 266 | ||
| 267 | test "async function with dot syntax" { | |
| 268 | const S = struct { | |
| 269 | var y: i32 = 1; | |
| 270 | fn foo() callconv(.Async) void { | |
| 271 | y += 1; | |
| 272 | suspend {} | |
| 273 | } | |
| 274 | }; | |
| 275 | const p = async S.foo(); | |
| 276 | expect(S.y == 2); | |
| 277 | } | |
| 278 | ||
| 279 | test "async fn pointer in a struct field" { | |
| 280 | var data: i32 = 1; | |
| 281 | const Foo = struct { | |
| 282 | bar: fn (*i32) callconv(.Async) void, | |
| 283 | }; | |
| 284 | var foo = Foo{ .bar = simpleAsyncFn2 }; | |
| 285 | var bytes: [64]u8 align(16) = undefined; | |
| 286 | const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); | |
| 287 | comptime expect(@TypeOf(f) == anyframe->void); | |
| 288 | expect(data == 2); | |
| 289 | resume f; | |
| 290 | expect(data == 4); | |
| 291 | _ = async doTheAwait(f); | |
| 292 | expect(data == 4); | |
| 293 | } | |
| 294 | ||
| 295 | fn doTheAwait(f: anyframe->void) void { | |
| 296 | await f; | |
| 297 | } | |
| 298 | fn simpleAsyncFn2(y: *i32) callconv(.Async) void { | |
| 299 | defer y.* += 2; | |
| 300 | y.* += 1; | |
| 301 | suspend {} | |
| 302 | } | |
| 303 | ||
| 304 | test "@asyncCall with return type" { | |
| 305 | const Foo = struct { | |
| 306 | bar: fn () callconv(.Async) i32, | |
| 307 | ||
| 308 | var global_frame: anyframe = undefined; | |
| 309 | fn middle() callconv(.Async) i32 { | |
| 310 | return afunc(); | |
| 311 | } | |
| 312 | ||
| 313 | fn afunc() i32 { | |
| 314 | global_frame = @frame(); | |
| 315 | suspend {} | |
| 316 | return 1234; | |
| 317 | } | |
| 318 | }; | |
| 319 | var foo = Foo{ .bar = Foo.middle }; | |
| 320 | var bytes: [150]u8 align(16) = undefined; | |
| 321 | var aresult: i32 = 0; | |
| 322 | _ = @asyncCall(&bytes, &aresult, foo.bar, .{}); | |
| 323 | expect(aresult == 0); | |
| 324 | resume Foo.global_frame; | |
| 325 | expect(aresult == 1234); | |
| 326 | } | |
| 327 | ||
| 328 | test "async fn with inferred error set" { | |
| 329 | const S = struct { | |
| 330 | var global_frame: anyframe = undefined; | |
| 331 | ||
| 332 | fn doTheTest() void { | |
| 333 | var frame: [1]@Frame(middle) = undefined; | |
| 334 | var fn_ptr = middle; | |
| 335 | var result: @typeInfo(@typeInfo(@TypeOf(fn_ptr)).Fn.return_type.?).ErrorUnion.error_set!void = undefined; | |
| 336 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr, .{}); | |
| 337 | resume global_frame; | |
| 338 | std.testing.expectError(error.Fail, result); | |
| 339 | } | |
| 340 | fn middle() callconv(.Async) !void { | |
| 341 | var f = async middle2(); | |
| 342 | return await f; | |
| 343 | } | |
| 344 | ||
| 345 | fn middle2() !void { | |
| 346 | return failing(); | |
| 347 | } | |
| 348 | ||
| 349 | fn failing() !void { | |
| 350 | global_frame = @frame(); | |
| 351 | suspend {} | |
| 352 | return error.Fail; | |
| 353 | } | |
| 354 | }; | |
| 355 | S.doTheTest(); | |
| 356 | } | |
| 357 | ||
| 358 | test "error return trace across suspend points - early return" { | |
| 359 | const p = nonFailing(); | |
| 360 | resume p; | |
| 361 | const p2 = async printTrace(p); | |
| 362 | } | |
| 363 | ||
| 364 | test "error return trace across suspend points - async return" { | |
| 365 | const p = nonFailing(); | |
| 366 | const p2 = async printTrace(p); | |
| 367 | resume p; | |
| 368 | } | |
| 369 | ||
| 370 | fn nonFailing() (anyframe->anyerror!void) { | |
| 371 | const Static = struct { | |
| 372 | var frame: @Frame(suspendThenFail) = undefined; | |
| 373 | }; | |
| 374 | Static.frame = async suspendThenFail(); | |
| 375 | return &Static.frame; | |
| 376 | } | |
| 377 | fn suspendThenFail() callconv(.Async) anyerror!void { | |
| 378 | suspend {} | |
| 379 | return error.Fail; | |
| 380 | } | |
| 381 | fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void { | |
| 382 | (await p) catch |e| { | |
| 383 | std.testing.expect(e == error.Fail); | |
| 384 | if (@errorReturnTrace()) |trace| { | |
| 385 | expect(trace.index == 1); | |
| 386 | } else switch (builtin.mode) { | |
| 387 | .Debug, .ReleaseSafe => @panic("expected return trace"), | |
| 388 | .ReleaseFast, .ReleaseSmall => {}, | |
| 389 | } | |
| 390 | }; | |
| 391 | } | |
| 392 | ||
| 393 | test "break from suspend" { | |
| 394 | var my_result: i32 = 1; | |
| 395 | const p = async testBreakFromSuspend(&my_result); | |
| 396 | std.testing.expect(my_result == 2); | |
| 397 | } | |
| 398 | fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void { | |
| 399 | suspend { | |
| 400 | resume @frame(); | |
| 401 | } | |
| 402 | my_result.* += 1; | |
| 403 | suspend {} | |
| 404 | my_result.* += 1; | |
| 405 | } | |
| 406 | ||
| 407 | test "heap allocated async function frame" { | |
| 408 | const S = struct { | |
| 409 | var x: i32 = 42; | |
| 410 | ||
| 411 | fn doTheTest() !void { | |
| 412 | const frame = try std.testing.allocator.create(@Frame(someFunc)); | |
| 413 | defer std.testing.allocator.destroy(frame); | |
| 414 | ||
| 415 | expect(x == 42); | |
| 416 | frame.* = async someFunc(); | |
| 417 | expect(x == 43); | |
| 418 | resume frame; | |
| 419 | expect(x == 44); | |
| 420 | } | |
| 421 | ||
| 422 | fn someFunc() void { | |
| 423 | x += 1; | |
| 424 | suspend {} | |
| 425 | x += 1; | |
| 426 | } | |
| 427 | }; | |
| 428 | try S.doTheTest(); | |
| 429 | } | |
| 430 | ||
| 431 | test "async function call return value" { | |
| 432 | const S = struct { | |
| 433 | var frame: anyframe = undefined; | |
| 434 | var pt = Point{ .x = 10, .y = 11 }; | |
| 435 | ||
| 436 | fn doTheTest() void { | |
| 437 | expectEqual(pt.x, 10); | |
| 438 | expectEqual(pt.y, 11); | |
| 439 | _ = async first(); | |
| 440 | expectEqual(pt.x, 10); | |
| 441 | expectEqual(pt.y, 11); | |
| 442 | resume frame; | |
| 443 | expectEqual(pt.x, 1); | |
| 444 | expectEqual(pt.y, 2); | |
| 445 | } | |
| 446 | ||
| 447 | fn first() void { | |
| 448 | pt = second(1, 2); | |
| 449 | } | |
| 450 | ||
| 451 | fn second(x: i32, y: i32) Point { | |
| 452 | return other(x, y); | |
| 453 | } | |
| 454 | ||
| 455 | fn other(x: i32, y: i32) Point { | |
| 456 | frame = @frame(); | |
| 457 | suspend {} | |
| 458 | return Point{ | |
| 459 | .x = x, | |
| 460 | .y = y, | |
| 461 | }; | |
| 462 | } | |
| 463 | ||
| 464 | const Point = struct { | |
| 465 | x: i32, | |
| 466 | y: i32, | |
| 467 | }; | |
| 468 | }; | |
| 469 | S.doTheTest(); | |
| 470 | } | |
| 471 | ||
| 472 | test "suspension points inside branching control flow" { | |
| 473 | const S = struct { | |
| 474 | var result: i32 = 10; | |
| 475 | ||
| 476 | fn doTheTest() void { | |
| 477 | expect(10 == result); | |
| 478 | var frame = async func(true); | |
| 479 | expect(10 == result); | |
| 480 | resume frame; | |
| 481 | expect(11 == result); | |
| 482 | resume frame; | |
| 483 | expect(12 == result); | |
| 484 | resume frame; | |
| 485 | expect(13 == result); | |
| 486 | } | |
| 487 | ||
| 488 | fn func(b: bool) void { | |
| 489 | while (b) { | |
| 490 | suspend {} | |
| 491 | result += 1; | |
| 492 | } | |
| 493 | } | |
| 494 | }; | |
| 495 | S.doTheTest(); | |
| 496 | } | |
| 497 | ||
| 498 | test "call async function which has struct return type" { | |
| 499 | const S = struct { | |
| 500 | var frame: anyframe = undefined; | |
| 501 | ||
| 502 | fn doTheTest() void { | |
| 503 | _ = async atest(); | |
| 504 | resume frame; | |
| 505 | } | |
| 506 | ||
| 507 | fn atest() void { | |
| 508 | const result = func(); | |
| 509 | expect(result.x == 5); | |
| 510 | expect(result.y == 6); | |
| 511 | } | |
| 512 | ||
| 513 | const Point = struct { | |
| 514 | x: usize, | |
| 515 | y: usize, | |
| 516 | }; | |
| 517 | ||
| 518 | fn func() Point { | |
| 519 | suspend { | |
| 520 | frame = @frame(); | |
| 521 | } | |
| 522 | return Point{ | |
| 523 | .x = 5, | |
| 524 | .y = 6, | |
| 525 | }; | |
| 526 | } | |
| 527 | }; | |
| 528 | S.doTheTest(); | |
| 529 | } | |
| 530 | ||
| 531 | test "pass string literal to async function" { | |
| 532 | const S = struct { | |
| 533 | var frame: anyframe = undefined; | |
| 534 | var ok: bool = false; | |
| 535 | ||
| 536 | fn doTheTest() void { | |
| 537 | _ = async hello("hello"); | |
| 538 | resume frame; | |
| 539 | expect(ok); | |
| 540 | } | |
| 541 | ||
| 542 | fn hello(msg: []const u8) void { | |
| 543 | frame = @frame(); | |
| 544 | suspend {} | |
| 545 | expectEqualStrings("hello", msg); | |
| 546 | ok = true; | |
| 547 | } | |
| 548 | }; | |
| 549 | S.doTheTest(); | |
| 550 | } | |
| 551 | ||
| 552 | test "await inside an errdefer" { | |
| 553 | const S = struct { | |
| 554 | var frame: anyframe = undefined; | |
| 555 | ||
| 556 | fn doTheTest() void { | |
| 557 | _ = async amainWrap(); | |
| 558 | resume frame; | |
| 559 | } | |
| 560 | ||
| 561 | fn amainWrap() !void { | |
| 562 | var foo = async func(); | |
| 563 | errdefer await foo; | |
| 564 | return error.Bad; | |
| 565 | } | |
| 566 | ||
| 567 | fn func() void { | |
| 568 | frame = @frame(); | |
| 569 | suspend {} | |
| 570 | } | |
| 571 | }; | |
| 572 | S.doTheTest(); | |
| 573 | } | |
| 574 | ||
| 575 | test "try in an async function with error union and non-zero-bit payload" { | |
| 576 | const S = struct { | |
| 577 | var frame: anyframe = undefined; | |
| 578 | var ok = false; | |
| 579 | ||
| 580 | fn doTheTest() void { | |
| 581 | _ = async amain(); | |
| 582 | resume frame; | |
| 583 | expect(ok); | |
| 584 | } | |
| 585 | ||
| 586 | fn amain() void { | |
| 587 | std.testing.expectError(error.Bad, theProblem()); | |
| 588 | ok = true; | |
| 589 | } | |
| 590 | ||
| 591 | fn theProblem() ![]u8 { | |
| 592 | frame = @frame(); | |
| 593 | suspend {} | |
| 594 | const result = try other(); | |
| 595 | return result; | |
| 596 | } | |
| 597 | ||
| 598 | fn other() ![]u8 { | |
| 599 | return error.Bad; | |
| 600 | } | |
| 601 | }; | |
| 602 | S.doTheTest(); | |
| 603 | } | |
| 604 | ||
| 605 | test "returning a const error from async function" { | |
| 606 | const S = struct { | |
| 607 | var frame: anyframe = undefined; | |
| 608 | var ok = false; | |
| 609 | ||
| 610 | fn doTheTest() void { | |
| 611 | _ = async amain(); | |
| 612 | resume frame; | |
| 613 | expect(ok); | |
| 614 | } | |
| 615 | ||
| 616 | fn amain() !void { | |
| 617 | var download_frame = async fetchUrl(10, "a string"); | |
| 618 | const download_text = try await download_frame; | |
| 619 | ||
| 620 | @panic("should not get here"); | |
| 621 | } | |
| 622 | ||
| 623 | fn fetchUrl(unused: i32, url: []const u8) ![]u8 { | |
| 624 | frame = @frame(); | |
| 625 | suspend {} | |
| 626 | ok = true; | |
| 627 | return error.OutOfMemory; | |
| 628 | } | |
| 629 | }; | |
| 630 | S.doTheTest(); | |
| 631 | } | |
| 632 | ||
| 633 | test "async/await typical usage" { | |
| 634 | inline for ([_]bool{ false, true }) |b1| { | |
| 635 | inline for ([_]bool{ false, true }) |b2| { | |
| 636 | inline for ([_]bool{ false, true }) |b3| { | |
| 637 | inline for ([_]bool{ false, true }) |b4| { | |
| 638 | testAsyncAwaitTypicalUsage(b1, b2, b3, b4).doTheTest(); | |
| 639 | } | |
| 640 | } | |
| 641 | } | |
| 642 | } | |
| 643 | } | |
| 644 | ||
| 645 | fn testAsyncAwaitTypicalUsage( | |
| 646 | comptime simulate_fail_download: bool, | |
| 647 | comptime simulate_fail_file: bool, | |
| 648 | comptime suspend_download: bool, | |
| 649 | comptime suspend_file: bool, | |
| 650 | ) type { | |
| 651 | return struct { | |
| 652 | fn doTheTest() void { | |
| 653 | _ = async amainWrap(); | |
| 654 | if (suspend_file) { | |
| 655 | resume global_file_frame; | |
| 656 | } | |
| 657 | if (suspend_download) { | |
| 658 | resume global_download_frame; | |
| 659 | } | |
| 660 | } | |
| 661 | fn amainWrap() void { | |
| 662 | if (amain()) |_| { | |
| 663 | expect(!simulate_fail_download); | |
| 664 | expect(!simulate_fail_file); | |
| 665 | } else |e| switch (e) { | |
| 666 | error.NoResponse => expect(simulate_fail_download), | |
| 667 | error.FileNotFound => expect(simulate_fail_file), | |
| 668 | else => @panic("test failure"), | |
| 669 | } | |
| 670 | } | |
| 671 | ||
| 672 | fn amain() !void { | |
| 673 | const allocator = std.testing.allocator; | |
| 674 | var download_frame = async fetchUrl(allocator, "https://example.com/"); | |
| 675 | var download_awaited = false; | |
| 676 | errdefer if (!download_awaited) { | |
| 677 | if (await download_frame) |x| allocator.free(x) else |_| {} | |
| 678 | }; | |
| 679 | ||
| 680 | var file_frame = async readFile(allocator, "something.txt"); | |
| 681 | var file_awaited = false; | |
| 682 | errdefer if (!file_awaited) { | |
| 683 | if (await file_frame) |x| allocator.free(x) else |_| {} | |
| 684 | }; | |
| 685 | ||
| 686 | download_awaited = true; | |
| 687 | const download_text = try await download_frame; | |
| 688 | defer allocator.free(download_text); | |
| 689 | ||
| 690 | file_awaited = true; | |
| 691 | const file_text = try await file_frame; | |
| 692 | defer allocator.free(file_text); | |
| 693 | ||
| 694 | expect(std.mem.eql(u8, "expected download text", download_text)); | |
| 695 | expect(std.mem.eql(u8, "expected file text", file_text)); | |
| 696 | } | |
| 697 | ||
| 698 | var global_download_frame: anyframe = undefined; | |
| 699 | fn fetchUrl(allocator: *std.mem.Allocator, url: []const u8) anyerror![]u8 { | |
| 700 | const result = try std.mem.dupe(allocator, u8, "expected download text"); | |
| 701 | errdefer allocator.free(result); | |
| 702 | if (suspend_download) { | |
| 703 | suspend { | |
| 704 | global_download_frame = @frame(); | |
| 705 | } | |
| 706 | } | |
| 707 | if (simulate_fail_download) return error.NoResponse; | |
| 708 | return result; | |
| 709 | } | |
| 710 | ||
| 711 | var global_file_frame: anyframe = undefined; | |
| 712 | fn readFile(allocator: *std.mem.Allocator, filename: []const u8) anyerror![]u8 { | |
| 713 | const result = try std.mem.dupe(allocator, u8, "expected file text"); | |
| 714 | errdefer allocator.free(result); | |
| 715 | if (suspend_file) { | |
| 716 | suspend { | |
| 717 | global_file_frame = @frame(); | |
| 718 | } | |
| 719 | } | |
| 720 | if (simulate_fail_file) return error.FileNotFound; | |
| 721 | return result; | |
| 722 | } | |
| 723 | }; | |
| 724 | } | |
| 725 | ||
| 726 | test "alignment of local variables in async functions" { | |
| 727 | const S = struct { | |
| 728 | fn doTheTest() void { | |
| 729 | var y: u8 = 123; | |
| 730 | var x: u8 align(128) = 1; | |
| 731 | expect(@ptrToInt(&x) % 128 == 0); | |
| 732 | } | |
| 733 | }; | |
| 734 | S.doTheTest(); | |
| 735 | } | |
| 736 | ||
| 737 | test "no reason to resolve frame still works" { | |
| 738 | _ = async simpleNothing(); | |
| 739 | } | |
| 740 | fn simpleNothing() void { | |
| 741 | var x: i32 = 1234; | |
| 742 | } | |
| 743 | ||
| 744 | test "async call a generic function" { | |
| 745 | const S = struct { | |
| 746 | fn doTheTest() void { | |
| 747 | var f = async func(i32, 2); | |
| 748 | const result = await f; | |
| 749 | expect(result == 3); | |
| 750 | } | |
| 751 | ||
| 752 | fn func(comptime T: type, inc: T) T { | |
| 753 | var x: T = 1; | |
| 754 | suspend { | |
| 755 | resume @frame(); | |
| 756 | } | |
| 757 | x += inc; | |
| 758 | return x; | |
| 759 | } | |
| 760 | }; | |
| 761 | _ = async S.doTheTest(); | |
| 762 | } | |
| 763 | ||
| 764 | test "return from suspend block" { | |
| 765 | const S = struct { | |
| 766 | fn doTheTest() void { | |
| 767 | expect(func() == 1234); | |
| 768 | } | |
| 769 | fn func() i32 { | |
| 770 | suspend { | |
| 771 | return 1234; | |
| 772 | } | |
| 773 | } | |
| 774 | }; | |
| 775 | _ = async S.doTheTest(); | |
| 776 | } | |
| 777 | ||
| 778 | test "struct parameter to async function is copied to the frame" { | |
| 779 | const S = struct { | |
| 780 | const Point = struct { | |
| 781 | x: i32, | |
| 782 | y: i32, | |
| 783 | }; | |
| 784 | ||
| 785 | var frame: anyframe = undefined; | |
| 786 | ||
| 787 | fn doTheTest() void { | |
| 788 | _ = async atest(); | |
| 789 | resume frame; | |
| 790 | } | |
| 791 | ||
| 792 | fn atest() void { | |
| 793 | var f: @Frame(foo) = undefined; | |
| 794 | bar(&f); | |
| 795 | clobberStack(10); | |
| 796 | } | |
| 797 | ||
| 798 | fn clobberStack(x: i32) void { | |
| 799 | if (x == 0) return; | |
| 800 | clobberStack(x - 1); | |
| 801 | var y: i32 = x; | |
| 802 | } | |
| 803 | ||
| 804 | fn bar(f: *@Frame(foo)) void { | |
| 805 | var pt = Point{ .x = 1, .y = 2 }; | |
| 806 | f.* = async foo(pt); | |
| 807 | var result = await f; | |
| 808 | expect(result == 1); | |
| 809 | } | |
| 810 | ||
| 811 | fn foo(point: Point) i32 { | |
| 812 | suspend { | |
| 813 | frame = @frame(); | |
| 814 | } | |
| 815 | return point.x; | |
| 816 | } | |
| 817 | }; | |
| 818 | S.doTheTest(); | |
| 819 | } | |
| 820 | ||
| 821 | test "cast fn to async fn when it is inferred to be async" { | |
| 822 | const S = struct { | |
| 823 | var frame: anyframe = undefined; | |
| 824 | var ok = false; | |
| 825 | ||
| 826 | fn doTheTest() void { | |
| 827 | var ptr: fn () callconv(.Async) i32 = undefined; | |
| 828 | ptr = func; | |
| 829 | var buf: [100]u8 align(16) = undefined; | |
| 830 | var result: i32 = undefined; | |
| 831 | const f = @asyncCall(&buf, &result, ptr, .{}); | |
| 832 | _ = await f; | |
| 833 | expect(result == 1234); | |
| 834 | ok = true; | |
| 835 | } | |
| 836 | ||
| 837 | fn func() i32 { | |
| 838 | suspend { | |
| 839 | frame = @frame(); | |
| 840 | } | |
| 841 | return 1234; | |
| 842 | } | |
| 843 | }; | |
| 844 | _ = async S.doTheTest(); | |
| 845 | resume S.frame; | |
| 846 | expect(S.ok); | |
| 847 | } | |
| 848 | ||
| 849 | test "cast fn to async fn when it is inferred to be async, awaited directly" { | |
| 850 | const S = struct { | |
| 851 | var frame: anyframe = undefined; | |
| 852 | var ok = false; | |
| 853 | ||
| 854 | fn doTheTest() void { | |
| 855 | var ptr: fn () callconv(.Async) i32 = undefined; | |
| 856 | ptr = func; | |
| 857 | var buf: [100]u8 align(16) = undefined; | |
| 858 | var result: i32 = undefined; | |
| 859 | _ = await @asyncCall(&buf, &result, ptr, .{}); | |
| 860 | expect(result == 1234); | |
| 861 | ok = true; | |
| 862 | } | |
| 863 | ||
| 864 | fn func() i32 { | |
| 865 | suspend { | |
| 866 | frame = @frame(); | |
| 867 | } | |
| 868 | return 1234; | |
| 869 | } | |
| 870 | }; | |
| 871 | _ = async S.doTheTest(); | |
| 872 | resume S.frame; | |
| 873 | expect(S.ok); | |
| 874 | } | |
| 875 | ||
| 876 | test "await does not force async if callee is blocking" { | |
| 877 | const S = struct { | |
| 878 | fn simple() i32 { | |
| 879 | return 1234; | |
| 880 | } | |
| 881 | }; | |
| 882 | var x = async S.simple(); | |
| 883 | expect(await x == 1234); | |
| 884 | } | |
| 885 | ||
| 886 | test "recursive async function" { | |
| 887 | expect(recursiveAsyncFunctionTest(false).doTheTest() == 55); | |
| 888 | expect(recursiveAsyncFunctionTest(true).doTheTest() == 55); | |
| 889 | } | |
| 890 | ||
| 891 | fn recursiveAsyncFunctionTest(comptime suspending_implementation: bool) type { | |
| 892 | return struct { | |
| 893 | fn fib(allocator: *std.mem.Allocator, x: u32) error{OutOfMemory}!u32 { | |
| 894 | if (x <= 1) return x; | |
| 895 | ||
| 896 | if (suspending_implementation) { | |
| 897 | suspend { | |
| 898 | resume @frame(); | |
| 899 | } | |
| 900 | } | |
| 901 | ||
| 902 | const f1 = try allocator.create(@Frame(fib)); | |
| 903 | defer allocator.destroy(f1); | |
| 904 | ||
| 905 | const f2 = try allocator.create(@Frame(fib)); | |
| 906 | defer allocator.destroy(f2); | |
| 907 | ||
| 908 | f1.* = async fib(allocator, x - 1); | |
| 909 | var f1_awaited = false; | |
| 910 | errdefer if (!f1_awaited) { | |
| 911 | _ = await f1; | |
| 912 | }; | |
| 913 | ||
| 914 | f2.* = async fib(allocator, x - 2); | |
| 915 | var f2_awaited = false; | |
| 916 | errdefer if (!f2_awaited) { | |
| 917 | _ = await f2; | |
| 918 | }; | |
| 919 | ||
| 920 | var sum: u32 = 0; | |
| 921 | ||
| 922 | f1_awaited = true; | |
| 923 | sum += try await f1; | |
| 924 | ||
| 925 | f2_awaited = true; | |
| 926 | sum += try await f2; | |
| 927 | ||
| 928 | return sum; | |
| 929 | } | |
| 930 | ||
| 931 | fn doTheTest() u32 { | |
| 932 | if (suspending_implementation) { | |
| 933 | var result: u32 = undefined; | |
| 934 | _ = async amain(&result); | |
| 935 | return result; | |
| 936 | } else { | |
| 937 | return fib(std.testing.allocator, 10) catch unreachable; | |
| 938 | } | |
| 939 | } | |
| 940 | ||
| 941 | fn amain(result: *u32) void { | |
| 942 | var x = async fib(std.testing.allocator, 10); | |
| 943 | result.* = (await x) catch unreachable; | |
| 944 | } | |
| 945 | }; | |
| 946 | } | |
| 947 | ||
| 948 | test "@asyncCall with comptime-known function, but not awaited directly" { | |
| 949 | const S = struct { | |
| 950 | var global_frame: anyframe = undefined; | |
| 951 | ||
| 952 | fn doTheTest() void { | |
| 953 | var frame: [1]@Frame(middle) = undefined; | |
| 954 | var result: @typeInfo(@typeInfo(@TypeOf(middle)).Fn.return_type.?).ErrorUnion.error_set!void = undefined; | |
| 955 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle, .{}); | |
| 956 | resume global_frame; | |
| 957 | std.testing.expectError(error.Fail, result); | |
| 958 | } | |
| 959 | fn middle() callconv(.Async) !void { | |
| 960 | var f = async middle2(); | |
| 961 | return await f; | |
| 962 | } | |
| 963 | ||
| 964 | fn middle2() !void { | |
| 965 | return failing(); | |
| 966 | } | |
| 967 | ||
| 968 | fn failing() !void { | |
| 969 | global_frame = @frame(); | |
| 970 | suspend {} | |
| 971 | return error.Fail; | |
| 972 | } | |
| 973 | }; | |
| 974 | S.doTheTest(); | |
| 975 | } | |
| 976 | ||
| 977 | test "@asyncCall with actual frame instead of byte buffer" { | |
| 978 | const S = struct { | |
| 979 | fn func() i32 { | |
| 980 | suspend {} | |
| 981 | return 1234; | |
| 982 | } | |
| 983 | }; | |
| 984 | var frame: @Frame(S.func) = undefined; | |
| 985 | var result: i32 = undefined; | |
| 986 | const ptr = @asyncCall(&frame, &result, S.func, .{}); | |
| 987 | resume ptr; | |
| 988 | expect(result == 1234); | |
| 989 | } | |
| 990 | ||
| 991 | test "@asyncCall using the result location inside the frame" { | |
| 992 | const S = struct { | |
| 993 | fn simple2(y: *i32) callconv(.Async) i32 { | |
| 994 | defer y.* += 2; | |
| 995 | y.* += 1; | |
| 996 | suspend {} | |
| 997 | return 1234; | |
| 998 | } | |
| 999 | fn getAnswer(f: anyframe->i32, out: *i32) void { | |
| 1000 | out.* = await f; | |
| 1001 | } | |
| 1002 | }; | |
| 1003 | var data: i32 = 1; | |
| 1004 | const Foo = struct { | |
| 1005 | bar: fn (*i32) callconv(.Async) i32, | |
| 1006 | }; | |
| 1007 | var foo = Foo{ .bar = S.simple2 }; | |
| 1008 | var bytes: [64]u8 align(16) = undefined; | |
| 1009 | const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); | |
| 1010 | comptime expect(@TypeOf(f) == anyframe->i32); | |
| 1011 | expect(data == 2); | |
| 1012 | resume f; | |
| 1013 | expect(data == 4); | |
| 1014 | _ = async S.getAnswer(f, &data); | |
| 1015 | expect(data == 1234); | |
| 1016 | } | |
| 1017 | ||
| 1018 | test "@TypeOf an async function call of generic fn with error union type" { | |
| 1019 | const S = struct { | |
| 1020 | fn func(comptime x: anytype) anyerror!i32 { | |
| 1021 | const T = @TypeOf(async func(x)); | |
| 1022 | comptime expect(T == @typeInfo(@TypeOf(@frame())).Pointer.child); | |
| 1023 | return undefined; | |
| 1024 | } | |
| 1025 | }; | |
| 1026 | _ = async S.func(i32); | |
| 1027 | } | |
| 1028 | ||
| 1029 | test "using @TypeOf on a generic function call" { | |
| 1030 | const S = struct { | |
| 1031 | var global_frame: anyframe = undefined; | |
| 1032 | var global_ok = false; | |
| 1033 | ||
| 1034 | var buf: [100]u8 align(16) = undefined; | |
| 1035 | ||
| 1036 | fn amain(x: anytype) void { | |
| 1037 | if (x == 0) { | |
| 1038 | global_ok = true; | |
| 1039 | return; | |
| 1040 | } | |
| 1041 | suspend { | |
| 1042 | global_frame = @frame(); | |
| 1043 | } | |
| 1044 | const F = @TypeOf(async amain(x - 1)); | |
| 1045 | const frame = @intToPtr(*F, @ptrToInt(&buf)); | |
| 1046 | return await @asyncCall(frame, {}, amain, .{x - 1}); | |
| 1047 | } | |
| 1048 | }; | |
| 1049 | _ = async S.amain(@as(u32, 1)); | |
| 1050 | resume S.global_frame; | |
| 1051 | expect(S.global_ok); | |
| 1052 | } | |
| 1053 | ||
| 1054 | test "recursive call of await @asyncCall with struct return type" { | |
| 1055 | const S = struct { | |
| 1056 | var global_frame: anyframe = undefined; | |
| 1057 | var global_ok = false; | |
| 1058 | ||
| 1059 | var buf: [100]u8 align(16) = undefined; | |
| 1060 | ||
| 1061 | fn amain(x: anytype) Foo { | |
| 1062 | if (x == 0) { | |
| 1063 | global_ok = true; | |
| 1064 | return Foo{ .x = 1, .y = 2, .z = 3 }; | |
| 1065 | } | |
| 1066 | suspend { | |
| 1067 | global_frame = @frame(); | |
| 1068 | } | |
| 1069 | const F = @TypeOf(async amain(x - 1)); | |
| 1070 | const frame = @intToPtr(*F, @ptrToInt(&buf)); | |
| 1071 | return await @asyncCall(frame, {}, amain, .{x - 1}); | |
| 1072 | } | |
| 1073 | ||
| 1074 | const Foo = struct { | |
| 1075 | x: u64, | |
| 1076 | y: u64, | |
| 1077 | z: u64, | |
| 1078 | }; | |
| 1079 | }; | |
| 1080 | var res: S.Foo = undefined; | |
| 1081 | var frame: @TypeOf(async S.amain(@as(u32, 1))) = undefined; | |
| 1082 | _ = @asyncCall(&frame, &res, S.amain, .{@as(u32, 1)}); | |
| 1083 | resume S.global_frame; | |
| 1084 | expect(S.global_ok); | |
| 1085 | expect(res.x == 1); | |
| 1086 | expect(res.y == 2); | |
| 1087 | expect(res.z == 3); | |
| 1088 | } | |
| 1089 | ||
| 1090 | test "nosuspend function call" { | |
| 1091 | const S = struct { | |
| 1092 | fn doTheTest() void { | |
| 1093 | const result = nosuspend add(50, 100); | |
| 1094 | expect(result == 150); | |
| 1095 | } | |
| 1096 | fn add(a: i32, b: i32) i32 { | |
| 1097 | if (a > 100) { | |
| 1098 | suspend {} | |
| 1099 | } | |
| 1100 | return a + b; | |
| 1101 | } | |
| 1102 | }; | |
| 1103 | S.doTheTest(); | |
| 1104 | } | |
| 1105 | ||
| 1106 | test "await used in expression and awaiting fn with no suspend but async calling convention" { | |
| 1107 | const S = struct { | |
| 1108 | fn atest() void { | |
| 1109 | var f1 = async add(1, 2); | |
| 1110 | var f2 = async add(3, 4); | |
| 1111 | ||
| 1112 | const sum = (await f1) + (await f2); | |
| 1113 | expect(sum == 10); | |
| 1114 | } | |
| 1115 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1116 | return a + b; | |
| 1117 | } | |
| 1118 | }; | |
| 1119 | _ = async S.atest(); | |
| 1120 | } | |
| 1121 | ||
| 1122 | test "await used in expression after a fn call" { | |
| 1123 | const S = struct { | |
| 1124 | fn atest() void { | |
| 1125 | var f1 = async add(3, 4); | |
| 1126 | var sum: i32 = 0; | |
| 1127 | sum = foo() + await f1; | |
| 1128 | expect(sum == 8); | |
| 1129 | } | |
| 1130 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1131 | return a + b; | |
| 1132 | } | |
| 1133 | fn foo() i32 { | |
| 1134 | return 1; | |
| 1135 | } | |
| 1136 | }; | |
| 1137 | _ = async S.atest(); | |
| 1138 | } | |
| 1139 | ||
| 1140 | test "async fn call used in expression after a fn call" { | |
| 1141 | const S = struct { | |
| 1142 | fn atest() void { | |
| 1143 | var sum: i32 = 0; | |
| 1144 | sum = foo() + add(3, 4); | |
| 1145 | expect(sum == 8); | |
| 1146 | } | |
| 1147 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1148 | return a + b; | |
| 1149 | } | |
| 1150 | fn foo() i32 { | |
| 1151 | return 1; | |
| 1152 | } | |
| 1153 | }; | |
| 1154 | _ = async S.atest(); | |
| 1155 | } | |
| 1156 | ||
| 1157 | test "suspend in for loop" { | |
| 1158 | const S = struct { | |
| 1159 | var global_frame: ?anyframe = null; | |
| 1160 | ||
| 1161 | fn doTheTest() void { | |
| 1162 | _ = async atest(); | |
| 1163 | while (global_frame) |f| resume f; | |
| 1164 | } | |
| 1165 | ||
| 1166 | fn atest() void { | |
| 1167 | expect(func(&[_]u8{ 1, 2, 3 }) == 6); | |
| 1168 | } | |
| 1169 | fn func(stuff: []const u8) u32 { | |
| 1170 | global_frame = @frame(); | |
| 1171 | var sum: u32 = 0; | |
| 1172 | for (stuff) |x| { | |
| 1173 | suspend {} | |
| 1174 | sum += x; | |
| 1175 | } | |
| 1176 | global_frame = null; | |
| 1177 | return sum; | |
| 1178 | } | |
| 1179 | }; | |
| 1180 | S.doTheTest(); | |
| 1181 | } | |
| 1182 | ||
| 1183 | test "suspend in while loop" { | |
| 1184 | const S = struct { | |
| 1185 | var global_frame: ?anyframe = null; | |
| 1186 | ||
| 1187 | fn doTheTest() void { | |
| 1188 | _ = async atest(); | |
| 1189 | while (global_frame) |f| resume f; | |
| 1190 | } | |
| 1191 | ||
| 1192 | fn atest() void { | |
| 1193 | expect(optional(6) == 6); | |
| 1194 | expect(errunion(6) == 6); | |
| 1195 | } | |
| 1196 | fn optional(stuff: ?u32) u32 { | |
| 1197 | global_frame = @frame(); | |
| 1198 | defer global_frame = null; | |
| 1199 | while (stuff) |val| { | |
| 1200 | suspend {} | |
| 1201 | return val; | |
| 1202 | } | |
| 1203 | return 0; | |
| 1204 | } | |
| 1205 | fn errunion(stuff: anyerror!u32) u32 { | |
| 1206 | global_frame = @frame(); | |
| 1207 | defer global_frame = null; | |
| 1208 | while (stuff) |val| { | |
| 1209 | suspend {} | |
| 1210 | return val; | |
| 1211 | } else |err| { | |
| 1212 | return 0; | |
| 1213 | } | |
| 1214 | } | |
| 1215 | }; | |
| 1216 | S.doTheTest(); | |
| 1217 | } | |
| 1218 | ||
| 1219 | test "correctly spill when returning the error union result of another async fn" { | |
| 1220 | const S = struct { | |
| 1221 | var global_frame: anyframe = undefined; | |
| 1222 | ||
| 1223 | fn doTheTest() void { | |
| 1224 | expect((atest() catch unreachable) == 1234); | |
| 1225 | } | |
| 1226 | ||
| 1227 | fn atest() !i32 { | |
| 1228 | return fallible1(); | |
| 1229 | } | |
| 1230 | ||
| 1231 | fn fallible1() anyerror!i32 { | |
| 1232 | suspend { | |
| 1233 | global_frame = @frame(); | |
| 1234 | } | |
| 1235 | return 1234; | |
| 1236 | } | |
| 1237 | }; | |
| 1238 | _ = async S.doTheTest(); | |
| 1239 | resume S.global_frame; | |
| 1240 | } | |
| 1241 | ||
| 1242 | test "spill target expr in a for loop" { | |
| 1243 | const S = struct { | |
| 1244 | var global_frame: anyframe = undefined; | |
| 1245 | ||
| 1246 | fn doTheTest() void { | |
| 1247 | var foo = Foo{ | |
| 1248 | .slice = &[_]i32{ 1, 2 }, | |
| 1249 | }; | |
| 1250 | expect(atest(&foo) == 3); | |
| 1251 | } | |
| 1252 | ||
| 1253 | const Foo = struct { | |
| 1254 | slice: []const i32, | |
| 1255 | }; | |
| 1256 | ||
| 1257 | fn atest(foo: *Foo) i32 { | |
| 1258 | var sum: i32 = 0; | |
| 1259 | for (foo.slice) |x| { | |
| 1260 | suspend { | |
| 1261 | global_frame = @frame(); | |
| 1262 | } | |
| 1263 | sum += x; | |
| 1264 | } | |
| 1265 | return sum; | |
| 1266 | } | |
| 1267 | }; | |
| 1268 | _ = async S.doTheTest(); | |
| 1269 | resume S.global_frame; | |
| 1270 | resume S.global_frame; | |
| 1271 | } | |
| 1272 | ||
| 1273 | test "spill target expr in a for loop, with a var decl in the loop body" { | |
| 1274 | const S = struct { | |
| 1275 | var global_frame: anyframe = undefined; | |
| 1276 | ||
| 1277 | fn doTheTest() void { | |
| 1278 | var foo = Foo{ | |
| 1279 | .slice = &[_]i32{ 1, 2 }, | |
| 1280 | }; | |
| 1281 | expect(atest(&foo) == 3); | |
| 1282 | } | |
| 1283 | ||
| 1284 | const Foo = struct { | |
| 1285 | slice: []const i32, | |
| 1286 | }; | |
| 1287 | ||
| 1288 | fn atest(foo: *Foo) i32 { | |
| 1289 | var sum: i32 = 0; | |
| 1290 | for (foo.slice) |x| { | |
| 1291 | // Previously this var decl would prevent spills. This test makes sure | |
| 1292 | // the for loop spills still happen even though there is a VarDecl in scope | |
| 1293 | // before the suspend. | |
| 1294 | var anything = true; | |
| 1295 | _ = anything; | |
| 1296 | suspend { | |
| 1297 | global_frame = @frame(); | |
| 1298 | } | |
| 1299 | sum += x; | |
| 1300 | } | |
| 1301 | return sum; | |
| 1302 | } | |
| 1303 | }; | |
| 1304 | _ = async S.doTheTest(); | |
| 1305 | resume S.global_frame; | |
| 1306 | resume S.global_frame; | |
| 1307 | } | |
| 1308 | ||
| 1309 | test "async call with @call" { | |
| 1310 | const S = struct { | |
| 1311 | var global_frame: anyframe = undefined; | |
| 1312 | fn doTheTest() void { | |
| 1313 | _ = @call(.{ .modifier = .async_kw }, atest, .{}); | |
| 1314 | resume global_frame; | |
| 1315 | } | |
| 1316 | fn atest() void { | |
| 1317 | var frame = @call(.{ .modifier = .async_kw }, afoo, .{}); | |
| 1318 | const res = await frame; | |
| 1319 | expect(res == 42); | |
| 1320 | } | |
| 1321 | fn afoo() i32 { | |
| 1322 | suspend { | |
| 1323 | global_frame = @frame(); | |
| 1324 | } | |
| 1325 | return 42; | |
| 1326 | } | |
| 1327 | }; | |
| 1328 | S.doTheTest(); | |
| 1329 | } | |
| 1330 | ||
| 1331 | test "async function passed 0-bit arg after non-0-bit arg" { | |
| 1332 | const S = struct { | |
| 1333 | var global_frame: anyframe = undefined; | |
| 1334 | var global_int: i32 = 0; | |
| 1335 | ||
| 1336 | fn foo() void { | |
| 1337 | bar(1, .{}) catch unreachable; | |
| 1338 | } | |
| 1339 | ||
| 1340 | fn bar(x: i32, args: anytype) anyerror!void { | |
| 1341 | global_frame = @frame(); | |
| 1342 | suspend {} | |
| 1343 | global_int = x; | |
| 1344 | } | |
| 1345 | }; | |
| 1346 | _ = async S.foo(); | |
| 1347 | resume S.global_frame; | |
| 1348 | expect(S.global_int == 1); | |
| 1349 | } | |
| 1350 | ||
| 1351 | test "async function passed align(16) arg after align(8) arg" { | |
| 1352 | const S = struct { | |
| 1353 | var global_frame: anyframe = undefined; | |
| 1354 | var global_int: u128 = 0; | |
| 1355 | ||
| 1356 | fn foo() void { | |
| 1357 | var a: u128 = 99; | |
| 1358 | bar(10, .{a}) catch unreachable; | |
| 1359 | } | |
| 1360 | ||
| 1361 | fn bar(x: u64, args: anytype) anyerror!void { | |
| 1362 | expect(x == 10); | |
| 1363 | global_frame = @frame(); | |
| 1364 | suspend {} | |
| 1365 | global_int = args[0]; | |
| 1366 | } | |
| 1367 | }; | |
| 1368 | _ = async S.foo(); | |
| 1369 | resume S.global_frame; | |
| 1370 | expect(S.global_int == 99); | |
| 1371 | } | |
| 1372 | ||
| 1373 | test "async function call resolves target fn frame, comptime func" { | |
| 1374 | const S = struct { | |
| 1375 | var global_frame: anyframe = undefined; | |
| 1376 | var global_int: i32 = 9; | |
| 1377 | ||
| 1378 | fn foo() anyerror!void { | |
| 1379 | const stack_size = 1000; | |
| 1380 | var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined; | |
| 1381 | return await @asyncCall(&stack_frame, {}, bar, .{}); | |
| 1382 | } | |
| 1383 | ||
| 1384 | fn bar() anyerror!void { | |
| 1385 | global_frame = @frame(); | |
| 1386 | suspend {} | |
| 1387 | global_int += 1; | |
| 1388 | } | |
| 1389 | }; | |
| 1390 | _ = async S.foo(); | |
| 1391 | resume S.global_frame; | |
| 1392 | expect(S.global_int == 10); | |
| 1393 | } | |
| 1394 | ||
| 1395 | test "async function call resolves target fn frame, runtime func" { | |
| 1396 | const S = struct { | |
| 1397 | var global_frame: anyframe = undefined; | |
| 1398 | var global_int: i32 = 9; | |
| 1399 | ||
| 1400 | fn foo() anyerror!void { | |
| 1401 | const stack_size = 1000; | |
| 1402 | var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined; | |
| 1403 | var func: fn () callconv(.Async) anyerror!void = bar; | |
| 1404 | return await @asyncCall(&stack_frame, {}, func, .{}); | |
| 1405 | } | |
| 1406 | ||
| 1407 | fn bar() anyerror!void { | |
| 1408 | global_frame = @frame(); | |
| 1409 | suspend {} | |
| 1410 | global_int += 1; | |
| 1411 | } | |
| 1412 | }; | |
| 1413 | _ = async S.foo(); | |
| 1414 | resume S.global_frame; | |
| 1415 | expect(S.global_int == 10); | |
| 1416 | } | |
| 1417 | ||
| 1418 | test "properly spill optional payload capture value" { | |
| 1419 | const S = struct { | |
| 1420 | var global_frame: anyframe = undefined; | |
| 1421 | var global_int: usize = 2; | |
| 1422 | ||
| 1423 | fn foo() void { | |
| 1424 | var opt: ?usize = 1234; | |
| 1425 | if (opt) |x| { | |
| 1426 | bar(); | |
| 1427 | global_int += x; | |
| 1428 | } | |
| 1429 | } | |
| 1430 | ||
| 1431 | fn bar() void { | |
| 1432 | global_frame = @frame(); | |
| 1433 | suspend {} | |
| 1434 | global_int += 1; | |
| 1435 | } | |
| 1436 | }; | |
| 1437 | _ = async S.foo(); | |
| 1438 | resume S.global_frame; | |
| 1439 | expect(S.global_int == 1237); | |
| 1440 | } | |
| 1441 | ||
| 1442 | test "handle defer interfering with return value spill" { | |
| 1443 | const S = struct { | |
| 1444 | var global_frame1: anyframe = undefined; | |
| 1445 | var global_frame2: anyframe = undefined; | |
| 1446 | var finished = false; | |
| 1447 | var baz_happened = false; | |
| 1448 | ||
| 1449 | fn doTheTest() void { | |
| 1450 | _ = async testFoo(); | |
| 1451 | resume global_frame1; | |
| 1452 | resume global_frame2; | |
| 1453 | expect(baz_happened); | |
| 1454 | expect(finished); | |
| 1455 | } | |
| 1456 | ||
| 1457 | fn testFoo() void { | |
| 1458 | expectError(error.Bad, foo()); | |
| 1459 | finished = true; | |
| 1460 | } | |
| 1461 | ||
| 1462 | fn foo() anyerror!void { | |
| 1463 | defer baz(); | |
| 1464 | return bar() catch |err| return err; | |
| 1465 | } | |
| 1466 | ||
| 1467 | fn bar() anyerror!void { | |
| 1468 | global_frame1 = @frame(); | |
| 1469 | suspend {} | |
| 1470 | return error.Bad; | |
| 1471 | } | |
| 1472 | ||
| 1473 | fn baz() void { | |
| 1474 | global_frame2 = @frame(); | |
| 1475 | suspend {} | |
| 1476 | baz_happened = true; | |
| 1477 | } | |
| 1478 | }; | |
| 1479 | S.doTheTest(); | |
| 1480 | } | |
| 1481 | ||
| 1482 | test "take address of temporary async frame" { | |
| 1483 | const S = struct { | |
| 1484 | var global_frame: anyframe = undefined; | |
| 1485 | var finished = false; | |
| 1486 | ||
| 1487 | fn doTheTest() void { | |
| 1488 | _ = async asyncDoTheTest(); | |
| 1489 | resume global_frame; | |
| 1490 | expect(finished); | |
| 1491 | } | |
| 1492 | ||
| 1493 | fn asyncDoTheTest() void { | |
| 1494 | expect(finishIt(&async foo(10)) == 1245); | |
| 1495 | finished = true; | |
| 1496 | } | |
| 1497 | ||
| 1498 | fn foo(arg: i32) i32 { | |
| 1499 | global_frame = @frame(); | |
| 1500 | suspend {} | |
| 1501 | return arg + 1234; | |
| 1502 | } | |
| 1503 | ||
| 1504 | fn finishIt(frame: anyframe->i32) i32 { | |
| 1505 | return (await frame) + 1; | |
| 1506 | } | |
| 1507 | }; | |
| 1508 | S.doTheTest(); | |
| 1509 | } | |
| 1510 | ||
| 1511 | test "nosuspend await" { | |
| 1512 | const S = struct { | |
| 1513 | var finished = false; | |
| 1514 | ||
| 1515 | fn doTheTest() void { | |
| 1516 | var frame = async foo(false); | |
| 1517 | expect(nosuspend await frame == 42); | |
| 1518 | finished = true; | |
| 1519 | } | |
| 1520 | ||
| 1521 | fn foo(want_suspend: bool) i32 { | |
| 1522 | if (want_suspend) { | |
| 1523 | suspend {} | |
| 1524 | } | |
| 1525 | return 42; | |
| 1526 | } | |
| 1527 | }; | |
| 1528 | S.doTheTest(); | |
| 1529 | expect(S.finished); | |
| 1530 | } | |
| 1531 | ||
| 1532 | test "nosuspend on function calls" { | |
| 1533 | const S0 = struct { | |
| 1534 | b: i32 = 42, | |
| 1535 | }; | |
| 1536 | const S1 = struct { | |
| 1537 | fn c() S0 { | |
| 1538 | return S0{}; | |
| 1539 | } | |
| 1540 | fn d() !S0 { | |
| 1541 | return S0{}; | |
| 1542 | } | |
| 1543 | }; | |
| 1544 | expectEqual(@as(i32, 42), nosuspend S1.c().b); | |
| 1545 | expectEqual(@as(i32, 42), (try nosuspend S1.d()).b); | |
| 1546 | } | |
| 1547 | ||
| 1548 | test "nosuspend on async function calls" { | |
| 1549 | const S0 = struct { | |
| 1550 | b: i32 = 42, | |
| 1551 | }; | |
| 1552 | const S1 = struct { | |
| 1553 | fn c() S0 { | |
| 1554 | return S0{}; | |
| 1555 | } | |
| 1556 | fn d() !S0 { | |
| 1557 | return S0{}; | |
| 1558 | } | |
| 1559 | }; | |
| 1560 | var frame_c = nosuspend async S1.c(); | |
| 1561 | expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1562 | var frame_d = nosuspend async S1.d(); | |
| 1563 | expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1564 | } | |
| 1565 | ||
| 1566 | // test "resume nosuspend async function calls" { | |
| 1567 | // const S0 = struct { | |
| 1568 | // b: i32 = 42, | |
| 1569 | // }; | |
| 1570 | // const S1 = struct { | |
| 1571 | // fn c() S0 { | |
| 1572 | // suspend {} | |
| 1573 | // return S0{}; | |
| 1574 | // } | |
| 1575 | // fn d() !S0 { | |
| 1576 | // suspend {} | |
| 1577 | // return S0{}; | |
| 1578 | // } | |
| 1579 | // }; | |
| 1580 | // var frame_c = nosuspend async S1.c(); | |
| 1581 | // resume frame_c; | |
| 1582 | // expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1583 | // var frame_d = nosuspend async S1.d(); | |
| 1584 | // resume frame_d; | |
| 1585 | // expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1586 | // } | |
| 1587 | ||
| 1588 | test "nosuspend resume async function calls" { | |
| 1589 | const S0 = struct { | |
| 1590 | b: i32 = 42, | |
| 1591 | }; | |
| 1592 | const S1 = struct { | |
| 1593 | fn c() S0 { | |
| 1594 | suspend {} | |
| 1595 | return S0{}; | |
| 1596 | } | |
| 1597 | fn d() !S0 { | |
| 1598 | suspend {} | |
| 1599 | return S0{}; | |
| 1600 | } | |
| 1601 | }; | |
| 1602 | var frame_c = async S1.c(); | |
| 1603 | nosuspend resume frame_c; | |
| 1604 | expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1605 | var frame_d = async S1.d(); | |
| 1606 | nosuspend resume frame_d; | |
| 1607 | expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1608 | } | |
| 1609 | ||
| 1610 | test "avoid forcing frame alignment resolution implicit cast to *c_void" { | |
| 1611 | const S = struct { | |
| 1612 | var x: ?*c_void = null; | |
| 1613 | ||
| 1614 | fn foo() bool { | |
| 1615 | suspend { | |
| 1616 | x = @frame(); | |
| 1617 | } | |
| 1618 | return true; | |
| 1619 | } | |
| 1620 | }; | |
| 1621 | var frame = async S.foo(); | |
| 1622 | resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x)); | |
| 1623 | expect(nosuspend await frame); | |
| 1624 | } | |
| 1625 | ||
| 1626 | test "@asyncCall with pass-by-value arguments" { | |
| 1627 | const F0: u64 = 0xbeefbeefbeefbeef; | |
| 1628 | const F1: u64 = 0xf00df00df00df00d; | |
| 1629 | const F2: u64 = 0xcafecafecafecafe; | |
| 1630 | ||
| 1631 | const S = struct { | |
| 1632 | pub const ST = struct { f0: usize, f1: usize }; | |
| 1633 | pub const AT = [5]u8; | |
| 1634 | ||
| 1635 | pub fn f(_fill0: u64, s: ST, _fill1: u64, a: AT, _fill2: u64) callconv(.Async) void { | |
| 1636 | // Check that the array and struct arguments passed by value don't | |
| 1637 | // end up overflowing the adjacent fields in the frame structure. | |
| 1638 | expectEqual(F0, _fill0); | |
| 1639 | expectEqual(F1, _fill1); | |
| 1640 | expectEqual(F2, _fill2); | |
| 1641 | } | |
| 1642 | }; | |
| 1643 | ||
| 1644 | var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined; | |
| 1645 | // The function pointer must not be comptime-known. | |
| 1646 | var t = S.f; | |
| 1647 | var frame_ptr = @asyncCall(&buffer, {}, t, .{ | |
| 1648 | F0, | |
| 1649 | .{ .f0 = 1, .f1 = 2 }, | |
| 1650 | F1, | |
| 1651 | [_]u8{ 1, 2, 3, 4, 5 }, | |
| 1652 | F2, | |
| 1653 | }); | |
| 1654 | } | |
| 1655 | ||
| 1656 | test "@asyncCall with arguments having non-standard alignment" { | |
| 1657 | const F0: u64 = 0xbeefbeef; | |
| 1658 | const F1: u64 = 0xf00df00df00df00d; | |
| 1659 | ||
| 1660 | const S = struct { | |
| 1661 | pub fn f(_fill0: u32, s: struct { x: u64 align(16) }, _fill1: u64) callconv(.Async) void { | |
| 1662 | // The compiler inserts extra alignment for s, check that the | |
| 1663 | // generated code picks the right slot for fill1. | |
| 1664 | expectEqual(F0, _fill0); | |
| 1665 | expectEqual(F1, _fill1); | |
| 1666 | } | |
| 1667 | }; | |
| 1668 | ||
| 1669 | var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined; | |
| 1670 | // The function pointer must not be comptime-known. | |
| 1671 | var t = S.f; | |
| 1672 | var frame_ptr = @asyncCall(&buffer, {}, t, .{ F0, undefined, F1 }); | |
| 1673 | } |
test/behavior/atomics.zig created+221| ... | ... | @@ -0,0 +1,221 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const builtin = @import("builtin"); | |
| 5 | ||
| 6 | test "cmpxchg" { | |
| 7 | testCmpxchg(); | |
| 8 | comptime testCmpxchg(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testCmpxchg() void { | |
| 12 | var x: i32 = 1234; | |
| 13 | if (@cmpxchgWeak(i32, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 14 | expect(x1 == 1234); | |
| 15 | } else { | |
| 16 | @panic("cmpxchg should have failed"); | |
| 17 | } | |
| 18 | ||
| 19 | while (@cmpxchgWeak(i32, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 20 | expect(x1 == 1234); | |
| 21 | } | |
| 22 | expect(x == 5678); | |
| 23 | ||
| 24 | expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null); | |
| 25 | expect(x == 42); | |
| 26 | } | |
| 27 | ||
| 28 | test "fence" { | |
| 29 | var x: i32 = 1234; | |
| 30 | @fence(.SeqCst); | |
| 31 | x = 5678; | |
| 32 | } | |
| 33 | ||
| 34 | test "atomicrmw and atomicload" { | |
| 35 | var data: u8 = 200; | |
| 36 | testAtomicRmw(&data); | |
| 37 | expect(data == 42); | |
| 38 | testAtomicLoad(&data); | |
| 39 | } | |
| 40 | ||
| 41 | fn testAtomicRmw(ptr: *u8) void { | |
| 42 | const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst); | |
| 43 | expect(prev_value == 200); | |
| 44 | comptime { | |
| 45 | var x: i32 = 1234; | |
| 46 | const y: i32 = 12345; | |
| 47 | expect(@atomicLoad(i32, &x, .SeqCst) == 1234); | |
| 48 | expect(@atomicLoad(i32, &y, .SeqCst) == 12345); | |
| 49 | } | |
| 50 | } | |
| 51 | ||
| 52 | fn testAtomicLoad(ptr: *u8) void { | |
| 53 | const x = @atomicLoad(u8, ptr, .SeqCst); | |
| 54 | expect(x == 42); | |
| 55 | } | |
| 56 | ||
| 57 | test "cmpxchg with ptr" { | |
| 58 | var data1: i32 = 1234; | |
| 59 | var data2: i32 = 5678; | |
| 60 | var data3: i32 = 9101; | |
| 61 | var x: *i32 = &data1; | |
| 62 | if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| { | |
| 63 | expect(x1 == &data1); | |
| 64 | } else { | |
| 65 | @panic("cmpxchg should have failed"); | |
| 66 | } | |
| 67 | ||
| 68 | while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| { | |
| 69 | expect(x1 == &data1); | |
| 70 | } | |
| 71 | expect(x == &data3); | |
| 72 | ||
| 73 | expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null); | |
| 74 | expect(x == &data2); | |
| 75 | } | |
| 76 | ||
| 77 | // TODO this test is disabled until this issue is resolved: | |
| 78 | // https://github.com/ziglang/zig/issues/2883 | |
| 79 | // otherwise cross compiling will result in: | |
| 80 | // lld: error: undefined symbol: __sync_val_compare_and_swap_16 | |
| 81 | //test "128-bit cmpxchg" { | |
| 82 | // var x: u128 align(16) = 1234; // TODO: https://github.com/ziglang/zig/issues/2987 | |
| 83 | // if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 84 | // expect(x1 == 1234); | |
| 85 | // } else { | |
| 86 | // @panic("cmpxchg should have failed"); | |
| 87 | // } | |
| 88 | // | |
| 89 | // while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 90 | // expect(x1 == 1234); | |
| 91 | // } | |
| 92 | // expect(x == 5678); | |
| 93 | // | |
| 94 | // expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null); | |
| 95 | // expect(x == 42); | |
| 96 | //} | |
| 97 | ||
| 98 | test "cmpxchg with ignored result" { | |
| 99 | var x: i32 = 1234; | |
| 100 | var ptr = &x; | |
| 101 | ||
| 102 | _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic); | |
| 103 | ||
| 104 | expectEqual(@as(i32, 5678), x); | |
| 105 | } | |
| 106 | ||
| 107 | var a_global_variable = @as(u32, 1234); | |
| 108 | ||
| 109 | test "cmpxchg on a global variable" { | |
| 110 | _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic); | |
| 111 | expectEqual(@as(u32, 42), a_global_variable); | |
| 112 | } | |
| 113 | ||
| 114 | test "atomic load and rmw with enum" { | |
| 115 | const Value = enum(u8) { | |
| 116 | a, | |
| 117 | b, | |
| 118 | c, | |
| 119 | }; | |
| 120 | var x = Value.a; | |
| 121 | ||
| 122 | expect(@atomicLoad(Value, &x, .SeqCst) != .b); | |
| 123 | ||
| 124 | _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst); | |
| 125 | expect(@atomicLoad(Value, &x, .SeqCst) == .c); | |
| 126 | expect(@atomicLoad(Value, &x, .SeqCst) != .a); | |
| 127 | expect(@atomicLoad(Value, &x, .SeqCst) != .b); | |
| 128 | } | |
| 129 | ||
| 130 | test "atomic store" { | |
| 131 | var x: u32 = 0; | |
| 132 | @atomicStore(u32, &x, 1, .SeqCst); | |
| 133 | expect(@atomicLoad(u32, &x, .SeqCst) == 1); | |
| 134 | @atomicStore(u32, &x, 12345678, .SeqCst); | |
| 135 | expect(@atomicLoad(u32, &x, .SeqCst) == 12345678); | |
| 136 | } | |
| 137 | ||
| 138 | test "atomic store comptime" { | |
| 139 | comptime testAtomicStore(); | |
| 140 | testAtomicStore(); | |
| 141 | } | |
| 142 | ||
| 143 | fn testAtomicStore() void { | |
| 144 | var x: u32 = 0; | |
| 145 | @atomicStore(u32, &x, 1, .SeqCst); | |
| 146 | expect(@atomicLoad(u32, &x, .SeqCst) == 1); | |
| 147 | @atomicStore(u32, &x, 12345678, .SeqCst); | |
| 148 | expect(@atomicLoad(u32, &x, .SeqCst) == 12345678); | |
| 149 | } | |
| 150 | ||
| 151 | test "atomicrmw with floats" { | |
| 152 | if (builtin.target.cpu.arch == .aarch64 or | |
| 153 | builtin.target.cpu.arch == .arm or | |
| 154 | builtin.target.cpu.arch == .riscv64) | |
| 155 | { | |
| 156 | // https://github.com/ziglang/zig/issues/4457 | |
| 157 | return error.SkipZigTest; | |
| 158 | } | |
| 159 | testAtomicRmwFloat(); | |
| 160 | comptime testAtomicRmwFloat(); | |
| 161 | } | |
| 162 | ||
| 163 | fn testAtomicRmwFloat() void { | |
| 164 | var x: f32 = 0; | |
| 165 | expect(x == 0); | |
| 166 | _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst); | |
| 167 | expect(x == 1); | |
| 168 | _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst); | |
| 169 | expect(x == 6); | |
| 170 | _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst); | |
| 171 | expect(x == 4); | |
| 172 | } | |
| 173 | ||
| 174 | test "atomicrmw with ints" { | |
| 175 | testAtomicRmwInt(); | |
| 176 | comptime testAtomicRmwInt(); | |
| 177 | } | |
| 178 | ||
| 179 | fn testAtomicRmwInt() void { | |
| 180 | var x: u8 = 1; | |
| 181 | var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst); | |
| 182 | expect(x == 3 and res == 1); | |
| 183 | _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst); | |
| 184 | expect(x == 6); | |
| 185 | _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst); | |
| 186 | expect(x == 5); | |
| 187 | _ = @atomicRmw(u8, &x, .And, 4, .SeqCst); | |
| 188 | expect(x == 4); | |
| 189 | _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst); | |
| 190 | expect(x == 0xfb); | |
| 191 | _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst); | |
| 192 | expect(x == 0xff); | |
| 193 | _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst); | |
| 194 | expect(x == 0xfd); | |
| 195 | ||
| 196 | _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst); | |
| 197 | expect(x == 0xfd); | |
| 198 | _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst); | |
| 199 | expect(x == 1); | |
| 200 | } | |
| 201 | ||
| 202 | test "atomics with different types" { | |
| 203 | testAtomicsWithType(bool, true, false); | |
| 204 | inline for (.{ u1, i5, u15 }) |T| { | |
| 205 | var x: T = 0; | |
| 206 | testAtomicsWithType(T, 0, 1); | |
| 207 | } | |
| 208 | testAtomicsWithType(u0, 0, 0); | |
| 209 | testAtomicsWithType(i0, 0, 0); | |
| 210 | } | |
| 211 | ||
| 212 | fn testAtomicsWithType(comptime T: type, a: T, b: T) void { | |
| 213 | var x: T = b; | |
| 214 | @atomicStore(T, &x, a, .SeqCst); | |
| 215 | expect(x == a); | |
| 216 | expect(@atomicLoad(T, &x, .SeqCst) == a); | |
| 217 | expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a); | |
| 218 | expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null); | |
| 219 | if (@sizeOf(T) != 0) | |
| 220 | expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a); | |
| 221 | } |
test/behavior/await_struct.zig created+44| ... | ... | @@ -0,0 +1,44 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | const Foo = struct { | |
| 6 | x: i32, | |
| 7 | }; | |
| 8 | ||
| 9 | var await_a_promise: anyframe = undefined; | |
| 10 | var await_final_result = Foo{ .x = 0 }; | |
| 11 | ||
| 12 | test "coroutine await struct" { | |
| 13 | await_seq('a'); | |
| 14 | var p = async await_amain(); | |
| 15 | await_seq('f'); | |
| 16 | resume await_a_promise; | |
| 17 | await_seq('i'); | |
| 18 | expect(await_final_result.x == 1234); | |
| 19 | expect(std.mem.eql(u8, &await_points, "abcdefghi")); | |
| 20 | } | |
| 21 | fn await_amain() callconv(.Async) void { | |
| 22 | await_seq('b'); | |
| 23 | var p = async await_another(); | |
| 24 | await_seq('e'); | |
| 25 | await_final_result = await p; | |
| 26 | await_seq('h'); | |
| 27 | } | |
| 28 | fn await_another() callconv(.Async) Foo { | |
| 29 | await_seq('c'); | |
| 30 | suspend { | |
| 31 | await_seq('d'); | |
| 32 | await_a_promise = @frame(); | |
| 33 | } | |
| 34 | await_seq('g'); | |
| 35 | return Foo{ .x = 1234 }; | |
| 36 | } | |
| 37 | ||
| 38 | var await_points = [_]u8{0} ** "abcdefghi".len; | |
| 39 | var await_seq_index: usize = 0; | |
| 40 | ||
| 41 | fn await_seq(c: u8) void { | |
| 42 | await_points[await_seq_index] = c; | |
| 43 | await_seq_index += 1; | |
| 44 | } |
test/behavior/bit_shifting.zig created+104| ... | ... | @@ -0,0 +1,104 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type { | |
| 5 | const key_bits = @typeInfo(Key).Int.bits; | |
| 6 | expect(Key == std.meta.Int(.unsigned, key_bits)); | |
| 7 | expect(key_bits >= mask_bit_count); | |
| 8 | const shard_key_bits = mask_bit_count; | |
| 9 | const ShardKey = std.meta.Int(.unsigned, mask_bit_count); | |
| 10 | const shift_amount = key_bits - shard_key_bits; | |
| 11 | return struct { | |
| 12 | const Self = @This(); | |
| 13 | shards: [1 << shard_key_bits]?*Node, | |
| 14 | ||
| 15 | pub fn create() Self { | |
| 16 | return Self{ .shards = [_]?*Node{null} ** (1 << shard_key_bits) }; | |
| 17 | } | |
| 18 | ||
| 19 | fn getShardKey(key: Key) ShardKey { | |
| 20 | // https://github.com/ziglang/zig/issues/1544 | |
| 21 | // this special case is needed because you can't u32 >> 32. | |
| 22 | if (ShardKey == u0) return 0; | |
| 23 | ||
| 24 | // this can be u1 >> u0 | |
| 25 | const shard_key = key >> shift_amount; | |
| 26 | ||
| 27 | // TODO: https://github.com/ziglang/zig/issues/1544 | |
| 28 | // This cast could be implicit if we teach the compiler that | |
| 29 | // u32 >> 30 -> u2 | |
| 30 | return @intCast(ShardKey, shard_key); | |
| 31 | } | |
| 32 | ||
| 33 | pub fn put(self: *Self, node: *Node) void { | |
| 34 | const shard_key = Self.getShardKey(node.key); | |
| 35 | node.next = self.shards[shard_key]; | |
| 36 | self.shards[shard_key] = node; | |
| 37 | } | |
| 38 | ||
| 39 | pub fn get(self: *Self, key: Key) ?*Node { | |
| 40 | const shard_key = Self.getShardKey(key); | |
| 41 | var maybe_node = self.shards[shard_key]; | |
| 42 | while (maybe_node) |node| : (maybe_node = node.next) { | |
| 43 | if (node.key == key) return node; | |
| 44 | } | |
| 45 | return null; | |
| 46 | } | |
| 47 | ||
| 48 | pub const Node = struct { | |
| 49 | key: Key, | |
| 50 | value: V, | |
| 51 | next: ?*Node, | |
| 52 | ||
| 53 | pub fn init(self: *Node, key: Key, value: V) void { | |
| 54 | self.key = key; | |
| 55 | self.value = value; | |
| 56 | self.next = null; | |
| 57 | } | |
| 58 | }; | |
| 59 | }; | |
| 60 | } | |
| 61 | ||
| 62 | test "sharded table" { | |
| 63 | // realistic 16-way sharding | |
| 64 | testShardedTable(u32, 4, 8); | |
| 65 | ||
| 66 | testShardedTable(u5, 0, 32); // ShardKey == u0 | |
| 67 | testShardedTable(u5, 2, 32); | |
| 68 | testShardedTable(u5, 5, 32); | |
| 69 | ||
| 70 | testShardedTable(u1, 0, 2); | |
| 71 | testShardedTable(u1, 1, 2); // this does u1 >> u0 | |
| 72 | ||
| 73 | testShardedTable(u0, 0, 1); | |
| 74 | } | |
| 75 | fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime node_count: comptime_int) void { | |
| 76 | const Table = ShardedTable(Key, mask_bit_count, void); | |
| 77 | ||
| 78 | var table = Table.create(); | |
| 79 | var node_buffer: [node_count]Table.Node = undefined; | |
| 80 | for (node_buffer) |*node, i| { | |
| 81 | const key = @intCast(Key, i); | |
| 82 | expect(table.get(key) == null); | |
| 83 | node.init(key, {}); | |
| 84 | table.put(node); | |
| 85 | } | |
| 86 | ||
| 87 | for (node_buffer) |*node, i| { | |
| 88 | expect(table.get(@intCast(Key, i)) == node); | |
| 89 | } | |
| 90 | } | |
| 91 | ||
| 92 | // #2225 | |
| 93 | test "comptime shr of BigInt" { | |
| 94 | comptime { | |
| 95 | var n0 = 0xdeadbeef0000000000000000; | |
| 96 | std.debug.assert(n0 >> 64 == 0xdeadbeef); | |
| 97 | var n1 = 17908056155735594659; | |
| 98 | std.debug.assert(n1 >> 64 == 0); | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | test "comptime shift safety check" { | |
| 103 | const x = @as(usize, 42) << @sizeOf(usize); | |
| 104 | } |
test/behavior/bitcast.zig created+197| ... | ... | @@ -0,0 +1,197 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 7 | ||
| 8 | test "@bitCast i32 -> u32" { | |
| 9 | testBitCast_i32_u32(); | |
| 10 | comptime testBitCast_i32_u32(); | |
| 11 | } | |
| 12 | ||
| 13 | fn testBitCast_i32_u32() void { | |
| 14 | expect(conv(-1) == maxInt(u32)); | |
| 15 | expect(conv2(maxInt(u32)) == -1); | |
| 16 | } | |
| 17 | ||
| 18 | fn conv(x: i32) u32 { | |
| 19 | return @bitCast(u32, x); | |
| 20 | } | |
| 21 | fn conv2(x: u32) i32 { | |
| 22 | return @bitCast(i32, x); | |
| 23 | } | |
| 24 | ||
| 25 | test "@bitCast extern enum to its integer type" { | |
| 26 | const SOCK = extern enum { | |
| 27 | A, | |
| 28 | B, | |
| 29 | ||
| 30 | fn testBitCastExternEnum() void { | |
| 31 | var SOCK_DGRAM = @This().B; | |
| 32 | var sock_dgram = @bitCast(c_int, SOCK_DGRAM); | |
| 33 | expect(sock_dgram == 1); | |
| 34 | } | |
| 35 | }; | |
| 36 | ||
| 37 | SOCK.testBitCastExternEnum(); | |
| 38 | comptime SOCK.testBitCastExternEnum(); | |
| 39 | } | |
| 40 | ||
| 41 | test "@bitCast packed structs at runtime and comptime" { | |
| 42 | const Full = packed struct { | |
| 43 | number: u16, | |
| 44 | }; | |
| 45 | const Divided = packed struct { | |
| 46 | half1: u8, | |
| 47 | quarter3: u4, | |
| 48 | quarter4: u4, | |
| 49 | }; | |
| 50 | const S = struct { | |
| 51 | fn doTheTest() void { | |
| 52 | var full = Full{ .number = 0x1234 }; | |
| 53 | var two_halves = @bitCast(Divided, full); | |
| 54 | switch (native_endian) { | |
| 55 | .Big => { | |
| 56 | expect(two_halves.half1 == 0x12); | |
| 57 | expect(two_halves.quarter3 == 0x3); | |
| 58 | expect(two_halves.quarter4 == 0x4); | |
| 59 | }, | |
| 60 | .Little => { | |
| 61 | expect(two_halves.half1 == 0x34); | |
| 62 | expect(two_halves.quarter3 == 0x2); | |
| 63 | expect(two_halves.quarter4 == 0x1); | |
| 64 | }, | |
| 65 | } | |
| 66 | } | |
| 67 | }; | |
| 68 | S.doTheTest(); | |
| 69 | comptime S.doTheTest(); | |
| 70 | } | |
| 71 | ||
| 72 | test "@bitCast extern structs at runtime and comptime" { | |
| 73 | const Full = extern struct { | |
| 74 | number: u16, | |
| 75 | }; | |
| 76 | const TwoHalves = extern struct { | |
| 77 | half1: u8, | |
| 78 | half2: u8, | |
| 79 | }; | |
| 80 | const S = struct { | |
| 81 | fn doTheTest() void { | |
| 82 | var full = Full{ .number = 0x1234 }; | |
| 83 | var two_halves = @bitCast(TwoHalves, full); | |
| 84 | switch (native_endian) { | |
| 85 | .Big => { | |
| 86 | expect(two_halves.half1 == 0x12); | |
| 87 | expect(two_halves.half2 == 0x34); | |
| 88 | }, | |
| 89 | .Little => { | |
| 90 | expect(two_halves.half1 == 0x34); | |
| 91 | expect(two_halves.half2 == 0x12); | |
| 92 | }, | |
| 93 | } | |
| 94 | } | |
| 95 | }; | |
| 96 | S.doTheTest(); | |
| 97 | comptime S.doTheTest(); | |
| 98 | } | |
| 99 | ||
| 100 | test "bitcast packed struct to integer and back" { | |
| 101 | const LevelUpMove = packed struct { | |
| 102 | move_id: u9, | |
| 103 | level: u7, | |
| 104 | }; | |
| 105 | const S = struct { | |
| 106 | fn doTheTest() void { | |
| 107 | var move = LevelUpMove{ .move_id = 1, .level = 2 }; | |
| 108 | var v = @bitCast(u16, move); | |
| 109 | var back_to_a_move = @bitCast(LevelUpMove, v); | |
| 110 | expect(back_to_a_move.move_id == 1); | |
| 111 | expect(back_to_a_move.level == 2); | |
| 112 | } | |
| 113 | }; | |
| 114 | S.doTheTest(); | |
| 115 | comptime S.doTheTest(); | |
| 116 | } | |
| 117 | ||
| 118 | test "implicit cast to error union by returning" { | |
| 119 | const S = struct { | |
| 120 | fn entry() void { | |
| 121 | expect((func(-1) catch unreachable) == maxInt(u64)); | |
| 122 | } | |
| 123 | pub fn func(sz: i64) anyerror!u64 { | |
| 124 | return @bitCast(u64, sz); | |
| 125 | } | |
| 126 | }; | |
| 127 | S.entry(); | |
| 128 | comptime S.entry(); | |
| 129 | } | |
| 130 | ||
| 131 | // issue #3010: compiler segfault | |
| 132 | test "bitcast literal [4]u8 param to u32" { | |
| 133 | const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 }); | |
| 134 | expect(ip == maxInt(u32)); | |
| 135 | } | |
| 136 | ||
| 137 | test "bitcast packed struct literal to byte" { | |
| 138 | const Foo = packed struct { | |
| 139 | value: u8, | |
| 140 | }; | |
| 141 | const casted = @bitCast(u8, Foo{ .value = 0xF }); | |
| 142 | expect(casted == 0xf); | |
| 143 | } | |
| 144 | ||
| 145 | test "comptime bitcast used in expression has the correct type" { | |
| 146 | const Foo = packed struct { | |
| 147 | value: u8, | |
| 148 | }; | |
| 149 | expect(@bitCast(u8, Foo{ .value = 0xF }) == 0xf); | |
| 150 | } | |
| 151 | ||
| 152 | test "bitcast result to _" { | |
| 153 | _ = @bitCast(u8, @as(i8, 1)); | |
| 154 | } | |
| 155 | ||
| 156 | test "nested bitcast" { | |
| 157 | const S = struct { | |
| 158 | fn moo(x: isize) void { | |
| 159 | @import("std").testing.expectEqual(@intCast(isize, 42), x); | |
| 160 | } | |
| 161 | ||
| 162 | fn foo(x: isize) void { | |
| 163 | @This().moo( | |
| 164 | @bitCast(isize, if (x != 0) @bitCast(usize, x) else @bitCast(usize, x)), | |
| 165 | ); | |
| 166 | } | |
| 167 | }; | |
| 168 | ||
| 169 | S.foo(42); | |
| 170 | comptime S.foo(42); | |
| 171 | } | |
| 172 | ||
| 173 | test "bitcast passed as tuple element" { | |
| 174 | const S = struct { | |
| 175 | fn foo(args: anytype) void { | |
| 176 | comptime expect(@TypeOf(args[0]) == f32); | |
| 177 | expect(args[0] == 12.34); | |
| 178 | } | |
| 179 | }; | |
| 180 | S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))}); | |
| 181 | } | |
| 182 | ||
| 183 | test "triple level result location with bitcast sandwich passed as tuple element" { | |
| 184 | const S = struct { | |
| 185 | fn foo(args: anytype) void { | |
| 186 | comptime expect(@TypeOf(args[0]) == f64); | |
| 187 | expect(args[0] > 12.33 and args[0] < 12.35); | |
| 188 | } | |
| 189 | }; | |
| 190 | S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))}); | |
| 191 | } | |
| 192 | ||
| 193 | test "bitcast generates a temporary value" { | |
| 194 | var y = @as(u16, 0x55AA); | |
| 195 | const x = @bitCast(u16, @bitCast([2]u8, y)); | |
| 196 | expectEqual(y, x); | |
| 197 | } |
test/behavior/bitreverse.zig created+69| ... | ... | @@ -0,0 +1,69 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const minInt = std.math.minInt; | |
| 4 | ||
| 5 | test "@bitReverse" { | |
| 6 | comptime testBitReverse(); | |
| 7 | testBitReverse(); | |
| 8 | } | |
| 9 | ||
| 10 | fn testBitReverse() void { | |
| 11 | // using comptime_ints, unsigned | |
| 12 | expect(@bitReverse(u0, 0) == 0); | |
| 13 | expect(@bitReverse(u5, 0x12) == 0x9); | |
| 14 | expect(@bitReverse(u8, 0x12) == 0x48); | |
| 15 | expect(@bitReverse(u16, 0x1234) == 0x2c48); | |
| 16 | expect(@bitReverse(u24, 0x123456) == 0x6a2c48); | |
| 17 | expect(@bitReverse(u32, 0x12345678) == 0x1e6a2c48); | |
| 18 | expect(@bitReverse(u40, 0x123456789a) == 0x591e6a2c48); | |
| 19 | expect(@bitReverse(u48, 0x123456789abc) == 0x3d591e6a2c48); | |
| 20 | expect(@bitReverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48); | |
| 21 | expect(@bitReverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48); | |
| 22 | expect(@bitReverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 23 | ||
| 24 | // using runtime uints, unsigned | |
| 25 | var num0: u0 = 0; | |
| 26 | expect(@bitReverse(u0, num0) == 0); | |
| 27 | var num5: u5 = 0x12; | |
| 28 | expect(@bitReverse(u5, num5) == 0x9); | |
| 29 | var num8: u8 = 0x12; | |
| 30 | expect(@bitReverse(u8, num8) == 0x48); | |
| 31 | var num16: u16 = 0x1234; | |
| 32 | expect(@bitReverse(u16, num16) == 0x2c48); | |
| 33 | var num24: u24 = 0x123456; | |
| 34 | expect(@bitReverse(u24, num24) == 0x6a2c48); | |
| 35 | var num32: u32 = 0x12345678; | |
| 36 | expect(@bitReverse(u32, num32) == 0x1e6a2c48); | |
| 37 | var num40: u40 = 0x123456789a; | |
| 38 | expect(@bitReverse(u40, num40) == 0x591e6a2c48); | |
| 39 | var num48: u48 = 0x123456789abc; | |
| 40 | expect(@bitReverse(u48, num48) == 0x3d591e6a2c48); | |
| 41 | var num56: u56 = 0x123456789abcde; | |
| 42 | expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48); | |
| 43 | var num64: u64 = 0x123456789abcdef1; | |
| 44 | expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48); | |
| 45 | var num128: u128 = 0x123456789abcdef11121314151617181; | |
| 46 | expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 47 | ||
| 48 | // using comptime_ints, signed, positive | |
| 49 | expect(@bitReverse(u8, @as(u8, 0)) == 0); | |
| 50 | expect(@bitReverse(i8, @bitCast(i8, @as(u8, 0x92))) == @bitCast(i8, @as(u8, 0x49))); | |
| 51 | expect(@bitReverse(i16, @bitCast(i16, @as(u16, 0x1234))) == @bitCast(i16, @as(u16, 0x2c48))); | |
| 52 | expect(@bitReverse(i24, @bitCast(i24, @as(u24, 0x123456))) == @bitCast(i24, @as(u24, 0x6a2c48))); | |
| 53 | expect(@bitReverse(i32, @bitCast(i32, @as(u32, 0x12345678))) == @bitCast(i32, @as(u32, 0x1e6a2c48))); | |
| 54 | expect(@bitReverse(i40, @bitCast(i40, @as(u40, 0x123456789a))) == @bitCast(i40, @as(u40, 0x591e6a2c48))); | |
| 55 | expect(@bitReverse(i48, @bitCast(i48, @as(u48, 0x123456789abc))) == @bitCast(i48, @as(u48, 0x3d591e6a2c48))); | |
| 56 | expect(@bitReverse(i56, @bitCast(i56, @as(u56, 0x123456789abcde))) == @bitCast(i56, @as(u56, 0x7b3d591e6a2c48))); | |
| 57 | expect(@bitReverse(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1))) == @bitCast(i64, @as(u64, 0x8f7b3d591e6a2c48))); | |
| 58 | expect(@bitReverse(i128, @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181))) == @bitCast(i128, @as(u128, 0x818e868a828c84888f7b3d591e6a2c48))); | |
| 59 | ||
| 60 | // using signed, negative. Compare to runtime ints returned from llvm. | |
| 61 | var neg8: i8 = -18; | |
| 62 | expect(@bitReverse(i8, @as(i8, -18)) == @bitReverse(i8, neg8)); | |
| 63 | var neg16: i16 = -32694; | |
| 64 | expect(@bitReverse(i16, @as(i16, -32694)) == @bitReverse(i16, neg16)); | |
| 65 | var neg24: i24 = -6773785; | |
| 66 | expect(@bitReverse(i24, @as(i24, -6773785)) == @bitReverse(i24, neg24)); | |
| 67 | var neg32: i32 = -16773785; | |
| 68 | expect(@bitReverse(i32, @as(i32, -16773785)) == @bitReverse(i32, neg32)); | |
| 69 | } |
test/behavior/bool.zig created+35| ... | ... | @@ -0,0 +1,35 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "bool literals" { | |
| 4 | expect(true); | |
| 5 | expect(!false); | |
| 6 | } | |
| 7 | ||
| 8 | test "cast bool to int" { | |
| 9 | const t = true; | |
| 10 | const f = false; | |
| 11 | expect(@boolToInt(t) == @as(u32, 1)); | |
| 12 | expect(@boolToInt(f) == @as(u32, 0)); | |
| 13 | nonConstCastBoolToInt(t, f); | |
| 14 | } | |
| 15 | ||
| 16 | fn nonConstCastBoolToInt(t: bool, f: bool) void { | |
| 17 | expect(@boolToInt(t) == @as(u32, 1)); | |
| 18 | expect(@boolToInt(f) == @as(u32, 0)); | |
| 19 | } | |
| 20 | ||
| 21 | test "bool cmp" { | |
| 22 | expect(testBoolCmp(true, false) == false); | |
| 23 | } | |
| 24 | fn testBoolCmp(a: bool, b: bool) bool { | |
| 25 | return a == b; | |
| 26 | } | |
| 27 | ||
| 28 | const global_f = false; | |
| 29 | const global_t = true; | |
| 30 | const not_global_f = !global_f; | |
| 31 | const not_global_t = !global_t; | |
| 32 | test "compile time bool not" { | |
| 33 | expect(not_global_f); | |
| 34 | expect(!not_global_t); | |
| 35 | } |
test/behavior/bugs/1025.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const A = struct { | |
| 2 | B: type, | |
| 3 | }; | |
| 4 | ||
| 5 | fn getA() A { | |
| 6 | return A{ .B = u8 }; | |
| 7 | } | |
| 8 | ||
| 9 | test "bug 1025" { | |
| 10 | const a = getA(); | |
| 11 | @import("std").testing.expect(a.B == u8); | |
| 12 | } |
test/behavior/bugs/1076.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "comptime code should not modify constant data" { | |
| 6 | testCastPtrOfArrayToSliceAndPtr(); | |
| 7 | comptime testCastPtrOfArrayToSliceAndPtr(); | |
| 8 | } | |
| 9 | ||
| 10 | fn testCastPtrOfArrayToSliceAndPtr() void { | |
| 11 | { | |
| 12 | var array = "aoeu".*; | |
| 13 | const x: [*]u8 = &array; | |
| 14 | x[0] += 1; | |
| 15 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 16 | } | |
| 17 | { | |
| 18 | var array: [4]u8 = "aoeu".*; | |
| 19 | const x: [*]u8 = &array; | |
| 20 | x[0] += 1; | |
| 21 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 22 | } | |
| 23 | } |
test/behavior/bugs/1111.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const Foo = extern enum { | |
| 2 | Bar = -1, | |
| 3 | }; | |
| 4 | ||
| 5 | test "issue 1111 fixed" { | |
| 6 | const v = Foo.Bar; | |
| 7 | ||
| 8 | switch (v) { | |
| 9 | Foo.Bar => return, | |
| 10 | } | |
| 11 | } |
test/behavior/bugs/1120.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const A = packed struct { | |
| 5 | a: u2, | |
| 6 | b: u6, | |
| 7 | }; | |
| 8 | const B = packed struct { | |
| 9 | q: u8, | |
| 10 | a: u2, | |
| 11 | b: u6, | |
| 12 | }; | |
| 13 | test "bug 1120" { | |
| 14 | var a = A{ .a = 2, .b = 2 }; | |
| 15 | var b = B{ .q = 22, .a = 3, .b = 2 }; | |
| 16 | var t: usize = 0; | |
| 17 | const ptr = switch (t) { | |
| 18 | 0 => &a.a, | |
| 19 | 1 => &b.a, | |
| 20 | else => unreachable, | |
| 21 | }; | |
| 22 | expect(ptr.* == 2); | |
| 23 | } |
test/behavior/bugs/1277.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const S = struct { | |
| 4 | f: ?fn () i32, | |
| 5 | }; | |
| 6 | ||
| 7 | const s = S{ .f = f }; | |
| 8 | ||
| 9 | fn f() i32 { | |
| 10 | return 1234; | |
| 11 | } | |
| 12 | ||
| 13 | test "don't emit an LLVM global for a const function when it's in an optional in a struct" { | |
| 14 | std.testing.expect(s.f.?() == 1234); | |
| 15 | } |
test/behavior/bugs/1310.zig created+24| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | pub const VM = ?[*]const struct_InvocationTable_; | |
| 5 | pub const struct_InvocationTable_ = extern struct { | |
| 6 | GetVM: ?fn (?[*]VM) callconv(.C) c_int, | |
| 7 | }; | |
| 8 | ||
| 9 | pub const struct_VM_ = extern struct { | |
| 10 | functions: ?[*]const struct_InvocationTable_, | |
| 11 | }; | |
| 12 | ||
| 13 | //excised output from stdlib.h etc | |
| 14 | ||
| 15 | pub const InvocationTable_ = struct_InvocationTable_; | |
| 16 | pub const VM_ = struct_VM_; | |
| 17 | ||
| 18 | fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 { | |
| 19 | return 11; | |
| 20 | } | |
| 21 | ||
| 22 | test "fixed" { | |
| 23 | expect(agent_callback(undefined, undefined) == 11); | |
| 24 | } |
test/behavior/bugs/1322.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const B = union(enum) { | |
| 4 | c: C, | |
| 5 | None, | |
| 6 | }; | |
| 7 | ||
| 8 | const A = struct { | |
| 9 | b: B, | |
| 10 | }; | |
| 11 | ||
| 12 | const C = struct {}; | |
| 13 | ||
| 14 | test "tagged union with all void fields but a meaningful tag" { | |
| 15 | var a: A = A{ .b = B{ .c = C{} } }; | |
| 16 | std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).c); | |
| 17 | a = A{ .b = B.None }; | |
| 18 | std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).None); | |
| 19 | } |
test/behavior/bugs/1381.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const B = union(enum) { | |
| 4 | D: u8, | |
| 5 | E: u16, | |
| 6 | }; | |
| 7 | ||
| 8 | const A = union(enum) { | |
| 9 | B: B, | |
| 10 | C: u8, | |
| 11 | }; | |
| 12 | ||
| 13 | test "union that needs padding bytes inside an array" { | |
| 14 | var as = [_]A{ | |
| 15 | A{ .B = B{ .D = 1 } }, | |
| 16 | A{ .B = B{ .D = 1 } }, | |
| 17 | }; | |
| 18 | ||
| 19 | const a = as[0].B; | |
| 20 | std.testing.expect(a.D == 1); | |
| 21 | } |
test/behavior/bugs/1421.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const S = struct { | |
| 5 | fn method() std.builtin.TypeInfo { | |
| 6 | return @typeInfo(S); | |
| 7 | } | |
| 8 | }; | |
| 9 | ||
| 10 | test "functions with return type required to be comptime are generic" { | |
| 11 | const ti = S.method(); | |
| 12 | expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct); | |
| 13 | } |
test/behavior/bugs/1442.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const Union = union(enum) { | |
| 4 | Text: []const u8, | |
| 5 | Color: u32, | |
| 6 | }; | |
| 7 | ||
| 8 | test "const error union field alignment" { | |
| 9 | var union_or_err: anyerror!Union = Union{ .Color = 1234 }; | |
| 10 | std.testing.expect((union_or_err catch unreachable).Color == 1234); | |
| 11 | } |
test/behavior/bugs/1467.zig created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | pub const E = enum(u32) { A, B, C }; | |
| 2 | pub const S = extern struct { | |
| 3 | e: E, | |
| 4 | }; | |
| 5 | test "bug 1467" { | |
| 6 | const s: S = undefined; | |
| 7 | } |
test/behavior/bugs/1486.zig created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const ptr = &global; | |
| 4 | var global: u64 = 123; | |
| 5 | ||
| 6 | test "constant pointer to global variable causes runtime load" { | |
| 7 | global = 1234; | |
| 8 | expect(&global == ptr); | |
| 9 | expect(ptr.* == 1234); | |
| 10 | } |
test/behavior/bugs/1500.zig created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | const A = struct { | |
| 2 | b: B, | |
| 3 | }; | |
| 4 | ||
| 5 | const B = fn (A) void; | |
| 6 | ||
| 7 | test "allow these dependencies" { | |
| 8 | var a: A = undefined; | |
| 9 | var b: B = undefined; | |
| 10 | } |
test/behavior/bugs/1607.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | ||
| 4 | const a = [_]u8{ 1, 2, 3 }; | |
| 5 | ||
| 6 | fn checkAddress(s: []const u8) void { | |
| 7 | for (s) |*i, j| { | |
| 8 | testing.expect(i == &a[j]); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | test "slices pointing at the same address as global array." { | |
| 13 | checkAddress(&a); | |
| 14 | comptime checkAddress(&a); | |
| 15 | } |
test/behavior/bugs/1735.zig created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const mystruct = struct { | |
| 4 | pending: ?listofstructs, | |
| 5 | }; | |
| 6 | pub fn TailQueue(comptime T: type) type { | |
| 7 | return struct { | |
| 8 | const Self = @This(); | |
| 9 | ||
| 10 | pub const Node = struct { | |
| 11 | prev: ?*Node, | |
| 12 | next: ?*Node, | |
| 13 | data: T, | |
| 14 | }; | |
| 15 | ||
| 16 | first: ?*Node, | |
| 17 | last: ?*Node, | |
| 18 | len: usize, | |
| 19 | ||
| 20 | pub fn init() Self { | |
| 21 | return Self{ | |
| 22 | .first = null, | |
| 23 | .last = null, | |
| 24 | .len = 0, | |
| 25 | }; | |
| 26 | } | |
| 27 | }; | |
| 28 | } | |
| 29 | const listofstructs = TailQueue(mystruct); | |
| 30 | ||
| 31 | const a = struct { | |
| 32 | const Self = @This(); | |
| 33 | ||
| 34 | foo: listofstructs, | |
| 35 | ||
| 36 | pub fn init() Self { | |
| 37 | return Self{ | |
| 38 | .foo = listofstructs.init(), | |
| 39 | }; | |
| 40 | } | |
| 41 | }; | |
| 42 | ||
| 43 | test "intialization" { | |
| 44 | var t = a.init(); | |
| 45 | std.testing.expect(t.foo.len == 0); | |
| 46 | } |
test/behavior/bugs/1741.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "fixed" { | |
| 4 | const x: f32 align(128) = 12.34; | |
| 5 | std.testing.expect(@ptrToInt(&x) % 128 == 0); | |
| 6 | } |
test/behavior/bugs/1851.zig created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "allocation and looping over 3-byte integer" { | |
| 5 | expect(@sizeOf(u24) == 4); | |
| 6 | expect(@sizeOf([1]u24) == 4); | |
| 7 | expect(@alignOf(u24) == 4); | |
| 8 | expect(@alignOf([1]u24) == 4); | |
| 9 | ||
| 10 | var x = try std.testing.allocator.alloc(u24, 2); | |
| 11 | defer std.testing.allocator.free(x); | |
| 12 | expect(x.len == 2); | |
| 13 | x[0] = 0xFFFFFF; | |
| 14 | x[1] = 0xFFFFFF; | |
| 15 | ||
| 16 | const bytes = std.mem.sliceAsBytes(x); | |
| 17 | expect(@TypeOf(bytes) == []align(4) u8); | |
| 18 | expect(bytes.len == 8); | |
| 19 | ||
| 20 | for (bytes) |*b| { | |
| 21 | b.* = 0x00; | |
| 22 | } | |
| 23 | ||
| 24 | expect(x[0] == 0x00); | |
| 25 | expect(x[1] == 0x00); | |
| 26 | } |
test/behavior/bugs/1914.zig created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const A = struct { | |
| 4 | b_list_pointer: *const []B, | |
| 5 | }; | |
| 6 | const B = struct { | |
| 7 | a_pointer: *const A, | |
| 8 | }; | |
| 9 | ||
| 10 | const b_list: []B = &[_]B{}; | |
| 11 | const a = A{ .b_list_pointer = &b_list }; | |
| 12 | ||
| 13 | test "segfault bug" { | |
| 14 | const assert = std.debug.assert; | |
| 15 | const obj = B{ .a_pointer = &a }; | |
| 16 | assert(obj.a_pointer == &a); // this makes zig crash | |
| 17 | } | |
| 18 | ||
| 19 | const A2 = struct { | |
| 20 | pointer: *B, | |
| 21 | }; | |
| 22 | ||
| 23 | pub const B2 = struct { | |
| 24 | pointer_array: []*A2, | |
| 25 | }; | |
| 26 | ||
| 27 | var b_value = B2{ .pointer_array = &[_]*A2{} }; | |
| 28 | ||
| 29 | test "basic stuff" { | |
| 30 | std.debug.assert(&b_value == &b_value); | |
| 31 | } |
test/behavior/bugs/2006.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const S = struct { | |
| 5 | p: *S, | |
| 6 | }; | |
| 7 | test "bug 2006" { | |
| 8 | var a: S = undefined; | |
| 9 | a = S{ .p = undefined }; | |
| 10 | expect(@sizeOf(S) != 0); | |
| 11 | expect(@sizeOf(*void) == 0); | |
| 12 | } |
test/behavior/bugs/2114.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const math = std.math; | |
| 4 | ||
| 5 | fn ctz(x: anytype) usize { | |
| 6 | return @ctz(@TypeOf(x), x); | |
| 7 | } | |
| 8 | ||
| 9 | test "fixed" { | |
| 10 | testClz(); | |
| 11 | comptime testClz(); | |
| 12 | } | |
| 13 | ||
| 14 | fn testClz() void { | |
| 15 | expect(ctz(@as(u128, 0x40000000000000000000000000000000)) == 126); | |
| 16 | expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000)); | |
| 17 | expect(ctz(@as(u128, 0x80000000000000000000000000000000)) == 127); | |
| 18 | expect(ctz(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127); | |
| 19 | } |
test/behavior/bugs/2346.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | test "fixed" { | |
| 2 | const a: *void = undefined; | |
| 3 | const b: *[1]void = a; | |
| 4 | const c: *[0]u8 = undefined; | |
| 5 | const d: []u8 = c; | |
| 6 | } |
test/behavior/bugs/2578.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const Foo = struct { | |
| 2 | y: u8, | |
| 3 | }; | |
| 4 | ||
| 5 | var foo: Foo = undefined; | |
| 6 | const t = &foo; | |
| 7 | ||
| 8 | fn bar(pointer: ?*c_void) void {} | |
| 9 | ||
| 10 | test "fixed" { | |
| 11 | bar(t); | |
| 12 | } |
test/behavior/bugs/2692.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | fn foo(a: []u8) void {} | |
| 2 | ||
| 3 | test "address of 0 length array" { | |
| 4 | var pt: [0]u8 = undefined; | |
| 5 | foo(&pt); | |
| 6 | } |
test/behavior/bugs/2889.zig created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const source = "A-"; | |
| 4 | ||
| 5 | fn parseNote() ?i32 { | |
| 6 | const letter = source[0]; | |
| 7 | const modifier = source[1]; | |
| 8 | ||
| 9 | const semitone = blk: { | |
| 10 | if (letter == 'C' and modifier == '-') break :blk @as(i32, 0); | |
| 11 | if (letter == 'C' and modifier == '#') break :blk @as(i32, 1); | |
| 12 | if (letter == 'D' and modifier == '-') break :blk @as(i32, 2); | |
| 13 | if (letter == 'D' and modifier == '#') break :blk @as(i32, 3); | |
| 14 | if (letter == 'E' and modifier == '-') break :blk @as(i32, 4); | |
| 15 | if (letter == 'F' and modifier == '-') break :blk @as(i32, 5); | |
| 16 | if (letter == 'F' and modifier == '#') break :blk @as(i32, 6); | |
| 17 | if (letter == 'G' and modifier == '-') break :blk @as(i32, 7); | |
| 18 | if (letter == 'G' and modifier == '#') break :blk @as(i32, 8); | |
| 19 | if (letter == 'A' and modifier == '-') break :blk @as(i32, 9); | |
| 20 | if (letter == 'A' and modifier == '#') break :blk @as(i32, 10); | |
| 21 | if (letter == 'B' and modifier == '-') break :blk @as(i32, 11); | |
| 22 | return null; | |
| 23 | }; | |
| 24 | ||
| 25 | return semitone; | |
| 26 | } | |
| 27 | ||
| 28 | test "fixed" { | |
| 29 | const result = parseNote(); | |
| 30 | std.testing.expect(result.? == 9); | |
| 31 | } |
test/behavior/bugs/3007.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | free: bool, | |
| 5 | ||
| 6 | pub const FooError = error{NotFree}; | |
| 7 | }; | |
| 8 | ||
| 9 | var foo = Foo{ .free = true }; | |
| 10 | var default_foo: ?*Foo = null; | |
| 11 | ||
| 12 | fn get_foo() Foo.FooError!*Foo { | |
| 13 | if (foo.free) { | |
| 14 | foo.free = false; | |
| 15 | return &foo; | |
| 16 | } | |
| 17 | return error.NotFree; | |
| 18 | } | |
| 19 | ||
| 20 | test "fixed" { | |
| 21 | default_foo = get_foo() catch null; // This Line | |
| 22 | std.testing.expect(!default_foo.?.free); | |
| 23 | } |
test/behavior/bugs/3046.zig created+19| ... | ... | @@ -0,0 +1,19 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const SomeStruct = struct { | |
| 5 | field: i32, | |
| 6 | }; | |
| 7 | ||
| 8 | fn couldFail() anyerror!i32 { | |
| 9 | return 1; | |
| 10 | } | |
| 11 | ||
| 12 | var some_struct: SomeStruct = undefined; | |
| 13 | ||
| 14 | test "fixed" { | |
| 15 | some_struct = SomeStruct{ | |
| 16 | .field = couldFail() catch |_| @as(i32, 0), | |
| 17 | }; | |
| 18 | expect(some_struct.field == 1); | |
| 19 | } |
test/behavior/bugs/3112.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const State = struct { | |
| 5 | const Self = @This(); | |
| 6 | enter: fn (previous: ?Self) void, | |
| 7 | }; | |
| 8 | ||
| 9 | fn prev(p: ?State) void { | |
| 10 | expect(p == null); | |
| 11 | } | |
| 12 | ||
| 13 | test "zig test crash" { | |
| 14 | var global: State = undefined; | |
| 15 | global.enter = prev; | |
| 16 | global.enter(null); | |
| 17 | } |
test/behavior/bugs/3367.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const Foo = struct { | |
| 2 | usingnamespace Mixin; | |
| 3 | }; | |
| 4 | ||
| 5 | const Mixin = struct { | |
| 6 | pub fn two(self: Foo) void {} | |
| 7 | }; | |
| 8 | ||
| 9 | test "container member access usingnamespace decls" { | |
| 10 | var foo = Foo{}; | |
| 11 | foo.two(); | |
| 12 | } |
test/behavior/bugs/3384.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "resolve array slice using builtin" { | |
| 5 | expect(@hasDecl(@This(), "std") == true); | |
| 6 | expect(@hasDecl(@This(), "std"[0..0]) == false); | |
| 7 | expect(@hasDecl(@This(), "std"[0..1]) == false); | |
| 8 | expect(@hasDecl(@This(), "std"[0..2]) == false); | |
| 9 | expect(@hasDecl(@This(), "std"[0..3]) == true); | |
| 10 | expect(@hasDecl(@This(), "std"[0..]) == true); | |
| 11 | } |
test/behavior/bugs/3468.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | // zig fmt: off | |
| 2 | test "pointer deref next to assignment" { | |
| 3 | var a:i32=2; | |
| 4 | var b=&a; | |
| 5 | b.*=3; | |
| 6 | } |
test/behavior/bugs/3586.zig created+11| ... | ... | @@ -0,0 +1,11 @@ |
| 1 | const NoteParams = struct {}; | |
| 2 | ||
| 3 | const Container = struct { | |
| 4 | params: ?NoteParams, | |
| 5 | }; | |
| 6 | ||
| 7 | test "fixed" { | |
| 8 | var ctr = Container{ | |
| 9 | .params = NoteParams{}, | |
| 10 | }; | |
| 11 | } |
test/behavior/bugs/3742.zig created+38| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub const GET = struct { | |
| 4 | key: []const u8, | |
| 5 | ||
| 6 | pub fn init(key: []const u8) GET { | |
| 7 | return .{ .key = key }; | |
| 8 | } | |
| 9 | ||
| 10 | pub const Redis = struct { | |
| 11 | pub const Command = struct { | |
| 12 | pub fn serialize(self: GET, comptime rootSerializer: type) void { | |
| 13 | return rootSerializer.serializeCommand(.{ "GET", self.key }); | |
| 14 | } | |
| 15 | }; | |
| 16 | }; | |
| 17 | }; | |
| 18 | ||
| 19 | pub fn isCommand(comptime T: type) bool { | |
| 20 | const tid = @typeInfo(T); | |
| 21 | return (tid == .Struct or tid == .Enum or tid == .Union) and | |
| 22 | @hasDecl(T, "Redis") and @hasDecl(T.Redis, "Command"); | |
| 23 | } | |
| 24 | ||
| 25 | pub const ArgSerializer = struct { | |
| 26 | pub fn serializeCommand(command: anytype) void { | |
| 27 | const CmdT = @TypeOf(command); | |
| 28 | ||
| 29 | if (comptime isCommand(CmdT)) { | |
| 30 | // COMMENTING THE NEXT LINE REMOVES THE ERROR | |
| 31 | return CmdT.Redis.Command.serialize(command, ArgSerializer); | |
| 32 | } | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | test "fixed" { | |
| 37 | ArgSerializer.serializeCommand(GET.init("banana")); | |
| 38 | } |
test/behavior/bugs/394.zig created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | const E = union(enum) { | |
| 2 | A: [9]u8, | |
| 3 | B: u64, | |
| 4 | }; | |
| 5 | const S = struct { | |
| 6 | x: u8, | |
| 7 | y: E, | |
| 8 | }; | |
| 9 | ||
| 10 | const expect = @import("std").testing.expect; | |
| 11 | ||
| 12 | test "bug 394 fixed" { | |
| 13 | const x = S{ | |
| 14 | .x = 3, | |
| 15 | .y = E{ .B = 1 }, | |
| 16 | }; | |
| 17 | expect(x.x == 3); | |
| 18 | } |
test/behavior/bugs/421.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "bitCast to array" { | |
| 4 | comptime testBitCastArray(); | |
| 5 | testBitCastArray(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testBitCastArray() void { | |
| 9 | expect(extractOne64(0x0123456789abcdef0123456789abcdef) == 0x0123456789abcdef); | |
| 10 | } | |
| 11 | ||
| 12 | fn extractOne64(a: u128) u64 { | |
| 13 | const x = @bitCast([2]u64, a); | |
| 14 | return x[1]; | |
| 15 | } |
test/behavior/bugs/4328.zig created+71| ... | ... | @@ -0,0 +1,71 @@ |
| 1 | const expectEqual = @import("std").testing.expectEqual; | |
| 2 | ||
| 3 | const FILE = extern struct { | |
| 4 | dummy_field: u8, | |
| 5 | }; | |
| 6 | ||
| 7 | extern fn printf([*c]const u8, ...) c_int; | |
| 8 | extern fn fputs([*c]const u8, noalias [*c]FILE) c_int; | |
| 9 | extern fn ftell([*c]FILE) c_long; | |
| 10 | extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE; | |
| 11 | ||
| 12 | const S = extern struct { | |
| 13 | state: c_short, | |
| 14 | ||
| 15 | extern fn s_do_thing([*c]S, b: c_int) c_short; | |
| 16 | }; | |
| 17 | ||
| 18 | test "Extern function calls in @TypeOf" { | |
| 19 | const Test = struct { | |
| 20 | fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) { | |
| 21 | return 0; | |
| 22 | } | |
| 23 | ||
| 24 | fn test_fn_2(a: anytype) @TypeOf((S{ .state = 0 }).s_do_thing(a)) { | |
| 25 | return 1; | |
| 26 | } | |
| 27 | ||
| 28 | fn doTheTest() void { | |
| 29 | expectEqual(c_int, @TypeOf(test_fn_1(0, 42))); | |
| 30 | expectEqual(c_short, @TypeOf(test_fn_2(0))); | |
| 31 | } | |
| 32 | }; | |
| 33 | ||
| 34 | Test.doTheTest(); | |
| 35 | comptime Test.doTheTest(); | |
| 36 | } | |
| 37 | ||
| 38 | test "Peer resolution of extern function calls in @TypeOf" { | |
| 39 | const Test = struct { | |
| 40 | fn test_fn() @TypeOf(ftell(null), fputs(null, null)) { | |
| 41 | return 0; | |
| 42 | } | |
| 43 | ||
| 44 | fn doTheTest() void { | |
| 45 | expectEqual(c_long, @TypeOf(test_fn())); | |
| 46 | } | |
| 47 | }; | |
| 48 | ||
| 49 | Test.doTheTest(); | |
| 50 | comptime Test.doTheTest(); | |
| 51 | } | |
| 52 | ||
| 53 | test "Extern function calls, dereferences and field access in @TypeOf" { | |
| 54 | const Test = struct { | |
| 55 | fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) { | |
| 56 | return .{ .dummy_field = 0 }; | |
| 57 | } | |
| 58 | ||
| 59 | fn test_fn_2(a: anytype) @TypeOf(fopen("test", "r").*.dummy_field) { | |
| 60 | return 255; | |
| 61 | } | |
| 62 | ||
| 63 | fn doTheTest() void { | |
| 64 | expectEqual(FILE, @TypeOf(test_fn_1(0))); | |
| 65 | expectEqual(u8, @TypeOf(test_fn_2(0))); | |
| 66 | } | |
| 67 | }; | |
| 68 | ||
| 69 | Test.doTheTest(); | |
| 70 | comptime Test.doTheTest(); | |
| 71 | } |
test/behavior/bugs/4560.zig created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "fixed" { | |
| 4 | var s: S = .{ | |
| 5 | .a = 1, | |
| 6 | .b = .{ | |
| 7 | .size = 123, | |
| 8 | .max_distance_from_start_index = 456, | |
| 9 | }, | |
| 10 | }; | |
| 11 | std.testing.expect(s.a == 1); | |
| 12 | std.testing.expect(s.b.size == 123); | |
| 13 | std.testing.expect(s.b.max_distance_from_start_index == 456); | |
| 14 | } | |
| 15 | ||
| 16 | const S = struct { | |
| 17 | a: u32, | |
| 18 | b: Map, | |
| 19 | ||
| 20 | const Map = StringHashMap(*S); | |
| 21 | }; | |
| 22 | ||
| 23 | pub fn StringHashMap(comptime V: type) type { | |
| 24 | return HashMap([]const u8, V); | |
| 25 | } | |
| 26 | ||
| 27 | pub fn HashMap(comptime K: type, comptime V: type) type { | |
| 28 | return struct { | |
| 29 | size: usize, | |
| 30 | max_distance_from_start_index: usize, | |
| 31 | }; | |
| 32 | } |
test/behavior/bugs/4769_a.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | // | |
| \ No newline at end of file |
test/behavior/bugs/4769_b.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | //! | |
| \ No newline at end of file |
test/behavior/bugs/4769_c.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | /// | |
| \ No newline at end of file |
test/behavior/bugs/4954.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | fn f(buf: []u8) void { | |
| 2 | var ptr = &buf[@sizeOf(u32)]; | |
| 3 | } | |
| 4 | ||
| 5 | test "crash" { | |
| 6 | var buf: [4096]u8 = undefined; | |
| 7 | f(&buf); | |
| 8 | } |
test/behavior/bugs/529.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | ||
| 5 | extern fn issue529(?*A) void; | |
| 6 | ||
| 7 | comptime { | |
| 8 | _ = @import("529_other_file_2.zig"); | |
| 9 | } | |
| 10 | ||
| 11 | test "issue 529 fixed" { | |
| 12 | @import("529_other_file.zig").issue529(null); | |
| 13 | issue529(null); | |
| 14 | } |
test/behavior/bugs/529_other_file.zig created+5| ... | ... | @@ -0,0 +1,5 @@ |
| 1 | pub const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | ||
| 5 | pub extern fn issue529(?*A) void; |
test/behavior/bugs/529_other_file_2.zig created+4| ... | ... | @@ -0,0 +1,4 @@ |
| 1 | pub const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | export fn issue529(a: ?*A) void {} |
test/behavior/bugs/5398.zig created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | ||
| 4 | pub const Mesh = struct { | |
| 5 | id: u32, | |
| 6 | }; | |
| 7 | pub const Material = struct { | |
| 8 | transparent: bool = true, | |
| 9 | emits_shadows: bool = true, | |
| 10 | render_color: bool = true, | |
| 11 | }; | |
| 12 | pub const Renderable = struct { | |
| 13 | material: Material, | |
| 14 | // The compiler inserts some padding here to ensure Mesh is correctly aligned. | |
| 15 | mesh: Mesh, | |
| 16 | }; | |
| 17 | ||
| 18 | var renderable: Renderable = undefined; | |
| 19 | ||
| 20 | test "assignment of field with padding" { | |
| 21 | renderable = Renderable{ | |
| 22 | .mesh = Mesh{ .id = 0 }, | |
| 23 | .material = Material{ | |
| 24 | .transparent = false, | |
| 25 | .emits_shadows = false, | |
| 26 | }, | |
| 27 | }; | |
| 28 | testing.expectEqual(false, renderable.material.transparent); | |
| 29 | testing.expectEqual(false, renderable.material.emits_shadows); | |
| 30 | testing.expectEqual(true, renderable.material.render_color); | |
| 31 | } |
test/behavior/bugs/5413.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "Peer type resolution with string literals and unknown length u8 pointers" { | |
| 4 | expect(@TypeOf("", "a", @as([*:0]const u8, "")) == [*:0]const u8); | |
| 5 | expect(@TypeOf(@as([*:0]const u8, "baz"), "foo", "bar") == [*:0]const u8); | |
| 6 | } |
test/behavior/bugs/5474.zig created+57| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | // baseline (control) struct with array of scalar | |
| 4 | const Box0 = struct { | |
| 5 | items: [4]Item, | |
| 6 | ||
| 7 | const Item = struct { | |
| 8 | num: u32, | |
| 9 | }; | |
| 10 | }; | |
| 11 | ||
| 12 | // struct with array of empty struct | |
| 13 | const Box1 = struct { | |
| 14 | items: [4]Item, | |
| 15 | ||
| 16 | const Item = struct {}; | |
| 17 | }; | |
| 18 | ||
| 19 | // struct with array of zero-size struct | |
| 20 | const Box2 = struct { | |
| 21 | items: [4]Item, | |
| 22 | ||
| 23 | const Item = struct { | |
| 24 | nothing: void, | |
| 25 | }; | |
| 26 | }; | |
| 27 | ||
| 28 | fn doTest() void { | |
| 29 | // var | |
| 30 | { | |
| 31 | var box0: Box0 = .{ .items = undefined }; | |
| 32 | std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == false); | |
| 33 | ||
| 34 | var box1: Box1 = .{ .items = undefined }; | |
| 35 | std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == false); | |
| 36 | ||
| 37 | var box2: Box2 = .{ .items = undefined }; | |
| 38 | std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == false); | |
| 39 | } | |
| 40 | ||
| 41 | // const | |
| 42 | { | |
| 43 | const box0: Box0 = .{ .items = undefined }; | |
| 44 | std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == true); | |
| 45 | ||
| 46 | const box1: Box1 = .{ .items = undefined }; | |
| 47 | std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == true); | |
| 48 | ||
| 49 | const box2: Box2 = .{ .items = undefined }; | |
| 50 | std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == true); | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | test "pointer-to-array constness for zero-size elements" { | |
| 55 | doTest(); | |
| 56 | comptime doTest(); | |
| 57 | } |
test/behavior/bugs/5487.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const io = @import("std").io; | |
| 2 | ||
| 3 | pub fn write(_: void, bytes: []const u8) !usize { | |
| 4 | return 0; | |
| 5 | } | |
| 6 | pub fn writer() io.Writer(void, @typeInfo(@typeInfo(@TypeOf(write)).Fn.return_type.?).ErrorUnion.error_set, write) { | |
| 7 | return io.Writer(void, @typeInfo(@typeInfo(@TypeOf(write)).Fn.return_type.?).ErrorUnion.error_set, write){ .context = {} }; | |
| 8 | } | |
| 9 | ||
| 10 | test "crash" { | |
| 11 | _ = io.multiWriter(.{writer()}); | |
| 12 | } |
test/behavior/bugs/624.zig created+23| ... | ... | @@ -0,0 +1,23 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const TestContext = struct { | |
| 5 | server_context: *ListenerContext, | |
| 6 | }; | |
| 7 | ||
| 8 | const ListenerContext = struct { | |
| 9 | context_alloc: *ContextAllocator, | |
| 10 | }; | |
| 11 | ||
| 12 | const ContextAllocator = MemoryPool(TestContext); | |
| 13 | ||
| 14 | fn MemoryPool(comptime T: type) type { | |
| 15 | return struct { | |
| 16 | n: usize, | |
| 17 | }; | |
| 18 | } | |
| 19 | ||
| 20 | test "foo" { | |
| 21 | var allocator = ContextAllocator{ .n = 10 }; | |
| 22 | expect(allocator.n == 10); | |
| 23 | } |
test/behavior/bugs/6456.zig created+42| ... | ... | @@ -0,0 +1,42 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const StructField = std.builtin.TypeInfo.StructField; | |
| 4 | const Declaration = std.builtin.TypeInfo.Declaration; | |
| 5 | ||
| 6 | const text = | |
| 7 | \\f1 | |
| 8 | \\f2 | |
| 9 | \\f3 | |
| 10 | ; | |
| 11 | ||
| 12 | test "issue 6456" { | |
| 13 | comptime { | |
| 14 | var fields: []const StructField = &[0]StructField{}; | |
| 15 | ||
| 16 | var it = std.mem.tokenize(text, "\n"); | |
| 17 | while (it.next()) |name| { | |
| 18 | fields = fields ++ &[_]StructField{StructField{ | |
| 19 | .alignment = 0, | |
| 20 | .name = name, | |
| 21 | .field_type = usize, | |
| 22 | .default_value = @as(?usize, null), | |
| 23 | .is_comptime = false, | |
| 24 | }}; | |
| 25 | } | |
| 26 | ||
| 27 | const T = @Type(.{ | |
| 28 | .Struct = .{ | |
| 29 | .layout = .Auto, | |
| 30 | .is_tuple = false, | |
| 31 | .fields = fields, | |
| 32 | .decls = &[_]Declaration{}, | |
| 33 | }, | |
| 34 | }); | |
| 35 | ||
| 36 | const gen_fields = @typeInfo(T).Struct.fields; | |
| 37 | testing.expectEqual(3, gen_fields.len); | |
| 38 | testing.expectEqualStrings("f1", gen_fields[0].name); | |
| 39 | testing.expectEqualStrings("f2", gen_fields[1].name); | |
| 40 | testing.expectEqualStrings("f3", gen_fields[2].name); | |
| 41 | } | |
| 42 | } |
test/behavior/bugs/655.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const std = @import("std"); | |
| 2 | const other_file = @import("655_other_file.zig"); | |
| 3 | ||
| 4 | test "function with *const parameter with type dereferenced by namespace" { | |
| 5 | const x: other_file.Integer = 1234; | |
| 6 | comptime std.testing.expect(@TypeOf(&x) == *const other_file.Integer); | |
| 7 | foo(&x); | |
| 8 | } | |
| 9 | ||
| 10 | fn foo(x: *const other_file.Integer) void { | |
| 11 | std.testing.expect(x.* == 1234); | |
| 12 | } |
test/behavior/bugs/655_other_file.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub const Integer = u32; |
test/behavior/bugs/656.zig created+31| ... | ... | @@ -0,0 +1,31 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const PrefixOp = union(enum) { | |
| 4 | Return, | |
| 5 | AddrOf: Value, | |
| 6 | }; | |
| 7 | ||
| 8 | const Value = struct { | |
| 9 | align_expr: ?u32, | |
| 10 | }; | |
| 11 | ||
| 12 | test "optional if after an if in a switch prong of a switch with 2 prongs in an else" { | |
| 13 | foo(false, true); | |
| 14 | } | |
| 15 | ||
| 16 | fn foo(a: bool, b: bool) void { | |
| 17 | var prefix_op = PrefixOp{ | |
| 18 | .AddrOf = Value{ .align_expr = 1234 }, | |
| 19 | }; | |
| 20 | if (a) {} else { | |
| 21 | switch (prefix_op) { | |
| 22 | PrefixOp.AddrOf => |addr_of_info| { | |
| 23 | if (b) {} | |
| 24 | if (addr_of_info.align_expr) |align_expr| { | |
| 25 | expect(align_expr == 1234); | |
| 26 | } | |
| 27 | }, | |
| 28 | PrefixOp.Return => {}, | |
| 29 | } | |
| 30 | } | |
| 31 | } |
test/behavior/bugs/6781.zig created+74| ... | ... | @@ -0,0 +1,74 @@ |
| 1 | const std = @import("std"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | ||
| 4 | const segfault = true; | |
| 5 | ||
| 6 | pub const JournalHeader = packed struct { | |
| 7 | hash_chain_root: u128 = undefined, | |
| 8 | prev_hash_chain_root: u128, | |
| 9 | checksum: u128 = undefined, | |
| 10 | magic: u64, | |
| 11 | command: u32, | |
| 12 | size: u32, | |
| 13 | ||
| 14 | pub fn calculate_checksum(self: *const JournalHeader, entry: []const u8) u128 { | |
| 15 | assert(entry.len >= @sizeOf(JournalHeader)); | |
| 16 | assert(entry.len == self.size); | |
| 17 | ||
| 18 | const checksum_offset = @byteOffsetOf(JournalHeader, "checksum"); | |
| 19 | const checksum_size = @sizeOf(@TypeOf(self.checksum)); | |
| 20 | assert(checksum_offset == 0 + 16 + 16); | |
| 21 | assert(checksum_size == 16); | |
| 22 | ||
| 23 | var target: [32]u8 = undefined; | |
| 24 | std.crypto.hash.Blake3.hash(entry[checksum_offset + checksum_size ..], target[0..], .{}); | |
| 25 | return @bitCast(u128, target[0..checksum_size].*); | |
| 26 | } | |
| 27 | ||
| 28 | pub fn calculate_hash_chain_root(self: *const JournalHeader) u128 { | |
| 29 | const hash_chain_root_size = @sizeOf(@TypeOf(self.hash_chain_root)); | |
| 30 | assert(hash_chain_root_size == 16); | |
| 31 | ||
| 32 | const prev_hash_chain_root_offset = @byteOffsetOf(JournalHeader, "prev_hash_chain_root"); | |
| 33 | const prev_hash_chain_root_size = @sizeOf(@TypeOf(self.prev_hash_chain_root)); | |
| 34 | assert(prev_hash_chain_root_offset == 0 + 16); | |
| 35 | assert(prev_hash_chain_root_size == 16); | |
| 36 | ||
| 37 | const checksum_offset = @byteOffsetOf(JournalHeader, "checksum"); | |
| 38 | const checksum_size = @sizeOf(@TypeOf(self.checksum)); | |
| 39 | assert(checksum_offset == 0 + 16 + 16); | |
| 40 | assert(checksum_size == 16); | |
| 41 | ||
| 42 | assert(prev_hash_chain_root_offset + prev_hash_chain_root_size == checksum_offset); | |
| 43 | ||
| 44 | const header = @bitCast([@sizeOf(JournalHeader)]u8, self.*); | |
| 45 | const source = header[prev_hash_chain_root_offset .. checksum_offset + checksum_size]; | |
| 46 | assert(source.len == prev_hash_chain_root_size + checksum_size); | |
| 47 | var target: [32]u8 = undefined; | |
| 48 | std.crypto.hash.Blake3.hash(source, target[0..], .{}); | |
| 49 | if (segfault) { | |
| 50 | return @bitCast(u128, target[0..hash_chain_root_size].*); | |
| 51 | } else { | |
| 52 | var array = target[0..hash_chain_root_size].*; | |
| 53 | return @bitCast(u128, array); | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | pub fn set_checksum_and_hash_chain_root(self: *JournalHeader, entry: []const u8) void { | |
| 58 | self.checksum = self.calculate_checksum(entry); | |
| 59 | self.hash_chain_root = self.calculate_hash_chain_root(); | |
| 60 | } | |
| 61 | }; | |
| 62 | ||
| 63 | test "fixed" { | |
| 64 | var buffer = [_]u8{0} ** 65536; | |
| 65 | var entry = std.mem.bytesAsValue(JournalHeader, buffer[0..@sizeOf(JournalHeader)]); | |
| 66 | entry.* = .{ | |
| 67 | .prev_hash_chain_root = 0, | |
| 68 | .magic = 0, | |
| 69 | .command = 0, | |
| 70 | .size = 64 + 128, | |
| 71 | }; | |
| 72 | entry.set_checksum_and_hash_chain_root(buffer[0..entry.size]); | |
| 73 | try std.io.null_writer.print("{}\n", .{entry}); | |
| 74 | } |
test/behavior/bugs/679.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | pub fn List(comptime T: type) type { | |
| 5 | return u32; | |
| 6 | } | |
| 7 | ||
| 8 | const ElementList = List(Element); | |
| 9 | const Element = struct { | |
| 10 | link: ElementList, | |
| 11 | }; | |
| 12 | ||
| 13 | test "false dependency loop in struct definition" { | |
| 14 | const listType = ElementList; | |
| 15 | var x: listType = 42; | |
| 16 | expect(x == 42); | |
| 17 | } |
test/behavior/bugs/6850.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "lazy sizeof comparison with zero" { | |
| 4 | const Empty = struct {}; | |
| 5 | const T = *Empty; | |
| 6 | ||
| 7 | std.testing.expect(hasNoBits(T)); | |
| 8 | } | |
| 9 | ||
| 10 | fn hasNoBits(comptime T: type) bool { | |
| 11 | return @sizeOf(T) == 0; | |
| 12 | } |
test/behavior/bugs/7003.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | test "@Type should resolve its children types" { | |
| 2 | const sparse = enum(u2) { a, b, c }; | |
| 3 | const dense = enum(u2) { a, b, c, d }; | |
| 4 | ||
| 5 | comptime var sparse_info = @typeInfo(anyerror!sparse); | |
| 6 | sparse_info.ErrorUnion.payload = dense; | |
| 7 | const B = @Type(sparse_info); | |
| 8 | } |
test/behavior/bugs/7027.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const Foobar = struct { | |
| 2 | myTypes: [128]type, | |
| 3 | str: [1024]u8, | |
| 4 | ||
| 5 | fn foo() @This() { | |
| 6 | comptime var foobar: Foobar = undefined; | |
| 7 | foobar.str = [_]u8{'a'} ** 1024; | |
| 8 | return foobar; | |
| 9 | } | |
| 10 | }; | |
| 11 | ||
| 12 | fn foo(arg: anytype) void {} | |
| 13 | ||
| 14 | test "" { | |
| 15 | comptime var foobar = Foobar.foo(); | |
| 16 | foo(foobar.str[0..10]); | |
| 17 | } |
test/behavior/bugs/704.zig created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | const xxx = struct { | |
| 2 | pub fn bar(self: *xxx) void {} | |
| 3 | }; | |
| 4 | test "bug 704" { | |
| 5 | var x: xxx = undefined; | |
| 6 | x.bar(); | |
| 7 | } |
test/behavior/bugs/7047.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const U = union(enum) { | |
| 4 | T: type, | |
| 5 | N: void, | |
| 6 | }; | |
| 7 | ||
| 8 | fn S(comptime query: U) type { | |
| 9 | return struct { | |
| 10 | fn tag() type { | |
| 11 | return query.T; | |
| 12 | } | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | test "compiler doesn't consider equal unions with different 'type' payload" { | |
| 17 | const s1 = S(U{ .T = u32 }).tag(); | |
| 18 | std.testing.expectEqual(u32, s1); | |
| 19 | ||
| 20 | const s2 = S(U{ .T = u64 }).tag(); | |
| 21 | std.testing.expectEqual(u64, s2); | |
| 22 | } |
test/behavior/bugs/718.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const Keys = struct { | |
| 5 | up: bool, | |
| 6 | down: bool, | |
| 7 | left: bool, | |
| 8 | right: bool, | |
| 9 | }; | |
| 10 | var keys: Keys = undefined; | |
| 11 | test "zero keys with @memset" { | |
| 12 | @memset(@ptrCast([*]u8, &keys), 0, @sizeOf(@TypeOf(keys))); | |
| 13 | expect(!keys.up); | |
| 14 | expect(!keys.down); | |
| 15 | expect(!keys.left); | |
| 16 | expect(!keys.right); | |
| 17 | } |
test/behavior/bugs/7250.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const nrfx_uart_t = extern struct { | |
| 2 | p_reg: [*c]u32, | |
| 3 | drv_inst_idx: u8, | |
| 4 | }; | |
| 5 | ||
| 6 | pub fn nrfx_uart_rx(p_instance: [*c]const nrfx_uart_t) void {} | |
| 7 | ||
| 8 | threadlocal var g_uart0 = nrfx_uart_t{ | |
| 9 | .p_reg = 0, | |
| 10 | .drv_inst_idx = 0, | |
| 11 | }; | |
| 12 | ||
| 13 | test "reference a global threadlocal variable" { | |
| 14 | _ = nrfx_uart_rx(&g_uart0); | |
| 15 | } |
test/behavior/bugs/726.zig created+15| ... | ... | @@ -0,0 +1,15 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@ptrCast from const to nullable" { | |
| 4 | const c: u8 = 4; | |
| 5 | var x: ?*const u8 = @ptrCast(?*const u8, &c); | |
| 6 | expect(x.?.* == 4); | |
| 7 | } | |
| 8 | ||
| 9 | test "@ptrCast from var in empty struct to nullable" { | |
| 10 | const container = struct { | |
| 11 | var c: u8 = 4; | |
| 12 | }; | |
| 13 | var x: ?*const u8 = @ptrCast(?*const u8, &container.c); | |
| 14 | expect(x.?.* == 4); | |
| 15 | } |
test/behavior/bugs/828.zig created+33| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | const CountBy = struct { | |
| 2 | a: usize, | |
| 3 | ||
| 4 | const One = CountBy{ .a = 1 }; | |
| 5 | ||
| 6 | pub fn counter(self: *const CountBy) Counter { | |
| 7 | return Counter{ .i = 0 }; | |
| 8 | } | |
| 9 | }; | |
| 10 | ||
| 11 | const Counter = struct { | |
| 12 | i: usize, | |
| 13 | ||
| 14 | pub fn count(self: *Counter) bool { | |
| 15 | self.i += 1; | |
| 16 | return self.i <= 10; | |
| 17 | } | |
| 18 | }; | |
| 19 | ||
| 20 | fn constCount(comptime cb: *const CountBy, comptime unused: u32) void { | |
| 21 | comptime { | |
| 22 | var cnt = cb.counter(); | |
| 23 | if (cnt.i != 0) @compileError("Counter instance reused!"); | |
| 24 | while (cnt.count()) {} | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | test "comptime struct return should not return the same instance" { | |
| 29 | //the first parameter must be passed by reference to trigger the bug | |
| 30 | //a second parameter is required to trigger the bug | |
| 31 | const ValA = constCount(&CountBy.One, 12); | |
| 32 | const ValB = constCount(&CountBy.One, 15); | |
| 33 | } |
test/behavior/bugs/920.zig created+65| ... | ... | @@ -0,0 +1,65 @@ |
| 1 | const std = @import("std"); | |
| 2 | const math = std.math; | |
| 3 | const Random = std.rand.Random; | |
| 4 | ||
| 5 | const ZigTable = struct { | |
| 6 | r: f64, | |
| 7 | x: [257]f64, | |
| 8 | f: [257]f64, | |
| 9 | ||
| 10 | pdf: fn (f64) f64, | |
| 11 | is_symmetric: bool, | |
| 12 | zero_case: fn (*Random, f64) f64, | |
| 13 | }; | |
| 14 | ||
| 15 | fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn (f64) f64, comptime f_inv: fn (f64) f64, comptime zero_case: fn (*Random, f64) f64) ZigTable { | |
| 16 | var tables: ZigTable = undefined; | |
| 17 | ||
| 18 | tables.is_symmetric = is_symmetric; | |
| 19 | tables.r = r; | |
| 20 | tables.pdf = f; | |
| 21 | tables.zero_case = zero_case; | |
| 22 | ||
| 23 | tables.x[0] = v / f(r); | |
| 24 | tables.x[1] = r; | |
| 25 | ||
| 26 | for (tables.x[2..256]) |*entry, i| { | |
| 27 | const last = tables.x[2 + i - 1]; | |
| 28 | entry.* = f_inv(v / last + f(last)); | |
| 29 | } | |
| 30 | tables.x[256] = 0; | |
| 31 | ||
| 32 | for (tables.f[0..]) |*entry, i| { | |
| 33 | entry.* = f(tables.x[i]); | |
| 34 | } | |
| 35 | ||
| 36 | return tables; | |
| 37 | } | |
| 38 | ||
| 39 | const norm_r = 3.6541528853610088; | |
| 40 | const norm_v = 0.00492867323399; | |
| 41 | ||
| 42 | fn norm_f(x: f64) f64 { | |
| 43 | return math.exp(-x * x / 2.0); | |
| 44 | } | |
| 45 | fn norm_f_inv(y: f64) f64 { | |
| 46 | return math.sqrt(-2.0 * math.ln(y)); | |
| 47 | } | |
| 48 | fn norm_zero_case(random: *Random, u: f64) f64 { | |
| 49 | return 0.0; | |
| 50 | } | |
| 51 | ||
| 52 | const NormalDist = blk: { | |
| 53 | @setEvalBranchQuota(30000); | |
| 54 | break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case); | |
| 55 | }; | |
| 56 | ||
| 57 | test "bug 920 fixed" { | |
| 58 | const NormalDist1 = blk: { | |
| 59 | break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case); | |
| 60 | }; | |
| 61 | ||
| 62 | for (NormalDist1.f) |_, i| { | |
| 63 | std.testing.expectEqual(NormalDist1.f[i], NormalDist.f[i]); | |
| 64 | } | |
| 65 | } |
test/behavior/byteswap.zig created+68| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@byteSwap integers" { | |
| 5 | const ByteSwapIntTest = struct { | |
| 6 | fn run() void { | |
| 7 | t(u0, 0, 0); | |
| 8 | t(u8, 0x12, 0x12); | |
| 9 | t(u16, 0x1234, 0x3412); | |
| 10 | t(u24, 0x123456, 0x563412); | |
| 11 | t(u32, 0x12345678, 0x78563412); | |
| 12 | t(u40, 0x123456789a, 0x9a78563412); | |
| 13 | t(i48, 0x123456789abc, @bitCast(i48, @as(u48, 0xbc9a78563412))); | |
| 14 | t(u56, 0x123456789abcde, 0xdebc9a78563412); | |
| 15 | t(u64, 0x123456789abcdef1, 0xf1debc9a78563412); | |
| 16 | t(u128, 0x123456789abcdef11121314151617181, 0x8171615141312111f1debc9a78563412); | |
| 17 | ||
| 18 | t(u0, @as(u0, 0), 0); | |
| 19 | t(i8, @as(i8, -50), -50); | |
| 20 | t(i16, @bitCast(i16, @as(u16, 0x1234)), @bitCast(i16, @as(u16, 0x3412))); | |
| 21 | t(i24, @bitCast(i24, @as(u24, 0x123456)), @bitCast(i24, @as(u24, 0x563412))); | |
| 22 | t(i32, @bitCast(i32, @as(u32, 0x12345678)), @bitCast(i32, @as(u32, 0x78563412))); | |
| 23 | t(u40, @bitCast(i40, @as(u40, 0x123456789a)), @as(u40, 0x9a78563412)); | |
| 24 | t(i48, @bitCast(i48, @as(u48, 0x123456789abc)), @bitCast(i48, @as(u48, 0xbc9a78563412))); | |
| 25 | t(i56, @bitCast(i56, @as(u56, 0x123456789abcde)), @bitCast(i56, @as(u56, 0xdebc9a78563412))); | |
| 26 | t(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1)), @bitCast(i64, @as(u64, 0xf1debc9a78563412))); | |
| 27 | t( | |
| 28 | i128, | |
| 29 | @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181)), | |
| 30 | @bitCast(i128, @as(u128, 0x8171615141312111f1debc9a78563412)), | |
| 31 | ); | |
| 32 | } | |
| 33 | fn t(comptime I: type, input: I, expected_output: I) void { | |
| 34 | std.testing.expectEqual(expected_output, @byteSwap(I, input)); | |
| 35 | } | |
| 36 | }; | |
| 37 | comptime ByteSwapIntTest.run(); | |
| 38 | ByteSwapIntTest.run(); | |
| 39 | } | |
| 40 | ||
| 41 | test "@byteSwap vectors" { | |
| 42 | // https://github.com/ziglang/zig/issues/3563 | |
| 43 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; | |
| 44 | ||
| 45 | // https://github.com/ziglang/zig/issues/3317 | |
| 46 | if (std.Target.current.cpu.arch == .mipsel or std.Target.current.cpu.arch == .mips) return error.SkipZigTest; | |
| 47 | ||
| 48 | const ByteSwapVectorTest = struct { | |
| 49 | fn run() void { | |
| 50 | t(u8, 2, [_]u8{ 0x12, 0x13 }, [_]u8{ 0x12, 0x13 }); | |
| 51 | t(u16, 2, [_]u16{ 0x1234, 0x2345 }, [_]u16{ 0x3412, 0x4523 }); | |
| 52 | t(u24, 2, [_]u24{ 0x123456, 0x234567 }, [_]u24{ 0x563412, 0x674523 }); | |
| 53 | } | |
| 54 | ||
| 55 | fn t( | |
| 56 | comptime I: type, | |
| 57 | comptime n: comptime_int, | |
| 58 | input: std.meta.Vector(n, I), | |
| 59 | expected_vector: std.meta.Vector(n, I), | |
| 60 | ) void { | |
| 61 | const actual_output: [n]I = @byteSwap(I, input); | |
| 62 | const expected_output: [n]I = expected_vector; | |
| 63 | std.testing.expectEqual(expected_output, actual_output); | |
| 64 | } | |
| 65 | }; | |
| 66 | comptime ByteSwapVectorTest.run(); | |
| 67 | ByteSwapVectorTest.run(); | |
| 68 | } |
test/behavior/byval_arg_var.zig created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | var result: []const u8 = "wrong"; | |
| 4 | ||
| 5 | test "pass string literal byvalue to a generic var param" { | |
| 6 | start(); | |
| 7 | blowUpStack(10); | |
| 8 | ||
| 9 | std.testing.expect(std.mem.eql(u8, result, "string literal")); | |
| 10 | } | |
| 11 | ||
| 12 | fn start() void { | |
| 13 | foo("string literal"); | |
| 14 | } | |
| 15 | ||
| 16 | fn foo(x: anytype) void { | |
| 17 | bar(x); | |
| 18 | } | |
| 19 | ||
| 20 | fn bar(x: anytype) void { | |
| 21 | result = x; | |
| 22 | } | |
| 23 | ||
| 24 | fn blowUpStack(x: u32) void { | |
| 25 | if (x == 0) return; | |
| 26 | blowUpStack(x - 1); | |
| 27 | } |
test/behavior/call.zig created+74| ... | ... | @@ -0,0 +1,74 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "basic invocations" { | |
| 6 | const foo = struct { | |
| 7 | fn foo() i32 { | |
| 8 | return 1234; | |
| 9 | } | |
| 10 | }.foo; | |
| 11 | expect(@call(.{}, foo, .{}) == 1234); | |
| 12 | comptime { | |
| 13 | // modifiers that allow comptime calls | |
| 14 | expect(@call(.{}, foo, .{}) == 1234); | |
| 15 | expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234); | |
| 16 | expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234); | |
| 17 | expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234); | |
| 18 | } | |
| 19 | { | |
| 20 | // comptime call without comptime keyword | |
| 21 | const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234; | |
| 22 | comptime expect(result); | |
| 23 | } | |
| 24 | { | |
| 25 | // call of non comptime-known function | |
| 26 | var alias_foo = foo; | |
| 27 | expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234); | |
| 28 | expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234); | |
| 29 | expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234); | |
| 30 | } | |
| 31 | } | |
| 32 | ||
| 33 | test "tuple parameters" { | |
| 34 | const add = struct { | |
| 35 | fn add(a: i32, b: i32) i32 { | |
| 36 | return a + b; | |
| 37 | } | |
| 38 | }.add; | |
| 39 | var a: i32 = 12; | |
| 40 | var b: i32 = 34; | |
| 41 | expect(@call(.{}, add, .{ a, 34 }) == 46); | |
| 42 | expect(@call(.{}, add, .{ 12, b }) == 46); | |
| 43 | expect(@call(.{}, add, .{ a, b }) == 46); | |
| 44 | expect(@call(.{}, add, .{ 12, 34 }) == 46); | |
| 45 | comptime expect(@call(.{}, add, .{ 12, 34 }) == 46); | |
| 46 | { | |
| 47 | const separate_args0 = .{ a, b }; | |
| 48 | const separate_args1 = .{ a, 34 }; | |
| 49 | const separate_args2 = .{ 12, 34 }; | |
| 50 | const separate_args3 = .{ 12, b }; | |
| 51 | expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46); | |
| 52 | expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46); | |
| 53 | expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46); | |
| 54 | expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46); | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | test "comptime call with bound function as parameter" { | |
| 59 | const S = struct { | |
| 60 | fn ReturnType(func: anytype) type { | |
| 61 | return switch (@typeInfo(@TypeOf(func))) { | |
| 62 | .BoundFn => |info| info, | |
| 63 | else => unreachable, | |
| 64 | }.return_type orelse void; | |
| 65 | } | |
| 66 | ||
| 67 | fn call_me_maybe() ?i32 { | |
| 68 | return 123; | |
| 69 | } | |
| 70 | }; | |
| 71 | ||
| 72 | var inst: S = undefined; | |
| 73 | expectEqual(?i32, S.ReturnType(inst.call_me_maybe)); | |
| 74 | } |
test/behavior/cast.zig created+927| ... | ... | @@ -0,0 +1,927 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | const maxInt = std.math.maxInt; | |
| 5 | const Vector = std.meta.Vector; | |
| 6 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 7 | ||
| 8 | test "int to ptr cast" { | |
| 9 | const x = @as(usize, 13); | |
| 10 | const y = @intToPtr(*u8, x); | |
| 11 | const z = @ptrToInt(y); | |
| 12 | expect(z == 13); | |
| 13 | } | |
| 14 | ||
| 15 | test "integer literal to pointer cast" { | |
| 16 | const vga_mem = @intToPtr(*u16, 0xB8000); | |
| 17 | expect(@ptrToInt(vga_mem) == 0xB8000); | |
| 18 | } | |
| 19 | ||
| 20 | test "pointer reinterpret const float to int" { | |
| 21 | // The hex representation is 0x3fe3333333333303. | |
| 22 | const float: f64 = 5.99999999999994648725e-01; | |
| 23 | const float_ptr = &float; | |
| 24 | const int_ptr = @ptrCast(*const i32, float_ptr); | |
| 25 | const int_val = int_ptr.*; | |
| 26 | if (native_endian == .Little) | |
| 27 | expect(int_val == 0x33333303) | |
| 28 | else | |
| 29 | expect(int_val == 0x3fe33333); | |
| 30 | } | |
| 31 | ||
| 32 | test "implicitly cast indirect pointer to maybe-indirect pointer" { | |
| 33 | const S = struct { | |
| 34 | const Self = @This(); | |
| 35 | x: u8, | |
| 36 | fn constConst(p: *const *const Self) u8 { | |
| 37 | return p.*.x; | |
| 38 | } | |
| 39 | fn maybeConstConst(p: ?*const *const Self) u8 { | |
| 40 | return p.?.*.x; | |
| 41 | } | |
| 42 | fn constConstConst(p: *const *const *const Self) u8 { | |
| 43 | return p.*.*.x; | |
| 44 | } | |
| 45 | fn maybeConstConstConst(p: ?*const *const *const Self) u8 { | |
| 46 | return p.?.*.*.x; | |
| 47 | } | |
| 48 | }; | |
| 49 | const s = S{ .x = 42 }; | |
| 50 | const p = &s; | |
| 51 | const q = &p; | |
| 52 | const r = &q; | |
| 53 | expect(42 == S.constConst(q)); | |
| 54 | expect(42 == S.maybeConstConst(q)); | |
| 55 | expect(42 == S.constConstConst(r)); | |
| 56 | expect(42 == S.maybeConstConstConst(r)); | |
| 57 | } | |
| 58 | ||
| 59 | test "explicit cast from integer to error type" { | |
| 60 | testCastIntToErr(error.ItBroke); | |
| 61 | comptime testCastIntToErr(error.ItBroke); | |
| 62 | } | |
| 63 | fn testCastIntToErr(err: anyerror) void { | |
| 64 | const x = @errorToInt(err); | |
| 65 | const y = @intToError(x); | |
| 66 | expect(error.ItBroke == y); | |
| 67 | } | |
| 68 | ||
| 69 | test "peer resolve arrays of different size to const slice" { | |
| 70 | expect(mem.eql(u8, boolToStr(true), "true")); | |
| 71 | expect(mem.eql(u8, boolToStr(false), "false")); | |
| 72 | comptime expect(mem.eql(u8, boolToStr(true), "true")); | |
| 73 | comptime expect(mem.eql(u8, boolToStr(false), "false")); | |
| 74 | } | |
| 75 | fn boolToStr(b: bool) []const u8 { | |
| 76 | return if (b) "true" else "false"; | |
| 77 | } | |
| 78 | ||
| 79 | test "peer resolve array and const slice" { | |
| 80 | testPeerResolveArrayConstSlice(true); | |
| 81 | comptime testPeerResolveArrayConstSlice(true); | |
| 82 | } | |
| 83 | fn testPeerResolveArrayConstSlice(b: bool) void { | |
| 84 | const value1 = if (b) "aoeu" else @as([]const u8, "zz"); | |
| 85 | const value2 = if (b) @as([]const u8, "zz") else "aoeu"; | |
| 86 | expect(mem.eql(u8, value1, "aoeu")); | |
| 87 | expect(mem.eql(u8, value2, "zz")); | |
| 88 | } | |
| 89 | ||
| 90 | test "implicitly cast from T to anyerror!?T" { | |
| 91 | castToOptionalTypeError(1); | |
| 92 | comptime castToOptionalTypeError(1); | |
| 93 | } | |
| 94 | ||
| 95 | const A = struct { | |
| 96 | a: i32, | |
| 97 | }; | |
| 98 | fn castToOptionalTypeError(z: i32) void { | |
| 99 | const x = @as(i32, 1); | |
| 100 | const y: anyerror!?i32 = x; | |
| 101 | expect((try y).? == 1); | |
| 102 | ||
| 103 | const f = z; | |
| 104 | const g: anyerror!?i32 = f; | |
| 105 | ||
| 106 | const a = A{ .a = z }; | |
| 107 | const b: anyerror!?A = a; | |
| 108 | expect((b catch unreachable).?.a == 1); | |
| 109 | } | |
| 110 | ||
| 111 | test "implicitly cast from int to anyerror!?T" { | |
| 112 | implicitIntLitToOptional(); | |
| 113 | comptime implicitIntLitToOptional(); | |
| 114 | } | |
| 115 | fn implicitIntLitToOptional() void { | |
| 116 | const f: ?i32 = 1; | |
| 117 | const g: anyerror!?i32 = 1; | |
| 118 | } | |
| 119 | ||
| 120 | test "return null from fn() anyerror!?&T" { | |
| 121 | const a = returnNullFromOptionalTypeErrorRef(); | |
| 122 | const b = returnNullLitFromOptionalTypeErrorRef(); | |
| 123 | expect((try a) == null and (try b) == null); | |
| 124 | } | |
| 125 | fn returnNullFromOptionalTypeErrorRef() anyerror!?*A { | |
| 126 | const a: ?*A = null; | |
| 127 | return a; | |
| 128 | } | |
| 129 | fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { | |
| 130 | return null; | |
| 131 | } | |
| 132 | ||
| 133 | test "peer type resolution: ?T and T" { | |
| 134 | expect(peerTypeTAndOptionalT(true, false).? == 0); | |
| 135 | expect(peerTypeTAndOptionalT(false, false).? == 3); | |
| 136 | comptime { | |
| 137 | expect(peerTypeTAndOptionalT(true, false).? == 0); | |
| 138 | expect(peerTypeTAndOptionalT(false, false).? == 3); | |
| 139 | } | |
| 140 | } | |
| 141 | fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { | |
| 142 | if (c) { | |
| 143 | return if (b) null else @as(usize, 0); | |
| 144 | } | |
| 145 | ||
| 146 | return @as(usize, 3); | |
| 147 | } | |
| 148 | ||
| 149 | test "peer type resolution: [0]u8 and []const u8" { | |
| 150 | expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | |
| 151 | expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | |
| 152 | comptime { | |
| 153 | expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | |
| 154 | expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | |
| 155 | } | |
| 156 | } | |
| 157 | fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { | |
| 158 | if (a) { | |
| 159 | return &[_]u8{}; | |
| 160 | } | |
| 161 | ||
| 162 | return slice[0..1]; | |
| 163 | } | |
| 164 | ||
| 165 | test "implicitly cast from [N]T to ?[]const T" { | |
| 166 | expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | |
| 167 | comptime expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | |
| 168 | } | |
| 169 | ||
| 170 | fn castToOptionalSlice() ?[]const u8 { | |
| 171 | return "hi"; | |
| 172 | } | |
| 173 | ||
| 174 | test "implicitly cast from [0]T to anyerror![]T" { | |
| 175 | testCastZeroArrayToErrSliceMut(); | |
| 176 | comptime testCastZeroArrayToErrSliceMut(); | |
| 177 | } | |
| 178 | ||
| 179 | fn testCastZeroArrayToErrSliceMut() void { | |
| 180 | expect((gimmeErrOrSlice() catch unreachable).len == 0); | |
| 181 | } | |
| 182 | ||
| 183 | fn gimmeErrOrSlice() anyerror![]u8 { | |
| 184 | return &[_]u8{}; | |
| 185 | } | |
| 186 | ||
| 187 | test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { | |
| 188 | const S = struct { | |
| 189 | fn doTheTest() anyerror!void { | |
| 190 | { | |
| 191 | var data = "hi".*; | |
| 192 | const slice = data[0..]; | |
| 193 | expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); | |
| 194 | expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); | |
| 195 | } | |
| 196 | { | |
| 197 | var data: [2]u8 = "hi".*; | |
| 198 | const slice = data[0..]; | |
| 199 | expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); | |
| 200 | expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); | |
| 201 | } | |
| 202 | } | |
| 203 | }; | |
| 204 | try S.doTheTest(); | |
| 205 | try comptime S.doTheTest(); | |
| 206 | } | |
| 207 | fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { | |
| 208 | if (a) { | |
| 209 | return &[_]u8{}; | |
| 210 | } | |
| 211 | ||
| 212 | return slice[0..1]; | |
| 213 | } | |
| 214 | ||
| 215 | test "resolve undefined with integer" { | |
| 216 | testResolveUndefWithInt(true, 1234); | |
| 217 | comptime testResolveUndefWithInt(true, 1234); | |
| 218 | } | |
| 219 | fn testResolveUndefWithInt(b: bool, x: i32) void { | |
| 220 | const value = if (b) x else undefined; | |
| 221 | if (b) { | |
| 222 | expect(value == x); | |
| 223 | } | |
| 224 | } | |
| 225 | ||
| 226 | test "implicit cast from &const [N]T to []const T" { | |
| 227 | testCastConstArrayRefToConstSlice(); | |
| 228 | comptime testCastConstArrayRefToConstSlice(); | |
| 229 | } | |
| 230 | ||
| 231 | fn testCastConstArrayRefToConstSlice() void { | |
| 232 | { | |
| 233 | const blah = "aoeu".*; | |
| 234 | const const_array_ref = &blah; | |
| 235 | expect(@TypeOf(const_array_ref) == *const [4:0]u8); | |
| 236 | const slice: []const u8 = const_array_ref; | |
| 237 | expect(mem.eql(u8, slice, "aoeu")); | |
| 238 | } | |
| 239 | { | |
| 240 | const blah: [4]u8 = "aoeu".*; | |
| 241 | const const_array_ref = &blah; | |
| 242 | expect(@TypeOf(const_array_ref) == *const [4]u8); | |
| 243 | const slice: []const u8 = const_array_ref; | |
| 244 | expect(mem.eql(u8, slice, "aoeu")); | |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | test "peer type resolution: error and [N]T" { | |
| 249 | expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); | |
| 250 | comptime expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); | |
| 251 | expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); | |
| 252 | comptime expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); | |
| 253 | } | |
| 254 | ||
| 255 | fn testPeerErrorAndArray(x: u8) anyerror![]const u8 { | |
| 256 | return switch (x) { | |
| 257 | 0x00 => "OK", | |
| 258 | else => error.BadValue, | |
| 259 | }; | |
| 260 | } | |
| 261 | fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { | |
| 262 | return switch (x) { | |
| 263 | 0x00 => "OK", | |
| 264 | 0x01 => "OKK", | |
| 265 | else => error.BadValue, | |
| 266 | }; | |
| 267 | } | |
| 268 | ||
| 269 | test "@floatToInt" { | |
| 270 | testFloatToInts(); | |
| 271 | comptime testFloatToInts(); | |
| 272 | } | |
| 273 | ||
| 274 | fn testFloatToInts() void { | |
| 275 | const x = @as(i32, 1e4); | |
| 276 | expect(x == 10000); | |
| 277 | const y = @floatToInt(i32, @as(f32, 1e4)); | |
| 278 | expect(y == 10000); | |
| 279 | expectFloatToInt(f16, 255.1, u8, 255); | |
| 280 | expectFloatToInt(f16, 127.2, i8, 127); | |
| 281 | expectFloatToInt(f16, -128.2, i8, -128); | |
| 282 | expectFloatToInt(f32, 255.1, u8, 255); | |
| 283 | expectFloatToInt(f32, 127.2, i8, 127); | |
| 284 | expectFloatToInt(f32, -128.2, i8, -128); | |
| 285 | expectFloatToInt(comptime_int, 1234, i16, 1234); | |
| 286 | } | |
| 287 | ||
| 288 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void { | |
| 289 | expect(@floatToInt(I, f) == i); | |
| 290 | } | |
| 291 | ||
| 292 | test "cast u128 to f128 and back" { | |
| 293 | comptime testCast128(); | |
| 294 | testCast128(); | |
| 295 | } | |
| 296 | ||
| 297 | fn testCast128() void { | |
| 298 | expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000); | |
| 299 | } | |
| 300 | ||
| 301 | fn cast128Int(x: f128) u128 { | |
| 302 | return @bitCast(u128, x); | |
| 303 | } | |
| 304 | ||
| 305 | fn cast128Float(x: u128) f128 { | |
| 306 | return @bitCast(f128, x); | |
| 307 | } | |
| 308 | ||
| 309 | test "single-item pointer of array to slice and to unknown length pointer" { | |
| 310 | testCastPtrOfArrayToSliceAndPtr(); | |
| 311 | comptime testCastPtrOfArrayToSliceAndPtr(); | |
| 312 | } | |
| 313 | ||
| 314 | fn testCastPtrOfArrayToSliceAndPtr() void { | |
| 315 | { | |
| 316 | var array = "aoeu".*; | |
| 317 | const x: [*]u8 = &array; | |
| 318 | x[0] += 1; | |
| 319 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 320 | const y: []u8 = &array; | |
| 321 | y[0] += 1; | |
| 322 | expect(mem.eql(u8, array[0..], "coeu")); | |
| 323 | } | |
| 324 | { | |
| 325 | var array: [4]u8 = "aoeu".*; | |
| 326 | const x: [*]u8 = &array; | |
| 327 | x[0] += 1; | |
| 328 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 329 | const y: []u8 = &array; | |
| 330 | y[0] += 1; | |
| 331 | expect(mem.eql(u8, array[0..], "coeu")); | |
| 332 | } | |
| 333 | } | |
| 334 | ||
| 335 | test "cast *[1][*]const u8 to [*]const ?[*]const u8" { | |
| 336 | const window_name = [1][*]const u8{"window name"}; | |
| 337 | const x: [*]const ?[*]const u8 = &window_name; | |
| 338 | expect(mem.eql(u8, std.mem.spanZ(@ptrCast([*:0]const u8, x[0].?)), "window name")); | |
| 339 | } | |
| 340 | ||
| 341 | test "@intCast comptime_int" { | |
| 342 | const result = @intCast(i32, 1234); | |
| 343 | expect(@TypeOf(result) == i32); | |
| 344 | expect(result == 1234); | |
| 345 | } | |
| 346 | ||
| 347 | test "@floatCast comptime_int and comptime_float" { | |
| 348 | { | |
| 349 | const result = @floatCast(f16, 1234); | |
| 350 | expect(@TypeOf(result) == f16); | |
| 351 | expect(result == 1234.0); | |
| 352 | } | |
| 353 | { | |
| 354 | const result = @floatCast(f16, 1234.0); | |
| 355 | expect(@TypeOf(result) == f16); | |
| 356 | expect(result == 1234.0); | |
| 357 | } | |
| 358 | { | |
| 359 | const result = @floatCast(f32, 1234); | |
| 360 | expect(@TypeOf(result) == f32); | |
| 361 | expect(result == 1234.0); | |
| 362 | } | |
| 363 | { | |
| 364 | const result = @floatCast(f32, 1234.0); | |
| 365 | expect(@TypeOf(result) == f32); | |
| 366 | expect(result == 1234.0); | |
| 367 | } | |
| 368 | } | |
| 369 | ||
| 370 | test "vector casts" { | |
| 371 | const S = struct { | |
| 372 | fn doTheTest() void { | |
| 373 | // Upcast (implicit, equivalent to @intCast) | |
| 374 | var up0: Vector(2, u8) = [_]u8{ 0x55, 0xaa }; | |
| 375 | var up1 = @as(Vector(2, u16), up0); | |
| 376 | var up2 = @as(Vector(2, u32), up0); | |
| 377 | var up3 = @as(Vector(2, u64), up0); | |
| 378 | // Downcast (safety-checked) | |
| 379 | var down0 = up3; | |
| 380 | var down1 = @intCast(Vector(2, u32), down0); | |
| 381 | var down2 = @intCast(Vector(2, u16), down0); | |
| 382 | var down3 = @intCast(Vector(2, u8), down0); | |
| 383 | ||
| 384 | expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa })); | |
| 385 | expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa })); | |
| 386 | expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa })); | |
| 387 | ||
| 388 | expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa })); | |
| 389 | expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa })); | |
| 390 | expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa })); | |
| 391 | } | |
| 392 | ||
| 393 | fn doTheTestFloat() void { | |
| 394 | var vec = @splat(2, @as(f32, 1234.0)); | |
| 395 | var wider: Vector(2, f64) = vec; | |
| 396 | expect(wider[0] == 1234.0); | |
| 397 | expect(wider[1] == 1234.0); | |
| 398 | } | |
| 399 | }; | |
| 400 | ||
| 401 | S.doTheTest(); | |
| 402 | comptime S.doTheTest(); | |
| 403 | S.doTheTestFloat(); | |
| 404 | comptime S.doTheTestFloat(); | |
| 405 | } | |
| 406 | ||
| 407 | test "comptime_int @intToFloat" { | |
| 408 | { | |
| 409 | const result = @intToFloat(f16, 1234); | |
| 410 | expect(@TypeOf(result) == f16); | |
| 411 | expect(result == 1234.0); | |
| 412 | } | |
| 413 | { | |
| 414 | const result = @intToFloat(f32, 1234); | |
| 415 | expect(@TypeOf(result) == f32); | |
| 416 | expect(result == 1234.0); | |
| 417 | } | |
| 418 | { | |
| 419 | const result = @intToFloat(f64, 1234); | |
| 420 | expect(@TypeOf(result) == f64); | |
| 421 | expect(result == 1234.0); | |
| 422 | } | |
| 423 | { | |
| 424 | const result = @intToFloat(f128, 1234); | |
| 425 | expect(@TypeOf(result) == f128); | |
| 426 | expect(result == 1234.0); | |
| 427 | } | |
| 428 | // big comptime_int (> 64 bits) to f128 conversion | |
| 429 | { | |
| 430 | const result = @intToFloat(f128, 0x1_0000_0000_0000_0000); | |
| 431 | expect(@TypeOf(result) == f128); | |
| 432 | expect(result == 0x1_0000_0000_0000_0000.0); | |
| 433 | } | |
| 434 | } | |
| 435 | ||
| 436 | test "@intCast i32 to u7" { | |
| 437 | var x: u128 = maxInt(u128); | |
| 438 | var y: i32 = 120; | |
| 439 | var z = x >> @intCast(u7, y); | |
| 440 | expect(z == 0xff); | |
| 441 | } | |
| 442 | ||
| 443 | test "@floatCast cast down" { | |
| 444 | { | |
| 445 | var double: f64 = 0.001534; | |
| 446 | var single = @floatCast(f32, double); | |
| 447 | expect(single == 0.001534); | |
| 448 | } | |
| 449 | { | |
| 450 | const double: f64 = 0.001534; | |
| 451 | const single = @floatCast(f32, double); | |
| 452 | expect(single == 0.001534); | |
| 453 | } | |
| 454 | } | |
| 455 | ||
| 456 | test "implicit cast undefined to optional" { | |
| 457 | expect(MakeType(void).getNull() == null); | |
| 458 | expect(MakeType(void).getNonNull() != null); | |
| 459 | } | |
| 460 | ||
| 461 | fn MakeType(comptime T: type) type { | |
| 462 | return struct { | |
| 463 | fn getNull() ?T { | |
| 464 | return null; | |
| 465 | } | |
| 466 | ||
| 467 | fn getNonNull() ?T { | |
| 468 | return @as(T, undefined); | |
| 469 | } | |
| 470 | }; | |
| 471 | } | |
| 472 | ||
| 473 | test "implicit cast from *[N]T to ?[*]T" { | |
| 474 | var x: ?[*]u16 = null; | |
| 475 | var y: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | |
| 476 | ||
| 477 | x = &y; | |
| 478 | expect(std.mem.eql(u16, x.?[0..4], y[0..4])); | |
| 479 | x.?[0] = 8; | |
| 480 | y[3] = 6; | |
| 481 | expect(std.mem.eql(u16, x.?[0..4], y[0..4])); | |
| 482 | } | |
| 483 | ||
| 484 | test "implicit cast from *[N]T to [*c]T" { | |
| 485 | var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | |
| 486 | var y: [*c]u16 = &x; | |
| 487 | ||
| 488 | expect(std.mem.eql(u16, x[0..4], y[0..4])); | |
| 489 | x[0] = 8; | |
| 490 | y[3] = 6; | |
| 491 | expect(std.mem.eql(u16, x[0..4], y[0..4])); | |
| 492 | } | |
| 493 | ||
| 494 | test "implicit cast from *T to ?*c_void" { | |
| 495 | var a: u8 = 1; | |
| 496 | incrementVoidPtrValue(&a); | |
| 497 | std.testing.expect(a == 2); | |
| 498 | } | |
| 499 | ||
| 500 | fn incrementVoidPtrValue(value: ?*c_void) void { | |
| 501 | @ptrCast(*u8, value.?).* += 1; | |
| 502 | } | |
| 503 | ||
| 504 | test "implicit cast from [*]T to ?*c_void" { | |
| 505 | var a = [_]u8{ 3, 2, 1 }; | |
| 506 | var runtime_zero: usize = 0; | |
| 507 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); | |
| 508 | expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); | |
| 509 | } | |
| 510 | ||
| 511 | fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { | |
| 512 | var n: usize = 0; | |
| 513 | while (n < len) : (n += 1) { | |
| 514 | @ptrCast([*]u8, array.?)[n] += 1; | |
| 515 | } | |
| 516 | } | |
| 517 | ||
| 518 | test "*usize to *void" { | |
| 519 | var i = @as(usize, 0); | |
| 520 | var v = @ptrCast(*void, &i); | |
| 521 | v.* = {}; | |
| 522 | } | |
| 523 | ||
| 524 | test "compile time int to ptr of function" { | |
| 525 | foobar(FUNCTION_CONSTANT); | |
| 526 | } | |
| 527 | ||
| 528 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | |
| 529 | pub const PFN_void = fn (*c_void) callconv(.C) void; | |
| 530 | ||
| 531 | fn foobar(func: PFN_void) void { | |
| 532 | std.testing.expect(@ptrToInt(func) == maxInt(usize)); | |
| 533 | } | |
| 534 | ||
| 535 | test "implicit ptr to *c_void" { | |
| 536 | var a: u32 = 1; | |
| 537 | var ptr: *align(@alignOf(u32)) c_void = &a; | |
| 538 | var b: *u32 = @ptrCast(*u32, ptr); | |
| 539 | expect(b.* == 1); | |
| 540 | var ptr2: ?*align(@alignOf(u32)) c_void = &a; | |
| 541 | var c: *u32 = @ptrCast(*u32, ptr2.?); | |
| 542 | expect(c.* == 1); | |
| 543 | } | |
| 544 | ||
| 545 | test "@intCast to comptime_int" { | |
| 546 | expect(@intCast(comptime_int, 0) == 0); | |
| 547 | } | |
| 548 | ||
| 549 | test "implicit cast comptime numbers to any type when the value fits" { | |
| 550 | const a: u64 = 255; | |
| 551 | var b: u8 = a; | |
| 552 | expect(b == 255); | |
| 553 | } | |
| 554 | ||
| 555 | test "@intToEnum passed a comptime_int to an enum with one item" { | |
| 556 | const E = enum { | |
| 557 | A, | |
| 558 | }; | |
| 559 | const x = @intToEnum(E, 0); | |
| 560 | expect(x == E.A); | |
| 561 | } | |
| 562 | ||
| 563 | test "@intToEnum runtime to an extern enum with duplicate values" { | |
| 564 | const E = extern enum(u8) { | |
| 565 | A = 1, | |
| 566 | B = 1, | |
| 567 | }; | |
| 568 | var a: u8 = 1; | |
| 569 | var x = @intToEnum(E, a); | |
| 570 | expect(x == E.A); | |
| 571 | expect(x == E.B); | |
| 572 | } | |
| 573 | ||
| 574 | test "@intCast to u0 and use the result" { | |
| 575 | const S = struct { | |
| 576 | fn doTheTest(zero: u1, one: u1, bigzero: i32) void { | |
| 577 | expect((one << @intCast(u0, bigzero)) == 1); | |
| 578 | expect((zero << @intCast(u0, bigzero)) == 0); | |
| 579 | } | |
| 580 | }; | |
| 581 | S.doTheTest(0, 1, 0); | |
| 582 | comptime S.doTheTest(0, 1, 0); | |
| 583 | } | |
| 584 | ||
| 585 | test "peer type resolution: unreachable, null, slice" { | |
| 586 | const S = struct { | |
| 587 | fn doTheTest(num: usize, word: []const u8) void { | |
| 588 | const result = switch (num) { | |
| 589 | 0 => null, | |
| 590 | 1 => word, | |
| 591 | else => unreachable, | |
| 592 | }; | |
| 593 | expect(mem.eql(u8, result.?, "hi")); | |
| 594 | } | |
| 595 | }; | |
| 596 | S.doTheTest(1, "hi"); | |
| 597 | } | |
| 598 | ||
| 599 | test "peer type resolution: unreachable, error set, unreachable" { | |
| 600 | const Error = error{ | |
| 601 | FileDescriptorAlreadyPresentInSet, | |
| 602 | OperationCausesCircularLoop, | |
| 603 | FileDescriptorNotRegistered, | |
| 604 | SystemResources, | |
| 605 | UserResourceLimitReached, | |
| 606 | FileDescriptorIncompatibleWithEpoll, | |
| 607 | Unexpected, | |
| 608 | }; | |
| 609 | var err = Error.SystemResources; | |
| 610 | const transformed_err = switch (err) { | |
| 611 | error.FileDescriptorAlreadyPresentInSet => unreachable, | |
| 612 | error.OperationCausesCircularLoop => unreachable, | |
| 613 | error.FileDescriptorNotRegistered => unreachable, | |
| 614 | error.SystemResources => error.SystemResources, | |
| 615 | error.UserResourceLimitReached => error.UserResourceLimitReached, | |
| 616 | error.FileDescriptorIncompatibleWithEpoll => unreachable, | |
| 617 | error.Unexpected => unreachable, | |
| 618 | }; | |
| 619 | expect(transformed_err == error.SystemResources); | |
| 620 | } | |
| 621 | ||
| 622 | test "implicit cast comptime_int to comptime_float" { | |
| 623 | comptime expect(@as(comptime_float, 10) == @as(f32, 10)); | |
| 624 | expect(2 == 2.0); | |
| 625 | } | |
| 626 | ||
| 627 | test "implicit cast *[0]T to E![]const u8" { | |
| 628 | var x = @as(anyerror![]const u8, &[0]u8{}); | |
| 629 | expect((x catch unreachable).len == 0); | |
| 630 | } | |
| 631 | ||
| 632 | test "peer cast *[0]T to E![]const T" { | |
| 633 | var buffer: [5]u8 = "abcde".*; | |
| 634 | var buf: anyerror![]const u8 = buffer[0..]; | |
| 635 | var b = false; | |
| 636 | var y = if (b) &[0]u8{} else buf; | |
| 637 | expect(mem.eql(u8, "abcde", y catch unreachable)); | |
| 638 | } | |
| 639 | ||
| 640 | test "peer cast *[0]T to []const T" { | |
| 641 | var buffer: [5]u8 = "abcde".*; | |
| 642 | var buf: []const u8 = buffer[0..]; | |
| 643 | var b = false; | |
| 644 | var y = if (b) &[0]u8{} else buf; | |
| 645 | expect(mem.eql(u8, "abcde", y)); | |
| 646 | } | |
| 647 | ||
| 648 | var global_array: [4]u8 = undefined; | |
| 649 | test "cast from array reference to fn" { | |
| 650 | const f = @ptrCast(fn () callconv(.C) void, &global_array); | |
| 651 | expect(@ptrToInt(f) == @ptrToInt(&global_array)); | |
| 652 | } | |
| 653 | ||
| 654 | test "*const [N]null u8 to ?[]const u8" { | |
| 655 | const S = struct { | |
| 656 | fn doTheTest() void { | |
| 657 | var a = "Hello"; | |
| 658 | var b: ?[]const u8 = a; | |
| 659 | expect(mem.eql(u8, b.?, "Hello")); | |
| 660 | } | |
| 661 | }; | |
| 662 | S.doTheTest(); | |
| 663 | comptime S.doTheTest(); | |
| 664 | } | |
| 665 | ||
| 666 | test "peer resolution of string literals" { | |
| 667 | const S = struct { | |
| 668 | const E = extern enum { | |
| 669 | a, | |
| 670 | b, | |
| 671 | c, | |
| 672 | d, | |
| 673 | }; | |
| 674 | ||
| 675 | fn doTheTest(e: E) void { | |
| 676 | const cmd = switch (e) { | |
| 677 | .a => "one", | |
| 678 | .b => "two", | |
| 679 | .c => "three", | |
| 680 | .d => "four", | |
| 681 | }; | |
| 682 | expect(mem.eql(u8, cmd, "two")); | |
| 683 | } | |
| 684 | }; | |
| 685 | S.doTheTest(.b); | |
| 686 | comptime S.doTheTest(.b); | |
| 687 | } | |
| 688 | ||
| 689 | test "type coercion related to sentinel-termination" { | |
| 690 | const S = struct { | |
| 691 | fn doTheTest() void { | |
| 692 | // [:x]T to []T | |
| 693 | { | |
| 694 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 695 | var slice: [:0]i32 = &array; | |
| 696 | var dest: []i32 = slice; | |
| 697 | expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 698 | } | |
| 699 | ||
| 700 | // [*:x]T to [*]T | |
| 701 | { | |
| 702 | var array = [4:99]i32{ 1, 2, 3, 4 }; | |
| 703 | var dest: [*]i32 = &array; | |
| 704 | expect(dest[0] == 1); | |
| 705 | expect(dest[1] == 2); | |
| 706 | expect(dest[2] == 3); | |
| 707 | expect(dest[3] == 4); | |
| 708 | expect(dest[4] == 99); | |
| 709 | } | |
| 710 | ||
| 711 | // [N:x]T to [N]T | |
| 712 | { | |
| 713 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 714 | var dest: [4]i32 = array; | |
| 715 | expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 716 | } | |
| 717 | ||
| 718 | // *[N:x]T to *[N]T | |
| 719 | { | |
| 720 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 721 | var dest: *[4]i32 = &array; | |
| 722 | expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 723 | } | |
| 724 | ||
| 725 | // [:x]T to [*:x]T | |
| 726 | { | |
| 727 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 728 | var slice: [:0]i32 = &array; | |
| 729 | var dest: [*:0]i32 = slice; | |
| 730 | expect(dest[0] == 1); | |
| 731 | expect(dest[1] == 2); | |
| 732 | expect(dest[2] == 3); | |
| 733 | expect(dest[3] == 4); | |
| 734 | expect(dest[4] == 0); | |
| 735 | } | |
| 736 | } | |
| 737 | }; | |
| 738 | S.doTheTest(); | |
| 739 | comptime S.doTheTest(); | |
| 740 | } | |
| 741 | ||
| 742 | test "cast i8 fn call peers to i32 result" { | |
| 743 | const S = struct { | |
| 744 | fn doTheTest() void { | |
| 745 | var cond = true; | |
| 746 | const value: i32 = if (cond) smallBoi() else bigBoi(); | |
| 747 | expect(value == 123); | |
| 748 | } | |
| 749 | fn smallBoi() i8 { | |
| 750 | return 123; | |
| 751 | } | |
| 752 | fn bigBoi() i16 { | |
| 753 | return 1234; | |
| 754 | } | |
| 755 | }; | |
| 756 | S.doTheTest(); | |
| 757 | comptime S.doTheTest(); | |
| 758 | } | |
| 759 | ||
| 760 | test "return u8 coercing into ?u32 return type" { | |
| 761 | const S = struct { | |
| 762 | fn doTheTest() void { | |
| 763 | expect(foo(123).? == 123); | |
| 764 | } | |
| 765 | fn foo(arg: u8) ?u32 { | |
| 766 | return arg; | |
| 767 | } | |
| 768 | }; | |
| 769 | S.doTheTest(); | |
| 770 | comptime S.doTheTest(); | |
| 771 | } | |
| 772 | ||
| 773 | test "peer result null and comptime_int" { | |
| 774 | const S = struct { | |
| 775 | fn blah(n: i32) ?i32 { | |
| 776 | if (n == 0) { | |
| 777 | return null; | |
| 778 | } else if (n < 0) { | |
| 779 | return -1; | |
| 780 | } else { | |
| 781 | return 1; | |
| 782 | } | |
| 783 | } | |
| 784 | }; | |
| 785 | ||
| 786 | expect(S.blah(0) == null); | |
| 787 | comptime expect(S.blah(0) == null); | |
| 788 | expect(S.blah(10).? == 1); | |
| 789 | comptime expect(S.blah(10).? == 1); | |
| 790 | expect(S.blah(-10).? == -1); | |
| 791 | comptime expect(S.blah(-10).? == -1); | |
| 792 | } | |
| 793 | ||
| 794 | test "peer type resolution implicit cast to return type" { | |
| 795 | const S = struct { | |
| 796 | fn doTheTest() void { | |
| 797 | for ("hello") |c| _ = f(c); | |
| 798 | } | |
| 799 | fn f(c: u8) []const u8 { | |
| 800 | return switch (c) { | |
| 801 | 'h', 'e' => &[_]u8{c}, // should cast to slice | |
| 802 | 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice | |
| 803 | else => ([_]u8{c})[0..], // is a slice | |
| 804 | }; | |
| 805 | } | |
| 806 | }; | |
| 807 | S.doTheTest(); | |
| 808 | comptime S.doTheTest(); | |
| 809 | } | |
| 810 | ||
| 811 | test "peer type resolution implicit cast to variable type" { | |
| 812 | const S = struct { | |
| 813 | fn doTheTest() void { | |
| 814 | var x: []const u8 = undefined; | |
| 815 | for ("hello") |c| x = switch (c) { | |
| 816 | 'h', 'e' => &[_]u8{c}, // should cast to slice | |
| 817 | 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice | |
| 818 | else => ([_]u8{c})[0..], // is a slice | |
| 819 | }; | |
| 820 | } | |
| 821 | }; | |
| 822 | S.doTheTest(); | |
| 823 | comptime S.doTheTest(); | |
| 824 | } | |
| 825 | ||
| 826 | test "variable initialization uses result locations properly with regards to the type" { | |
| 827 | var b = true; | |
| 828 | const x: i32 = if (b) 1 else 2; | |
| 829 | expect(x == 1); | |
| 830 | } | |
| 831 | ||
| 832 | test "cast between [*c]T and ?[*:0]T on fn parameter" { | |
| 833 | const S = struct { | |
| 834 | const Handler = ?fn ([*c]const u8) callconv(.C) void; | |
| 835 | fn addCallback(handler: Handler) void {} | |
| 836 | ||
| 837 | fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {} | |
| 838 | ||
| 839 | fn doTheTest() void { | |
| 840 | addCallback(myCallback); | |
| 841 | } | |
| 842 | }; | |
| 843 | S.doTheTest(); | |
| 844 | } | |
| 845 | ||
| 846 | test "cast between C pointer with different but compatible types" { | |
| 847 | const S = struct { | |
| 848 | fn foo(arg: [*]c_ushort) u16 { | |
| 849 | return arg[0]; | |
| 850 | } | |
| 851 | fn doTheTest() void { | |
| 852 | var x = [_]u16{ 4, 2, 1, 3 }; | |
| 853 | expect(foo(@ptrCast([*]u16, &x)) == 4); | |
| 854 | } | |
| 855 | }; | |
| 856 | S.doTheTest(); | |
| 857 | } | |
| 858 | ||
| 859 | var global_struct: struct { f0: usize } = undefined; | |
| 860 | ||
| 861 | test "assignment to optional pointer result loc" { | |
| 862 | var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct }; | |
| 863 | expect(foo.ptr.? == @ptrCast(*c_void, &global_struct)); | |
| 864 | } | |
| 865 | ||
| 866 | test "peer type resolve string lit with sentinel-terminated mutable slice" { | |
| 867 | var array: [4:0]u8 = undefined; | |
| 868 | array[4] = 0; // TODO remove this when #4372 is solved | |
| 869 | var slice: [:0]u8 = array[0..4 :0]; | |
| 870 | comptime expect(@TypeOf(slice, "hi") == [:0]const u8); | |
| 871 | comptime expect(@TypeOf("hi", slice) == [:0]const u8); | |
| 872 | } | |
| 873 | ||
| 874 | test "peer type unsigned int to signed" { | |
| 875 | var w: u31 = 5; | |
| 876 | var x: u8 = 7; | |
| 877 | var y: i32 = -5; | |
| 878 | var a = w + y + x; | |
| 879 | comptime expect(@TypeOf(a) == i32); | |
| 880 | expect(a == 7); | |
| 881 | } | |
| 882 | ||
| 883 | test "peer type resolve array pointers, one of them const" { | |
| 884 | var array1: [4]u8 = undefined; | |
| 885 | const array2: [5]u8 = undefined; | |
| 886 | comptime expect(@TypeOf(&array1, &array2) == []const u8); | |
| 887 | comptime expect(@TypeOf(&array2, &array1) == []const u8); | |
| 888 | } | |
| 889 | ||
| 890 | test "peer type resolve array pointer and unknown pointer" { | |
| 891 | const const_array: [4]u8 = undefined; | |
| 892 | var array: [4]u8 = undefined; | |
| 893 | var const_ptr: [*]const u8 = undefined; | |
| 894 | var ptr: [*]u8 = undefined; | |
| 895 | ||
| 896 | comptime expect(@TypeOf(&array, ptr) == [*]u8); | |
| 897 | comptime expect(@TypeOf(ptr, &array) == [*]u8); | |
| 898 | ||
| 899 | comptime expect(@TypeOf(&const_array, ptr) == [*]const u8); | |
| 900 | comptime expect(@TypeOf(ptr, &const_array) == [*]const u8); | |
| 901 | ||
| 902 | comptime expect(@TypeOf(&array, const_ptr) == [*]const u8); | |
| 903 | comptime expect(@TypeOf(const_ptr, &array) == [*]const u8); | |
| 904 | ||
| 905 | comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8); | |
| 906 | comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8); | |
| 907 | } | |
| 908 | ||
| 909 | test "comptime float casts" { | |
| 910 | const a = @intToFloat(comptime_float, 1); | |
| 911 | expect(a == 1); | |
| 912 | expect(@TypeOf(a) == comptime_float); | |
| 913 | const b = @floatToInt(comptime_int, 2); | |
| 914 | expect(b == 2); | |
| 915 | expect(@TypeOf(b) == comptime_int); | |
| 916 | } | |
| 917 | ||
| 918 | test "cast from ?[*]T to ??[*]T" { | |
| 919 | const a: ??[*]u8 = @as(?[*]u8, null); | |
| 920 | expect(a != null and a.? == null); | |
| 921 | } | |
| 922 | ||
| 923 | test "cast between *[N]void and []void" { | |
| 924 | var a: [4]void = undefined; | |
| 925 | var b: []void = &a; | |
| 926 | expect(b.len == 4); | |
| 927 | } |
test/behavior/const_slice_child.zig created+47| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | const std = @import("std"); | |
| 2 | const debug = std.debug; | |
| 3 | const testing = std.testing; | |
| 4 | const expect = testing.expect; | |
| 5 | ||
| 6 | var argv: [*]const [*]const u8 = undefined; | |
| 7 | ||
| 8 | test "const slice child" { | |
| 9 | const strs = [_][*]const u8{ | |
| 10 | "one", | |
| 11 | "two", | |
| 12 | "three", | |
| 13 | }; | |
| 14 | argv = &strs; | |
| 15 | bar(strs.len); | |
| 16 | } | |
| 17 | ||
| 18 | fn foo(args: [][]const u8) void { | |
| 19 | expect(args.len == 3); | |
| 20 | expect(streql(args[0], "one")); | |
| 21 | expect(streql(args[1], "two")); | |
| 22 | expect(streql(args[2], "three")); | |
| 23 | } | |
| 24 | ||
| 25 | fn bar(argc: usize) void { | |
| 26 | const args = testing.allocator.alloc([]const u8, argc) catch unreachable; | |
| 27 | defer testing.allocator.free(args); | |
| 28 | for (args) |_, i| { | |
| 29 | const ptr = argv[i]; | |
| 30 | args[i] = ptr[0..strlen(ptr)]; | |
| 31 | } | |
| 32 | foo(args); | |
| 33 | } | |
| 34 | ||
| 35 | fn strlen(ptr: [*]const u8) usize { | |
| 36 | var count: usize = 0; | |
| 37 | while (ptr[count] != 0) : (count += 1) {} | |
| 38 | return count; | |
| 39 | } | |
| 40 | ||
| 41 | fn streql(a: []const u8, b: []const u8) bool { | |
| 42 | if (a.len != b.len) return false; | |
| 43 | for (a) |item, index| { | |
| 44 | if (b[index] != item) return false; | |
| 45 | } | |
| 46 | return true; | |
| 47 | } |
test/behavior/defer.zig created+114| ... | ... | @@ -0,0 +1,114 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const expectError = std.testing.expectError; | |
| 5 | ||
| 6 | var result: [3]u8 = undefined; | |
| 7 | var index: usize = undefined; | |
| 8 | ||
| 9 | fn runSomeErrorDefers(x: bool) !bool { | |
| 10 | index = 0; | |
| 11 | defer { | |
| 12 | result[index] = 'a'; | |
| 13 | index += 1; | |
| 14 | } | |
| 15 | errdefer { | |
| 16 | result[index] = 'b'; | |
| 17 | index += 1; | |
| 18 | } | |
| 19 | defer { | |
| 20 | result[index] = 'c'; | |
| 21 | index += 1; | |
| 22 | } | |
| 23 | return if (x) x else error.FalseNotAllowed; | |
| 24 | } | |
| 25 | ||
| 26 | test "mixing normal and error defers" { | |
| 27 | expect(runSomeErrorDefers(true) catch unreachable); | |
| 28 | expect(result[0] == 'c'); | |
| 29 | expect(result[1] == 'a'); | |
| 30 | ||
| 31 | const ok = runSomeErrorDefers(false) catch |err| x: { | |
| 32 | expect(err == error.FalseNotAllowed); | |
| 33 | break :x true; | |
| 34 | }; | |
| 35 | expect(ok); | |
| 36 | expect(result[0] == 'c'); | |
| 37 | expect(result[1] == 'b'); | |
| 38 | expect(result[2] == 'a'); | |
| 39 | } | |
| 40 | ||
| 41 | test "break and continue inside loop inside defer expression" { | |
| 42 | testBreakContInDefer(10); | |
| 43 | comptime testBreakContInDefer(10); | |
| 44 | } | |
| 45 | ||
| 46 | fn testBreakContInDefer(x: usize) void { | |
| 47 | defer { | |
| 48 | var i: usize = 0; | |
| 49 | while (i < x) : (i += 1) { | |
| 50 | if (i < 5) continue; | |
| 51 | if (i == 5) break; | |
| 52 | } | |
| 53 | expect(i == 5); | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | test "defer and labeled break" { | |
| 58 | var i = @as(usize, 0); | |
| 59 | ||
| 60 | blk: { | |
| 61 | defer i += 1; | |
| 62 | break :blk; | |
| 63 | } | |
| 64 | ||
| 65 | expect(i == 1); | |
| 66 | } | |
| 67 | ||
| 68 | test "errdefer does not apply to fn inside fn" { | |
| 69 | if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| expect(e == error.Bad); | |
| 70 | } | |
| 71 | ||
| 72 | fn testNestedFnErrDefer() anyerror!void { | |
| 73 | var a: i32 = 0; | |
| 74 | errdefer a += 1; | |
| 75 | const S = struct { | |
| 76 | fn baz() anyerror { | |
| 77 | return error.Bad; | |
| 78 | } | |
| 79 | }; | |
| 80 | return S.baz(); | |
| 81 | } | |
| 82 | ||
| 83 | test "return variable while defer expression in scope to modify it" { | |
| 84 | const S = struct { | |
| 85 | fn doTheTest() void { | |
| 86 | expect(notNull().? == 1); | |
| 87 | } | |
| 88 | ||
| 89 | fn notNull() ?u8 { | |
| 90 | var res: ?u8 = 1; | |
| 91 | defer res = null; | |
| 92 | return res; | |
| 93 | } | |
| 94 | }; | |
| 95 | ||
| 96 | S.doTheTest(); | |
| 97 | comptime S.doTheTest(); | |
| 98 | } | |
| 99 | ||
| 100 | test "errdefer with payload" { | |
| 101 | const S = struct { | |
| 102 | fn foo() !i32 { | |
| 103 | errdefer |a| { | |
| 104 | expectEqual(error.One, a); | |
| 105 | } | |
| 106 | return error.One; | |
| 107 | } | |
| 108 | fn doTheTest() void { | |
| 109 | expectError(error.One, foo()); | |
| 110 | } | |
| 111 | }; | |
| 112 | S.doTheTest(); | |
| 113 | comptime S.doTheTest(); | |
| 114 | } |
test/behavior/enum.zig created+1204| ... | ... | @@ -0,0 +1,1204 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const Tag = @import("std").meta.Tag; | |
| 4 | ||
| 5 | test "extern enum" { | |
| 6 | const S = struct { | |
| 7 | const i = extern enum { | |
| 8 | n = 0, | |
| 9 | o = 2, | |
| 10 | p = 4, | |
| 11 | q = 4, | |
| 12 | }; | |
| 13 | fn doTheTest(y: c_int) void { | |
| 14 | var x = i.o; | |
| 15 | switch (x) { | |
| 16 | .n, .p => unreachable, | |
| 17 | .o => {}, | |
| 18 | } | |
| 19 | } | |
| 20 | }; | |
| 21 | S.doTheTest(52); | |
| 22 | comptime S.doTheTest(52); | |
| 23 | } | |
| 24 | ||
| 25 | test "non-exhaustive enum" { | |
| 26 | const S = struct { | |
| 27 | const E = enum(u8) { | |
| 28 | a, | |
| 29 | b, | |
| 30 | _, | |
| 31 | }; | |
| 32 | fn doTheTest(y: u8) void { | |
| 33 | var e: E = .b; | |
| 34 | expect(switch (e) { | |
| 35 | .a => false, | |
| 36 | .b => true, | |
| 37 | _ => false, | |
| 38 | }); | |
| 39 | e = @intToEnum(E, 12); | |
| 40 | expect(switch (e) { | |
| 41 | .a => false, | |
| 42 | .b => false, | |
| 43 | _ => true, | |
| 44 | }); | |
| 45 | ||
| 46 | expect(switch (e) { | |
| 47 | .a => false, | |
| 48 | .b => false, | |
| 49 | else => true, | |
| 50 | }); | |
| 51 | e = .b; | |
| 52 | expect(switch (e) { | |
| 53 | .a => false, | |
| 54 | else => true, | |
| 55 | }); | |
| 56 | ||
| 57 | expect(@typeInfo(E).Enum.fields.len == 2); | |
| 58 | e = @intToEnum(E, 12); | |
| 59 | expect(@enumToInt(e) == 12); | |
| 60 | e = @intToEnum(E, y); | |
| 61 | expect(@enumToInt(e) == 52); | |
| 62 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 63 | } | |
| 64 | }; | |
| 65 | S.doTheTest(52); | |
| 66 | comptime S.doTheTest(52); | |
| 67 | } | |
| 68 | ||
| 69 | test "empty non-exhaustive enum" { | |
| 70 | const S = struct { | |
| 71 | const E = enum(u8) { | |
| 72 | _, | |
| 73 | }; | |
| 74 | fn doTheTest(y: u8) void { | |
| 75 | var e = @intToEnum(E, y); | |
| 76 | expect(switch (e) { | |
| 77 | _ => true, | |
| 78 | }); | |
| 79 | expect(@enumToInt(e) == y); | |
| 80 | ||
| 81 | expect(@typeInfo(E).Enum.fields.len == 0); | |
| 82 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 83 | } | |
| 84 | }; | |
| 85 | S.doTheTest(42); | |
| 86 | comptime S.doTheTest(42); | |
| 87 | } | |
| 88 | ||
| 89 | test "single field non-exhaustive enum" { | |
| 90 | const S = struct { | |
| 91 | const E = enum(u8) { | |
| 92 | a, | |
| 93 | _, | |
| 94 | }; | |
| 95 | fn doTheTest(y: u8) void { | |
| 96 | var e: E = .a; | |
| 97 | expect(switch (e) { | |
| 98 | .a => true, | |
| 99 | _ => false, | |
| 100 | }); | |
| 101 | e = @intToEnum(E, 12); | |
| 102 | expect(switch (e) { | |
| 103 | .a => false, | |
| 104 | _ => true, | |
| 105 | }); | |
| 106 | ||
| 107 | expect(switch (e) { | |
| 108 | .a => false, | |
| 109 | else => true, | |
| 110 | }); | |
| 111 | e = .a; | |
| 112 | expect(switch (e) { | |
| 113 | .a => true, | |
| 114 | else => false, | |
| 115 | }); | |
| 116 | ||
| 117 | expect(@enumToInt(@intToEnum(E, y)) == y); | |
| 118 | expect(@typeInfo(E).Enum.fields.len == 1); | |
| 119 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 120 | } | |
| 121 | }; | |
| 122 | S.doTheTest(23); | |
| 123 | comptime S.doTheTest(23); | |
| 124 | } | |
| 125 | ||
| 126 | test "enum type" { | |
| 127 | const foo1 = Foo{ .One = 13 }; | |
| 128 | const foo2 = Foo{ | |
| 129 | .Two = Point{ | |
| 130 | .x = 1234, | |
| 131 | .y = 5678, | |
| 132 | }, | |
| 133 | }; | |
| 134 | const bar = Bar.B; | |
| 135 | ||
| 136 | expect(bar == Bar.B); | |
| 137 | expect(@typeInfo(Foo).Union.fields.len == 3); | |
| 138 | expect(@typeInfo(Bar).Enum.fields.len == 4); | |
| 139 | expect(@sizeOf(Foo) == @sizeOf(FooNoVoid)); | |
| 140 | expect(@sizeOf(Bar) == 1); | |
| 141 | } | |
| 142 | ||
| 143 | test "enum as return value" { | |
| 144 | switch (returnAnInt(13)) { | |
| 145 | Foo.One => |value| expect(value == 13), | |
| 146 | else => unreachable, | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | const Point = struct { | |
| 151 | x: u64, | |
| 152 | y: u64, | |
| 153 | }; | |
| 154 | const Foo = union(enum) { | |
| 155 | One: i32, | |
| 156 | Two: Point, | |
| 157 | Three: void, | |
| 158 | }; | |
| 159 | const FooNoVoid = union(enum) { | |
| 160 | One: i32, | |
| 161 | Two: Point, | |
| 162 | }; | |
| 163 | const Bar = enum { | |
| 164 | A, | |
| 165 | B, | |
| 166 | C, | |
| 167 | D, | |
| 168 | }; | |
| 169 | ||
| 170 | fn returnAnInt(x: i32) Foo { | |
| 171 | return Foo{ .One = x }; | |
| 172 | } | |
| 173 | ||
| 174 | test "constant enum with payload" { | |
| 175 | var empty = AnEnumWithPayload{ .Empty = {} }; | |
| 176 | var full = AnEnumWithPayload{ .Full = 13 }; | |
| 177 | shouldBeEmpty(empty); | |
| 178 | shouldBeNotEmpty(full); | |
| 179 | } | |
| 180 | ||
| 181 | fn shouldBeEmpty(x: AnEnumWithPayload) void { | |
| 182 | switch (x) { | |
| 183 | AnEnumWithPayload.Empty => {}, | |
| 184 | else => unreachable, | |
| 185 | } | |
| 186 | } | |
| 187 | ||
| 188 | fn shouldBeNotEmpty(x: AnEnumWithPayload) void { | |
| 189 | switch (x) { | |
| 190 | AnEnumWithPayload.Empty => unreachable, | |
| 191 | else => {}, | |
| 192 | } | |
| 193 | } | |
| 194 | ||
| 195 | const AnEnumWithPayload = union(enum) { | |
| 196 | Empty: void, | |
| 197 | Full: i32, | |
| 198 | }; | |
| 199 | ||
| 200 | const Number = enum { | |
| 201 | Zero, | |
| 202 | One, | |
| 203 | Two, | |
| 204 | Three, | |
| 205 | Four, | |
| 206 | }; | |
| 207 | ||
| 208 | test "enum to int" { | |
| 209 | shouldEqual(Number.Zero, 0); | |
| 210 | shouldEqual(Number.One, 1); | |
| 211 | shouldEqual(Number.Two, 2); | |
| 212 | shouldEqual(Number.Three, 3); | |
| 213 | shouldEqual(Number.Four, 4); | |
| 214 | } | |
| 215 | ||
| 216 | fn shouldEqual(n: Number, expected: u3) void { | |
| 217 | expect(@enumToInt(n) == expected); | |
| 218 | } | |
| 219 | ||
| 220 | test "int to enum" { | |
| 221 | testIntToEnumEval(3); | |
| 222 | } | |
| 223 | fn testIntToEnumEval(x: i32) void { | |
| 224 | expect(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three); | |
| 225 | } | |
| 226 | const IntToEnumNumber = enum { | |
| 227 | Zero, | |
| 228 | One, | |
| 229 | Two, | |
| 230 | Three, | |
| 231 | Four, | |
| 232 | }; | |
| 233 | ||
| 234 | test "@tagName" { | |
| 235 | expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 236 | comptime expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 237 | } | |
| 238 | ||
| 239 | test "@tagName extern enum with duplicates" { | |
| 240 | expect(mem.eql(u8, testEnumTagNameBare(ExternDuplicates.B), "A")); | |
| 241 | comptime expect(mem.eql(u8, testEnumTagNameBare(ExternDuplicates.B), "A")); | |
| 242 | } | |
| 243 | ||
| 244 | test "@tagName non-exhaustive enum" { | |
| 245 | expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); | |
| 246 | comptime expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); | |
| 247 | } | |
| 248 | ||
| 249 | fn testEnumTagNameBare(n: anytype) []const u8 { | |
| 250 | return @tagName(n); | |
| 251 | } | |
| 252 | ||
| 253 | const BareNumber = enum { | |
| 254 | One, | |
| 255 | Two, | |
| 256 | Three, | |
| 257 | }; | |
| 258 | ||
| 259 | const ExternDuplicates = extern enum(u8) { | |
| 260 | A = 1, | |
| 261 | B = 1, | |
| 262 | }; | |
| 263 | ||
| 264 | const NonExhaustive = enum(u8) { | |
| 265 | A, | |
| 266 | B, | |
| 267 | _, | |
| 268 | }; | |
| 269 | ||
| 270 | test "enum alignment" { | |
| 271 | comptime { | |
| 272 | expect(@alignOf(AlignTestEnum) >= @alignOf([9]u8)); | |
| 273 | expect(@alignOf(AlignTestEnum) >= @alignOf(u64)); | |
| 274 | } | |
| 275 | } | |
| 276 | ||
| 277 | const AlignTestEnum = union(enum) { | |
| 278 | A: [9]u8, | |
| 279 | B: u64, | |
| 280 | }; | |
| 281 | ||
| 282 | const ValueCount1 = enum { | |
| 283 | I0, | |
| 284 | }; | |
| 285 | const ValueCount2 = enum { | |
| 286 | I0, | |
| 287 | I1, | |
| 288 | }; | |
| 289 | const ValueCount256 = enum { | |
| 290 | I0, | |
| 291 | I1, | |
| 292 | I2, | |
| 293 | I3, | |
| 294 | I4, | |
| 295 | I5, | |
| 296 | I6, | |
| 297 | I7, | |
| 298 | I8, | |
| 299 | I9, | |
| 300 | I10, | |
| 301 | I11, | |
| 302 | I12, | |
| 303 | I13, | |
| 304 | I14, | |
| 305 | I15, | |
| 306 | I16, | |
| 307 | I17, | |
| 308 | I18, | |
| 309 | I19, | |
| 310 | I20, | |
| 311 | I21, | |
| 312 | I22, | |
| 313 | I23, | |
| 314 | I24, | |
| 315 | I25, | |
| 316 | I26, | |
| 317 | I27, | |
| 318 | I28, | |
| 319 | I29, | |
| 320 | I30, | |
| 321 | I31, | |
| 322 | I32, | |
| 323 | I33, | |
| 324 | I34, | |
| 325 | I35, | |
| 326 | I36, | |
| 327 | I37, | |
| 328 | I38, | |
| 329 | I39, | |
| 330 | I40, | |
| 331 | I41, | |
| 332 | I42, | |
| 333 | I43, | |
| 334 | I44, | |
| 335 | I45, | |
| 336 | I46, | |
| 337 | I47, | |
| 338 | I48, | |
| 339 | I49, | |
| 340 | I50, | |
| 341 | I51, | |
| 342 | I52, | |
| 343 | I53, | |
| 344 | I54, | |
| 345 | I55, | |
| 346 | I56, | |
| 347 | I57, | |
| 348 | I58, | |
| 349 | I59, | |
| 350 | I60, | |
| 351 | I61, | |
| 352 | I62, | |
| 353 | I63, | |
| 354 | I64, | |
| 355 | I65, | |
| 356 | I66, | |
| 357 | I67, | |
| 358 | I68, | |
| 359 | I69, | |
| 360 | I70, | |
| 361 | I71, | |
| 362 | I72, | |
| 363 | I73, | |
| 364 | I74, | |
| 365 | I75, | |
| 366 | I76, | |
| 367 | I77, | |
| 368 | I78, | |
| 369 | I79, | |
| 370 | I80, | |
| 371 | I81, | |
| 372 | I82, | |
| 373 | I83, | |
| 374 | I84, | |
| 375 | I85, | |
| 376 | I86, | |
| 377 | I87, | |
| 378 | I88, | |
| 379 | I89, | |
| 380 | I90, | |
| 381 | I91, | |
| 382 | I92, | |
| 383 | I93, | |
| 384 | I94, | |
| 385 | I95, | |
| 386 | I96, | |
| 387 | I97, | |
| 388 | I98, | |
| 389 | I99, | |
| 390 | I100, | |
| 391 | I101, | |
| 392 | I102, | |
| 393 | I103, | |
| 394 | I104, | |
| 395 | I105, | |
| 396 | I106, | |
| 397 | I107, | |
| 398 | I108, | |
| 399 | I109, | |
| 400 | I110, | |
| 401 | I111, | |
| 402 | I112, | |
| 403 | I113, | |
| 404 | I114, | |
| 405 | I115, | |
| 406 | I116, | |
| 407 | I117, | |
| 408 | I118, | |
| 409 | I119, | |
| 410 | I120, | |
| 411 | I121, | |
| 412 | I122, | |
| 413 | I123, | |
| 414 | I124, | |
| 415 | I125, | |
| 416 | I126, | |
| 417 | I127, | |
| 418 | I128, | |
| 419 | I129, | |
| 420 | I130, | |
| 421 | I131, | |
| 422 | I132, | |
| 423 | I133, | |
| 424 | I134, | |
| 425 | I135, | |
| 426 | I136, | |
| 427 | I137, | |
| 428 | I138, | |
| 429 | I139, | |
| 430 | I140, | |
| 431 | I141, | |
| 432 | I142, | |
| 433 | I143, | |
| 434 | I144, | |
| 435 | I145, | |
| 436 | I146, | |
| 437 | I147, | |
| 438 | I148, | |
| 439 | I149, | |
| 440 | I150, | |
| 441 | I151, | |
| 442 | I152, | |
| 443 | I153, | |
| 444 | I154, | |
| 445 | I155, | |
| 446 | I156, | |
| 447 | I157, | |
| 448 | I158, | |
| 449 | I159, | |
| 450 | I160, | |
| 451 | I161, | |
| 452 | I162, | |
| 453 | I163, | |
| 454 | I164, | |
| 455 | I165, | |
| 456 | I166, | |
| 457 | I167, | |
| 458 | I168, | |
| 459 | I169, | |
| 460 | I170, | |
| 461 | I171, | |
| 462 | I172, | |
| 463 | I173, | |
| 464 | I174, | |
| 465 | I175, | |
| 466 | I176, | |
| 467 | I177, | |
| 468 | I178, | |
| 469 | I179, | |
| 470 | I180, | |
| 471 | I181, | |
| 472 | I182, | |
| 473 | I183, | |
| 474 | I184, | |
| 475 | I185, | |
| 476 | I186, | |
| 477 | I187, | |
| 478 | I188, | |
| 479 | I189, | |
| 480 | I190, | |
| 481 | I191, | |
| 482 | I192, | |
| 483 | I193, | |
| 484 | I194, | |
| 485 | I195, | |
| 486 | I196, | |
| 487 | I197, | |
| 488 | I198, | |
| 489 | I199, | |
| 490 | I200, | |
| 491 | I201, | |
| 492 | I202, | |
| 493 | I203, | |
| 494 | I204, | |
| 495 | I205, | |
| 496 | I206, | |
| 497 | I207, | |
| 498 | I208, | |
| 499 | I209, | |
| 500 | I210, | |
| 501 | I211, | |
| 502 | I212, | |
| 503 | I213, | |
| 504 | I214, | |
| 505 | I215, | |
| 506 | I216, | |
| 507 | I217, | |
| 508 | I218, | |
| 509 | I219, | |
| 510 | I220, | |
| 511 | I221, | |
| 512 | I222, | |
| 513 | I223, | |
| 514 | I224, | |
| 515 | I225, | |
| 516 | I226, | |
| 517 | I227, | |
| 518 | I228, | |
| 519 | I229, | |
| 520 | I230, | |
| 521 | I231, | |
| 522 | I232, | |
| 523 | I233, | |
| 524 | I234, | |
| 525 | I235, | |
| 526 | I236, | |
| 527 | I237, | |
| 528 | I238, | |
| 529 | I239, | |
| 530 | I240, | |
| 531 | I241, | |
| 532 | I242, | |
| 533 | I243, | |
| 534 | I244, | |
| 535 | I245, | |
| 536 | I246, | |
| 537 | I247, | |
| 538 | I248, | |
| 539 | I249, | |
| 540 | I250, | |
| 541 | I251, | |
| 542 | I252, | |
| 543 | I253, | |
| 544 | I254, | |
| 545 | I255, | |
| 546 | }; | |
| 547 | const ValueCount257 = enum { | |
| 548 | I0, | |
| 549 | I1, | |
| 550 | I2, | |
| 551 | I3, | |
| 552 | I4, | |
| 553 | I5, | |
| 554 | I6, | |
| 555 | I7, | |
| 556 | I8, | |
| 557 | I9, | |
| 558 | I10, | |
| 559 | I11, | |
| 560 | I12, | |
| 561 | I13, | |
| 562 | I14, | |
| 563 | I15, | |
| 564 | I16, | |
| 565 | I17, | |
| 566 | I18, | |
| 567 | I19, | |
| 568 | I20, | |
| 569 | I21, | |
| 570 | I22, | |
| 571 | I23, | |
| 572 | I24, | |
| 573 | I25, | |
| 574 | I26, | |
| 575 | I27, | |
| 576 | I28, | |
| 577 | I29, | |
| 578 | I30, | |
| 579 | I31, | |
| 580 | I32, | |
| 581 | I33, | |
| 582 | I34, | |
| 583 | I35, | |
| 584 | I36, | |
| 585 | I37, | |
| 586 | I38, | |
| 587 | I39, | |
| 588 | I40, | |
| 589 | I41, | |
| 590 | I42, | |
| 591 | I43, | |
| 592 | I44, | |
| 593 | I45, | |
| 594 | I46, | |
| 595 | I47, | |
| 596 | I48, | |
| 597 | I49, | |
| 598 | I50, | |
| 599 | I51, | |
| 600 | I52, | |
| 601 | I53, | |
| 602 | I54, | |
| 603 | I55, | |
| 604 | I56, | |
| 605 | I57, | |
| 606 | I58, | |
| 607 | I59, | |
| 608 | I60, | |
| 609 | I61, | |
| 610 | I62, | |
| 611 | I63, | |
| 612 | I64, | |
| 613 | I65, | |
| 614 | I66, | |
| 615 | I67, | |
| 616 | I68, | |
| 617 | I69, | |
| 618 | I70, | |
| 619 | I71, | |
| 620 | I72, | |
| 621 | I73, | |
| 622 | I74, | |
| 623 | I75, | |
| 624 | I76, | |
| 625 | I77, | |
| 626 | I78, | |
| 627 | I79, | |
| 628 | I80, | |
| 629 | I81, | |
| 630 | I82, | |
| 631 | I83, | |
| 632 | I84, | |
| 633 | I85, | |
| 634 | I86, | |
| 635 | I87, | |
| 636 | I88, | |
| 637 | I89, | |
| 638 | I90, | |
| 639 | I91, | |
| 640 | I92, | |
| 641 | I93, | |
| 642 | I94, | |
| 643 | I95, | |
| 644 | I96, | |
| 645 | I97, | |
| 646 | I98, | |
| 647 | I99, | |
| 648 | I100, | |
| 649 | I101, | |
| 650 | I102, | |
| 651 | I103, | |
| 652 | I104, | |
| 653 | I105, | |
| 654 | I106, | |
| 655 | I107, | |
| 656 | I108, | |
| 657 | I109, | |
| 658 | I110, | |
| 659 | I111, | |
| 660 | I112, | |
| 661 | I113, | |
| 662 | I114, | |
| 663 | I115, | |
| 664 | I116, | |
| 665 | I117, | |
| 666 | I118, | |
| 667 | I119, | |
| 668 | I120, | |
| 669 | I121, | |
| 670 | I122, | |
| 671 | I123, | |
| 672 | I124, | |
| 673 | I125, | |
| 674 | I126, | |
| 675 | I127, | |
| 676 | I128, | |
| 677 | I129, | |
| 678 | I130, | |
| 679 | I131, | |
| 680 | I132, | |
| 681 | I133, | |
| 682 | I134, | |
| 683 | I135, | |
| 684 | I136, | |
| 685 | I137, | |
| 686 | I138, | |
| 687 | I139, | |
| 688 | I140, | |
| 689 | I141, | |
| 690 | I142, | |
| 691 | I143, | |
| 692 | I144, | |
| 693 | I145, | |
| 694 | I146, | |
| 695 | I147, | |
| 696 | I148, | |
| 697 | I149, | |
| 698 | I150, | |
| 699 | I151, | |
| 700 | I152, | |
| 701 | I153, | |
| 702 | I154, | |
| 703 | I155, | |
| 704 | I156, | |
| 705 | I157, | |
| 706 | I158, | |
| 707 | I159, | |
| 708 | I160, | |
| 709 | I161, | |
| 710 | I162, | |
| 711 | I163, | |
| 712 | I164, | |
| 713 | I165, | |
| 714 | I166, | |
| 715 | I167, | |
| 716 | I168, | |
| 717 | I169, | |
| 718 | I170, | |
| 719 | I171, | |
| 720 | I172, | |
| 721 | I173, | |
| 722 | I174, | |
| 723 | I175, | |
| 724 | I176, | |
| 725 | I177, | |
| 726 | I178, | |
| 727 | I179, | |
| 728 | I180, | |
| 729 | I181, | |
| 730 | I182, | |
| 731 | I183, | |
| 732 | I184, | |
| 733 | I185, | |
| 734 | I186, | |
| 735 | I187, | |
| 736 | I188, | |
| 737 | I189, | |
| 738 | I190, | |
| 739 | I191, | |
| 740 | I192, | |
| 741 | I193, | |
| 742 | I194, | |
| 743 | I195, | |
| 744 | I196, | |
| 745 | I197, | |
| 746 | I198, | |
| 747 | I199, | |
| 748 | I200, | |
| 749 | I201, | |
| 750 | I202, | |
| 751 | I203, | |
| 752 | I204, | |
| 753 | I205, | |
| 754 | I206, | |
| 755 | I207, | |
| 756 | I208, | |
| 757 | I209, | |
| 758 | I210, | |
| 759 | I211, | |
| 760 | I212, | |
| 761 | I213, | |
| 762 | I214, | |
| 763 | I215, | |
| 764 | I216, | |
| 765 | I217, | |
| 766 | I218, | |
| 767 | I219, | |
| 768 | I220, | |
| 769 | I221, | |
| 770 | I222, | |
| 771 | I223, | |
| 772 | I224, | |
| 773 | I225, | |
| 774 | I226, | |
| 775 | I227, | |
| 776 | I228, | |
| 777 | I229, | |
| 778 | I230, | |
| 779 | I231, | |
| 780 | I232, | |
| 781 | I233, | |
| 782 | I234, | |
| 783 | I235, | |
| 784 | I236, | |
| 785 | I237, | |
| 786 | I238, | |
| 787 | I239, | |
| 788 | I240, | |
| 789 | I241, | |
| 790 | I242, | |
| 791 | I243, | |
| 792 | I244, | |
| 793 | I245, | |
| 794 | I246, | |
| 795 | I247, | |
| 796 | I248, | |
| 797 | I249, | |
| 798 | I250, | |
| 799 | I251, | |
| 800 | I252, | |
| 801 | I253, | |
| 802 | I254, | |
| 803 | I255, | |
| 804 | I256, | |
| 805 | }; | |
| 806 | ||
| 807 | test "enum sizes" { | |
| 808 | comptime { | |
| 809 | expect(@sizeOf(ValueCount1) == 0); | |
| 810 | expect(@sizeOf(ValueCount2) == 1); | |
| 811 | expect(@sizeOf(ValueCount256) == 1); | |
| 812 | expect(@sizeOf(ValueCount257) == 2); | |
| 813 | } | |
| 814 | } | |
| 815 | ||
| 816 | const Small2 = enum(u2) { | |
| 817 | One, | |
| 818 | Two, | |
| 819 | }; | |
| 820 | const Small = enum(u2) { | |
| 821 | One, | |
| 822 | Two, | |
| 823 | Three, | |
| 824 | Four, | |
| 825 | }; | |
| 826 | ||
| 827 | test "set enum tag type" { | |
| 828 | { | |
| 829 | var x = Small.One; | |
| 830 | x = Small.Two; | |
| 831 | comptime expect(Tag(Small) == u2); | |
| 832 | } | |
| 833 | { | |
| 834 | var x = Small2.One; | |
| 835 | x = Small2.Two; | |
| 836 | comptime expect(Tag(Small2) == u2); | |
| 837 | } | |
| 838 | } | |
| 839 | ||
| 840 | const A = enum(u3) { | |
| 841 | One, | |
| 842 | Two, | |
| 843 | Three, | |
| 844 | Four, | |
| 845 | One2, | |
| 846 | Two2, | |
| 847 | Three2, | |
| 848 | Four2, | |
| 849 | }; | |
| 850 | ||
| 851 | const B = enum(u3) { | |
| 852 | One3, | |
| 853 | Two3, | |
| 854 | Three3, | |
| 855 | Four3, | |
| 856 | One23, | |
| 857 | Two23, | |
| 858 | Three23, | |
| 859 | Four23, | |
| 860 | }; | |
| 861 | ||
| 862 | const C = enum(u2) { | |
| 863 | One4, | |
| 864 | Two4, | |
| 865 | Three4, | |
| 866 | Four4, | |
| 867 | }; | |
| 868 | ||
| 869 | const BitFieldOfEnums = packed struct { | |
| 870 | a: A, | |
| 871 | b: B, | |
| 872 | c: C, | |
| 873 | }; | |
| 874 | ||
| 875 | const bit_field_1 = BitFieldOfEnums{ | |
| 876 | .a = A.Two, | |
| 877 | .b = B.Three3, | |
| 878 | .c = C.Four4, | |
| 879 | }; | |
| 880 | ||
| 881 | test "bit field access with enum fields" { | |
| 882 | var data = bit_field_1; | |
| 883 | expect(getA(&data) == A.Two); | |
| 884 | expect(getB(&data) == B.Three3); | |
| 885 | expect(getC(&data) == C.Four4); | |
| 886 | comptime expect(@sizeOf(BitFieldOfEnums) == 1); | |
| 887 | ||
| 888 | data.b = B.Four3; | |
| 889 | expect(data.b == B.Four3); | |
| 890 | ||
| 891 | data.a = A.Three; | |
| 892 | expect(data.a == A.Three); | |
| 893 | expect(data.b == B.Four3); | |
| 894 | } | |
| 895 | ||
| 896 | fn getA(data: *const BitFieldOfEnums) A { | |
| 897 | return data.a; | |
| 898 | } | |
| 899 | ||
| 900 | fn getB(data: *const BitFieldOfEnums) B { | |
| 901 | return data.b; | |
| 902 | } | |
| 903 | ||
| 904 | fn getC(data: *const BitFieldOfEnums) C { | |
| 905 | return data.c; | |
| 906 | } | |
| 907 | ||
| 908 | test "casting enum to its tag type" { | |
| 909 | testCastEnumTag(Small2.Two); | |
| 910 | comptime testCastEnumTag(Small2.Two); | |
| 911 | } | |
| 912 | ||
| 913 | fn testCastEnumTag(value: Small2) void { | |
| 914 | expect(@enumToInt(value) == 1); | |
| 915 | } | |
| 916 | ||
| 917 | const MultipleChoice = enum(u32) { | |
| 918 | A = 20, | |
| 919 | B = 40, | |
| 920 | C = 60, | |
| 921 | D = 1000, | |
| 922 | }; | |
| 923 | ||
| 924 | test "enum with specified tag values" { | |
| 925 | testEnumWithSpecifiedTagValues(MultipleChoice.C); | |
| 926 | comptime testEnumWithSpecifiedTagValues(MultipleChoice.C); | |
| 927 | } | |
| 928 | ||
| 929 | fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void { | |
| 930 | expect(@enumToInt(x) == 60); | |
| 931 | expect(1234 == switch (x) { | |
| 932 | MultipleChoice.A => 1, | |
| 933 | MultipleChoice.B => 2, | |
| 934 | MultipleChoice.C => @as(u32, 1234), | |
| 935 | MultipleChoice.D => 4, | |
| 936 | }); | |
| 937 | } | |
| 938 | ||
| 939 | const MultipleChoice2 = enum(u32) { | |
| 940 | Unspecified1, | |
| 941 | A = 20, | |
| 942 | Unspecified2, | |
| 943 | B = 40, | |
| 944 | Unspecified3, | |
| 945 | C = 60, | |
| 946 | Unspecified4, | |
| 947 | D = 1000, | |
| 948 | Unspecified5, | |
| 949 | }; | |
| 950 | ||
| 951 | test "enum with specified and unspecified tag values" { | |
| 952 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); | |
| 953 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); | |
| 954 | } | |
| 955 | ||
| 956 | fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void { | |
| 957 | expect(@enumToInt(x) == 1000); | |
| 958 | expect(1234 == switch (x) { | |
| 959 | MultipleChoice2.A => 1, | |
| 960 | MultipleChoice2.B => 2, | |
| 961 | MultipleChoice2.C => 3, | |
| 962 | MultipleChoice2.D => @as(u32, 1234), | |
| 963 | MultipleChoice2.Unspecified1 => 5, | |
| 964 | MultipleChoice2.Unspecified2 => 6, | |
| 965 | MultipleChoice2.Unspecified3 => 7, | |
| 966 | MultipleChoice2.Unspecified4 => 8, | |
| 967 | MultipleChoice2.Unspecified5 => 9, | |
| 968 | }); | |
| 969 | } | |
| 970 | ||
| 971 | test "cast integer literal to enum" { | |
| 972 | expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1); | |
| 973 | expect(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B); | |
| 974 | } | |
| 975 | ||
| 976 | const EnumWithOneMember = enum { | |
| 977 | Eof, | |
| 978 | }; | |
| 979 | ||
| 980 | fn doALoopThing(id: EnumWithOneMember) void { | |
| 981 | while (true) { | |
| 982 | if (id == EnumWithOneMember.Eof) { | |
| 983 | break; | |
| 984 | } | |
| 985 | @compileError("above if condition should be comptime"); | |
| 986 | } | |
| 987 | } | |
| 988 | ||
| 989 | test "comparison operator on enum with one member is comptime known" { | |
| 990 | doALoopThing(EnumWithOneMember.Eof); | |
| 991 | } | |
| 992 | ||
| 993 | const State = enum { | |
| 994 | Start, | |
| 995 | }; | |
| 996 | test "switch on enum with one member is comptime known" { | |
| 997 | var state = State.Start; | |
| 998 | switch (state) { | |
| 999 | State.Start => return, | |
| 1000 | } | |
| 1001 | @compileError("analysis should not reach here"); | |
| 1002 | } | |
| 1003 | ||
| 1004 | const EnumWithTagValues = enum(u4) { | |
| 1005 | A = 1 << 0, | |
| 1006 | B = 1 << 1, | |
| 1007 | C = 1 << 2, | |
| 1008 | D = 1 << 3, | |
| 1009 | }; | |
| 1010 | test "enum with tag values don't require parens" { | |
| 1011 | expect(@enumToInt(EnumWithTagValues.C) == 0b0100); | |
| 1012 | } | |
| 1013 | ||
| 1014 | test "enum with 1 field but explicit tag type should still have the tag type" { | |
| 1015 | const Enum = enum(u8) { | |
| 1016 | B = 2, | |
| 1017 | }; | |
| 1018 | comptime @import("std").testing.expect(@sizeOf(Enum) == @sizeOf(u8)); | |
| 1019 | } | |
| 1020 | ||
| 1021 | test "empty extern enum with members" { | |
| 1022 | const E = extern enum { | |
| 1023 | A, | |
| 1024 | B, | |
| 1025 | C, | |
| 1026 | }; | |
| 1027 | expect(@sizeOf(E) == @sizeOf(c_int)); | |
| 1028 | } | |
| 1029 | ||
| 1030 | test "tag name with assigned enum values" { | |
| 1031 | const LocalFoo = enum { | |
| 1032 | A = 1, | |
| 1033 | B = 0, | |
| 1034 | }; | |
| 1035 | var b = LocalFoo.B; | |
| 1036 | expect(mem.eql(u8, @tagName(b), "B")); | |
| 1037 | } | |
| 1038 | ||
| 1039 | test "enum literal equality" { | |
| 1040 | const x = .hi; | |
| 1041 | const y = .ok; | |
| 1042 | const z = .hi; | |
| 1043 | ||
| 1044 | expect(x != y); | |
| 1045 | expect(x == z); | |
| 1046 | } | |
| 1047 | ||
| 1048 | test "enum literal cast to enum" { | |
| 1049 | const Color = enum { | |
| 1050 | Auto, | |
| 1051 | Off, | |
| 1052 | On, | |
| 1053 | }; | |
| 1054 | ||
| 1055 | var color1: Color = .Auto; | |
| 1056 | var color2 = Color.Auto; | |
| 1057 | expect(color1 == color2); | |
| 1058 | } | |
| 1059 | ||
| 1060 | test "peer type resolution with enum literal" { | |
| 1061 | const Items = enum { | |
| 1062 | one, | |
| 1063 | two, | |
| 1064 | }; | |
| 1065 | ||
| 1066 | expect(Items.two == .two); | |
| 1067 | expect(.two == Items.two); | |
| 1068 | } | |
| 1069 | ||
| 1070 | test "enum literal in array literal" { | |
| 1071 | const Items = enum { | |
| 1072 | one, | |
| 1073 | two, | |
| 1074 | }; | |
| 1075 | ||
| 1076 | const array = [_]Items{ | |
| 1077 | .one, | |
| 1078 | .two, | |
| 1079 | }; | |
| 1080 | ||
| 1081 | expect(array[0] == .one); | |
| 1082 | expect(array[1] == .two); | |
| 1083 | } | |
| 1084 | ||
| 1085 | test "signed integer as enum tag" { | |
| 1086 | const SignedEnum = enum(i2) { | |
| 1087 | A0 = -1, | |
| 1088 | A1 = 0, | |
| 1089 | A2 = 1, | |
| 1090 | }; | |
| 1091 | ||
| 1092 | expect(@enumToInt(SignedEnum.A0) == -1); | |
| 1093 | expect(@enumToInt(SignedEnum.A1) == 0); | |
| 1094 | expect(@enumToInt(SignedEnum.A2) == 1); | |
| 1095 | } | |
| 1096 | ||
| 1097 | test "enum value allocation" { | |
| 1098 | const LargeEnum = enum(u32) { | |
| 1099 | A0 = 0x80000000, | |
| 1100 | A1, | |
| 1101 | A2, | |
| 1102 | }; | |
| 1103 | ||
| 1104 | expect(@enumToInt(LargeEnum.A0) == 0x80000000); | |
| 1105 | expect(@enumToInt(LargeEnum.A1) == 0x80000001); | |
| 1106 | expect(@enumToInt(LargeEnum.A2) == 0x80000002); | |
| 1107 | } | |
| 1108 | ||
| 1109 | test "enum literal casting to tagged union" { | |
| 1110 | const Arch = union(enum) { | |
| 1111 | x86_64, | |
| 1112 | arm: Arm32, | |
| 1113 | ||
| 1114 | const Arm32 = enum { | |
| 1115 | v8_5a, | |
| 1116 | v8_4a, | |
| 1117 | }; | |
| 1118 | }; | |
| 1119 | ||
| 1120 | var t = true; | |
| 1121 | var x: Arch = .x86_64; | |
| 1122 | var y = if (t) x else .x86_64; | |
| 1123 | switch (y) { | |
| 1124 | .x86_64 => {}, | |
| 1125 | else => @panic("fail"), | |
| 1126 | } | |
| 1127 | } | |
| 1128 | ||
| 1129 | test "enum with one member and custom tag type" { | |
| 1130 | const E = enum(u2) { | |
| 1131 | One, | |
| 1132 | }; | |
| 1133 | expect(@enumToInt(E.One) == 0); | |
| 1134 | const E2 = enum(u2) { | |
| 1135 | One = 2, | |
| 1136 | }; | |
| 1137 | expect(@enumToInt(E2.One) == 2); | |
| 1138 | } | |
| 1139 | ||
| 1140 | test "enum literal casting to optional" { | |
| 1141 | var bar: ?Bar = undefined; | |
| 1142 | bar = .B; | |
| 1143 | ||
| 1144 | expect(bar.? == Bar.B); | |
| 1145 | } | |
| 1146 | ||
| 1147 | test "enum literal casting to error union with payload enum" { | |
| 1148 | var bar: error{B}!Bar = undefined; | |
| 1149 | bar = .B; // should never cast to the error set | |
| 1150 | ||
| 1151 | expect((try bar) == Bar.B); | |
| 1152 | } | |
| 1153 | ||
| 1154 | test "enum with one member and u1 tag type @enumToInt" { | |
| 1155 | const Enum = enum(u1) { | |
| 1156 | Test, | |
| 1157 | }; | |
| 1158 | expect(@enumToInt(Enum.Test) == 0); | |
| 1159 | } | |
| 1160 | ||
| 1161 | test "enum with comptime_int tag type" { | |
| 1162 | const Enum = enum(comptime_int) { | |
| 1163 | One = 3, | |
| 1164 | Two = 2, | |
| 1165 | Three = 1, | |
| 1166 | }; | |
| 1167 | comptime expect(Tag(Enum) == comptime_int); | |
| 1168 | } | |
| 1169 | ||
| 1170 | test "enum with one member default to u0 tag type" { | |
| 1171 | const E0 = enum { | |
| 1172 | X, | |
| 1173 | }; | |
| 1174 | comptime expect(Tag(E0) == u0); | |
| 1175 | } | |
| 1176 | ||
| 1177 | test "tagName on enum literals" { | |
| 1178 | expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); | |
| 1179 | comptime expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); | |
| 1180 | } | |
| 1181 | ||
| 1182 | test "method call on an enum" { | |
| 1183 | const S = struct { | |
| 1184 | const E = enum { | |
| 1185 | one, | |
| 1186 | two, | |
| 1187 | ||
| 1188 | fn method(self: *E) bool { | |
| 1189 | return self.* == .two; | |
| 1190 | } | |
| 1191 | ||
| 1192 | fn generic_method(self: *E, foo: anytype) bool { | |
| 1193 | return self.* == .two and foo == bool; | |
| 1194 | } | |
| 1195 | }; | |
| 1196 | fn doTheTest() void { | |
| 1197 | var e = E.two; | |
| 1198 | expect(e.method()); | |
| 1199 | expect(e.generic_method(bool)); | |
| 1200 | } | |
| 1201 | }; | |
| 1202 | S.doTheTest(); | |
| 1203 | comptime S.doTheTest(); | |
| 1204 | } |
test/behavior/enum_with_members.zig created+27| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const fmt = @import("std").fmt; | |
| 4 | ||
| 5 | const ET = union(enum) { | |
| 6 | SINT: i32, | |
| 7 | UINT: u32, | |
| 8 | ||
| 9 | pub fn print(a: *const ET, buf: []u8) anyerror!usize { | |
| 10 | return switch (a.*) { | |
| 11 | ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}), | |
| 12 | ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}), | |
| 13 | }; | |
| 14 | } | |
| 15 | }; | |
| 16 | ||
| 17 | test "enum with members" { | |
| 18 | const a = ET{ .SINT = -42 }; | |
| 19 | const b = ET{ .UINT = 42 }; | |
| 20 | var buf: [20]u8 = undefined; | |
| 21 | ||
| 22 | expect((a.print(buf[0..]) catch unreachable) == 3); | |
| 23 | expect(mem.eql(u8, buf[0..3], "-42")); | |
| 24 | ||
| 25 | expect((b.print(buf[0..]) catch unreachable) == 2); | |
| 26 | expect(mem.eql(u8, buf[0..2], "42")); | |
| 27 | } |
test/behavior/error.zig created+452| ... | ... | @@ -0,0 +1,452 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectError = std.testing.expectError; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const mem = std.mem; | |
| 6 | ||
| 7 | pub fn foo() anyerror!i32 { | |
| 8 | const x = try bar(); | |
| 9 | return x + 1; | |
| 10 | } | |
| 11 | ||
| 12 | pub fn bar() anyerror!i32 { | |
| 13 | return 13; | |
| 14 | } | |
| 15 | ||
| 16 | pub fn baz() anyerror!i32 { | |
| 17 | const y = foo() catch 1234; | |
| 18 | return y + 1; | |
| 19 | } | |
| 20 | ||
| 21 | test "error wrapping" { | |
| 22 | expect((baz() catch unreachable) == 15); | |
| 23 | } | |
| 24 | ||
| 25 | fn gimmeItBroke() []const u8 { | |
| 26 | return @errorName(error.ItBroke); | |
| 27 | } | |
| 28 | ||
| 29 | test "@errorName" { | |
| 30 | expect(mem.eql(u8, @errorName(error.AnError), "AnError")); | |
| 31 | expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName")); | |
| 32 | } | |
| 33 | ||
| 34 | test "error values" { | |
| 35 | const a = @errorToInt(error.err1); | |
| 36 | const b = @errorToInt(error.err2); | |
| 37 | expect(a != b); | |
| 38 | } | |
| 39 | ||
| 40 | test "redefinition of error values allowed" { | |
| 41 | shouldBeNotEqual(error.AnError, error.SecondError); | |
| 42 | } | |
| 43 | fn shouldBeNotEqual(a: anyerror, b: anyerror) void { | |
| 44 | if (a == b) unreachable; | |
| 45 | } | |
| 46 | ||
| 47 | test "error binary operator" { | |
| 48 | const a = errBinaryOperatorG(true) catch 3; | |
| 49 | const b = errBinaryOperatorG(false) catch 3; | |
| 50 | expect(a == 3); | |
| 51 | expect(b == 10); | |
| 52 | } | |
| 53 | fn errBinaryOperatorG(x: bool) anyerror!isize { | |
| 54 | return if (x) error.ItBroke else @as(isize, 10); | |
| 55 | } | |
| 56 | ||
| 57 | test "unwrap simple value from error" { | |
| 58 | const i = unwrapSimpleValueFromErrorDo() catch unreachable; | |
| 59 | expect(i == 13); | |
| 60 | } | |
| 61 | fn unwrapSimpleValueFromErrorDo() anyerror!isize { | |
| 62 | return 13; | |
| 63 | } | |
| 64 | ||
| 65 | test "error return in assignment" { | |
| 66 | doErrReturnInAssignment() catch unreachable; | |
| 67 | } | |
| 68 | ||
| 69 | fn doErrReturnInAssignment() anyerror!void { | |
| 70 | var x: i32 = undefined; | |
| 71 | x = try makeANonErr(); | |
| 72 | } | |
| 73 | ||
| 74 | fn makeANonErr() anyerror!i32 { | |
| 75 | return 1; | |
| 76 | } | |
| 77 | ||
| 78 | test "error union type " { | |
| 79 | testErrorUnionType(); | |
| 80 | comptime testErrorUnionType(); | |
| 81 | } | |
| 82 | ||
| 83 | fn testErrorUnionType() void { | |
| 84 | const x: anyerror!i32 = 1234; | |
| 85 | if (x) |value| expect(value == 1234) else |_| unreachable; | |
| 86 | expect(@typeInfo(@TypeOf(x)) == .ErrorUnion); | |
| 87 | expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet); | |
| 88 | expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror); | |
| 89 | } | |
| 90 | ||
| 91 | test "error set type" { | |
| 92 | testErrorSetType(); | |
| 93 | comptime testErrorSetType(); | |
| 94 | } | |
| 95 | ||
| 96 | const MyErrSet = error{ | |
| 97 | OutOfMemory, | |
| 98 | FileNotFound, | |
| 99 | }; | |
| 100 | ||
| 101 | fn testErrorSetType() void { | |
| 102 | expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2); | |
| 103 | ||
| 104 | const a: MyErrSet!i32 = 5678; | |
| 105 | const b: MyErrSet!i32 = MyErrSet.OutOfMemory; | |
| 106 | ||
| 107 | if (a) |value| expect(value == 5678) else |err| switch (err) { | |
| 108 | error.OutOfMemory => unreachable, | |
| 109 | error.FileNotFound => unreachable, | |
| 110 | } | |
| 111 | } | |
| 112 | ||
| 113 | test "explicit error set cast" { | |
| 114 | testExplicitErrorSetCast(Set1.A); | |
| 115 | comptime testExplicitErrorSetCast(Set1.A); | |
| 116 | } | |
| 117 | ||
| 118 | const Set1 = error{ | |
| 119 | A, | |
| 120 | B, | |
| 121 | }; | |
| 122 | const Set2 = error{ | |
| 123 | A, | |
| 124 | C, | |
| 125 | }; | |
| 126 | ||
| 127 | fn testExplicitErrorSetCast(set1: Set1) void { | |
| 128 | var x = @errSetCast(Set2, set1); | |
| 129 | var y = @errSetCast(Set1, x); | |
| 130 | expect(y == error.A); | |
| 131 | } | |
| 132 | ||
| 133 | test "comptime test error for empty error set" { | |
| 134 | testComptimeTestErrorEmptySet(1234); | |
| 135 | comptime testComptimeTestErrorEmptySet(1234); | |
| 136 | } | |
| 137 | ||
| 138 | const EmptyErrorSet = error{}; | |
| 139 | ||
| 140 | fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void { | |
| 141 | if (x) |v| expect(v == 1234) else |err| @compileError("bad"); | |
| 142 | } | |
| 143 | ||
| 144 | test "syntax: optional operator in front of error union operator" { | |
| 145 | comptime { | |
| 146 | expect(?(anyerror!i32) == ?(anyerror!i32)); | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | test "comptime err to int of error set with only 1 possible value" { | |
| 151 | testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A)); | |
| 152 | comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A)); | |
| 153 | } | |
| 154 | fn testErrToIntWithOnePossibleValue( | |
| 155 | x: error{A}, | |
| 156 | comptime value: u32, | |
| 157 | ) void { | |
| 158 | if (@errorToInt(x) != value) { | |
| 159 | @compileError("bad"); | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | test "empty error union" { | |
| 164 | const x = error{} || error{}; | |
| 165 | } | |
| 166 | ||
| 167 | test "error union peer type resolution" { | |
| 168 | testErrorUnionPeerTypeResolution(1); | |
| 169 | } | |
| 170 | ||
| 171 | fn testErrorUnionPeerTypeResolution(x: i32) void { | |
| 172 | const y = switch (x) { | |
| 173 | 1 => bar_1(), | |
| 174 | 2 => baz_1(), | |
| 175 | else => quux_1(), | |
| 176 | }; | |
| 177 | if (y) |_| { | |
| 178 | @panic("expected error"); | |
| 179 | } else |e| { | |
| 180 | expect(e == error.A); | |
| 181 | } | |
| 182 | } | |
| 183 | ||
| 184 | fn bar_1() anyerror { | |
| 185 | return error.A; | |
| 186 | } | |
| 187 | ||
| 188 | fn baz_1() !i32 { | |
| 189 | return error.B; | |
| 190 | } | |
| 191 | ||
| 192 | fn quux_1() !i32 { | |
| 193 | return error.C; | |
| 194 | } | |
| 195 | ||
| 196 | test "error: fn returning empty error set can be passed as fn returning any error" { | |
| 197 | entry(); | |
| 198 | comptime entry(); | |
| 199 | } | |
| 200 | ||
| 201 | fn entry() void { | |
| 202 | foo2(bar2); | |
| 203 | } | |
| 204 | ||
| 205 | fn foo2(f: fn () anyerror!void) void { | |
| 206 | const x = f(); | |
| 207 | } | |
| 208 | ||
| 209 | fn bar2() (error{}!void) {} | |
| 210 | ||
| 211 | test "error: Zero sized error set returned with value payload crash" { | |
| 212 | _ = foo3(0) catch {}; | |
| 213 | _ = comptime foo3(0) catch {}; | |
| 214 | } | |
| 215 | ||
| 216 | const Error = error{}; | |
| 217 | fn foo3(b: usize) Error!usize { | |
| 218 | return b; | |
| 219 | } | |
| 220 | ||
| 221 | test "error: Infer error set from literals" { | |
| 222 | _ = nullLiteral("n") catch |err| handleErrors(err); | |
| 223 | _ = floatLiteral("n") catch |err| handleErrors(err); | |
| 224 | _ = intLiteral("n") catch |err| handleErrors(err); | |
| 225 | _ = comptime nullLiteral("n") catch |err| handleErrors(err); | |
| 226 | _ = comptime floatLiteral("n") catch |err| handleErrors(err); | |
| 227 | _ = comptime intLiteral("n") catch |err| handleErrors(err); | |
| 228 | } | |
| 229 | ||
| 230 | fn handleErrors(err: anytype) noreturn { | |
| 231 | switch (err) { | |
| 232 | error.T => {}, | |
| 233 | } | |
| 234 | ||
| 235 | unreachable; | |
| 236 | } | |
| 237 | ||
| 238 | fn nullLiteral(str: []const u8) !?i64 { | |
| 239 | if (str[0] == 'n') return null; | |
| 240 | ||
| 241 | return error.T; | |
| 242 | } | |
| 243 | ||
| 244 | fn floatLiteral(str: []const u8) !?f64 { | |
| 245 | if (str[0] == 'n') return 1.0; | |
| 246 | ||
| 247 | return error.T; | |
| 248 | } | |
| 249 | ||
| 250 | fn intLiteral(str: []const u8) !?i64 { | |
| 251 | if (str[0] == 'n') return 1; | |
| 252 | ||
| 253 | return error.T; | |
| 254 | } | |
| 255 | ||
| 256 | test "nested error union function call in optional unwrap" { | |
| 257 | const S = struct { | |
| 258 | const Foo = struct { | |
| 259 | a: i32, | |
| 260 | }; | |
| 261 | ||
| 262 | fn errorable() !i32 { | |
| 263 | var x: Foo = (try getFoo()) orelse return error.Other; | |
| 264 | return x.a; | |
| 265 | } | |
| 266 | ||
| 267 | fn errorable2() !i32 { | |
| 268 | var x: Foo = (try getFoo2()) orelse return error.Other; | |
| 269 | return x.a; | |
| 270 | } | |
| 271 | ||
| 272 | fn errorable3() !i32 { | |
| 273 | var x: Foo = (try getFoo3()) orelse return error.Other; | |
| 274 | return x.a; | |
| 275 | } | |
| 276 | ||
| 277 | fn getFoo() anyerror!?Foo { | |
| 278 | return Foo{ .a = 1234 }; | |
| 279 | } | |
| 280 | ||
| 281 | fn getFoo2() anyerror!?Foo { | |
| 282 | return error.Failure; | |
| 283 | } | |
| 284 | ||
| 285 | fn getFoo3() anyerror!?Foo { | |
| 286 | return null; | |
| 287 | } | |
| 288 | }; | |
| 289 | expect((try S.errorable()) == 1234); | |
| 290 | expectError(error.Failure, S.errorable2()); | |
| 291 | expectError(error.Other, S.errorable3()); | |
| 292 | comptime { | |
| 293 | expect((try S.errorable()) == 1234); | |
| 294 | expectError(error.Failure, S.errorable2()); | |
| 295 | expectError(error.Other, S.errorable3()); | |
| 296 | } | |
| 297 | } | |
| 298 | ||
| 299 | test "widen cast integer payload of error union function call" { | |
| 300 | const S = struct { | |
| 301 | fn errorable() !u64 { | |
| 302 | var x = @as(u64, try number()); | |
| 303 | return x; | |
| 304 | } | |
| 305 | ||
| 306 | fn number() anyerror!u32 { | |
| 307 | return 1234; | |
| 308 | } | |
| 309 | }; | |
| 310 | expect((try S.errorable()) == 1234); | |
| 311 | } | |
| 312 | ||
| 313 | test "return function call to error set from error union function" { | |
| 314 | const S = struct { | |
| 315 | fn errorable() anyerror!i32 { | |
| 316 | return fail(); | |
| 317 | } | |
| 318 | ||
| 319 | fn fail() anyerror { | |
| 320 | return error.Failure; | |
| 321 | } | |
| 322 | }; | |
| 323 | expectError(error.Failure, S.errorable()); | |
| 324 | comptime expectError(error.Failure, S.errorable()); | |
| 325 | } | |
| 326 | ||
| 327 | test "optional error set is the same size as error set" { | |
| 328 | comptime expect(@sizeOf(?anyerror) == @sizeOf(anyerror)); | |
| 329 | const S = struct { | |
| 330 | fn returnsOptErrSet() ?anyerror { | |
| 331 | return null; | |
| 332 | } | |
| 333 | }; | |
| 334 | expect(S.returnsOptErrSet() == null); | |
| 335 | comptime expect(S.returnsOptErrSet() == null); | |
| 336 | } | |
| 337 | ||
| 338 | test "debug info for optional error set" { | |
| 339 | const SomeError = error{Hello}; | |
| 340 | var a_local_variable: ?SomeError = null; | |
| 341 | } | |
| 342 | ||
| 343 | test "nested catch" { | |
| 344 | const S = struct { | |
| 345 | fn entry() void { | |
| 346 | expectError(error.Bad, func()); | |
| 347 | } | |
| 348 | fn fail() anyerror!Foo { | |
| 349 | return error.Wrong; | |
| 350 | } | |
| 351 | fn func() anyerror!Foo { | |
| 352 | const x = fail() catch | |
| 353 | fail() catch | |
| 354 | return error.Bad; | |
| 355 | unreachable; | |
| 356 | } | |
| 357 | const Foo = struct { | |
| 358 | field: i32, | |
| 359 | }; | |
| 360 | }; | |
| 361 | S.entry(); | |
| 362 | comptime S.entry(); | |
| 363 | } | |
| 364 | ||
| 365 | test "implicit cast to optional to error union to return result loc" { | |
| 366 | const S = struct { | |
| 367 | fn entry() void { | |
| 368 | var x: Foo = undefined; | |
| 369 | if (func(&x)) |opt| { | |
| 370 | expect(opt != null); | |
| 371 | } else |_| @panic("expected non error"); | |
| 372 | } | |
| 373 | fn func(f: *Foo) anyerror!?*Foo { | |
| 374 | return f; | |
| 375 | } | |
| 376 | const Foo = struct { | |
| 377 | field: i32, | |
| 378 | }; | |
| 379 | }; | |
| 380 | S.entry(); | |
| 381 | //comptime S.entry(); TODO | |
| 382 | } | |
| 383 | ||
| 384 | test "function pointer with return type that is error union with payload which is pointer of parent struct" { | |
| 385 | const S = struct { | |
| 386 | const Foo = struct { | |
| 387 | fun: fn (a: i32) (anyerror!*Foo), | |
| 388 | }; | |
| 389 | ||
| 390 | const Err = error{UnspecifiedErr}; | |
| 391 | ||
| 392 | fn bar(a: i32) anyerror!*Foo { | |
| 393 | return Err.UnspecifiedErr; | |
| 394 | } | |
| 395 | ||
| 396 | fn doTheTest() void { | |
| 397 | var x = Foo{ .fun = bar }; | |
| 398 | expectError(error.UnspecifiedErr, x.fun(1)); | |
| 399 | } | |
| 400 | }; | |
| 401 | S.doTheTest(); | |
| 402 | } | |
| 403 | ||
| 404 | test "return result loc as peer result loc in inferred error set function" { | |
| 405 | const S = struct { | |
| 406 | fn doTheTest() void { | |
| 407 | if (foo(2)) |x| { | |
| 408 | expect(x.Two); | |
| 409 | } else |e| switch (e) { | |
| 410 | error.Whatever => @panic("fail"), | |
| 411 | } | |
| 412 | expectError(error.Whatever, foo(99)); | |
| 413 | } | |
| 414 | const FormValue = union(enum) { | |
| 415 | One: void, | |
| 416 | Two: bool, | |
| 417 | }; | |
| 418 | ||
| 419 | fn foo(id: u64) !FormValue { | |
| 420 | return switch (id) { | |
| 421 | 2 => FormValue{ .Two = true }, | |
| 422 | 1 => FormValue{ .One = {} }, | |
| 423 | else => return error.Whatever, | |
| 424 | }; | |
| 425 | } | |
| 426 | }; | |
| 427 | S.doTheTest(); | |
| 428 | comptime S.doTheTest(); | |
| 429 | } | |
| 430 | ||
| 431 | test "error payload type is correctly resolved" { | |
| 432 | const MyIntWrapper = struct { | |
| 433 | const Self = @This(); | |
| 434 | ||
| 435 | x: i32, | |
| 436 | ||
| 437 | pub fn create() anyerror!Self { | |
| 438 | return Self{ .x = 42 }; | |
| 439 | } | |
| 440 | }; | |
| 441 | ||
| 442 | expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create()); | |
| 443 | } | |
| 444 | ||
| 445 | test "error union comptime caching" { | |
| 446 | const S = struct { | |
| 447 | fn foo(comptime arg: anytype) void {} | |
| 448 | }; | |
| 449 | ||
| 450 | S.foo(@as(anyerror!void, {})); | |
| 451 | S.foo(@as(anyerror!void, {})); | |
| 452 | } | |
| \ No newline at end of file |
test/behavior/eval.zig created+832| ... | ... | @@ -0,0 +1,832 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "compile time recursion" { | |
| 6 | expect(some_data.len == 21); | |
| 7 | } | |
| 8 | var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined; | |
| 9 | fn fibonacci(x: i32) i32 { | |
| 10 | if (x <= 1) return 1; | |
| 11 | return fibonacci(x - 1) + fibonacci(x - 2); | |
| 12 | } | |
| 13 | ||
| 14 | fn unwrapAndAddOne(blah: ?i32) i32 { | |
| 15 | return blah.? + 1; | |
| 16 | } | |
| 17 | const should_be_1235 = unwrapAndAddOne(1234); | |
| 18 | test "static add one" { | |
| 19 | expect(should_be_1235 == 1235); | |
| 20 | } | |
| 21 | ||
| 22 | test "inlined loop" { | |
| 23 | comptime var i = 0; | |
| 24 | comptime var sum = 0; | |
| 25 | inline while (i <= 5) : (i += 1) | |
| 26 | sum += i; | |
| 27 | expect(sum == 15); | |
| 28 | } | |
| 29 | ||
| 30 | fn gimme1or2(comptime a: bool) i32 { | |
| 31 | const x: i32 = 1; | |
| 32 | const y: i32 = 2; | |
| 33 | comptime var z: i32 = if (a) x else y; | |
| 34 | return z; | |
| 35 | } | |
| 36 | test "inline variable gets result of const if" { | |
| 37 | expect(gimme1or2(true) == 1); | |
| 38 | expect(gimme1or2(false) == 2); | |
| 39 | } | |
| 40 | ||
| 41 | test "static function evaluation" { | |
| 42 | expect(statically_added_number == 3); | |
| 43 | } | |
| 44 | const statically_added_number = staticAdd(1, 2); | |
| 45 | fn staticAdd(a: i32, b: i32) i32 { | |
| 46 | return a + b; | |
| 47 | } | |
| 48 | ||
| 49 | test "const expr eval on single expr blocks" { | |
| 50 | expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 51 | comptime expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 52 | } | |
| 53 | ||
| 54 | fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 { | |
| 55 | const literal = 3; | |
| 56 | ||
| 57 | const result = if (b) b: { | |
| 58 | break :b literal; | |
| 59 | } else b: { | |
| 60 | break :b x; | |
| 61 | }; | |
| 62 | ||
| 63 | return result; | |
| 64 | } | |
| 65 | ||
| 66 | test "statically initialized list" { | |
| 67 | expect(static_point_list[0].x == 1); | |
| 68 | expect(static_point_list[0].y == 2); | |
| 69 | expect(static_point_list[1].x == 3); | |
| 70 | expect(static_point_list[1].y == 4); | |
| 71 | } | |
| 72 | const Point = struct { | |
| 73 | x: i32, | |
| 74 | y: i32, | |
| 75 | }; | |
| 76 | const static_point_list = [_]Point{ | |
| 77 | makePoint(1, 2), | |
| 78 | makePoint(3, 4), | |
| 79 | }; | |
| 80 | fn makePoint(x: i32, y: i32) Point { | |
| 81 | return Point{ | |
| 82 | .x = x, | |
| 83 | .y = y, | |
| 84 | }; | |
| 85 | } | |
| 86 | ||
| 87 | test "static eval list init" { | |
| 88 | expect(static_vec3.data[2] == 1.0); | |
| 89 | expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0); | |
| 90 | } | |
| 91 | const static_vec3 = vec3(0.0, 0.0, 1.0); | |
| 92 | pub const Vec3 = struct { | |
| 93 | data: [3]f32, | |
| 94 | }; | |
| 95 | pub fn vec3(x: f32, y: f32, z: f32) Vec3 { | |
| 96 | return Vec3{ | |
| 97 | .data = [_]f32{ | |
| 98 | x, | |
| 99 | y, | |
| 100 | z, | |
| 101 | }, | |
| 102 | }; | |
| 103 | } | |
| 104 | ||
| 105 | test "constant expressions" { | |
| 106 | var array: [array_size]u8 = undefined; | |
| 107 | expect(@sizeOf(@TypeOf(array)) == 20); | |
| 108 | } | |
| 109 | const array_size: u8 = 20; | |
| 110 | ||
| 111 | test "constant struct with negation" { | |
| 112 | expect(vertices[0].x == -0.6); | |
| 113 | } | |
| 114 | const Vertex = struct { | |
| 115 | x: f32, | |
| 116 | y: f32, | |
| 117 | r: f32, | |
| 118 | g: f32, | |
| 119 | b: f32, | |
| 120 | }; | |
| 121 | const vertices = [_]Vertex{ | |
| 122 | Vertex{ | |
| 123 | .x = -0.6, | |
| 124 | .y = -0.4, | |
| 125 | .r = 1.0, | |
| 126 | .g = 0.0, | |
| 127 | .b = 0.0, | |
| 128 | }, | |
| 129 | Vertex{ | |
| 130 | .x = 0.6, | |
| 131 | .y = -0.4, | |
| 132 | .r = 0.0, | |
| 133 | .g = 1.0, | |
| 134 | .b = 0.0, | |
| 135 | }, | |
| 136 | Vertex{ | |
| 137 | .x = 0.0, | |
| 138 | .y = 0.6, | |
| 139 | .r = 0.0, | |
| 140 | .g = 0.0, | |
| 141 | .b = 1.0, | |
| 142 | }, | |
| 143 | }; | |
| 144 | ||
| 145 | test "statically initialized struct" { | |
| 146 | st_init_str_foo.x += 1; | |
| 147 | expect(st_init_str_foo.x == 14); | |
| 148 | } | |
| 149 | const StInitStrFoo = struct { | |
| 150 | x: i32, | |
| 151 | y: bool, | |
| 152 | }; | |
| 153 | var st_init_str_foo = StInitStrFoo{ | |
| 154 | .x = 13, | |
| 155 | .y = true, | |
| 156 | }; | |
| 157 | ||
| 158 | test "statically initalized array literal" { | |
| 159 | const y: [4]u8 = st_init_arr_lit_x; | |
| 160 | expect(y[3] == 4); | |
| 161 | } | |
| 162 | const st_init_arr_lit_x = [_]u8{ | |
| 163 | 1, | |
| 164 | 2, | |
| 165 | 3, | |
| 166 | 4, | |
| 167 | }; | |
| 168 | ||
| 169 | test "const slice" { | |
| 170 | comptime { | |
| 171 | const a = "1234567890"; | |
| 172 | expect(a.len == 10); | |
| 173 | const b = a[1..2]; | |
| 174 | expect(b.len == 1); | |
| 175 | expect(b[0] == '2'); | |
| 176 | } | |
| 177 | } | |
| 178 | ||
| 179 | test "try to trick eval with runtime if" { | |
| 180 | expect(testTryToTrickEvalWithRuntimeIf(true) == 10); | |
| 181 | } | |
| 182 | ||
| 183 | fn testTryToTrickEvalWithRuntimeIf(b: bool) usize { | |
| 184 | comptime var i: usize = 0; | |
| 185 | inline while (i < 10) : (i += 1) { | |
| 186 | const result = if (b) false else true; | |
| 187 | } | |
| 188 | comptime { | |
| 189 | return i; | |
| 190 | } | |
| 191 | } | |
| 192 | ||
| 193 | test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { | |
| 194 | var runtime = [1]i32{3}; | |
| 195 | comptime var i: usize = 0; | |
| 196 | inline while (i < 2) : (i += 1) { | |
| 197 | const result = if (i == 0) [1]i32{2} else runtime; | |
| 198 | } | |
| 199 | comptime { | |
| 200 | expect(i == 2); | |
| 201 | } | |
| 202 | } | |
| 203 | ||
| 204 | fn max(comptime T: type, a: T, b: T) T { | |
| 205 | if (T == bool) { | |
| 206 | return a or b; | |
| 207 | } else if (a > b) { | |
| 208 | return a; | |
| 209 | } else { | |
| 210 | return b; | |
| 211 | } | |
| 212 | } | |
| 213 | fn letsTryToCompareBools(a: bool, b: bool) bool { | |
| 214 | return max(bool, a, b); | |
| 215 | } | |
| 216 | test "inlined block and runtime block phi" { | |
| 217 | expect(letsTryToCompareBools(true, true)); | |
| 218 | expect(letsTryToCompareBools(true, false)); | |
| 219 | expect(letsTryToCompareBools(false, true)); | |
| 220 | expect(!letsTryToCompareBools(false, false)); | |
| 221 | ||
| 222 | comptime { | |
| 223 | expect(letsTryToCompareBools(true, true)); | |
| 224 | expect(letsTryToCompareBools(true, false)); | |
| 225 | expect(letsTryToCompareBools(false, true)); | |
| 226 | expect(!letsTryToCompareBools(false, false)); | |
| 227 | } | |
| 228 | } | |
| 229 | ||
| 230 | const CmdFn = struct { | |
| 231 | name: []const u8, | |
| 232 | func: fn (i32) i32, | |
| 233 | }; | |
| 234 | ||
| 235 | const cmd_fns = [_]CmdFn{ | |
| 236 | CmdFn{ | |
| 237 | .name = "one", | |
| 238 | .func = one, | |
| 239 | }, | |
| 240 | CmdFn{ | |
| 241 | .name = "two", | |
| 242 | .func = two, | |
| 243 | }, | |
| 244 | CmdFn{ | |
| 245 | .name = "three", | |
| 246 | .func = three, | |
| 247 | }, | |
| 248 | }; | |
| 249 | fn one(value: i32) i32 { | |
| 250 | return value + 1; | |
| 251 | } | |
| 252 | fn two(value: i32) i32 { | |
| 253 | return value + 2; | |
| 254 | } | |
| 255 | fn three(value: i32) i32 { | |
| 256 | return value + 3; | |
| 257 | } | |
| 258 | ||
| 259 | fn performFn(comptime prefix_char: u8, start_value: i32) i32 { | |
| 260 | var result: i32 = start_value; | |
| 261 | comptime var i = 0; | |
| 262 | inline while (i < cmd_fns.len) : (i += 1) { | |
| 263 | if (cmd_fns[i].name[0] == prefix_char) { | |
| 264 | result = cmd_fns[i].func(result); | |
| 265 | } | |
| 266 | } | |
| 267 | return result; | |
| 268 | } | |
| 269 | ||
| 270 | test "comptime iterate over fn ptr list" { | |
| 271 | expect(performFn('t', 1) == 6); | |
| 272 | expect(performFn('o', 0) == 1); | |
| 273 | expect(performFn('w', 99) == 99); | |
| 274 | } | |
| 275 | ||
| 276 | test "eval @setRuntimeSafety at compile-time" { | |
| 277 | const result = comptime fnWithSetRuntimeSafety(); | |
| 278 | expect(result == 1234); | |
| 279 | } | |
| 280 | ||
| 281 | fn fnWithSetRuntimeSafety() i32 { | |
| 282 | @setRuntimeSafety(true); | |
| 283 | return 1234; | |
| 284 | } | |
| 285 | ||
| 286 | test "eval @setFloatMode at compile-time" { | |
| 287 | const result = comptime fnWithFloatMode(); | |
| 288 | expect(result == 1234.0); | |
| 289 | } | |
| 290 | ||
| 291 | fn fnWithFloatMode() f32 { | |
| 292 | @setFloatMode(std.builtin.FloatMode.Strict); | |
| 293 | return 1234.0; | |
| 294 | } | |
| 295 | ||
| 296 | const SimpleStruct = struct { | |
| 297 | field: i32, | |
| 298 | ||
| 299 | fn method(self: *const SimpleStruct) i32 { | |
| 300 | return self.field + 3; | |
| 301 | } | |
| 302 | }; | |
| 303 | ||
| 304 | var simple_struct = SimpleStruct{ .field = 1234 }; | |
| 305 | ||
| 306 | const bound_fn = simple_struct.method; | |
| 307 | ||
| 308 | test "call method on bound fn referring to var instance" { | |
| 309 | expect(bound_fn() == 1237); | |
| 310 | } | |
| 311 | ||
| 312 | test "ptr to local array argument at comptime" { | |
| 313 | comptime { | |
| 314 | var bytes: [10]u8 = undefined; | |
| 315 | modifySomeBytes(bytes[0..]); | |
| 316 | expect(bytes[0] == 'a'); | |
| 317 | expect(bytes[9] == 'b'); | |
| 318 | } | |
| 319 | } | |
| 320 | ||
| 321 | fn modifySomeBytes(bytes: []u8) void { | |
| 322 | bytes[0] = 'a'; | |
| 323 | bytes[9] = 'b'; | |
| 324 | } | |
| 325 | ||
| 326 | test "comparisons 0 <= uint and 0 > uint should be comptime" { | |
| 327 | testCompTimeUIntComparisons(1234); | |
| 328 | } | |
| 329 | fn testCompTimeUIntComparisons(x: u32) void { | |
| 330 | if (!(0 <= x)) { | |
| 331 | @compileError("this condition should be comptime known"); | |
| 332 | } | |
| 333 | if (0 > x) { | |
| 334 | @compileError("this condition should be comptime known"); | |
| 335 | } | |
| 336 | if (!(x >= 0)) { | |
| 337 | @compileError("this condition should be comptime known"); | |
| 338 | } | |
| 339 | if (x < 0) { | |
| 340 | @compileError("this condition should be comptime known"); | |
| 341 | } | |
| 342 | } | |
| 343 | ||
| 344 | test "const ptr to variable data changes at runtime" { | |
| 345 | expect(foo_ref.name[0] == 'a'); | |
| 346 | foo_ref.name = "b"; | |
| 347 | expect(foo_ref.name[0] == 'b'); | |
| 348 | } | |
| 349 | ||
| 350 | const Foo = struct { | |
| 351 | name: []const u8, | |
| 352 | }; | |
| 353 | ||
| 354 | var foo_contents = Foo{ .name = "a" }; | |
| 355 | const foo_ref = &foo_contents; | |
| 356 | ||
| 357 | test "create global array with for loop" { | |
| 358 | expect(global_array[5] == 5 * 5); | |
| 359 | expect(global_array[9] == 9 * 9); | |
| 360 | } | |
| 361 | ||
| 362 | const global_array = x: { | |
| 363 | var result: [10]usize = undefined; | |
| 364 | for (result) |*item, index| { | |
| 365 | item.* = index * index; | |
| 366 | } | |
| 367 | break :x result; | |
| 368 | }; | |
| 369 | ||
| 370 | test "compile-time downcast when the bits fit" { | |
| 371 | comptime { | |
| 372 | const spartan_count: u16 = 255; | |
| 373 | const byte = @intCast(u8, spartan_count); | |
| 374 | expect(byte == 255); | |
| 375 | } | |
| 376 | } | |
| 377 | ||
| 378 | const hi1 = "hi"; | |
| 379 | const hi2 = hi1; | |
| 380 | test "const global shares pointer with other same one" { | |
| 381 | assertEqualPtrs(&hi1[0], &hi2[0]); | |
| 382 | comptime expect(&hi1[0] == &hi2[0]); | |
| 383 | } | |
| 384 | fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) void { | |
| 385 | expect(ptr1 == ptr2); | |
| 386 | } | |
| 387 | ||
| 388 | test "@setEvalBranchQuota" { | |
| 389 | comptime { | |
| 390 | // 1001 for the loop and then 1 more for the expect fn call | |
| 391 | @setEvalBranchQuota(1002); | |
| 392 | var i = 0; | |
| 393 | var sum = 0; | |
| 394 | while (i < 1001) : (i += 1) { | |
| 395 | sum += i; | |
| 396 | } | |
| 397 | expect(sum == 500500); | |
| 398 | } | |
| 399 | } | |
| 400 | ||
| 401 | test "float literal at compile time not lossy" { | |
| 402 | expect(16777216.0 + 1.0 == 16777217.0); | |
| 403 | expect(9007199254740992.0 + 1.0 == 9007199254740993.0); | |
| 404 | } | |
| 405 | ||
| 406 | test "f32 at compile time is lossy" { | |
| 407 | expect(@as(f32, 1 << 24) + 1 == 1 << 24); | |
| 408 | } | |
| 409 | ||
| 410 | test "f64 at compile time is lossy" { | |
| 411 | expect(@as(f64, 1 << 53) + 1 == 1 << 53); | |
| 412 | } | |
| 413 | ||
| 414 | test "f128 at compile time is lossy" { | |
| 415 | expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0); | |
| 416 | } | |
| 417 | ||
| 418 | comptime { | |
| 419 | expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192); | |
| 420 | } | |
| 421 | ||
| 422 | pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type { | |
| 423 | return struct { | |
| 424 | pub const Node = struct {}; | |
| 425 | }; | |
| 426 | } | |
| 427 | ||
| 428 | test "string literal used as comptime slice is memoized" { | |
| 429 | const a = "link"; | |
| 430 | const b = "link"; | |
| 431 | comptime expect(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node); | |
| 432 | comptime expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); | |
| 433 | } | |
| 434 | ||
| 435 | test "comptime slice of undefined pointer of length 0" { | |
| 436 | const slice1 = @as([*]i32, undefined)[0..0]; | |
| 437 | expect(slice1.len == 0); | |
| 438 | const slice2 = @as([*]i32, undefined)[100..100]; | |
| 439 | expect(slice2.len == 0); | |
| 440 | } | |
| 441 | ||
| 442 | fn copyWithPartialInline(s: []u32, b: []u8) void { | |
| 443 | comptime var i: usize = 0; | |
| 444 | inline while (i < 4) : (i += 1) { | |
| 445 | s[i] = 0; | |
| 446 | s[i] |= @as(u32, b[i * 4 + 0]) << 24; | |
| 447 | s[i] |= @as(u32, b[i * 4 + 1]) << 16; | |
| 448 | s[i] |= @as(u32, b[i * 4 + 2]) << 8; | |
| 449 | s[i] |= @as(u32, b[i * 4 + 3]) << 0; | |
| 450 | } | |
| 451 | } | |
| 452 | ||
| 453 | test "binary math operator in partially inlined function" { | |
| 454 | var s: [4]u32 = undefined; | |
| 455 | var b: [16]u8 = undefined; | |
| 456 | ||
| 457 | for (b) |*r, i| | |
| 458 | r.* = @intCast(u8, i + 1); | |
| 459 | ||
| 460 | copyWithPartialInline(s[0..], b[0..]); | |
| 461 | expect(s[0] == 0x1020304); | |
| 462 | expect(s[1] == 0x5060708); | |
| 463 | expect(s[2] == 0x90a0b0c); | |
| 464 | expect(s[3] == 0xd0e0f10); | |
| 465 | } | |
| 466 | ||
| 467 | test "comptime function with the same args is memoized" { | |
| 468 | comptime { | |
| 469 | expect(MakeType(i32) == MakeType(i32)); | |
| 470 | expect(MakeType(i32) != MakeType(f64)); | |
| 471 | } | |
| 472 | } | |
| 473 | ||
| 474 | fn MakeType(comptime T: type) type { | |
| 475 | return struct { | |
| 476 | field: T, | |
| 477 | }; | |
| 478 | } | |
| 479 | ||
| 480 | test "comptime function with mutable pointer is not memoized" { | |
| 481 | comptime { | |
| 482 | var x: i32 = 1; | |
| 483 | const ptr = &x; | |
| 484 | increment(ptr); | |
| 485 | increment(ptr); | |
| 486 | expect(x == 3); | |
| 487 | } | |
| 488 | } | |
| 489 | ||
| 490 | fn increment(value: *i32) void { | |
| 491 | value.* += 1; | |
| 492 | } | |
| 493 | ||
| 494 | fn generateTable(comptime T: type) [1010]T { | |
| 495 | var res: [1010]T = undefined; | |
| 496 | var i: usize = 0; | |
| 497 | while (i < 1010) : (i += 1) { | |
| 498 | res[i] = @intCast(T, i); | |
| 499 | } | |
| 500 | return res; | |
| 501 | } | |
| 502 | ||
| 503 | fn doesAlotT(comptime T: type, value: usize) T { | |
| 504 | @setEvalBranchQuota(5000); | |
| 505 | const table = comptime blk: { | |
| 506 | break :blk generateTable(T); | |
| 507 | }; | |
| 508 | return table[value]; | |
| 509 | } | |
| 510 | ||
| 511 | test "@setEvalBranchQuota at same scope as generic function call" { | |
| 512 | expect(doesAlotT(u32, 2) == 2); | |
| 513 | } | |
| 514 | ||
| 515 | test "comptime slice of slice preserves comptime var" { | |
| 516 | comptime { | |
| 517 | var buff: [10]u8 = undefined; | |
| 518 | buff[0..][0..][0] = 1; | |
| 519 | expect(buff[0..][0..][0] == 1); | |
| 520 | } | |
| 521 | } | |
| 522 | ||
| 523 | test "comptime slice of pointer preserves comptime var" { | |
| 524 | comptime { | |
| 525 | var buff: [10]u8 = undefined; | |
| 526 | var a = @ptrCast([*]u8, &buff); | |
| 527 | a[0..1][0] = 1; | |
| 528 | expect(buff[0..][0..][0] == 1); | |
| 529 | } | |
| 530 | } | |
| 531 | ||
| 532 | const SingleFieldStruct = struct { | |
| 533 | x: i32, | |
| 534 | ||
| 535 | fn read_x(self: *const SingleFieldStruct) i32 { | |
| 536 | return self.x; | |
| 537 | } | |
| 538 | }; | |
| 539 | test "const ptr to comptime mutable data is not memoized" { | |
| 540 | comptime { | |
| 541 | var foo = SingleFieldStruct{ .x = 1 }; | |
| 542 | expect(foo.read_x() == 1); | |
| 543 | foo.x = 2; | |
| 544 | expect(foo.read_x() == 2); | |
| 545 | } | |
| 546 | } | |
| 547 | ||
| 548 | test "array concat of slices gives slice" { | |
| 549 | comptime { | |
| 550 | var a: []const u8 = "aoeu"; | |
| 551 | var b: []const u8 = "asdf"; | |
| 552 | const c = a ++ b; | |
| 553 | expect(std.mem.eql(u8, c, "aoeuasdf")); | |
| 554 | } | |
| 555 | } | |
| 556 | ||
| 557 | test "comptime shlWithOverflow" { | |
| 558 | const ct_shifted: u64 = comptime amt: { | |
| 559 | var amt = @as(u64, 0); | |
| 560 | _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt); | |
| 561 | break :amt amt; | |
| 562 | }; | |
| 563 | ||
| 564 | const rt_shifted: u64 = amt: { | |
| 565 | var amt = @as(u64, 0); | |
| 566 | _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt); | |
| 567 | break :amt amt; | |
| 568 | }; | |
| 569 | ||
| 570 | expect(ct_shifted == rt_shifted); | |
| 571 | } | |
| 572 | ||
| 573 | test "runtime 128 bit integer division" { | |
| 574 | var a: u128 = 152313999999999991610955792383; | |
| 575 | var b: u128 = 10000000000000000000; | |
| 576 | var c = a / b; | |
| 577 | expect(c == 15231399999); | |
| 578 | } | |
| 579 | ||
| 580 | pub const Info = struct { | |
| 581 | version: u8, | |
| 582 | }; | |
| 583 | ||
| 584 | pub const diamond_info = Info{ .version = 0 }; | |
| 585 | ||
| 586 | test "comptime modification of const struct field" { | |
| 587 | comptime { | |
| 588 | var res = diamond_info; | |
| 589 | res.version = 1; | |
| 590 | expect(diamond_info.version == 0); | |
| 591 | expect(res.version == 1); | |
| 592 | } | |
| 593 | } | |
| 594 | ||
| 595 | test "pointer to type" { | |
| 596 | comptime { | |
| 597 | var T: type = i32; | |
| 598 | expect(T == i32); | |
| 599 | var ptr = &T; | |
| 600 | expect(@TypeOf(ptr) == *type); | |
| 601 | ptr.* = f32; | |
| 602 | expect(T == f32); | |
| 603 | expect(*T == *f32); | |
| 604 | } | |
| 605 | } | |
| 606 | ||
| 607 | test "slice of type" { | |
| 608 | comptime { | |
| 609 | var types_array = [_]type{ i32, f64, type }; | |
| 610 | for (types_array) |T, i| { | |
| 611 | switch (i) { | |
| 612 | 0 => expect(T == i32), | |
| 613 | 1 => expect(T == f64), | |
| 614 | 2 => expect(T == type), | |
| 615 | else => unreachable, | |
| 616 | } | |
| 617 | } | |
| 618 | for (types_array[0..]) |T, i| { | |
| 619 | switch (i) { | |
| 620 | 0 => expect(T == i32), | |
| 621 | 1 => expect(T == f64), | |
| 622 | 2 => expect(T == type), | |
| 623 | else => unreachable, | |
| 624 | } | |
| 625 | } | |
| 626 | } | |
| 627 | } | |
| 628 | ||
| 629 | const Wrapper = struct { | |
| 630 | T: type, | |
| 631 | }; | |
| 632 | ||
| 633 | fn wrap(comptime T: type) Wrapper { | |
| 634 | return Wrapper{ .T = T }; | |
| 635 | } | |
| 636 | ||
| 637 | test "function which returns struct with type field causes implicit comptime" { | |
| 638 | const ty = wrap(i32).T; | |
| 639 | expect(ty == i32); | |
| 640 | } | |
| 641 | ||
| 642 | test "call method with comptime pass-by-non-copying-value self parameter" { | |
| 643 | const S = struct { | |
| 644 | a: u8, | |
| 645 | ||
| 646 | fn b(comptime s: @This()) u8 { | |
| 647 | return s.a; | |
| 648 | } | |
| 649 | }; | |
| 650 | ||
| 651 | const s = S{ .a = 2 }; | |
| 652 | var b = s.b(); | |
| 653 | expect(b == 2); | |
| 654 | } | |
| 655 | ||
| 656 | test "@tagName of @typeInfo" { | |
| 657 | const str = @tagName(@typeInfo(u8)); | |
| 658 | expect(std.mem.eql(u8, str, "Int")); | |
| 659 | } | |
| 660 | ||
| 661 | test "setting backward branch quota just before a generic fn call" { | |
| 662 | @setEvalBranchQuota(1001); | |
| 663 | loopNTimes(1001); | |
| 664 | } | |
| 665 | ||
| 666 | fn loopNTimes(comptime n: usize) void { | |
| 667 | comptime var i = 0; | |
| 668 | inline while (i < n) : (i += 1) {} | |
| 669 | } | |
| 670 | ||
| 671 | test "variable inside inline loop that has different types on different iterations" { | |
| 672 | testVarInsideInlineLoop(.{ true, @as(u32, 42) }); | |
| 673 | } | |
| 674 | ||
| 675 | fn testVarInsideInlineLoop(args: anytype) void { | |
| 676 | comptime var i = 0; | |
| 677 | inline while (i < args.len) : (i += 1) { | |
| 678 | const x = args[i]; | |
| 679 | if (i == 0) expect(x); | |
| 680 | if (i == 1) expect(x == 42); | |
| 681 | } | |
| 682 | } | |
| 683 | ||
| 684 | test "inline for with same type but different values" { | |
| 685 | var res: usize = 0; | |
| 686 | inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| { | |
| 687 | var a: T = undefined; | |
| 688 | res += a.len; | |
| 689 | } | |
| 690 | expect(res == 5); | |
| 691 | } | |
| 692 | ||
| 693 | test "refer to the type of a generic function" { | |
| 694 | const Func = fn (type) void; | |
| 695 | const f: Func = doNothingWithType; | |
| 696 | f(i32); | |
| 697 | } | |
| 698 | ||
| 699 | fn doNothingWithType(comptime T: type) void {} | |
| 700 | ||
| 701 | test "zero extend from u0 to u1" { | |
| 702 | var zero_u0: u0 = 0; | |
| 703 | var zero_u1: u1 = zero_u0; | |
| 704 | expect(zero_u1 == 0); | |
| 705 | } | |
| 706 | ||
| 707 | test "bit shift a u1" { | |
| 708 | var x: u1 = 1; | |
| 709 | var y = x << 0; | |
| 710 | expect(y == 1); | |
| 711 | } | |
| 712 | ||
| 713 | test "comptime pointer cast array and then slice" { | |
| 714 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; | |
| 715 | ||
| 716 | const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); | |
| 717 | const sliceA: []const u8 = ptrA[0..2]; | |
| 718 | ||
| 719 | const ptrB: [*]const u8 = &array; | |
| 720 | const sliceB: []const u8 = ptrB[0..2]; | |
| 721 | ||
| 722 | expect(sliceA[1] == 2); | |
| 723 | expect(sliceB[1] == 2); | |
| 724 | } | |
| 725 | ||
| 726 | test "slice bounds in comptime concatenation" { | |
| 727 | const bs = comptime blk: { | |
| 728 | const b = "........1........"; | |
| 729 | break :blk b[8..9]; | |
| 730 | }; | |
| 731 | const str = "" ++ bs; | |
| 732 | expect(str.len == 1); | |
| 733 | expect(std.mem.eql(u8, str, "1")); | |
| 734 | ||
| 735 | const str2 = bs ++ ""; | |
| 736 | expect(str2.len == 1); | |
| 737 | expect(std.mem.eql(u8, str2, "1")); | |
| 738 | } | |
| 739 | ||
| 740 | test "comptime bitwise operators" { | |
| 741 | comptime { | |
| 742 | expect(3 & 1 == 1); | |
| 743 | expect(3 & -1 == 3); | |
| 744 | expect(-3 & -1 == -3); | |
| 745 | expect(3 | -1 == -1); | |
| 746 | expect(-3 | -1 == -1); | |
| 747 | expect(3 ^ -1 == -4); | |
| 748 | expect(-3 ^ -1 == 2); | |
| 749 | expect(~@as(i8, -1) == 0); | |
| 750 | expect(~@as(i128, -1) == 0); | |
| 751 | expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611); | |
| 752 | expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615); | |
| 753 | expect(~@as(u128, 0) == 0xffffffffffffffffffffffffffffffff); | |
| 754 | } | |
| 755 | } | |
| 756 | ||
| 757 | test "*align(1) u16 is the same as *align(1:0:2) u16" { | |
| 758 | comptime { | |
| 759 | expect(*align(1:0:2) u16 == *align(1) u16); | |
| 760 | expect(*align(2:0:2) u16 == *u16); | |
| 761 | } | |
| 762 | } | |
| 763 | ||
| 764 | test "array concatenation forces comptime" { | |
| 765 | var a = oneItem(3) ++ oneItem(4); | |
| 766 | expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); | |
| 767 | } | |
| 768 | ||
| 769 | test "array multiplication forces comptime" { | |
| 770 | var a = oneItem(3) ** scalar(2); | |
| 771 | expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); | |
| 772 | } | |
| 773 | ||
| 774 | fn oneItem(x: i32) [1]i32 { | |
| 775 | return [_]i32{x}; | |
| 776 | } | |
| 777 | ||
| 778 | fn scalar(x: u32) u32 { | |
| 779 | return x; | |
| 780 | } | |
| 781 | ||
| 782 | test "no undeclared identifier error in unanalyzed branches" { | |
| 783 | if (false) { | |
| 784 | lol_this_doesnt_exist = nonsense; | |
| 785 | } | |
| 786 | } | |
| 787 | ||
| 788 | test "comptime assign int to optional int" { | |
| 789 | comptime { | |
| 790 | var x: ?i32 = null; | |
| 791 | x = 2; | |
| 792 | x.? *= 10; | |
| 793 | expectEqual(20, x.?); | |
| 794 | } | |
| 795 | } | |
| 796 | ||
| 797 | test "return 0 from function that has u0 return type" { | |
| 798 | const S = struct { | |
| 799 | fn foo_zero() u0 { | |
| 800 | return 0; | |
| 801 | } | |
| 802 | }; | |
| 803 | comptime { | |
| 804 | if (S.foo_zero() != 0) { | |
| 805 | @compileError("test failed"); | |
| 806 | } | |
| 807 | } | |
| 808 | } | |
| 809 | ||
| 810 | test "two comptime calls with array default initialized to undefined" { | |
| 811 | const S = struct { | |
| 812 | const CrossTarget = struct { | |
| 813 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 814 | ||
| 815 | pub fn parse() void { | |
| 816 | var result: CrossTarget = .{}; | |
| 817 | result.getCpuArch(); | |
| 818 | } | |
| 819 | ||
| 820 | pub fn getCpuArch(self: CrossTarget) void {} | |
| 821 | }; | |
| 822 | ||
| 823 | const DynamicLinker = struct { | |
| 824 | buffer: [255]u8 = undefined, | |
| 825 | }; | |
| 826 | }; | |
| 827 | ||
| 828 | comptime { | |
| 829 | S.CrossTarget.parse(); | |
| 830 | S.CrossTarget.parse(); | |
| 831 | } | |
| 832 | } |
test/behavior/field_parent_ptr.zig created+41| ... | ... | @@ -0,0 +1,41 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@fieldParentPtr non-first field" { | |
| 4 | testParentFieldPtr(&foo.c); | |
| 5 | comptime testParentFieldPtr(&foo.c); | |
| 6 | } | |
| 7 | ||
| 8 | test "@fieldParentPtr first field" { | |
| 9 | testParentFieldPtrFirst(&foo.a); | |
| 10 | comptime testParentFieldPtrFirst(&foo.a); | |
| 11 | } | |
| 12 | ||
| 13 | const Foo = struct { | |
| 14 | a: bool, | |
| 15 | b: f32, | |
| 16 | c: i32, | |
| 17 | d: i32, | |
| 18 | }; | |
| 19 | ||
| 20 | const foo = Foo{ | |
| 21 | .a = true, | |
| 22 | .b = 0.123, | |
| 23 | .c = 1234, | |
| 24 | .d = -10, | |
| 25 | }; | |
| 26 | ||
| 27 | fn testParentFieldPtr(c: *const i32) void { | |
| 28 | expect(c == &foo.c); | |
| 29 | ||
| 30 | const base = @fieldParentPtr(Foo, "c", c); | |
| 31 | expect(base == &foo); | |
| 32 | expect(&base.c == c); | |
| 33 | } | |
| 34 | ||
| 35 | fn testParentFieldPtrFirst(a: *const bool) void { | |
| 36 | expect(a == &foo.a); | |
| 37 | ||
| 38 | const base = @fieldParentPtr(Foo, "a", a); | |
| 39 | expect(base == &foo); | |
| 40 | expect(&base.a == a); | |
| 41 | } |
test/behavior/floatop.zig created+465| ... | ... | @@ -0,0 +1,465 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const math = std.math; | |
| 4 | const pi = std.math.pi; | |
| 5 | const e = std.math.e; | |
| 6 | const Vector = std.meta.Vector; | |
| 7 | ||
| 8 | const epsilon = 0.000001; | |
| 9 | ||
| 10 | test "@sqrt" { | |
| 11 | comptime testSqrt(); | |
| 12 | testSqrt(); | |
| 13 | } | |
| 14 | ||
| 15 | fn testSqrt() void { | |
| 16 | { | |
| 17 | var a: f16 = 4; | |
| 18 | expect(@sqrt(a) == 2); | |
| 19 | } | |
| 20 | { | |
| 21 | var a: f32 = 9; | |
| 22 | expect(@sqrt(a) == 3); | |
| 23 | var b: f32 = 1.1; | |
| 24 | expect(math.approxEqAbs(f32, @sqrt(b), 1.0488088481701516, epsilon)); | |
| 25 | } | |
| 26 | { | |
| 27 | var a: f64 = 25; | |
| 28 | expect(@sqrt(a) == 5); | |
| 29 | } | |
| 30 | { | |
| 31 | const a: comptime_float = 25.0; | |
| 32 | expect(@sqrt(a) == 5.0); | |
| 33 | } | |
| 34 | // TODO https://github.com/ziglang/zig/issues/4026 | |
| 35 | //{ | |
| 36 | // var a: f128 = 49; | |
| 37 | // expect(@sqrt(a) == 7); | |
| 38 | //} | |
| 39 | { | |
| 40 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 41 | var result = @sqrt(v); | |
| 42 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon)); | |
| 43 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon)); | |
| 44 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon)); | |
| 45 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon)); | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | test "more @sqrt f16 tests" { | |
| 50 | // TODO these are not all passing at comptime | |
| 51 | expect(@sqrt(@as(f16, 0.0)) == 0.0); | |
| 52 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon)); | |
| 53 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon)); | |
| 54 | expect(@sqrt(@as(f16, 4.0)) == 2.0); | |
| 55 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 7.539840)), 2.745877, epsilon)); | |
| 56 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 19.230934)), 4.385309, epsilon)); | |
| 57 | expect(@sqrt(@as(f16, 64.0)) == 8.0); | |
| 58 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 64.1)), 8.006248, epsilon)); | |
| 59 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 8942.230469)), 94.563370, epsilon)); | |
| 60 | ||
| 61 | // special cases | |
| 62 | expect(math.isPositiveInf(@sqrt(@as(f16, math.inf(f16))))); | |
| 63 | expect(@sqrt(@as(f16, 0.0)) == 0.0); | |
| 64 | expect(@sqrt(@as(f16, -0.0)) == -0.0); | |
| 65 | expect(math.isNan(@sqrt(@as(f16, -1.0)))); | |
| 66 | expect(math.isNan(@sqrt(@as(f16, math.nan(f16))))); | |
| 67 | } | |
| 68 | ||
| 69 | test "@sin" { | |
| 70 | comptime testSin(); | |
| 71 | testSin(); | |
| 72 | } | |
| 73 | ||
| 74 | fn testSin() void { | |
| 75 | // TODO test f128, and c_longdouble | |
| 76 | // https://github.com/ziglang/zig/issues/4026 | |
| 77 | { | |
| 78 | var a: f16 = 0; | |
| 79 | expect(@sin(a) == 0); | |
| 80 | } | |
| 81 | { | |
| 82 | var a: f32 = 0; | |
| 83 | expect(@sin(a) == 0); | |
| 84 | } | |
| 85 | { | |
| 86 | var a: f64 = 0; | |
| 87 | expect(@sin(a) == 0); | |
| 88 | } | |
| 89 | { | |
| 90 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 91 | var result = @sin(v); | |
| 92 | expect(math.approxEqAbs(f32, @sin(@as(f32, 1.1)), result[0], epsilon)); | |
| 93 | expect(math.approxEqAbs(f32, @sin(@as(f32, 2.2)), result[1], epsilon)); | |
| 94 | expect(math.approxEqAbs(f32, @sin(@as(f32, 3.3)), result[2], epsilon)); | |
| 95 | expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon)); | |
| 96 | } | |
| 97 | } | |
| 98 | ||
| 99 | test "@cos" { | |
| 100 | comptime testCos(); | |
| 101 | testCos(); | |
| 102 | } | |
| 103 | ||
| 104 | fn testCos() void { | |
| 105 | // TODO test f128, and c_longdouble | |
| 106 | // https://github.com/ziglang/zig/issues/4026 | |
| 107 | { | |
| 108 | var a: f16 = 0; | |
| 109 | expect(@cos(a) == 1); | |
| 110 | } | |
| 111 | { | |
| 112 | var a: f32 = 0; | |
| 113 | expect(@cos(a) == 1); | |
| 114 | } | |
| 115 | { | |
| 116 | var a: f64 = 0; | |
| 117 | expect(@cos(a) == 1); | |
| 118 | } | |
| 119 | { | |
| 120 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 121 | var result = @cos(v); | |
| 122 | expect(math.approxEqAbs(f32, @cos(@as(f32, 1.1)), result[0], epsilon)); | |
| 123 | expect(math.approxEqAbs(f32, @cos(@as(f32, 2.2)), result[1], epsilon)); | |
| 124 | expect(math.approxEqAbs(f32, @cos(@as(f32, 3.3)), result[2], epsilon)); | |
| 125 | expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon)); | |
| 126 | } | |
| 127 | } | |
| 128 | ||
| 129 | test "@exp" { | |
| 130 | comptime testExp(); | |
| 131 | testExp(); | |
| 132 | } | |
| 133 | ||
| 134 | fn testExp() void { | |
| 135 | // TODO test f128, and c_longdouble | |
| 136 | // https://github.com/ziglang/zig/issues/4026 | |
| 137 | { | |
| 138 | var a: f16 = 0; | |
| 139 | expect(@exp(a) == 1); | |
| 140 | } | |
| 141 | { | |
| 142 | var a: f32 = 0; | |
| 143 | expect(@exp(a) == 1); | |
| 144 | } | |
| 145 | { | |
| 146 | var a: f64 = 0; | |
| 147 | expect(@exp(a) == 1); | |
| 148 | } | |
| 149 | { | |
| 150 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 151 | var result = @exp(v); | |
| 152 | expect(math.approxEqAbs(f32, @exp(@as(f32, 1.1)), result[0], epsilon)); | |
| 153 | expect(math.approxEqAbs(f32, @exp(@as(f32, 2.2)), result[1], epsilon)); | |
| 154 | expect(math.approxEqAbs(f32, @exp(@as(f32, 0.3)), result[2], epsilon)); | |
| 155 | expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon)); | |
| 156 | } | |
| 157 | } | |
| 158 | ||
| 159 | test "@exp2" { | |
| 160 | comptime testExp2(); | |
| 161 | testExp2(); | |
| 162 | } | |
| 163 | ||
| 164 | fn testExp2() void { | |
| 165 | // TODO test f128, and c_longdouble | |
| 166 | // https://github.com/ziglang/zig/issues/4026 | |
| 167 | { | |
| 168 | var a: f16 = 2; | |
| 169 | expect(@exp2(a) == 4); | |
| 170 | } | |
| 171 | { | |
| 172 | var a: f32 = 2; | |
| 173 | expect(@exp2(a) == 4); | |
| 174 | } | |
| 175 | { | |
| 176 | var a: f64 = 2; | |
| 177 | expect(@exp2(a) == 4); | |
| 178 | } | |
| 179 | { | |
| 180 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 181 | var result = @exp2(v); | |
| 182 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 1.1)), result[0], epsilon)); | |
| 183 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 2.2)), result[1], epsilon)); | |
| 184 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.3)), result[2], epsilon)); | |
| 185 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon)); | |
| 186 | } | |
| 187 | } | |
| 188 | ||
| 189 | test "@log" { | |
| 190 | // Old musl (and glibc?), and our current math.ln implementation do not return 1 | |
| 191 | // so also accept those values. | |
| 192 | comptime testLog(); | |
| 193 | testLog(); | |
| 194 | } | |
| 195 | ||
| 196 | fn testLog() void { | |
| 197 | // TODO test f128, and c_longdouble | |
| 198 | // https://github.com/ziglang/zig/issues/4026 | |
| 199 | { | |
| 200 | var a: f16 = e; | |
| 201 | expect(math.approxEqAbs(f16, @log(a), 1, epsilon)); | |
| 202 | } | |
| 203 | { | |
| 204 | var a: f32 = e; | |
| 205 | expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff))); | |
| 206 | } | |
| 207 | { | |
| 208 | var a: f64 = e; | |
| 209 | expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000))); | |
| 210 | } | |
| 211 | { | |
| 212 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 213 | var result = @log(v); | |
| 214 | expect(math.approxEqAbs(f32, @log(@as(f32, 1.1)), result[0], epsilon)); | |
| 215 | expect(math.approxEqAbs(f32, @log(@as(f32, 2.2)), result[1], epsilon)); | |
| 216 | expect(math.approxEqAbs(f32, @log(@as(f32, 0.3)), result[2], epsilon)); | |
| 217 | expect(math.approxEqAbs(f32, @log(@as(f32, 0.4)), result[3], epsilon)); | |
| 218 | } | |
| 219 | } | |
| 220 | ||
| 221 | test "@log2" { | |
| 222 | comptime testLog2(); | |
| 223 | testLog2(); | |
| 224 | } | |
| 225 | ||
| 226 | fn testLog2() void { | |
| 227 | // TODO test f128, and c_longdouble | |
| 228 | // https://github.com/ziglang/zig/issues/4026 | |
| 229 | { | |
| 230 | var a: f16 = 4; | |
| 231 | expect(@log2(a) == 2); | |
| 232 | } | |
| 233 | { | |
| 234 | var a: f32 = 4; | |
| 235 | expect(@log2(a) == 2); | |
| 236 | } | |
| 237 | { | |
| 238 | var a: f64 = 4; | |
| 239 | expect(@log2(a) == 2); | |
| 240 | } | |
| 241 | { | |
| 242 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 243 | var result = @log2(v); | |
| 244 | expect(math.approxEqAbs(f32, @log2(@as(f32, 1.1)), result[0], epsilon)); | |
| 245 | expect(math.approxEqAbs(f32, @log2(@as(f32, 2.2)), result[1], epsilon)); | |
| 246 | expect(math.approxEqAbs(f32, @log2(@as(f32, 0.3)), result[2], epsilon)); | |
| 247 | expect(math.approxEqAbs(f32, @log2(@as(f32, 0.4)), result[3], epsilon)); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | test "@log10" { | |
| 252 | comptime testLog10(); | |
| 253 | testLog10(); | |
| 254 | } | |
| 255 | ||
| 256 | fn testLog10() void { | |
| 257 | // TODO test f128, and c_longdouble | |
| 258 | // https://github.com/ziglang/zig/issues/4026 | |
| 259 | { | |
| 260 | var a: f16 = 100; | |
| 261 | expect(@log10(a) == 2); | |
| 262 | } | |
| 263 | { | |
| 264 | var a: f32 = 100; | |
| 265 | expect(@log10(a) == 2); | |
| 266 | } | |
| 267 | { | |
| 268 | var a: f64 = 1000; | |
| 269 | expect(@log10(a) == 3); | |
| 270 | } | |
| 271 | { | |
| 272 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 273 | var result = @log10(v); | |
| 274 | expect(math.approxEqAbs(f32, @log10(@as(f32, 1.1)), result[0], epsilon)); | |
| 275 | expect(math.approxEqAbs(f32, @log10(@as(f32, 2.2)), result[1], epsilon)); | |
| 276 | expect(math.approxEqAbs(f32, @log10(@as(f32, 0.3)), result[2], epsilon)); | |
| 277 | expect(math.approxEqAbs(f32, @log10(@as(f32, 0.4)), result[3], epsilon)); | |
| 278 | } | |
| 279 | } | |
| 280 | ||
| 281 | test "@fabs" { | |
| 282 | comptime testFabs(); | |
| 283 | testFabs(); | |
| 284 | } | |
| 285 | ||
| 286 | fn testFabs() void { | |
| 287 | // TODO test f128, and c_longdouble | |
| 288 | // https://github.com/ziglang/zig/issues/4026 | |
| 289 | { | |
| 290 | var a: f16 = -2.5; | |
| 291 | var b: f16 = 2.5; | |
| 292 | expect(@fabs(a) == 2.5); | |
| 293 | expect(@fabs(b) == 2.5); | |
| 294 | } | |
| 295 | { | |
| 296 | var a: f32 = -2.5; | |
| 297 | var b: f32 = 2.5; | |
| 298 | expect(@fabs(a) == 2.5); | |
| 299 | expect(@fabs(b) == 2.5); | |
| 300 | } | |
| 301 | { | |
| 302 | var a: f64 = -2.5; | |
| 303 | var b: f64 = 2.5; | |
| 304 | expect(@fabs(a) == 2.5); | |
| 305 | expect(@fabs(b) == 2.5); | |
| 306 | } | |
| 307 | { | |
| 308 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 309 | var result = @fabs(v); | |
| 310 | expect(math.approxEqAbs(f32, @fabs(@as(f32, 1.1)), result[0], epsilon)); | |
| 311 | expect(math.approxEqAbs(f32, @fabs(@as(f32, -2.2)), result[1], epsilon)); | |
| 312 | expect(math.approxEqAbs(f32, @fabs(@as(f32, 0.3)), result[2], epsilon)); | |
| 313 | expect(math.approxEqAbs(f32, @fabs(@as(f32, -0.4)), result[3], epsilon)); | |
| 314 | } | |
| 315 | } | |
| 316 | ||
| 317 | test "@floor" { | |
| 318 | comptime testFloor(); | |
| 319 | testFloor(); | |
| 320 | } | |
| 321 | ||
| 322 | fn testFloor() void { | |
| 323 | // TODO test f128, and c_longdouble | |
| 324 | // https://github.com/ziglang/zig/issues/4026 | |
| 325 | { | |
| 326 | var a: f16 = 2.1; | |
| 327 | expect(@floor(a) == 2); | |
| 328 | } | |
| 329 | { | |
| 330 | var a: f32 = 2.1; | |
| 331 | expect(@floor(a) == 2); | |
| 332 | } | |
| 333 | { | |
| 334 | var a: f64 = 3.5; | |
| 335 | expect(@floor(a) == 3); | |
| 336 | } | |
| 337 | { | |
| 338 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 339 | var result = @floor(v); | |
| 340 | expect(math.approxEqAbs(f32, @floor(@as(f32, 1.1)), result[0], epsilon)); | |
| 341 | expect(math.approxEqAbs(f32, @floor(@as(f32, -2.2)), result[1], epsilon)); | |
| 342 | expect(math.approxEqAbs(f32, @floor(@as(f32, 0.3)), result[2], epsilon)); | |
| 343 | expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon)); | |
| 344 | } | |
| 345 | } | |
| 346 | ||
| 347 | test "@ceil" { | |
| 348 | comptime testCeil(); | |
| 349 | testCeil(); | |
| 350 | } | |
| 351 | ||
| 352 | fn testCeil() void { | |
| 353 | // TODO test f128, and c_longdouble | |
| 354 | // https://github.com/ziglang/zig/issues/4026 | |
| 355 | { | |
| 356 | var a: f16 = 2.1; | |
| 357 | expect(@ceil(a) == 3); | |
| 358 | } | |
| 359 | { | |
| 360 | var a: f32 = 2.1; | |
| 361 | expect(@ceil(a) == 3); | |
| 362 | } | |
| 363 | { | |
| 364 | var a: f64 = 3.5; | |
| 365 | expect(@ceil(a) == 4); | |
| 366 | } | |
| 367 | { | |
| 368 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 369 | var result = @ceil(v); | |
| 370 | expect(math.approxEqAbs(f32, @ceil(@as(f32, 1.1)), result[0], epsilon)); | |
| 371 | expect(math.approxEqAbs(f32, @ceil(@as(f32, -2.2)), result[1], epsilon)); | |
| 372 | expect(math.approxEqAbs(f32, @ceil(@as(f32, 0.3)), result[2], epsilon)); | |
| 373 | expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon)); | |
| 374 | } | |
| 375 | } | |
| 376 | ||
| 377 | test "@trunc" { | |
| 378 | comptime testTrunc(); | |
| 379 | testTrunc(); | |
| 380 | } | |
| 381 | ||
| 382 | fn testTrunc() void { | |
| 383 | // TODO test f128, and c_longdouble | |
| 384 | // https://github.com/ziglang/zig/issues/4026 | |
| 385 | { | |
| 386 | var a: f16 = 2.1; | |
| 387 | expect(@trunc(a) == 2); | |
| 388 | } | |
| 389 | { | |
| 390 | var a: f32 = 2.1; | |
| 391 | expect(@trunc(a) == 2); | |
| 392 | } | |
| 393 | { | |
| 394 | var a: f64 = -3.5; | |
| 395 | expect(@trunc(a) == -3); | |
| 396 | } | |
| 397 | { | |
| 398 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 399 | var result = @trunc(v); | |
| 400 | expect(math.approxEqAbs(f32, @trunc(@as(f32, 1.1)), result[0], epsilon)); | |
| 401 | expect(math.approxEqAbs(f32, @trunc(@as(f32, -2.2)), result[1], epsilon)); | |
| 402 | expect(math.approxEqAbs(f32, @trunc(@as(f32, 0.3)), result[2], epsilon)); | |
| 403 | expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); | |
| 404 | } | |
| 405 | } | |
| 406 | ||
| 407 | test "floating point comparisons" { | |
| 408 | testFloatComparisons(); | |
| 409 | comptime testFloatComparisons(); | |
| 410 | } | |
| 411 | ||
| 412 | fn testFloatComparisons() void { | |
| 413 | inline for ([_]type{ f16, f32, f64, f128 }) |ty| { | |
| 414 | // No decimal part | |
| 415 | { | |
| 416 | const x: ty = 1.0; | |
| 417 | expect(x == 1); | |
| 418 | expect(x != 0); | |
| 419 | expect(x > 0); | |
| 420 | expect(x < 2); | |
| 421 | expect(x >= 1); | |
| 422 | expect(x <= 1); | |
| 423 | } | |
| 424 | // Non-zero decimal part | |
| 425 | { | |
| 426 | const x: ty = 1.5; | |
| 427 | expect(x != 1); | |
| 428 | expect(x != 2); | |
| 429 | expect(x > 1); | |
| 430 | expect(x < 2); | |
| 431 | expect(x >= 1); | |
| 432 | expect(x <= 2); | |
| 433 | } | |
| 434 | } | |
| 435 | } | |
| 436 | ||
| 437 | test "different sized float comparisons" { | |
| 438 | testDifferentSizedFloatComparisons(); | |
| 439 | comptime testDifferentSizedFloatComparisons(); | |
| 440 | } | |
| 441 | ||
| 442 | fn testDifferentSizedFloatComparisons() void { | |
| 443 | var a: f16 = 1; | |
| 444 | var b: f64 = 2; | |
| 445 | expect(a < b); | |
| 446 | } | |
| 447 | ||
| 448 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) | |
| 449 | //test "@nearbyint" { | |
| 450 | // comptime testNearbyInt(); | |
| 451 | // testNearbyInt(); | |
| 452 | //} | |
| 453 | ||
| 454 | //fn testNearbyInt() void { | |
| 455 | // // TODO test f16, f128, and c_longdouble | |
| 456 | // // https://github.com/ziglang/zig/issues/4026 | |
| 457 | // { | |
| 458 | // var a: f32 = 2.1; | |
| 459 | // expect(@nearbyint(a) == 2); | |
| 460 | // } | |
| 461 | // { | |
| 462 | // var a: f64 = -3.75; | |
| 463 | // expect(@nearbyint(a) == -4); | |
| 464 | // } | |
| 465 | //} |
test/behavior/fn.zig created+287| ... | ... | @@ -0,0 +1,287 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const testing = std.testing; | |
| 4 | const expect = testing.expect; | |
| 5 | const expectEqual = testing.expectEqual; | |
| 6 | ||
| 7 | test "params" { | |
| 8 | expect(testParamsAdd(22, 11) == 33); | |
| 9 | } | |
| 10 | fn testParamsAdd(a: i32, b: i32) i32 { | |
| 11 | return a + b; | |
| 12 | } | |
| 13 | ||
| 14 | test "local variables" { | |
| 15 | testLocVars(2); | |
| 16 | } | |
| 17 | fn testLocVars(b: i32) void { | |
| 18 | const a: i32 = 1; | |
| 19 | if (a + b != 3) unreachable; | |
| 20 | } | |
| 21 | ||
| 22 | test "void parameters" { | |
| 23 | voidFun(1, void{}, 2, {}); | |
| 24 | } | |
| 25 | fn voidFun(a: i32, b: void, c: i32, d: void) void { | |
| 26 | const v = b; | |
| 27 | const vv: void = if (a == 1) v else {}; | |
| 28 | expect(a + c == 3); | |
| 29 | return vv; | |
| 30 | } | |
| 31 | ||
| 32 | test "mutable local variables" { | |
| 33 | var zero: i32 = 0; | |
| 34 | expect(zero == 0); | |
| 35 | ||
| 36 | var i = @as(i32, 0); | |
| 37 | while (i != 3) { | |
| 38 | i += 1; | |
| 39 | } | |
| 40 | expect(i == 3); | |
| 41 | } | |
| 42 | ||
| 43 | test "separate block scopes" { | |
| 44 | { | |
| 45 | const no_conflict: i32 = 5; | |
| 46 | expect(no_conflict == 5); | |
| 47 | } | |
| 48 | ||
| 49 | const c = x: { | |
| 50 | const no_conflict = @as(i32, 10); | |
| 51 | break :x no_conflict; | |
| 52 | }; | |
| 53 | expect(c == 10); | |
| 54 | } | |
| 55 | ||
| 56 | test "call function with empty string" { | |
| 57 | acceptsString(""); | |
| 58 | } | |
| 59 | ||
| 60 | fn acceptsString(foo: []u8) void {} | |
| 61 | ||
| 62 | fn @"weird function name"() i32 { | |
| 63 | return 1234; | |
| 64 | } | |
| 65 | test "weird function name" { | |
| 66 | expect(@"weird function name"() == 1234); | |
| 67 | } | |
| 68 | ||
| 69 | test "implicit cast function unreachable return" { | |
| 70 | wantsFnWithVoid(fnWithUnreachable); | |
| 71 | } | |
| 72 | ||
| 73 | fn wantsFnWithVoid(f: fn () void) void {} | |
| 74 | ||
| 75 | fn fnWithUnreachable() noreturn { | |
| 76 | unreachable; | |
| 77 | } | |
| 78 | ||
| 79 | test "function pointers" { | |
| 80 | const fns = [_]@TypeOf(fn1){ | |
| 81 | fn1, | |
| 82 | fn2, | |
| 83 | fn3, | |
| 84 | fn4, | |
| 85 | }; | |
| 86 | for (fns) |f, i| { | |
| 87 | expect(f() == @intCast(u32, i) + 5); | |
| 88 | } | |
| 89 | } | |
| 90 | fn fn1() u32 { | |
| 91 | return 5; | |
| 92 | } | |
| 93 | fn fn2() u32 { | |
| 94 | return 6; | |
| 95 | } | |
| 96 | fn fn3() u32 { | |
| 97 | return 7; | |
| 98 | } | |
| 99 | fn fn4() u32 { | |
| 100 | return 8; | |
| 101 | } | |
| 102 | ||
| 103 | test "number literal as an argument" { | |
| 104 | numberLiteralArg(3); | |
| 105 | comptime numberLiteralArg(3); | |
| 106 | } | |
| 107 | ||
| 108 | fn numberLiteralArg(a: anytype) void { | |
| 109 | expect(a == 3); | |
| 110 | } | |
| 111 | ||
| 112 | test "assign inline fn to const variable" { | |
| 113 | const a = inlineFn; | |
| 114 | a(); | |
| 115 | } | |
| 116 | ||
| 117 | fn inlineFn() callconv(.Inline) void {} | |
| 118 | ||
| 119 | test "pass by non-copying value" { | |
| 120 | expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); | |
| 121 | } | |
| 122 | ||
| 123 | const Point = struct { | |
| 124 | x: i32, | |
| 125 | y: i32, | |
| 126 | }; | |
| 127 | ||
| 128 | fn addPointCoords(pt: Point) i32 { | |
| 129 | return pt.x + pt.y; | |
| 130 | } | |
| 131 | ||
| 132 | test "pass by non-copying value through var arg" { | |
| 133 | expect(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3); | |
| 134 | } | |
| 135 | ||
| 136 | fn addPointCoordsVar(pt: anytype) i32 { | |
| 137 | comptime expect(@TypeOf(pt) == Point); | |
| 138 | return pt.x + pt.y; | |
| 139 | } | |
| 140 | ||
| 141 | test "pass by non-copying value as method" { | |
| 142 | var pt = Point2{ .x = 1, .y = 2 }; | |
| 143 | expect(pt.addPointCoords() == 3); | |
| 144 | } | |
| 145 | ||
| 146 | const Point2 = struct { | |
| 147 | x: i32, | |
| 148 | y: i32, | |
| 149 | ||
| 150 | fn addPointCoords(self: Point2) i32 { | |
| 151 | return self.x + self.y; | |
| 152 | } | |
| 153 | }; | |
| 154 | ||
| 155 | test "pass by non-copying value as method, which is generic" { | |
| 156 | var pt = Point3{ .x = 1, .y = 2 }; | |
| 157 | expect(pt.addPointCoords(i32) == 3); | |
| 158 | } | |
| 159 | ||
| 160 | const Point3 = struct { | |
| 161 | x: i32, | |
| 162 | y: i32, | |
| 163 | ||
| 164 | fn addPointCoords(self: Point3, comptime T: type) i32 { | |
| 165 | return self.x + self.y; | |
| 166 | } | |
| 167 | }; | |
| 168 | ||
| 169 | test "pass by non-copying value as method, at comptime" { | |
| 170 | comptime { | |
| 171 | var pt = Point2{ .x = 1, .y = 2 }; | |
| 172 | expect(pt.addPointCoords() == 3); | |
| 173 | } | |
| 174 | } | |
| 175 | ||
| 176 | fn outer(y: u32) fn (u32) u32 { | |
| 177 | const Y = @TypeOf(y); | |
| 178 | const st = struct { | |
| 179 | fn get(z: u32) u32 { | |
| 180 | return z + @sizeOf(Y); | |
| 181 | } | |
| 182 | }; | |
| 183 | return st.get; | |
| 184 | } | |
| 185 | ||
| 186 | test "return inner function which references comptime variable of outer function" { | |
| 187 | var func = outer(10); | |
| 188 | expect(func(3) == 7); | |
| 189 | } | |
| 190 | ||
| 191 | test "extern struct with stdcallcc fn pointer" { | |
| 192 | const S = extern struct { | |
| 193 | ptr: fn () callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32, | |
| 194 | ||
| 195 | fn foo() callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32 { | |
| 196 | return 1234; | |
| 197 | } | |
| 198 | }; | |
| 199 | ||
| 200 | var s: S = undefined; | |
| 201 | s.ptr = S.foo; | |
| 202 | expect(s.ptr() == 1234); | |
| 203 | } | |
| 204 | ||
| 205 | test "implicit cast fn call result to optional in field result" { | |
| 206 | const S = struct { | |
| 207 | fn entry() void { | |
| 208 | var x = Foo{ | |
| 209 | .field = optionalPtr(), | |
| 210 | }; | |
| 211 | expect(x.field.?.* == 999); | |
| 212 | } | |
| 213 | ||
| 214 | const glob: i32 = 999; | |
| 215 | ||
| 216 | fn optionalPtr() *const i32 { | |
| 217 | return &glob; | |
| 218 | } | |
| 219 | ||
| 220 | const Foo = struct { | |
| 221 | field: ?*const i32, | |
| 222 | }; | |
| 223 | }; | |
| 224 | S.entry(); | |
| 225 | comptime S.entry(); | |
| 226 | } | |
| 227 | ||
| 228 | test "discard the result of a function that returns a struct" { | |
| 229 | const S = struct { | |
| 230 | fn entry() void { | |
| 231 | _ = func(); | |
| 232 | } | |
| 233 | ||
| 234 | fn func() Foo { | |
| 235 | return undefined; | |
| 236 | } | |
| 237 | ||
| 238 | const Foo = struct { | |
| 239 | a: u64, | |
| 240 | b: u64, | |
| 241 | }; | |
| 242 | }; | |
| 243 | S.entry(); | |
| 244 | comptime S.entry(); | |
| 245 | } | |
| 246 | ||
| 247 | test "function call with anon list literal" { | |
| 248 | const S = struct { | |
| 249 | fn doTheTest() void { | |
| 250 | consumeVec(.{ 9, 8, 7 }); | |
| 251 | } | |
| 252 | ||
| 253 | fn consumeVec(vec: [3]f32) void { | |
| 254 | expect(vec[0] == 9); | |
| 255 | expect(vec[1] == 8); | |
| 256 | expect(vec[2] == 7); | |
| 257 | } | |
| 258 | }; | |
| 259 | S.doTheTest(); | |
| 260 | comptime S.doTheTest(); | |
| 261 | } | |
| 262 | ||
| 263 | test "ability to give comptime types and non comptime types to same parameter" { | |
| 264 | const S = struct { | |
| 265 | fn doTheTest() void { | |
| 266 | var x: i32 = 1; | |
| 267 | expect(foo(x) == 10); | |
| 268 | expect(foo(i32) == 20); | |
| 269 | } | |
| 270 | ||
| 271 | fn foo(arg: anytype) i32 { | |
| 272 | if (@typeInfo(@TypeOf(arg)) == .Type and arg == i32) return 20; | |
| 273 | return 9 + arg; | |
| 274 | } | |
| 275 | }; | |
| 276 | S.doTheTest(); | |
| 277 | comptime S.doTheTest(); | |
| 278 | } | |
| 279 | ||
| 280 | test "function with inferred error set but returning no error" { | |
| 281 | const S = struct { | |
| 282 | fn foo() !void {} | |
| 283 | }; | |
| 284 | ||
| 285 | const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?; | |
| 286 | expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len); | |
| 287 | } |
test/behavior/fn_delegation.zig created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | a: u64 = 10, | |
| 5 | ||
| 6 | fn one(self: Foo) u64 { | |
| 7 | return self.a + 1; | |
| 8 | } | |
| 9 | ||
| 10 | const two = __two; | |
| 11 | ||
| 12 | fn __two(self: Foo) u64 { | |
| 13 | return self.a + 2; | |
| 14 | } | |
| 15 | ||
| 16 | const three = __three; | |
| 17 | ||
| 18 | const four = custom(Foo, 4); | |
| 19 | }; | |
| 20 | ||
| 21 | fn __three(self: Foo) u64 { | |
| 22 | return self.a + 3; | |
| 23 | } | |
| 24 | ||
| 25 | fn custom(comptime T: type, comptime num: u64) fn (T) u64 { | |
| 26 | return struct { | |
| 27 | fn function(self: T) u64 { | |
| 28 | return self.a + num; | |
| 29 | } | |
| 30 | }.function; | |
| 31 | } | |
| 32 | ||
| 33 | test "fn delegation" { | |
| 34 | const foo = Foo{}; | |
| 35 | expect(foo.one() == 11); | |
| 36 | expect(foo.two() == 12); | |
| 37 | expect(foo.three() == 13); | |
| 38 | expect(foo.four() == 14); | |
| 39 | } |
test/behavior/fn_in_struct_in_comptime.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn get_foo() fn (*u8) usize { | |
| 4 | comptime { | |
| 5 | return struct { | |
| 6 | fn func(ptr: *u8) usize { | |
| 7 | var u = @ptrToInt(ptr); | |
| 8 | return u; | |
| 9 | } | |
| 10 | }.func; | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | test "define a function in an anonymous struct in comptime" { | |
| 15 | const foo = get_foo(); | |
| 16 | expect(foo(@intToPtr(*u8, 12345)) == 12345); | |
| 17 | } |
test/behavior/for.zig created+172| ... | ... | @@ -0,0 +1,172 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const mem = std.mem; | |
| 5 | ||
| 6 | test "continue in for loop" { | |
| 7 | const array = [_]i32{ | |
| 8 | 1, | |
| 9 | 2, | |
| 10 | 3, | |
| 11 | 4, | |
| 12 | 5, | |
| 13 | }; | |
| 14 | var sum: i32 = 0; | |
| 15 | for (array) |x| { | |
| 16 | sum += x; | |
| 17 | if (x < 3) { | |
| 18 | continue; | |
| 19 | } | |
| 20 | break; | |
| 21 | } | |
| 22 | if (sum != 6) unreachable; | |
| 23 | } | |
| 24 | ||
| 25 | test "for loop with pointer elem var" { | |
| 26 | const source = "abcdefg"; | |
| 27 | var target: [source.len]u8 = undefined; | |
| 28 | mem.copy(u8, target[0..], source); | |
| 29 | mangleString(target[0..]); | |
| 30 | expect(mem.eql(u8, &target, "bcdefgh")); | |
| 31 | ||
| 32 | for (source) |*c, i| | |
| 33 | expect(@TypeOf(c) == *const u8); | |
| 34 | for (target) |*c, i| | |
| 35 | expect(@TypeOf(c) == *u8); | |
| 36 | } | |
| 37 | ||
| 38 | fn mangleString(s: []u8) void { | |
| 39 | for (s) |*c| { | |
| 40 | c.* += 1; | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | test "basic for loop" { | |
| 45 | const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; | |
| 46 | ||
| 47 | var buffer: [expected_result.len]u8 = undefined; | |
| 48 | var buf_index: usize = 0; | |
| 49 | ||
| 50 | const array = [_]u8{ 9, 8, 7, 6 }; | |
| 51 | for (array) |item| { | |
| 52 | buffer[buf_index] = item; | |
| 53 | buf_index += 1; | |
| 54 | } | |
| 55 | for (array) |item, index| { | |
| 56 | buffer[buf_index] = @intCast(u8, index); | |
| 57 | buf_index += 1; | |
| 58 | } | |
| 59 | const array_ptr = &array; | |
| 60 | for (array_ptr) |item| { | |
| 61 | buffer[buf_index] = item; | |
| 62 | buf_index += 1; | |
| 63 | } | |
| 64 | for (array_ptr) |item, index| { | |
| 65 | buffer[buf_index] = @intCast(u8, index); | |
| 66 | buf_index += 1; | |
| 67 | } | |
| 68 | const unknown_size: []const u8 = &array; | |
| 69 | for (unknown_size) |item| { | |
| 70 | buffer[buf_index] = item; | |
| 71 | buf_index += 1; | |
| 72 | } | |
| 73 | for (unknown_size) |item, index| { | |
| 74 | buffer[buf_index] = @intCast(u8, index); | |
| 75 | buf_index += 1; | |
| 76 | } | |
| 77 | ||
| 78 | expect(mem.eql(u8, buffer[0..buf_index], &expected_result)); | |
| 79 | } | |
| 80 | ||
| 81 | test "break from outer for loop" { | |
| 82 | testBreakOuter(); | |
| 83 | comptime testBreakOuter(); | |
| 84 | } | |
| 85 | ||
| 86 | fn testBreakOuter() void { | |
| 87 | var array = "aoeu"; | |
| 88 | var count: usize = 0; | |
| 89 | outer: for (array) |_| { | |
| 90 | for (array) |_| { | |
| 91 | count += 1; | |
| 92 | break :outer; | |
| 93 | } | |
| 94 | } | |
| 95 | expect(count == 1); | |
| 96 | } | |
| 97 | ||
| 98 | test "continue outer for loop" { | |
| 99 | testContinueOuter(); | |
| 100 | comptime testContinueOuter(); | |
| 101 | } | |
| 102 | ||
| 103 | fn testContinueOuter() void { | |
| 104 | var array = "aoeu"; | |
| 105 | var counter: usize = 0; | |
| 106 | outer: for (array) |_| { | |
| 107 | for (array) |_| { | |
| 108 | counter += 1; | |
| 109 | continue :outer; | |
| 110 | } | |
| 111 | } | |
| 112 | expect(counter == array.len); | |
| 113 | } | |
| 114 | ||
| 115 | test "2 break statements and an else" { | |
| 116 | const S = struct { | |
| 117 | fn entry(t: bool, f: bool) void { | |
| 118 | var buf: [10]u8 = undefined; | |
| 119 | var ok = false; | |
| 120 | ok = for (buf) |item| { | |
| 121 | if (f) break false; | |
| 122 | if (t) break true; | |
| 123 | } else false; | |
| 124 | expect(ok); | |
| 125 | } | |
| 126 | }; | |
| 127 | S.entry(true, false); | |
| 128 | comptime S.entry(true, false); | |
| 129 | } | |
| 130 | ||
| 131 | test "for with null and T peer types and inferred result location type" { | |
| 132 | const S = struct { | |
| 133 | fn doTheTest(slice: []const u8) void { | |
| 134 | if (for (slice) |item| { | |
| 135 | if (item == 10) { | |
| 136 | break item; | |
| 137 | } | |
| 138 | } else null) |v| { | |
| 139 | @panic("fail"); | |
| 140 | } | |
| 141 | } | |
| 142 | }; | |
| 143 | S.doTheTest(&[_]u8{ 1, 2 }); | |
| 144 | comptime S.doTheTest(&[_]u8{ 1, 2 }); | |
| 145 | } | |
| 146 | ||
| 147 | test "for copies its payload" { | |
| 148 | const S = struct { | |
| 149 | fn doTheTest() void { | |
| 150 | var x = [_]usize{ 1, 2, 3 }; | |
| 151 | for (x) |value, i| { | |
| 152 | // Modify the original array | |
| 153 | x[i] += 99; | |
| 154 | expectEqual(value, i + 1); | |
| 155 | } | |
| 156 | } | |
| 157 | }; | |
| 158 | S.doTheTest(); | |
| 159 | comptime S.doTheTest(); | |
| 160 | } | |
| 161 | ||
| 162 | test "for on slice with allowzero ptr" { | |
| 163 | const S = struct { | |
| 164 | fn doTheTest(slice: []const u8) void { | |
| 165 | var ptr = @ptrCast([*]allowzero const u8, slice.ptr)[0..slice.len]; | |
| 166 | for (ptr) |x, i| expect(x == i + 1); | |
| 167 | for (ptr) |*x, i| expect(x.* == i + 1); | |
| 168 | } | |
| 169 | }; | |
| 170 | S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); | |
| 171 | comptime S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); | |
| 172 | } |
test/behavior/generics.zig created+169| ... | ... | @@ -0,0 +1,169 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | test "simple generic fn" { | |
| 7 | expect(max(i32, 3, -1) == 3); | |
| 8 | expect(max(f32, 0.123, 0.456) == 0.456); | |
| 9 | expect(add(2, 3) == 5); | |
| 10 | } | |
| 11 | ||
| 12 | fn max(comptime T: type, a: T, b: T) T { | |
| 13 | return if (a > b) a else b; | |
| 14 | } | |
| 15 | ||
| 16 | fn add(comptime a: i32, b: i32) i32 { | |
| 17 | return (comptime a) + b; | |
| 18 | } | |
| 19 | ||
| 20 | const the_max = max(u32, 1234, 5678); | |
| 21 | test "compile time generic eval" { | |
| 22 | expect(the_max == 5678); | |
| 23 | } | |
| 24 | ||
| 25 | fn gimmeTheBigOne(a: u32, b: u32) u32 { | |
| 26 | return max(u32, a, b); | |
| 27 | } | |
| 28 | ||
| 29 | fn shouldCallSameInstance(a: u32, b: u32) u32 { | |
| 30 | return max(u32, a, b); | |
| 31 | } | |
| 32 | ||
| 33 | fn sameButWithFloats(a: f64, b: f64) f64 { | |
| 34 | return max(f64, a, b); | |
| 35 | } | |
| 36 | ||
| 37 | test "fn with comptime args" { | |
| 38 | expect(gimmeTheBigOne(1234, 5678) == 5678); | |
| 39 | expect(shouldCallSameInstance(34, 12) == 34); | |
| 40 | expect(sameButWithFloats(0.43, 0.49) == 0.49); | |
| 41 | } | |
| 42 | ||
| 43 | test "var params" { | |
| 44 | expect(max_i32(12, 34) == 34); | |
| 45 | expect(max_f64(1.2, 3.4) == 3.4); | |
| 46 | } | |
| 47 | ||
| 48 | comptime { | |
| 49 | expect(max_i32(12, 34) == 34); | |
| 50 | expect(max_f64(1.2, 3.4) == 3.4); | |
| 51 | } | |
| 52 | ||
| 53 | fn max_var(a: anytype, b: anytype) @TypeOf(a + b) { | |
| 54 | return if (a > b) a else b; | |
| 55 | } | |
| 56 | ||
| 57 | fn max_i32(a: i32, b: i32) i32 { | |
| 58 | return max_var(a, b); | |
| 59 | } | |
| 60 | ||
| 61 | fn max_f64(a: f64, b: f64) f64 { | |
| 62 | return max_var(a, b); | |
| 63 | } | |
| 64 | ||
| 65 | pub fn List(comptime T: type) type { | |
| 66 | return SmallList(T, 8); | |
| 67 | } | |
| 68 | ||
| 69 | pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { | |
| 70 | return struct { | |
| 71 | items: []T, | |
| 72 | length: usize, | |
| 73 | prealloc_items: [STATIC_SIZE]T, | |
| 74 | }; | |
| 75 | } | |
| 76 | ||
| 77 | test "function with return type type" { | |
| 78 | var list: List(i32) = undefined; | |
| 79 | var list2: List(i32) = undefined; | |
| 80 | list.length = 10; | |
| 81 | list2.length = 10; | |
| 82 | expect(list.prealloc_items.len == 8); | |
| 83 | expect(list2.prealloc_items.len == 8); | |
| 84 | } | |
| 85 | ||
| 86 | test "generic struct" { | |
| 87 | var a1 = GenNode(i32){ | |
| 88 | .value = 13, | |
| 89 | .next = null, | |
| 90 | }; | |
| 91 | var b1 = GenNode(bool){ | |
| 92 | .value = true, | |
| 93 | .next = null, | |
| 94 | }; | |
| 95 | expect(a1.value == 13); | |
| 96 | expect(a1.value == a1.getVal()); | |
| 97 | expect(b1.getVal()); | |
| 98 | } | |
| 99 | fn GenNode(comptime T: type) type { | |
| 100 | return struct { | |
| 101 | value: T, | |
| 102 | next: ?*GenNode(T), | |
| 103 | fn getVal(n: *const GenNode(T)) T { | |
| 104 | return n.value; | |
| 105 | } | |
| 106 | }; | |
| 107 | } | |
| 108 | ||
| 109 | test "const decls in struct" { | |
| 110 | expect(GenericDataThing(3).count_plus_one == 4); | |
| 111 | } | |
| 112 | fn GenericDataThing(comptime count: isize) type { | |
| 113 | return struct { | |
| 114 | const count_plus_one = count + 1; | |
| 115 | }; | |
| 116 | } | |
| 117 | ||
| 118 | test "use generic param in generic param" { | |
| 119 | expect(aGenericFn(i32, 3, 4) == 7); | |
| 120 | } | |
| 121 | fn aGenericFn(comptime T: type, comptime a: T, b: T) T { | |
| 122 | return a + b; | |
| 123 | } | |
| 124 | ||
| 125 | test "generic fn with implicit cast" { | |
| 126 | expect(getFirstByte(u8, &[_]u8{13}) == 13); | |
| 127 | expect(getFirstByte(u16, &[_]u16{ | |
| 128 | 0, | |
| 129 | 13, | |
| 130 | }) == 0); | |
| 131 | } | |
| 132 | fn getByte(ptr: ?*const u8) u8 { | |
| 133 | return ptr.?.*; | |
| 134 | } | |
| 135 | fn getFirstByte(comptime T: type, mem: []const T) u8 { | |
| 136 | return getByte(@ptrCast(*const u8, &mem[0])); | |
| 137 | } | |
| 138 | ||
| 139 | const foos = [_]fn (anytype) bool{ | |
| 140 | foo1, | |
| 141 | foo2, | |
| 142 | }; | |
| 143 | ||
| 144 | fn foo1(arg: anytype) bool { | |
| 145 | return arg; | |
| 146 | } | |
| 147 | fn foo2(arg: anytype) bool { | |
| 148 | return !arg; | |
| 149 | } | |
| 150 | ||
| 151 | test "array of generic fns" { | |
| 152 | expect(foos[0](true)); | |
| 153 | expect(!foos[1](true)); | |
| 154 | } | |
| 155 | ||
| 156 | test "generic fn keeps non-generic parameter types" { | |
| 157 | const A = 128; | |
| 158 | ||
| 159 | const S = struct { | |
| 160 | fn f(comptime T: type, s: []T) void { | |
| 161 | expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment); | |
| 162 | } | |
| 163 | }; | |
| 164 | ||
| 165 | // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that | |
| 166 | // `x` type not affect `s` parameter type. | |
| 167 | var x: [16]u8 align(A) = undefined; | |
| 168 | S.f(u8, &x); | |
| 169 | } |
test/behavior/hasdecl.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const Foo = @import("hasdecl/foo.zig"); | |
| 5 | ||
| 6 | const Bar = struct { | |
| 7 | nope: i32, | |
| 8 | ||
| 9 | const hi = 1; | |
| 10 | pub var blah = "xxx"; | |
| 11 | }; | |
| 12 | ||
| 13 | test "@hasDecl" { | |
| 14 | expect(@hasDecl(Foo, "public_thing")); | |
| 15 | expect(!@hasDecl(Foo, "private_thing")); | |
| 16 | expect(!@hasDecl(Foo, "no_thing")); | |
| 17 | ||
| 18 | expect(@hasDecl(Bar, "hi")); | |
| 19 | expect(@hasDecl(Bar, "blah")); | |
| 20 | expect(!@hasDecl(Bar, "nope")); | |
| 21 | } |
test/behavior/hasdecl/foo.zig created+2| ... | ... | @@ -0,0 +1,2 @@ |
| 1 | pub const public_thing = 42; | |
| 2 | const private_thing = 666; |
test/behavior/hasfield.zig created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const builtin = @import("builtin"); | |
| 3 | ||
| 4 | test "@hasField" { | |
| 5 | const struc = struct { | |
| 6 | a: i32, | |
| 7 | b: []u8, | |
| 8 | ||
| 9 | pub const nope = 1; | |
| 10 | }; | |
| 11 | expect(@hasField(struc, "a") == true); | |
| 12 | expect(@hasField(struc, "b") == true); | |
| 13 | expect(@hasField(struc, "non-existant") == false); | |
| 14 | expect(@hasField(struc, "nope") == false); | |
| 15 | ||
| 16 | const unin = union { | |
| 17 | a: u64, | |
| 18 | b: []u16, | |
| 19 | ||
| 20 | pub const nope = 1; | |
| 21 | }; | |
| 22 | expect(@hasField(unin, "a") == true); | |
| 23 | expect(@hasField(unin, "b") == true); | |
| 24 | expect(@hasField(unin, "non-existant") == false); | |
| 25 | expect(@hasField(unin, "nope") == false); | |
| 26 | ||
| 27 | const enm = enum { | |
| 28 | a, | |
| 29 | b, | |
| 30 | ||
| 31 | pub const nope = 1; | |
| 32 | }; | |
| 33 | expect(@hasField(enm, "a") == true); | |
| 34 | expect(@hasField(enm, "b") == true); | |
| 35 | expect(@hasField(enm, "non-existant") == false); | |
| 36 | expect(@hasField(enm, "nope") == false); | |
| 37 | } |
test/behavior/if.zig created+109| ... | ... | @@ -0,0 +1,109 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "if statements" { | |
| 6 | shouldBeEqual(1, 1); | |
| 7 | firstEqlThird(2, 1, 2); | |
| 8 | } | |
| 9 | fn shouldBeEqual(a: i32, b: i32) void { | |
| 10 | if (a != b) { | |
| 11 | unreachable; | |
| 12 | } else { | |
| 13 | return; | |
| 14 | } | |
| 15 | } | |
| 16 | fn firstEqlThird(a: i32, b: i32, c: i32) void { | |
| 17 | if (a == b) { | |
| 18 | unreachable; | |
| 19 | } else if (b == c) { | |
| 20 | unreachable; | |
| 21 | } else if (a == c) { | |
| 22 | return; | |
| 23 | } else { | |
| 24 | unreachable; | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | test "else if expression" { | |
| 29 | expect(elseIfExpressionF(1) == 1); | |
| 30 | } | |
| 31 | fn elseIfExpressionF(c: u8) u8 { | |
| 32 | if (c == 0) { | |
| 33 | return 0; | |
| 34 | } else if (c == 1) { | |
| 35 | return 1; | |
| 36 | } else { | |
| 37 | return @as(u8, 2); | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | // #2297 | |
| 42 | var global_with_val: anyerror!u32 = 0; | |
| 43 | var global_with_err: anyerror!u32 = error.SomeError; | |
| 44 | ||
| 45 | test "unwrap mutable global var" { | |
| 46 | if (global_with_val) |v| { | |
| 47 | expect(v == 0); | |
| 48 | } else |e| { | |
| 49 | unreachable; | |
| 50 | } | |
| 51 | if (global_with_err) |_| { | |
| 52 | unreachable; | |
| 53 | } else |e| { | |
| 54 | expect(e == error.SomeError); | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | test "labeled break inside comptime if inside runtime if" { | |
| 59 | var answer: i32 = 0; | |
| 60 | var c = true; | |
| 61 | if (c) { | |
| 62 | answer = if (true) blk: { | |
| 63 | break :blk @as(i32, 42); | |
| 64 | }; | |
| 65 | } | |
| 66 | expect(answer == 42); | |
| 67 | } | |
| 68 | ||
| 69 | test "const result loc, runtime if cond, else unreachable" { | |
| 70 | const Num = enum { | |
| 71 | One, | |
| 72 | Two, | |
| 73 | }; | |
| 74 | ||
| 75 | var t = true; | |
| 76 | const x = if (t) Num.Two else unreachable; | |
| 77 | expect(x == .Two); | |
| 78 | } | |
| 79 | ||
| 80 | test "if prongs cast to expected type instead of peer type resolution" { | |
| 81 | const S = struct { | |
| 82 | fn doTheTest(f: bool) void { | |
| 83 | var x: i32 = 0; | |
| 84 | x = if (f) 1 else 2; | |
| 85 | expect(x == 2); | |
| 86 | ||
| 87 | var b = true; | |
| 88 | const y: i32 = if (b) 1 else 2; | |
| 89 | expect(y == 1); | |
| 90 | } | |
| 91 | }; | |
| 92 | S.doTheTest(false); | |
| 93 | comptime S.doTheTest(false); | |
| 94 | } | |
| 95 | ||
| 96 | test "while copies its payload" { | |
| 97 | const S = struct { | |
| 98 | fn doTheTest() void { | |
| 99 | var tmp: ?i32 = 10; | |
| 100 | if (tmp) |value| { | |
| 101 | // Modify the original variable | |
| 102 | tmp = null; | |
| 103 | expectEqual(@as(i32, 10), value); | |
| 104 | } else unreachable; | |
| 105 | } | |
| 106 | }; | |
| 107 | S.doTheTest(); | |
| 108 | comptime S.doTheTest(); | |
| 109 | } |
test/behavior/import.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const expectEqual = @import("std").testing.expectEqual; | |
| 3 | const a_namespace = @import("import/a_namespace.zig"); | |
| 4 | ||
| 5 | test "call fn via namespace lookup" { | |
| 6 | expectEqual(@as(i32, 1234), a_namespace.foo()); | |
| 7 | } | |
| 8 | ||
| 9 | test "importing the same thing gives the same import" { | |
| 10 | expect(@import("std") == @import("std")); | |
| 11 | } | |
| 12 | ||
| 13 | test "import in non-toplevel scope" { | |
| 14 | const S = struct { | |
| 15 | usingnamespace @import("import/a_namespace.zig"); | |
| 16 | }; | |
| 17 | expectEqual(@as(i32, 1234), S.foo()); | |
| 18 | } | |
| 19 | ||
| 20 | test "import empty file" { | |
| 21 | const empty = @import("import/empty.zig"); | |
| 22 | } |
test/behavior/import/a_namespace.zig created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | pub fn foo() i32 { | |
| 2 | return 1234; | |
| 3 | } |
test/behavior/import/empty.zig createdtest/behavior/incomplete_struct_param_tld.zig created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const A = struct { | |
| 4 | b: B, | |
| 5 | }; | |
| 6 | ||
| 7 | const B = struct { | |
| 8 | c: C, | |
| 9 | }; | |
| 10 | ||
| 11 | const C = struct { | |
| 12 | x: i32, | |
| 13 | ||
| 14 | fn d(c: *const C) i32 { | |
| 15 | return c.x; | |
| 16 | } | |
| 17 | }; | |
| 18 | ||
| 19 | fn foo(a: A) i32 { | |
| 20 | return a.b.c.d(); | |
| 21 | } | |
| 22 | ||
| 23 | test "incomplete struct param top level declaration" { | |
| 24 | const a = A{ | |
| 25 | .b = B{ | |
| 26 | .c = C{ .x = 13 }, | |
| 27 | }, | |
| 28 | }; | |
| 29 | expect(foo(a) == 13); | |
| 30 | } |
test/behavior/inttoptr.zig created+26| ... | ... | @@ -0,0 +1,26 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "casting random address to function pointer" { | |
| 6 | randomAddressToFunction(); | |
| 7 | comptime randomAddressToFunction(); | |
| 8 | } | |
| 9 | ||
| 10 | fn randomAddressToFunction() void { | |
| 11 | var addr: usize = 0xdeadbeef; | |
| 12 | var ptr = @intToPtr(fn () void, addr); | |
| 13 | } | |
| 14 | ||
| 15 | test "mutate through ptr initialized with constant intToPtr value" { | |
| 16 | forceCompilerAnalyzeBranchHardCodedPtrDereference(false); | |
| 17 | } | |
| 18 | ||
| 19 | fn forceCompilerAnalyzeBranchHardCodedPtrDereference(x: bool) void { | |
| 20 | const hardCodedP = @intToPtr(*volatile u8, 0xdeadbeef); | |
| 21 | if (x) { | |
| 22 | hardCodedP.* = hardCodedP.* | 10; | |
| 23 | } else { | |
| 24 | return; | |
| 25 | } | |
| 26 | } |
test/behavior/ir_block_deps.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn foo(id: u64) !i32 { | |
| 4 | return switch (id) { | |
| 5 | 1 => getErrInt(), | |
| 6 | 2 => { | |
| 7 | const size = try getErrInt(); | |
| 8 | return try getErrInt(); | |
| 9 | }, | |
| 10 | else => error.ItBroke, | |
| 11 | }; | |
| 12 | } | |
| 13 | ||
| 14 | fn getErrInt() anyerror!i32 { | |
| 15 | return 0; | |
| 16 | } | |
| 17 | ||
| 18 | test "ir block deps" { | |
| 19 | expect((foo(1) catch unreachable) == 0); | |
| 20 | expect((foo(2) catch unreachable) == 0); | |
| 21 | } |
test/behavior/math.zig created+872| ... | ... | @@ -0,0 +1,872 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | const minInt = std.math.minInt; | |
| 7 | const mem = std.mem; | |
| 8 | ||
| 9 | test "division" { | |
| 10 | testDivision(); | |
| 11 | comptime testDivision(); | |
| 12 | } | |
| 13 | fn testDivision() void { | |
| 14 | expect(div(u32, 13, 3) == 4); | |
| 15 | expect(div(f16, 1.0, 2.0) == 0.5); | |
| 16 | expect(div(f32, 1.0, 2.0) == 0.5); | |
| 17 | ||
| 18 | expect(divExact(u32, 55, 11) == 5); | |
| 19 | expect(divExact(i32, -55, 11) == -5); | |
| 20 | expect(divExact(f16, 55.0, 11.0) == 5.0); | |
| 21 | expect(divExact(f16, -55.0, 11.0) == -5.0); | |
| 22 | expect(divExact(f32, 55.0, 11.0) == 5.0); | |
| 23 | expect(divExact(f32, -55.0, 11.0) == -5.0); | |
| 24 | ||
| 25 | expect(divFloor(i32, 5, 3) == 1); | |
| 26 | expect(divFloor(i32, -5, 3) == -2); | |
| 27 | expect(divFloor(f16, 5.0, 3.0) == 1.0); | |
| 28 | expect(divFloor(f16, -5.0, 3.0) == -2.0); | |
| 29 | expect(divFloor(f32, 5.0, 3.0) == 1.0); | |
| 30 | expect(divFloor(f32, -5.0, 3.0) == -2.0); | |
| 31 | expect(divFloor(i32, -0x80000000, -2) == 0x40000000); | |
| 32 | expect(divFloor(i32, 0, -0x80000000) == 0); | |
| 33 | expect(divFloor(i32, -0x40000001, 0x40000000) == -2); | |
| 34 | expect(divFloor(i32, -0x80000000, 1) == -0x80000000); | |
| 35 | expect(divFloor(i32, 10, 12) == 0); | |
| 36 | expect(divFloor(i32, -14, 12) == -2); | |
| 37 | expect(divFloor(i32, -2, 12) == -1); | |
| 38 | ||
| 39 | expect(divTrunc(i32, 5, 3) == 1); | |
| 40 | expect(divTrunc(i32, -5, 3) == -1); | |
| 41 | expect(divTrunc(f16, 5.0, 3.0) == 1.0); | |
| 42 | expect(divTrunc(f16, -5.0, 3.0) == -1.0); | |
| 43 | expect(divTrunc(f32, 5.0, 3.0) == 1.0); | |
| 44 | expect(divTrunc(f32, -5.0, 3.0) == -1.0); | |
| 45 | expect(divTrunc(f64, 5.0, 3.0) == 1.0); | |
| 46 | expect(divTrunc(f64, -5.0, 3.0) == -1.0); | |
| 47 | expect(divTrunc(i32, 10, 12) == 0); | |
| 48 | expect(divTrunc(i32, -14, 12) == -1); | |
| 49 | expect(divTrunc(i32, -2, 12) == 0); | |
| 50 | ||
| 51 | expect(mod(i32, 10, 12) == 10); | |
| 52 | expect(mod(i32, -14, 12) == 10); | |
| 53 | expect(mod(i32, -2, 12) == 10); | |
| 54 | ||
| 55 | comptime { | |
| 56 | expect( | |
| 57 | 1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600, | |
| 58 | ); | |
| 59 | expect( | |
| 60 | @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600, | |
| 61 | ); | |
| 62 | expect( | |
| 63 | 1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2, | |
| 64 | ); | |
| 65 | expect( | |
| 66 | @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2, | |
| 67 | ); | |
| 68 | expect( | |
| 69 | @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2, | |
| 70 | ); | |
| 71 | expect( | |
| 72 | @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2, | |
| 73 | ); | |
| 74 | expect( | |
| 75 | 4126227191251978491697987544882340798050766755606969681711 % 10 == 1, | |
| 76 | ); | |
| 77 | } | |
| 78 | } | |
| 79 | fn div(comptime T: type, a: T, b: T) T { | |
| 80 | return a / b; | |
| 81 | } | |
| 82 | fn divExact(comptime T: type, a: T, b: T) T { | |
| 83 | return @divExact(a, b); | |
| 84 | } | |
| 85 | fn divFloor(comptime T: type, a: T, b: T) T { | |
| 86 | return @divFloor(a, b); | |
| 87 | } | |
| 88 | fn divTrunc(comptime T: type, a: T, b: T) T { | |
| 89 | return @divTrunc(a, b); | |
| 90 | } | |
| 91 | fn mod(comptime T: type, a: T, b: T) T { | |
| 92 | return @mod(a, b); | |
| 93 | } | |
| 94 | ||
| 95 | test "@addWithOverflow" { | |
| 96 | var result: u8 = undefined; | |
| 97 | expect(@addWithOverflow(u8, 250, 100, &result)); | |
| 98 | expect(!@addWithOverflow(u8, 100, 150, &result)); | |
| 99 | expect(result == 250); | |
| 100 | } | |
| 101 | ||
| 102 | // TODO test mulWithOverflow | |
| 103 | // TODO test subWithOverflow | |
| 104 | ||
| 105 | test "@shlWithOverflow" { | |
| 106 | var result: u16 = undefined; | |
| 107 | expect(@shlWithOverflow(u16, 0b0010111111111111, 3, &result)); | |
| 108 | expect(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result)); | |
| 109 | expect(result == 0b1011111111111100); | |
| 110 | } | |
| 111 | ||
| 112 | test "@*WithOverflow with u0 values" { | |
| 113 | var result: u0 = undefined; | |
| 114 | expect(!@addWithOverflow(u0, 0, 0, &result)); | |
| 115 | expect(!@subWithOverflow(u0, 0, 0, &result)); | |
| 116 | expect(!@mulWithOverflow(u0, 0, 0, &result)); | |
| 117 | expect(!@shlWithOverflow(u0, 0, 0, &result)); | |
| 118 | } | |
| 119 | ||
| 120 | test "@clz" { | |
| 121 | testClz(); | |
| 122 | comptime testClz(); | |
| 123 | } | |
| 124 | ||
| 125 | fn testClz() void { | |
| 126 | expect(clz(u8, 0b10001010) == 0); | |
| 127 | expect(clz(u8, 0b00001010) == 4); | |
| 128 | expect(clz(u8, 0b00011010) == 3); | |
| 129 | expect(clz(u8, 0b00000000) == 8); | |
| 130 | expect(clz(u128, 0xffffffffffffffff) == 64); | |
| 131 | expect(clz(u128, 0x10000000000000000) == 63); | |
| 132 | } | |
| 133 | ||
| 134 | fn clz(comptime T: type, x: T) usize { | |
| 135 | return @clz(T, x); | |
| 136 | } | |
| 137 | ||
| 138 | test "@ctz" { | |
| 139 | testCtz(); | |
| 140 | comptime testCtz(); | |
| 141 | } | |
| 142 | ||
| 143 | fn testCtz() void { | |
| 144 | expect(ctz(u8, 0b10100000) == 5); | |
| 145 | expect(ctz(u8, 0b10001010) == 1); | |
| 146 | expect(ctz(u8, 0b00000000) == 8); | |
| 147 | expect(ctz(u16, 0b00000000) == 16); | |
| 148 | } | |
| 149 | ||
| 150 | fn ctz(comptime T: type, x: T) usize { | |
| 151 | return @ctz(T, x); | |
| 152 | } | |
| 153 | ||
| 154 | test "assignment operators" { | |
| 155 | var i: u32 = 0; | |
| 156 | i += 5; | |
| 157 | expect(i == 5); | |
| 158 | i -= 2; | |
| 159 | expect(i == 3); | |
| 160 | i *= 20; | |
| 161 | expect(i == 60); | |
| 162 | i /= 3; | |
| 163 | expect(i == 20); | |
| 164 | i %= 11; | |
| 165 | expect(i == 9); | |
| 166 | i <<= 1; | |
| 167 | expect(i == 18); | |
| 168 | i >>= 2; | |
| 169 | expect(i == 4); | |
| 170 | i = 6; | |
| 171 | i &= 5; | |
| 172 | expect(i == 4); | |
| 173 | i ^= 6; | |
| 174 | expect(i == 2); | |
| 175 | i = 6; | |
| 176 | i |= 3; | |
| 177 | expect(i == 7); | |
| 178 | } | |
| 179 | ||
| 180 | test "three expr in a row" { | |
| 181 | testThreeExprInARow(false, true); | |
| 182 | comptime testThreeExprInARow(false, true); | |
| 183 | } | |
| 184 | fn testThreeExprInARow(f: bool, t: bool) void { | |
| 185 | assertFalse(f or f or f); | |
| 186 | assertFalse(t and t and f); | |
| 187 | assertFalse(1 | 2 | 4 != 7); | |
| 188 | assertFalse(3 ^ 6 ^ 8 != 13); | |
| 189 | assertFalse(7 & 14 & 28 != 4); | |
| 190 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 191 | assertFalse(90 >> 1 >> 2 != 90 >> 3); | |
| 192 | assertFalse(100 - 1 + 1000 != 1099); | |
| 193 | assertFalse(5 * 4 / 2 % 3 != 1); | |
| 194 | assertFalse(@as(i32, @as(i32, 5)) != 5); | |
| 195 | assertFalse(!!false); | |
| 196 | assertFalse(@as(i32, 7) != --(@as(i32, 7))); | |
| 197 | } | |
| 198 | fn assertFalse(b: bool) void { | |
| 199 | expect(!b); | |
| 200 | } | |
| 201 | ||
| 202 | test "const number literal" { | |
| 203 | const one = 1; | |
| 204 | const eleven = ten + one; | |
| 205 | ||
| 206 | expect(eleven == 11); | |
| 207 | } | |
| 208 | const ten = 10; | |
| 209 | ||
| 210 | test "unsigned wrapping" { | |
| 211 | testUnsignedWrappingEval(maxInt(u32)); | |
| 212 | comptime testUnsignedWrappingEval(maxInt(u32)); | |
| 213 | } | |
| 214 | fn testUnsignedWrappingEval(x: u32) void { | |
| 215 | const zero = x +% 1; | |
| 216 | expect(zero == 0); | |
| 217 | const orig = zero -% 1; | |
| 218 | expect(orig == maxInt(u32)); | |
| 219 | } | |
| 220 | ||
| 221 | test "signed wrapping" { | |
| 222 | testSignedWrappingEval(maxInt(i32)); | |
| 223 | comptime testSignedWrappingEval(maxInt(i32)); | |
| 224 | } | |
| 225 | fn testSignedWrappingEval(x: i32) void { | |
| 226 | const min_val = x +% 1; | |
| 227 | expect(min_val == minInt(i32)); | |
| 228 | const max_val = min_val -% 1; | |
| 229 | expect(max_val == maxInt(i32)); | |
| 230 | } | |
| 231 | ||
| 232 | test "signed negation wrapping" { | |
| 233 | testSignedNegationWrappingEval(minInt(i16)); | |
| 234 | comptime testSignedNegationWrappingEval(minInt(i16)); | |
| 235 | } | |
| 236 | fn testSignedNegationWrappingEval(x: i16) void { | |
| 237 | expect(x == -32768); | |
| 238 | const neg = -%x; | |
| 239 | expect(neg == -32768); | |
| 240 | } | |
| 241 | ||
| 242 | test "unsigned negation wrapping" { | |
| 243 | testUnsignedNegationWrappingEval(1); | |
| 244 | comptime testUnsignedNegationWrappingEval(1); | |
| 245 | } | |
| 246 | fn testUnsignedNegationWrappingEval(x: u16) void { | |
| 247 | expect(x == 1); | |
| 248 | const neg = -%x; | |
| 249 | expect(neg == maxInt(u16)); | |
| 250 | } | |
| 251 | ||
| 252 | test "unsigned 64-bit division" { | |
| 253 | test_u64_div(); | |
| 254 | comptime test_u64_div(); | |
| 255 | } | |
| 256 | fn test_u64_div() void { | |
| 257 | const result = divWithResult(1152921504606846976, 34359738365); | |
| 258 | expect(result.quotient == 33554432); | |
| 259 | expect(result.remainder == 100663296); | |
| 260 | } | |
| 261 | fn divWithResult(a: u64, b: u64) DivResult { | |
| 262 | return DivResult{ | |
| 263 | .quotient = a / b, | |
| 264 | .remainder = a % b, | |
| 265 | }; | |
| 266 | } | |
| 267 | const DivResult = struct { | |
| 268 | quotient: u64, | |
| 269 | remainder: u64, | |
| 270 | }; | |
| 271 | ||
| 272 | test "binary not" { | |
| 273 | expect(comptime x: { | |
| 274 | break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101; | |
| 275 | }); | |
| 276 | expect(comptime x: { | |
| 277 | break :x ~@as(u64, 2147483647) == 18446744071562067968; | |
| 278 | }); | |
| 279 | testBinaryNot(0b1010101010101010); | |
| 280 | } | |
| 281 | ||
| 282 | fn testBinaryNot(x: u16) void { | |
| 283 | expect(~x == 0b0101010101010101); | |
| 284 | } | |
| 285 | ||
| 286 | test "small int addition" { | |
| 287 | var x: u2 = 0; | |
| 288 | expect(x == 0); | |
| 289 | ||
| 290 | x += 1; | |
| 291 | expect(x == 1); | |
| 292 | ||
| 293 | x += 1; | |
| 294 | expect(x == 2); | |
| 295 | ||
| 296 | x += 1; | |
| 297 | expect(x == 3); | |
| 298 | ||
| 299 | var result: @TypeOf(x) = 3; | |
| 300 | expect(@addWithOverflow(@TypeOf(x), x, 1, &result)); | |
| 301 | ||
| 302 | expect(result == 0); | |
| 303 | } | |
| 304 | ||
| 305 | test "float equality" { | |
| 306 | const x: f64 = 0.012; | |
| 307 | const y: f64 = x + 1.0; | |
| 308 | ||
| 309 | testFloatEqualityImpl(x, y); | |
| 310 | comptime testFloatEqualityImpl(x, y); | |
| 311 | } | |
| 312 | ||
| 313 | fn testFloatEqualityImpl(x: f64, y: f64) void { | |
| 314 | const y2 = x + 1.0; | |
| 315 | expect(y == y2); | |
| 316 | } | |
| 317 | ||
| 318 | test "allow signed integer division/remainder when values are comptime known and positive or exact" { | |
| 319 | expect(5 / 3 == 1); | |
| 320 | expect(-5 / -3 == 1); | |
| 321 | expect(-6 / 3 == -2); | |
| 322 | ||
| 323 | expect(5 % 3 == 2); | |
| 324 | expect(-6 % 3 == 0); | |
| 325 | } | |
| 326 | ||
| 327 | test "hex float literal parsing" { | |
| 328 | comptime expect(0x1.0 == 1.0); | |
| 329 | } | |
| 330 | ||
| 331 | test "quad hex float literal parsing in range" { | |
| 332 | const a = 0x1.af23456789bbaaab347645365cdep+5; | |
| 333 | const b = 0x1.dedafcff354b6ae9758763545432p-9; | |
| 334 | const c = 0x1.2f34dd5f437e849b4baab754cdefp+4534; | |
| 335 | const d = 0x1.edcbff8ad76ab5bf46463233214fp-435; | |
| 336 | } | |
| 337 | ||
| 338 | test "quad hex float literal parsing accurate" { | |
| 339 | const a: f128 = 0x1.1111222233334444555566667777p+0; | |
| 340 | ||
| 341 | // implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing. | |
| 342 | const expected: u128 = 0x3fff1111222233334444555566667777; | |
| 343 | expect(@bitCast(u128, a) == expected); | |
| 344 | ||
| 345 | // non-normalized | |
| 346 | const b: f128 = 0x11.111222233334444555566667777p-4; | |
| 347 | expect(@bitCast(u128, b) == expected); | |
| 348 | ||
| 349 | const S = struct { | |
| 350 | fn doTheTest() void { | |
| 351 | { | |
| 352 | var f: f128 = 0x1.2eab345678439abcdefea56782346p+5; | |
| 353 | expect(@bitCast(u128, f) == 0x40042eab345678439abcdefea5678234); | |
| 354 | } | |
| 355 | { | |
| 356 | var f: f128 = 0x1.edcb34a235253948765432134674fp-1; | |
| 357 | expect(@bitCast(u128, f) == 0x3ffeedcb34a235253948765432134674); | |
| 358 | } | |
| 359 | { | |
| 360 | var f: f128 = 0x1.353e45674d89abacc3a2ebf3ff4ffp-50; | |
| 361 | expect(@bitCast(u128, f) == 0x3fcd353e45674d89abacc3a2ebf3ff50); | |
| 362 | } | |
| 363 | { | |
| 364 | var f: f128 = 0x1.ed8764648369535adf4be3214567fp-9; | |
| 365 | expect(@bitCast(u128, f) == 0x3ff6ed8764648369535adf4be3214568); | |
| 366 | } | |
| 367 | const exp2ft = [_]f64{ | |
| 368 | 0x1.6a09e667f3bcdp-1, | |
| 369 | 0x1.7a11473eb0187p-1, | |
| 370 | 0x1.8ace5422aa0dbp-1, | |
| 371 | 0x1.9c49182a3f090p-1, | |
| 372 | 0x1.ae89f995ad3adp-1, | |
| 373 | 0x1.c199bdd85529cp-1, | |
| 374 | 0x1.d5818dcfba487p-1, | |
| 375 | 0x1.ea4afa2a490dap-1, | |
| 376 | 0x1.0000000000000p+0, | |
| 377 | 0x1.0b5586cf9890fp+0, | |
| 378 | 0x1.172b83c7d517bp+0, | |
| 379 | 0x1.2387a6e756238p+0, | |
| 380 | 0x1.306fe0a31b715p+0, | |
| 381 | 0x1.3dea64c123422p+0, | |
| 382 | 0x1.4bfdad5362a27p+0, | |
| 383 | 0x1.5ab07dd485429p+0, | |
| 384 | 0x1.8p23, | |
| 385 | 0x1.62e430p-1, | |
| 386 | 0x1.ebfbe0p-3, | |
| 387 | 0x1.c6b348p-5, | |
| 388 | 0x1.3b2c9cp-7, | |
| 389 | 0x1.0p127, | |
| 390 | -0x1.0p-149, | |
| 391 | }; | |
| 392 | ||
| 393 | const answers = [_]u64{ | |
| 394 | 0x3fe6a09e667f3bcd, | |
| 395 | 0x3fe7a11473eb0187, | |
| 396 | 0x3fe8ace5422aa0db, | |
| 397 | 0x3fe9c49182a3f090, | |
| 398 | 0x3feae89f995ad3ad, | |
| 399 | 0x3fec199bdd85529c, | |
| 400 | 0x3fed5818dcfba487, | |
| 401 | 0x3feea4afa2a490da, | |
| 402 | 0x3ff0000000000000, | |
| 403 | 0x3ff0b5586cf9890f, | |
| 404 | 0x3ff172b83c7d517b, | |
| 405 | 0x3ff2387a6e756238, | |
| 406 | 0x3ff306fe0a31b715, | |
| 407 | 0x3ff3dea64c123422, | |
| 408 | 0x3ff4bfdad5362a27, | |
| 409 | 0x3ff5ab07dd485429, | |
| 410 | 0x4168000000000000, | |
| 411 | 0x3fe62e4300000000, | |
| 412 | 0x3fcebfbe00000000, | |
| 413 | 0x3fac6b3480000000, | |
| 414 | 0x3f83b2c9c0000000, | |
| 415 | 0x47e0000000000000, | |
| 416 | 0xb6a0000000000000, | |
| 417 | }; | |
| 418 | ||
| 419 | for (exp2ft) |x, i| { | |
| 420 | expect(@bitCast(u64, x) == answers[i]); | |
| 421 | } | |
| 422 | } | |
| 423 | }; | |
| 424 | S.doTheTest(); | |
| 425 | comptime S.doTheTest(); | |
| 426 | } | |
| 427 | ||
| 428 | test "underscore separator parsing" { | |
| 429 | expect(0_0_0_0 == 0); | |
| 430 | expect(1_234_567 == 1234567); | |
| 431 | expect(001_234_567 == 1234567); | |
| 432 | expect(0_0_1_2_3_4_5_6_7 == 1234567); | |
| 433 | ||
| 434 | expect(0b0_0_0_0 == 0); | |
| 435 | expect(0b1010_1010 == 0b10101010); | |
| 436 | expect(0b0000_1010_1010 == 0b10101010); | |
| 437 | expect(0b1_0_1_0_1_0_1_0 == 0b10101010); | |
| 438 | ||
| 439 | expect(0o0_0_0_0 == 0); | |
| 440 | expect(0o1010_1010 == 0o10101010); | |
| 441 | expect(0o0000_1010_1010 == 0o10101010); | |
| 442 | expect(0o1_0_1_0_1_0_1_0 == 0o10101010); | |
| 443 | ||
| 444 | expect(0x0_0_0_0 == 0); | |
| 445 | expect(0x1010_1010 == 0x10101010); | |
| 446 | expect(0x0000_1010_1010 == 0x10101010); | |
| 447 | expect(0x1_0_1_0_1_0_1_0 == 0x10101010); | |
| 448 | ||
| 449 | expect(123_456.789_000e1_0 == 123456.789000e10); | |
| 450 | expect(0_1_2_3_4_5_6.7_8_9_0_0_0e0_0_1_0 == 123456.789000e10); | |
| 451 | ||
| 452 | expect(0x1234_5678.9ABC_DEF0p-1_0 == 0x12345678.9ABCDEF0p-10); | |
| 453 | expect(0x1_2_3_4_5_6_7_8.9_A_B_C_D_E_F_0p-0_0_0_1_0 == 0x12345678.9ABCDEF0p-10); | |
| 454 | } | |
| 455 | ||
| 456 | test "hex float literal within range" { | |
| 457 | const a = 0x1.0p16383; | |
| 458 | const b = 0x0.1p16387; | |
| 459 | const c = 0x1.0p-16382; | |
| 460 | } | |
| 461 | ||
| 462 | test "truncating shift left" { | |
| 463 | testShlTrunc(maxInt(u16)); | |
| 464 | comptime testShlTrunc(maxInt(u16)); | |
| 465 | } | |
| 466 | fn testShlTrunc(x: u16) void { | |
| 467 | const shifted = x << 1; | |
| 468 | expect(shifted == 65534); | |
| 469 | } | |
| 470 | ||
| 471 | test "truncating shift right" { | |
| 472 | testShrTrunc(maxInt(u16)); | |
| 473 | comptime testShrTrunc(maxInt(u16)); | |
| 474 | } | |
| 475 | fn testShrTrunc(x: u16) void { | |
| 476 | const shifted = x >> 1; | |
| 477 | expect(shifted == 32767); | |
| 478 | } | |
| 479 | ||
| 480 | test "exact shift left" { | |
| 481 | testShlExact(0b00110101); | |
| 482 | comptime testShlExact(0b00110101); | |
| 483 | } | |
| 484 | fn testShlExact(x: u8) void { | |
| 485 | const shifted = @shlExact(x, 2); | |
| 486 | expect(shifted == 0b11010100); | |
| 487 | } | |
| 488 | ||
| 489 | test "exact shift right" { | |
| 490 | testShrExact(0b10110100); | |
| 491 | comptime testShrExact(0b10110100); | |
| 492 | } | |
| 493 | fn testShrExact(x: u8) void { | |
| 494 | const shifted = @shrExact(x, 2); | |
| 495 | expect(shifted == 0b00101101); | |
| 496 | } | |
| 497 | ||
| 498 | test "shift left/right on u0 operand" { | |
| 499 | const S = struct { | |
| 500 | fn doTheTest() void { | |
| 501 | var x: u0 = 0; | |
| 502 | var y: u0 = 0; | |
| 503 | expectEqual(@as(u0, 0), x << 0); | |
| 504 | expectEqual(@as(u0, 0), x >> 0); | |
| 505 | expectEqual(@as(u0, 0), x << y); | |
| 506 | expectEqual(@as(u0, 0), x >> y); | |
| 507 | expectEqual(@as(u0, 0), @shlExact(x, 0)); | |
| 508 | expectEqual(@as(u0, 0), @shrExact(x, 0)); | |
| 509 | expectEqual(@as(u0, 0), @shlExact(x, y)); | |
| 510 | expectEqual(@as(u0, 0), @shrExact(x, y)); | |
| 511 | } | |
| 512 | }; | |
| 513 | S.doTheTest(); | |
| 514 | comptime S.doTheTest(); | |
| 515 | } | |
| 516 | ||
| 517 | test "comptime_int addition" { | |
| 518 | comptime { | |
| 519 | expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950); | |
| 520 | expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380); | |
| 521 | } | |
| 522 | } | |
| 523 | ||
| 524 | test "comptime_int multiplication" { | |
| 525 | comptime { | |
| 526 | expect( | |
| 527 | 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567, | |
| 528 | ); | |
| 529 | expect( | |
| 530 | 594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016, | |
| 531 | ); | |
| 532 | } | |
| 533 | } | |
| 534 | ||
| 535 | test "comptime_int shifting" { | |
| 536 | comptime { | |
| 537 | expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000); | |
| 538 | } | |
| 539 | } | |
| 540 | ||
| 541 | test "comptime_int multi-limb shift and mask" { | |
| 542 | comptime { | |
| 543 | var a = 0xefffffffa0000001eeeeeeefaaaaaaab; | |
| 544 | ||
| 545 | expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab); | |
| 546 | a >>= 32; | |
| 547 | expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef); | |
| 548 | a >>= 32; | |
| 549 | expect(@as(u32, a & 0xffffffff) == 0xa0000001); | |
| 550 | a >>= 32; | |
| 551 | expect(@as(u32, a & 0xffffffff) == 0xefffffff); | |
| 552 | a >>= 32; | |
| 553 | ||
| 554 | expect(a == 0); | |
| 555 | } | |
| 556 | } | |
| 557 | ||
| 558 | test "comptime_int multi-limb partial shift right" { | |
| 559 | comptime { | |
| 560 | var a = 0x1ffffffffeeeeeeee; | |
| 561 | a >>= 16; | |
| 562 | expect(a == 0x1ffffffffeeee); | |
| 563 | } | |
| 564 | } | |
| 565 | ||
| 566 | test "xor" { | |
| 567 | test_xor(); | |
| 568 | comptime test_xor(); | |
| 569 | } | |
| 570 | ||
| 571 | fn test_xor() void { | |
| 572 | expect(0xFF ^ 0x00 == 0xFF); | |
| 573 | expect(0xF0 ^ 0x0F == 0xFF); | |
| 574 | expect(0xFF ^ 0xF0 == 0x0F); | |
| 575 | expect(0xFF ^ 0x0F == 0xF0); | |
| 576 | expect(0xFF ^ 0xFF == 0x00); | |
| 577 | } | |
| 578 | ||
| 579 | test "comptime_int xor" { | |
| 580 | comptime { | |
| 581 | expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 582 | expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 583 | expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF); | |
| 584 | expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000); | |
| 585 | expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000); | |
| 586 | expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 587 | expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF); | |
| 588 | expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000); | |
| 589 | } | |
| 590 | } | |
| 591 | ||
| 592 | test "f128" { | |
| 593 | test_f128(); | |
| 594 | comptime test_f128(); | |
| 595 | } | |
| 596 | ||
| 597 | fn make_f128(x: f128) f128 { | |
| 598 | return x; | |
| 599 | } | |
| 600 | ||
| 601 | fn test_f128() void { | |
| 602 | expect(@sizeOf(f128) == 16); | |
| 603 | expect(make_f128(1.0) == 1.0); | |
| 604 | expect(make_f128(1.0) != 1.1); | |
| 605 | expect(make_f128(1.0) > 0.9); | |
| 606 | expect(make_f128(1.0) >= 0.9); | |
| 607 | expect(make_f128(1.0) >= 1.0); | |
| 608 | should_not_be_zero(1.0); | |
| 609 | } | |
| 610 | ||
| 611 | fn should_not_be_zero(x: f128) void { | |
| 612 | expect(x != 0.0); | |
| 613 | } | |
| 614 | ||
| 615 | test "comptime float rem int" { | |
| 616 | comptime { | |
| 617 | var x = @as(f32, 1) % 2; | |
| 618 | expect(x == 1.0); | |
| 619 | } | |
| 620 | } | |
| 621 | ||
| 622 | test "remainder division" { | |
| 623 | comptime remdiv(f16); | |
| 624 | comptime remdiv(f32); | |
| 625 | comptime remdiv(f64); | |
| 626 | comptime remdiv(f128); | |
| 627 | remdiv(f16); | |
| 628 | remdiv(f64); | |
| 629 | remdiv(f128); | |
| 630 | } | |
| 631 | ||
| 632 | fn remdiv(comptime T: type) void { | |
| 633 | expect(@as(T, 1) == @as(T, 1) % @as(T, 2)); | |
| 634 | expect(@as(T, 1) == @as(T, 7) % @as(T, 3)); | |
| 635 | } | |
| 636 | ||
| 637 | test "@sqrt" { | |
| 638 | testSqrt(f64, 12.0); | |
| 639 | comptime testSqrt(f64, 12.0); | |
| 640 | testSqrt(f32, 13.0); | |
| 641 | comptime testSqrt(f32, 13.0); | |
| 642 | testSqrt(f16, 13.0); | |
| 643 | comptime testSqrt(f16, 13.0); | |
| 644 | ||
| 645 | const x = 14.0; | |
| 646 | const y = x * x; | |
| 647 | const z = @sqrt(y); | |
| 648 | comptime expect(z == x); | |
| 649 | } | |
| 650 | ||
| 651 | fn testSqrt(comptime T: type, x: T) void { | |
| 652 | expect(@sqrt(x * x) == x); | |
| 653 | } | |
| 654 | ||
| 655 | test "@fabs" { | |
| 656 | testFabs(f128, 12.0); | |
| 657 | comptime testFabs(f128, 12.0); | |
| 658 | testFabs(f64, 12.0); | |
| 659 | comptime testFabs(f64, 12.0); | |
| 660 | testFabs(f32, 12.0); | |
| 661 | comptime testFabs(f32, 12.0); | |
| 662 | testFabs(f16, 12.0); | |
| 663 | comptime testFabs(f16, 12.0); | |
| 664 | ||
| 665 | const x = 14.0; | |
| 666 | const y = -x; | |
| 667 | const z = @fabs(y); | |
| 668 | comptime expectEqual(x, z); | |
| 669 | } | |
| 670 | ||
| 671 | fn testFabs(comptime T: type, x: T) void { | |
| 672 | const y = -x; | |
| 673 | const z = @fabs(y); | |
| 674 | expectEqual(x, z); | |
| 675 | } | |
| 676 | ||
| 677 | test "@floor" { | |
| 678 | // FIXME: Generates a floorl function call | |
| 679 | // testFloor(f128, 12.0); | |
| 680 | comptime testFloor(f128, 12.0); | |
| 681 | testFloor(f64, 12.0); | |
| 682 | comptime testFloor(f64, 12.0); | |
| 683 | testFloor(f32, 12.0); | |
| 684 | comptime testFloor(f32, 12.0); | |
| 685 | testFloor(f16, 12.0); | |
| 686 | comptime testFloor(f16, 12.0); | |
| 687 | ||
| 688 | const x = 14.0; | |
| 689 | const y = x + 0.7; | |
| 690 | const z = @floor(y); | |
| 691 | comptime expectEqual(x, z); | |
| 692 | } | |
| 693 | ||
| 694 | fn testFloor(comptime T: type, x: T) void { | |
| 695 | const y = x + 0.6; | |
| 696 | const z = @floor(y); | |
| 697 | expectEqual(x, z); | |
| 698 | } | |
| 699 | ||
| 700 | test "@ceil" { | |
| 701 | // FIXME: Generates a ceill function call | |
| 702 | //testCeil(f128, 12.0); | |
| 703 | comptime testCeil(f128, 12.0); | |
| 704 | testCeil(f64, 12.0); | |
| 705 | comptime testCeil(f64, 12.0); | |
| 706 | testCeil(f32, 12.0); | |
| 707 | comptime testCeil(f32, 12.0); | |
| 708 | testCeil(f16, 12.0); | |
| 709 | comptime testCeil(f16, 12.0); | |
| 710 | ||
| 711 | const x = 14.0; | |
| 712 | const y = x - 0.7; | |
| 713 | const z = @ceil(y); | |
| 714 | comptime expectEqual(x, z); | |
| 715 | } | |
| 716 | ||
| 717 | fn testCeil(comptime T: type, x: T) void { | |
| 718 | const y = x - 0.8; | |
| 719 | const z = @ceil(y); | |
| 720 | expectEqual(x, z); | |
| 721 | } | |
| 722 | ||
| 723 | test "@trunc" { | |
| 724 | // FIXME: Generates a truncl function call | |
| 725 | //testTrunc(f128, 12.0); | |
| 726 | comptime testTrunc(f128, 12.0); | |
| 727 | testTrunc(f64, 12.0); | |
| 728 | comptime testTrunc(f64, 12.0); | |
| 729 | testTrunc(f32, 12.0); | |
| 730 | comptime testTrunc(f32, 12.0); | |
| 731 | testTrunc(f16, 12.0); | |
| 732 | comptime testTrunc(f16, 12.0); | |
| 733 | ||
| 734 | const x = 14.0; | |
| 735 | const y = x + 0.7; | |
| 736 | const z = @trunc(y); | |
| 737 | comptime expectEqual(x, z); | |
| 738 | } | |
| 739 | ||
| 740 | fn testTrunc(comptime T: type, x: T) void { | |
| 741 | { | |
| 742 | const y = x + 0.8; | |
| 743 | const z = @trunc(y); | |
| 744 | expectEqual(x, z); | |
| 745 | } | |
| 746 | ||
| 747 | { | |
| 748 | const y = -x - 0.8; | |
| 749 | const z = @trunc(y); | |
| 750 | expectEqual(-x, z); | |
| 751 | } | |
| 752 | } | |
| 753 | ||
| 754 | test "@round" { | |
| 755 | // FIXME: Generates a roundl function call | |
| 756 | //testRound(f128, 12.0); | |
| 757 | comptime testRound(f128, 12.0); | |
| 758 | testRound(f64, 12.0); | |
| 759 | comptime testRound(f64, 12.0); | |
| 760 | testRound(f32, 12.0); | |
| 761 | comptime testRound(f32, 12.0); | |
| 762 | testRound(f16, 12.0); | |
| 763 | comptime testRound(f16, 12.0); | |
| 764 | ||
| 765 | const x = 14.0; | |
| 766 | const y = x + 0.4; | |
| 767 | const z = @round(y); | |
| 768 | comptime expectEqual(x, z); | |
| 769 | } | |
| 770 | ||
| 771 | fn testRound(comptime T: type, x: T) void { | |
| 772 | const y = x - 0.5; | |
| 773 | const z = @round(y); | |
| 774 | expectEqual(x, z); | |
| 775 | } | |
| 776 | ||
| 777 | test "comptime_int param and return" { | |
| 778 | const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702); | |
| 779 | expect(a == 137114567242441932203689521744947848950); | |
| 780 | ||
| 781 | const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768); | |
| 782 | expect(b == 985095453608931032642182098849559179469148836107390954364380); | |
| 783 | } | |
| 784 | ||
| 785 | fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int { | |
| 786 | return a + b; | |
| 787 | } | |
| 788 | ||
| 789 | test "vector integer addition" { | |
| 790 | const S = struct { | |
| 791 | fn doTheTest() void { | |
| 792 | var a: std.meta.Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; | |
| 793 | var b: std.meta.Vector(4, i32) = [_]i32{ 5, 6, 7, 8 }; | |
| 794 | var result = a + b; | |
| 795 | var result_array: [4]i32 = result; | |
| 796 | const expected = [_]i32{ 6, 8, 10, 12 }; | |
| 797 | expectEqualSlices(i32, &expected, &result_array); | |
| 798 | } | |
| 799 | }; | |
| 800 | S.doTheTest(); | |
| 801 | comptime S.doTheTest(); | |
| 802 | } | |
| 803 | ||
| 804 | test "NaN comparison" { | |
| 805 | testNanEqNan(f16); | |
| 806 | testNanEqNan(f32); | |
| 807 | testNanEqNan(f64); | |
| 808 | testNanEqNan(f128); | |
| 809 | comptime testNanEqNan(f16); | |
| 810 | comptime testNanEqNan(f32); | |
| 811 | comptime testNanEqNan(f64); | |
| 812 | comptime testNanEqNan(f128); | |
| 813 | } | |
| 814 | ||
| 815 | fn testNanEqNan(comptime F: type) void { | |
| 816 | var nan1 = std.math.nan(F); | |
| 817 | var nan2 = std.math.nan(F); | |
| 818 | expect(nan1 != nan2); | |
| 819 | expect(!(nan1 == nan2)); | |
| 820 | expect(!(nan1 > nan2)); | |
| 821 | expect(!(nan1 >= nan2)); | |
| 822 | expect(!(nan1 < nan2)); | |
| 823 | expect(!(nan1 <= nan2)); | |
| 824 | } | |
| 825 | ||
| 826 | test "128-bit multiplication" { | |
| 827 | var a: i128 = 3; | |
| 828 | var b: i128 = 2; | |
| 829 | var c = a * b; | |
| 830 | expect(c == 6); | |
| 831 | } | |
| 832 | ||
| 833 | test "vector comparison" { | |
| 834 | const S = struct { | |
| 835 | fn doTheTest() void { | |
| 836 | var a: std.meta.Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 }; | |
| 837 | var b: std.meta.Vector(6, i32) = [_]i32{ -1, 3, 0, 6, 10, -10 }; | |
| 838 | expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{ false, false, true, true, true, false })); | |
| 839 | expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{ false, true, true, true, true, false })); | |
| 840 | expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{ false, true, false, false, false, false })); | |
| 841 | expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{ true, false, true, true, true, true })); | |
| 842 | expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{ true, false, false, false, false, true })); | |
| 843 | expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{ true, true, false, false, false, true })); | |
| 844 | } | |
| 845 | }; | |
| 846 | S.doTheTest(); | |
| 847 | comptime S.doTheTest(); | |
| 848 | } | |
| 849 | ||
| 850 | test "compare undefined literal with comptime_int" { | |
| 851 | var x = undefined == 1; | |
| 852 | // x is now undefined with type bool | |
| 853 | x = true; | |
| 854 | expect(x); | |
| 855 | } | |
| 856 | ||
| 857 | test "signed zeros are represented properly" { | |
| 858 | const S = struct { | |
| 859 | fn doTheTest() void { | |
| 860 | inline for ([_]type{ f16, f32, f64, f128 }) |T| { | |
| 861 | const ST = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); | |
| 862 | var as_fp_val = -@as(T, 0.0); | |
| 863 | var as_uint_val = @bitCast(ST, as_fp_val); | |
| 864 | // Ensure the sign bit is set. | |
| 865 | expect(as_uint_val >> (@typeInfo(T).Float.bits - 1) == 1); | |
| 866 | } | |
| 867 | } | |
| 868 | }; | |
| 869 | ||
| 870 | S.doTheTest(); | |
| 871 | comptime S.doTheTest(); | |
| 872 | } |
test/behavior/merge_error_sets.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | const A = error{ | |
| 2 | FileNotFound, | |
| 3 | NotDir, | |
| 4 | }; | |
| 5 | const B = error{OutOfMemory}; | |
| 6 | ||
| 7 | const C = A || B; | |
| 8 | ||
| 9 | fn foo() C!void { | |
| 10 | return error.NotDir; | |
| 11 | } | |
| 12 | ||
| 13 | test "merge error sets" { | |
| 14 | if (foo()) { | |
| 15 | @panic("unexpected"); | |
| 16 | } else |err| switch (err) { | |
| 17 | error.OutOfMemory => @panic("unexpected"), | |
| 18 | error.FileNotFound => @panic("unexpected"), | |
| 19 | error.NotDir => {}, | |
| 20 | } | |
| 21 | } |
test/behavior/misc.zig created+761| ... | ... | @@ -0,0 +1,761 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | const mem = std.mem; | |
| 5 | const builtin = @import("builtin"); | |
| 6 | ||
| 7 | // normal comment | |
| 8 | ||
| 9 | /// this is a documentation comment | |
| 10 | /// doc comment line 2 | |
| 11 | fn emptyFunctionWithComments() void {} | |
| 12 | ||
| 13 | test "empty function with comments" { | |
| 14 | emptyFunctionWithComments(); | |
| 15 | } | |
| 16 | ||
| 17 | comptime { | |
| 18 | @export(disabledExternFn, .{ .name = "disabledExternFn", .linkage = .Internal }); | |
| 19 | } | |
| 20 | ||
| 21 | fn disabledExternFn() callconv(.C) void {} | |
| 22 | ||
| 23 | test "call disabled extern fn" { | |
| 24 | disabledExternFn(); | |
| 25 | } | |
| 26 | ||
| 27 | test "short circuit" { | |
| 28 | testShortCircuit(false, true); | |
| 29 | comptime testShortCircuit(false, true); | |
| 30 | } | |
| 31 | ||
| 32 | fn testShortCircuit(f: bool, t: bool) void { | |
| 33 | var hit_1 = f; | |
| 34 | var hit_2 = f; | |
| 35 | var hit_3 = f; | |
| 36 | var hit_4 = f; | |
| 37 | ||
| 38 | if (t or x: { | |
| 39 | expect(f); | |
| 40 | break :x f; | |
| 41 | }) { | |
| 42 | hit_1 = t; | |
| 43 | } | |
| 44 | if (f or x: { | |
| 45 | hit_2 = t; | |
| 46 | break :x f; | |
| 47 | }) { | |
| 48 | expect(f); | |
| 49 | } | |
| 50 | ||
| 51 | if (t and x: { | |
| 52 | hit_3 = t; | |
| 53 | break :x f; | |
| 54 | }) { | |
| 55 | expect(f); | |
| 56 | } | |
| 57 | if (f and x: { | |
| 58 | expect(f); | |
| 59 | break :x f; | |
| 60 | }) { | |
| 61 | expect(f); | |
| 62 | } else { | |
| 63 | hit_4 = t; | |
| 64 | } | |
| 65 | expect(hit_1); | |
| 66 | expect(hit_2); | |
| 67 | expect(hit_3); | |
| 68 | expect(hit_4); | |
| 69 | } | |
| 70 | ||
| 71 | test "truncate" { | |
| 72 | expect(testTruncate(0x10fd) == 0xfd); | |
| 73 | } | |
| 74 | fn testTruncate(x: u32) u8 { | |
| 75 | return @truncate(u8, x); | |
| 76 | } | |
| 77 | ||
| 78 | fn first4KeysOfHomeRow() []const u8 { | |
| 79 | return "aoeu"; | |
| 80 | } | |
| 81 | ||
| 82 | test "return string from function" { | |
| 83 | expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); | |
| 84 | } | |
| 85 | ||
| 86 | const g1: i32 = 1233 + 1; | |
| 87 | var g2: i32 = 0; | |
| 88 | ||
| 89 | test "global variables" { | |
| 90 | expect(g2 == 0); | |
| 91 | g2 = g1; | |
| 92 | expect(g2 == 1234); | |
| 93 | } | |
| 94 | ||
| 95 | test "memcpy and memset intrinsics" { | |
| 96 | var foo: [20]u8 = undefined; | |
| 97 | var bar: [20]u8 = undefined; | |
| 98 | ||
| 99 | @memset(&foo, 'A', foo.len); | |
| 100 | @memcpy(&bar, &foo, bar.len); | |
| 101 | ||
| 102 | if (bar[11] != 'A') unreachable; | |
| 103 | } | |
| 104 | ||
| 105 | test "builtin static eval" { | |
| 106 | const x: i32 = comptime x: { | |
| 107 | break :x 1 + 2 + 3; | |
| 108 | }; | |
| 109 | expect(x == comptime 6); | |
| 110 | } | |
| 111 | ||
| 112 | test "slicing" { | |
| 113 | var array: [20]i32 = undefined; | |
| 114 | ||
| 115 | array[5] = 1234; | |
| 116 | ||
| 117 | var slice = array[5..10]; | |
| 118 | ||
| 119 | if (slice.len != 5) unreachable; | |
| 120 | ||
| 121 | const ptr = &slice[0]; | |
| 122 | if (ptr.* != 1234) unreachable; | |
| 123 | ||
| 124 | var slice_rest = array[10..]; | |
| 125 | if (slice_rest.len != 10) unreachable; | |
| 126 | } | |
| 127 | ||
| 128 | test "constant equal function pointers" { | |
| 129 | const alias = emptyFn; | |
| 130 | expect(comptime x: { | |
| 131 | break :x emptyFn == alias; | |
| 132 | }); | |
| 133 | } | |
| 134 | ||
| 135 | fn emptyFn() void {} | |
| 136 | ||
| 137 | test "hex escape" { | |
| 138 | expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); | |
| 139 | } | |
| 140 | ||
| 141 | test "string concatenation" { | |
| 142 | expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); | |
| 143 | } | |
| 144 | ||
| 145 | test "array mult operator" { | |
| 146 | expect(mem.eql(u8, "ab" ** 5, "ababababab")); | |
| 147 | } | |
| 148 | ||
| 149 | test "string escapes" { | |
| 150 | expect(mem.eql(u8, "\"", "\x22")); | |
| 151 | expect(mem.eql(u8, "\'", "\x27")); | |
| 152 | expect(mem.eql(u8, "\n", "\x0a")); | |
| 153 | expect(mem.eql(u8, "\r", "\x0d")); | |
| 154 | expect(mem.eql(u8, "\t", "\x09")); | |
| 155 | expect(mem.eql(u8, "\\", "\x5c")); | |
| 156 | expect(mem.eql(u8, "\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01")); | |
| 157 | } | |
| 158 | ||
| 159 | test "multiline string" { | |
| 160 | const s1 = | |
| 161 | \\one | |
| 162 | \\two) | |
| 163 | \\three | |
| 164 | ; | |
| 165 | const s2 = "one\ntwo)\nthree"; | |
| 166 | expect(mem.eql(u8, s1, s2)); | |
| 167 | } | |
| 168 | ||
| 169 | test "multiline string comments at start" { | |
| 170 | const s1 = | |
| 171 | //\\one | |
| 172 | \\two) | |
| 173 | \\three | |
| 174 | ; | |
| 175 | const s2 = "two)\nthree"; | |
| 176 | expect(mem.eql(u8, s1, s2)); | |
| 177 | } | |
| 178 | ||
| 179 | test "multiline string comments at end" { | |
| 180 | const s1 = | |
| 181 | \\one | |
| 182 | \\two) | |
| 183 | //\\three | |
| 184 | ; | |
| 185 | const s2 = "one\ntwo)"; | |
| 186 | expect(mem.eql(u8, s1, s2)); | |
| 187 | } | |
| 188 | ||
| 189 | test "multiline string comments in middle" { | |
| 190 | const s1 = | |
| 191 | \\one | |
| 192 | //\\two) | |
| 193 | \\three | |
| 194 | ; | |
| 195 | const s2 = "one\nthree"; | |
| 196 | expect(mem.eql(u8, s1, s2)); | |
| 197 | } | |
| 198 | ||
| 199 | test "multiline string comments at multiple places" { | |
| 200 | const s1 = | |
| 201 | \\one | |
| 202 | //\\two | |
| 203 | \\three | |
| 204 | //\\four | |
| 205 | \\five | |
| 206 | ; | |
| 207 | const s2 = "one\nthree\nfive"; | |
| 208 | expect(mem.eql(u8, s1, s2)); | |
| 209 | } | |
| 210 | ||
| 211 | test "multiline C string" { | |
| 212 | const s1 = | |
| 213 | \\one | |
| 214 | \\two) | |
| 215 | \\three | |
| 216 | ; | |
| 217 | const s2 = "one\ntwo)\nthree"; | |
| 218 | expect(std.cstr.cmp(s1, s2) == 0); | |
| 219 | } | |
| 220 | ||
| 221 | test "type equality" { | |
| 222 | expect(*const u8 != *u8); | |
| 223 | } | |
| 224 | ||
| 225 | const global_a: i32 = 1234; | |
| 226 | const global_b: *const i32 = &global_a; | |
| 227 | const global_c: *const f32 = @ptrCast(*const f32, global_b); | |
| 228 | test "compile time global reinterpret" { | |
| 229 | const d = @ptrCast(*const i32, global_c); | |
| 230 | expect(d.* == 1234); | |
| 231 | } | |
| 232 | ||
| 233 | test "explicit cast maybe pointers" { | |
| 234 | const a: ?*i32 = undefined; | |
| 235 | const b: ?*f32 = @ptrCast(?*f32, a); | |
| 236 | } | |
| 237 | ||
| 238 | test "generic malloc free" { | |
| 239 | const a = memAlloc(u8, 10) catch unreachable; | |
| 240 | memFree(u8, a); | |
| 241 | } | |
| 242 | var some_mem: [100]u8 = undefined; | |
| 243 | fn memAlloc(comptime T: type, n: usize) anyerror![]T { | |
| 244 | return @ptrCast([*]T, &some_mem[0])[0..n]; | |
| 245 | } | |
| 246 | fn memFree(comptime T: type, memory: []T) void {} | |
| 247 | ||
| 248 | test "cast undefined" { | |
| 249 | const array: [100]u8 = undefined; | |
| 250 | const slice = @as([]const u8, &array); | |
| 251 | testCastUndefined(slice); | |
| 252 | } | |
| 253 | fn testCastUndefined(x: []const u8) void {} | |
| 254 | ||
| 255 | test "cast small unsigned to larger signed" { | |
| 256 | expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200)); | |
| 257 | expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999)); | |
| 258 | } | |
| 259 | fn castSmallUnsignedToLargerSigned1(x: u8) i16 { | |
| 260 | return x; | |
| 261 | } | |
| 262 | fn castSmallUnsignedToLargerSigned2(x: u16) i64 { | |
| 263 | return x; | |
| 264 | } | |
| 265 | ||
| 266 | test "implicit cast after unreachable" { | |
| 267 | expect(outer() == 1234); | |
| 268 | } | |
| 269 | fn inner() i32 { | |
| 270 | return 1234; | |
| 271 | } | |
| 272 | fn outer() i64 { | |
| 273 | return inner(); | |
| 274 | } | |
| 275 | ||
| 276 | test "pointer dereferencing" { | |
| 277 | var x = @as(i32, 3); | |
| 278 | const y = &x; | |
| 279 | ||
| 280 | y.* += 1; | |
| 281 | ||
| 282 | expect(x == 4); | |
| 283 | expect(y.* == 4); | |
| 284 | } | |
| 285 | ||
| 286 | test "call result of if else expression" { | |
| 287 | expect(mem.eql(u8, f2(true), "a")); | |
| 288 | expect(mem.eql(u8, f2(false), "b")); | |
| 289 | } | |
| 290 | fn f2(x: bool) []const u8 { | |
| 291 | return (if (x) fA else fB)(); | |
| 292 | } | |
| 293 | fn fA() []const u8 { | |
| 294 | return "a"; | |
| 295 | } | |
| 296 | fn fB() []const u8 { | |
| 297 | return "b"; | |
| 298 | } | |
| 299 | ||
| 300 | test "const expression eval handling of variables" { | |
| 301 | var x = true; | |
| 302 | while (x) { | |
| 303 | x = false; | |
| 304 | } | |
| 305 | } | |
| 306 | ||
| 307 | test "constant enum initialization with differing sizes" { | |
| 308 | test3_1(test3_foo); | |
| 309 | test3_2(test3_bar); | |
| 310 | } | |
| 311 | const Test3Foo = union(enum) { | |
| 312 | One: void, | |
| 313 | Two: f32, | |
| 314 | Three: Test3Point, | |
| 315 | }; | |
| 316 | const Test3Point = struct { | |
| 317 | x: i32, | |
| 318 | y: i32, | |
| 319 | }; | |
| 320 | const test3_foo = Test3Foo{ | |
| 321 | .Three = Test3Point{ | |
| 322 | .x = 3, | |
| 323 | .y = 4, | |
| 324 | }, | |
| 325 | }; | |
| 326 | const test3_bar = Test3Foo{ .Two = 13 }; | |
| 327 | fn test3_1(f: Test3Foo) void { | |
| 328 | switch (f) { | |
| 329 | Test3Foo.Three => |pt| { | |
| 330 | expect(pt.x == 3); | |
| 331 | expect(pt.y == 4); | |
| 332 | }, | |
| 333 | else => unreachable, | |
| 334 | } | |
| 335 | } | |
| 336 | fn test3_2(f: Test3Foo) void { | |
| 337 | switch (f) { | |
| 338 | Test3Foo.Two => |x| { | |
| 339 | expect(x == 13); | |
| 340 | }, | |
| 341 | else => unreachable, | |
| 342 | } | |
| 343 | } | |
| 344 | ||
| 345 | test "character literals" { | |
| 346 | expect('\'' == single_quote); | |
| 347 | } | |
| 348 | const single_quote = '\''; | |
| 349 | ||
| 350 | test "take address of parameter" { | |
| 351 | testTakeAddressOfParameter(12.34); | |
| 352 | } | |
| 353 | fn testTakeAddressOfParameter(f: f32) void { | |
| 354 | const f_ptr = &f; | |
| 355 | expect(f_ptr.* == 12.34); | |
| 356 | } | |
| 357 | ||
| 358 | test "pointer comparison" { | |
| 359 | const a = @as([]const u8, "a"); | |
| 360 | const b = &a; | |
| 361 | expect(ptrEql(b, b)); | |
| 362 | } | |
| 363 | fn ptrEql(a: *const []const u8, b: *const []const u8) bool { | |
| 364 | return a == b; | |
| 365 | } | |
| 366 | ||
| 367 | test "string concatenation" { | |
| 368 | const a = "OK" ++ " IT " ++ "WORKED"; | |
| 369 | const b = "OK IT WORKED"; | |
| 370 | ||
| 371 | comptime expect(@TypeOf(a) == *const [12:0]u8); | |
| 372 | comptime expect(@TypeOf(b) == *const [12:0]u8); | |
| 373 | ||
| 374 | const len = mem.len(b); | |
| 375 | const len_with_null = len + 1; | |
| 376 | { | |
| 377 | var i: u32 = 0; | |
| 378 | while (i < len_with_null) : (i += 1) { | |
| 379 | expect(a[i] == b[i]); | |
| 380 | } | |
| 381 | } | |
| 382 | expect(a[len] == 0); | |
| 383 | expect(b[len] == 0); | |
| 384 | } | |
| 385 | ||
| 386 | test "pointer to void return type" { | |
| 387 | testPointerToVoidReturnType() catch unreachable; | |
| 388 | } | |
| 389 | fn testPointerToVoidReturnType() anyerror!void { | |
| 390 | const a = testPointerToVoidReturnType2(); | |
| 391 | return a.*; | |
| 392 | } | |
| 393 | const test_pointer_to_void_return_type_x = void{}; | |
| 394 | fn testPointerToVoidReturnType2() *const void { | |
| 395 | return &test_pointer_to_void_return_type_x; | |
| 396 | } | |
| 397 | ||
| 398 | test "non const ptr to aliased type" { | |
| 399 | const int = i32; | |
| 400 | expect(?*int == ?*i32); | |
| 401 | } | |
| 402 | ||
| 403 | test "array 2D const double ptr" { | |
| 404 | const rect_2d_vertexes = [_][1]f32{ | |
| 405 | [_]f32{1.0}, | |
| 406 | [_]f32{2.0}, | |
| 407 | }; | |
| 408 | testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]); | |
| 409 | } | |
| 410 | ||
| 411 | fn testArray2DConstDoublePtr(ptr: *const f32) void { | |
| 412 | const ptr2 = @ptrCast([*]const f32, ptr); | |
| 413 | expect(ptr2[0] == 1.0); | |
| 414 | expect(ptr2[1] == 2.0); | |
| 415 | } | |
| 416 | ||
| 417 | const AStruct = struct { | |
| 418 | x: i32, | |
| 419 | }; | |
| 420 | const AnEnum = enum { | |
| 421 | One, | |
| 422 | Two, | |
| 423 | }; | |
| 424 | const AUnionEnum = union(enum) { | |
| 425 | One: i32, | |
| 426 | Two: void, | |
| 427 | }; | |
| 428 | const AUnion = union { | |
| 429 | One: void, | |
| 430 | Two: void, | |
| 431 | }; | |
| 432 | ||
| 433 | test "@typeName" { | |
| 434 | const Struct = struct {}; | |
| 435 | const Union = union { | |
| 436 | unused: u8, | |
| 437 | }; | |
| 438 | const Enum = enum { | |
| 439 | Unused, | |
| 440 | }; | |
| 441 | comptime { | |
| 442 | expect(mem.eql(u8, @typeName(i64), "i64")); | |
| 443 | expect(mem.eql(u8, @typeName(*usize), "*usize")); | |
| 444 | // https://github.com/ziglang/zig/issues/675 | |
| 445 | expect(mem.eql(u8, "behavior.misc.TypeFromFn(u8)", @typeName(TypeFromFn(u8)))); | |
| 446 | expect(mem.eql(u8, @typeName(Struct), "Struct")); | |
| 447 | expect(mem.eql(u8, @typeName(Union), "Union")); | |
| 448 | expect(mem.eql(u8, @typeName(Enum), "Enum")); | |
| 449 | } | |
| 450 | } | |
| 451 | ||
| 452 | fn TypeFromFn(comptime T: type) type { | |
| 453 | return struct {}; | |
| 454 | } | |
| 455 | ||
| 456 | test "double implicit cast in same expression" { | |
| 457 | var x = @as(i32, @as(u16, nine())); | |
| 458 | expect(x == 9); | |
| 459 | } | |
| 460 | fn nine() u8 { | |
| 461 | return 9; | |
| 462 | } | |
| 463 | ||
| 464 | test "global variable initialized to global variable array element" { | |
| 465 | expect(global_ptr == &gdt[0]); | |
| 466 | } | |
| 467 | const GDTEntry = struct { | |
| 468 | field: i32, | |
| 469 | }; | |
| 470 | var gdt = [_]GDTEntry{ | |
| 471 | GDTEntry{ .field = 1 }, | |
| 472 | GDTEntry{ .field = 2 }, | |
| 473 | }; | |
| 474 | var global_ptr = &gdt[0]; | |
| 475 | ||
| 476 | // can't really run this test but we can make sure it has no compile error | |
| 477 | // and generates code | |
| 478 | const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000]; | |
| 479 | export fn writeToVRam() void { | |
| 480 | vram[0] = 'X'; | |
| 481 | } | |
| 482 | ||
| 483 | const OpaqueA = opaque {}; | |
| 484 | const OpaqueB = opaque {}; | |
| 485 | test "opaque types" { | |
| 486 | expect(*OpaqueA != *OpaqueB); | |
| 487 | expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA")); | |
| 488 | expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB")); | |
| 489 | } | |
| 490 | ||
| 491 | test "variable is allowed to be a pointer to an opaque type" { | |
| 492 | var x: i32 = 1234; | |
| 493 | _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x)); | |
| 494 | } | |
| 495 | fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA { | |
| 496 | var a = ptr; | |
| 497 | return a; | |
| 498 | } | |
| 499 | ||
| 500 | test "comptime if inside runtime while which unconditionally breaks" { | |
| 501 | testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); | |
| 502 | comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); | |
| 503 | } | |
| 504 | fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void { | |
| 505 | while (cond) { | |
| 506 | if (false) {} | |
| 507 | break; | |
| 508 | } | |
| 509 | } | |
| 510 | ||
| 511 | test "implicit comptime while" { | |
| 512 | while (false) { | |
| 513 | @compileError("bad"); | |
| 514 | } | |
| 515 | } | |
| 516 | ||
| 517 | fn fnThatClosesOverLocalConst() type { | |
| 518 | const c = 1; | |
| 519 | return struct { | |
| 520 | fn g() i32 { | |
| 521 | return c; | |
| 522 | } | |
| 523 | }; | |
| 524 | } | |
| 525 | ||
| 526 | test "function closes over local const" { | |
| 527 | const x = fnThatClosesOverLocalConst().g(); | |
| 528 | expect(x == 1); | |
| 529 | } | |
| 530 | ||
| 531 | test "cold function" { | |
| 532 | thisIsAColdFn(); | |
| 533 | comptime thisIsAColdFn(); | |
| 534 | } | |
| 535 | ||
| 536 | fn thisIsAColdFn() void { | |
| 537 | @setCold(true); | |
| 538 | } | |
| 539 | ||
| 540 | const PackedStruct = packed struct { | |
| 541 | a: u8, | |
| 542 | b: u8, | |
| 543 | }; | |
| 544 | const PackedUnion = packed union { | |
| 545 | a: u8, | |
| 546 | b: u32, | |
| 547 | }; | |
| 548 | const PackedEnum = packed enum { | |
| 549 | A, | |
| 550 | B, | |
| 551 | }; | |
| 552 | ||
| 553 | test "packed struct, enum, union parameters in extern function" { | |
| 554 | testPackedStuff(&(PackedStruct{ | |
| 555 | .a = 1, | |
| 556 | .b = 2, | |
| 557 | }), &(PackedUnion{ .a = 1 }), PackedEnum.A); | |
| 558 | } | |
| 559 | ||
| 560 | export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion, c: PackedEnum) void {} | |
| 561 | ||
| 562 | test "slicing zero length array" { | |
| 563 | const s1 = ""[0..]; | |
| 564 | const s2 = ([_]u32{})[0..]; | |
| 565 | expect(s1.len == 0); | |
| 566 | expect(s2.len == 0); | |
| 567 | expect(mem.eql(u8, s1, "")); | |
| 568 | expect(mem.eql(u32, s2, &[_]u32{})); | |
| 569 | } | |
| 570 | ||
| 571 | const addr1 = @ptrCast(*const u8, emptyFn); | |
| 572 | test "comptime cast fn to ptr" { | |
| 573 | const addr2 = @ptrCast(*const u8, emptyFn); | |
| 574 | comptime expect(addr1 == addr2); | |
| 575 | } | |
| 576 | ||
| 577 | test "equality compare fn ptrs" { | |
| 578 | var a = emptyFn; | |
| 579 | expect(a == a); | |
| 580 | } | |
| 581 | ||
| 582 | test "self reference through fn ptr field" { | |
| 583 | const S = struct { | |
| 584 | const A = struct { | |
| 585 | f: fn (A) u8, | |
| 586 | }; | |
| 587 | ||
| 588 | fn foo(a: A) u8 { | |
| 589 | return 12; | |
| 590 | } | |
| 591 | }; | |
| 592 | var a: S.A = undefined; | |
| 593 | a.f = S.foo; | |
| 594 | expect(a.f(a) == 12); | |
| 595 | } | |
| 596 | ||
| 597 | test "volatile load and store" { | |
| 598 | var number: i32 = 1234; | |
| 599 | const ptr = @as(*volatile i32, &number); | |
| 600 | ptr.* += 1; | |
| 601 | expect(ptr.* == 1235); | |
| 602 | } | |
| 603 | ||
| 604 | test "slice string literal has correct type" { | |
| 605 | comptime { | |
| 606 | expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8); | |
| 607 | const array = [_]i32{ 1, 2, 3, 4 }; | |
| 608 | expect(@TypeOf(array[0..]) == *const [4]i32); | |
| 609 | } | |
| 610 | var runtime_zero: usize = 0; | |
| 611 | comptime expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8); | |
| 612 | const array = [_]i32{ 1, 2, 3, 4 }; | |
| 613 | comptime expect(@TypeOf(array[runtime_zero..]) == []const i32); | |
| 614 | } | |
| 615 | ||
| 616 | test "struct inside function" { | |
| 617 | testStructInFn(); | |
| 618 | comptime testStructInFn(); | |
| 619 | } | |
| 620 | ||
| 621 | fn testStructInFn() void { | |
| 622 | const BlockKind = u32; | |
| 623 | ||
| 624 | const Block = struct { | |
| 625 | kind: BlockKind, | |
| 626 | }; | |
| 627 | ||
| 628 | var block = Block{ .kind = 1234 }; | |
| 629 | ||
| 630 | block.kind += 1; | |
| 631 | ||
| 632 | expect(block.kind == 1235); | |
| 633 | } | |
| 634 | ||
| 635 | test "fn call returning scalar optional in equality expression" { | |
| 636 | expect(getNull() == null); | |
| 637 | } | |
| 638 | ||
| 639 | fn getNull() ?*i32 { | |
| 640 | return null; | |
| 641 | } | |
| 642 | ||
| 643 | test "thread local variable" { | |
| 644 | const S = struct { | |
| 645 | threadlocal var t: i32 = 1234; | |
| 646 | }; | |
| 647 | S.t += 1; | |
| 648 | expect(S.t == 1235); | |
| 649 | } | |
| 650 | ||
| 651 | test "unicode escape in character literal" { | |
| 652 | var a: u24 = '\u{01f4a9}'; | |
| 653 | expect(a == 128169); | |
| 654 | } | |
| 655 | ||
| 656 | test "unicode character in character literal" { | |
| 657 | expect('💩' == 128169); | |
| 658 | } | |
| 659 | ||
| 660 | test "result location zero sized array inside struct field implicit cast to slice" { | |
| 661 | const E = struct { | |
| 662 | entries: []u32, | |
| 663 | }; | |
| 664 | var foo = E{ .entries = &[_]u32{} }; | |
| 665 | expect(foo.entries.len == 0); | |
| 666 | } | |
| 667 | ||
| 668 | var global_foo: *i32 = undefined; | |
| 669 | ||
| 670 | test "global variable assignment with optional unwrapping with var initialized to undefined" { | |
| 671 | const S = struct { | |
| 672 | var data: i32 = 1234; | |
| 673 | fn foo() ?*i32 { | |
| 674 | return &data; | |
| 675 | } | |
| 676 | }; | |
| 677 | global_foo = S.foo() orelse { | |
| 678 | @panic("bad"); | |
| 679 | }; | |
| 680 | expect(global_foo.* == 1234); | |
| 681 | } | |
| 682 | ||
| 683 | test "peer result location with typed parent, runtime condition, comptime prongs" { | |
| 684 | const S = struct { | |
| 685 | fn doTheTest(arg: i32) i32 { | |
| 686 | const st = Structy{ | |
| 687 | .bleh = if (arg == 1) 1 else 1, | |
| 688 | }; | |
| 689 | ||
| 690 | if (st.bleh == 1) | |
| 691 | return 1234; | |
| 692 | return 0; | |
| 693 | } | |
| 694 | ||
| 695 | const Structy = struct { | |
| 696 | bleh: i32, | |
| 697 | }; | |
| 698 | }; | |
| 699 | expect(S.doTheTest(0) == 1234); | |
| 700 | expect(S.doTheTest(1) == 1234); | |
| 701 | } | |
| 702 | ||
| 703 | test "nested optional field in struct" { | |
| 704 | const S2 = struct { | |
| 705 | y: u8, | |
| 706 | }; | |
| 707 | const S1 = struct { | |
| 708 | x: ?S2, | |
| 709 | }; | |
| 710 | var s = S1{ | |
| 711 | .x = S2{ .y = 127 }, | |
| 712 | }; | |
| 713 | expect(s.x.?.y == 127); | |
| 714 | } | |
| 715 | ||
| 716 | fn maybe(x: bool) anyerror!?u32 { | |
| 717 | return switch (x) { | |
| 718 | true => @as(u32, 42), | |
| 719 | else => null, | |
| 720 | }; | |
| 721 | } | |
| 722 | ||
| 723 | test "result location is optional inside error union" { | |
| 724 | const x = maybe(true) catch unreachable; | |
| 725 | expect(x.? == 42); | |
| 726 | } | |
| 727 | ||
| 728 | threadlocal var buffer: [11]u8 = undefined; | |
| 729 | ||
| 730 | test "pointer to thread local array" { | |
| 731 | const s = "Hello world"; | |
| 732 | std.mem.copy(u8, buffer[0..], s); | |
| 733 | std.testing.expectEqualSlices(u8, buffer[0..], s); | |
| 734 | } | |
| 735 | ||
| 736 | test "auto created variables have correct alignment" { | |
| 737 | const S = struct { | |
| 738 | fn foo(str: [*]const u8) u32 { | |
| 739 | for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| { | |
| 740 | return v; | |
| 741 | } | |
| 742 | return 0; | |
| 743 | } | |
| 744 | }; | |
| 745 | expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); | |
| 746 | comptime expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); | |
| 747 | } | |
| 748 | ||
| 749 | extern var opaque_extern_var: opaque {}; | |
| 750 | var var_to_export: u32 = 42; | |
| 751 | test "extern variable with non-pointer opaque type" { | |
| 752 | @export(var_to_export, .{ .name = "opaque_extern_var" }); | |
| 753 | expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42); | |
| 754 | } | |
| 755 | ||
| 756 | test "lazy typeInfo value as generic parameter" { | |
| 757 | const S = struct { | |
| 758 | fn foo(args: anytype) void {} | |
| 759 | }; | |
| 760 | S.foo(@typeInfo(@TypeOf(.{}))); | |
| 761 | } |
test/behavior/muladd.zig created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@mulAdd" { | |
| 4 | comptime testMulAdd(); | |
| 5 | testMulAdd(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testMulAdd() void { | |
| 9 | { | |
| 10 | var a: f16 = 5.5; | |
| 11 | var b: f16 = 2.5; | |
| 12 | var c: f16 = 6.25; | |
| 13 | expect(@mulAdd(f16, a, b, c) == 20); | |
| 14 | } | |
| 15 | { | |
| 16 | var a: f32 = 5.5; | |
| 17 | var b: f32 = 2.5; | |
| 18 | var c: f32 = 6.25; | |
| 19 | expect(@mulAdd(f32, a, b, c) == 20); | |
| 20 | } | |
| 21 | { | |
| 22 | var a: f64 = 5.5; | |
| 23 | var b: f64 = 2.5; | |
| 24 | var c: f64 = 6.25; | |
| 25 | expect(@mulAdd(f64, a, b, c) == 20); | |
| 26 | } | |
| 27 | // Awaits implementation in libm.zig | |
| 28 | //{ | |
| 29 | // var a: f16 = 5.5; | |
| 30 | // var b: f128 = 2.5; | |
| 31 | // var c: f128 = 6.25; | |
| 32 | // expect(@mulAdd(f128, a, b, c) == 20); | |
| 33 | //} | |
| 34 | } |
test/behavior/namespace_depends_on_compile_var.zig created+14| ... | ... | @@ -0,0 +1,14 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "namespace depends on compile var" { | |
| 5 | if (some_namespace.a_bool) { | |
| 6 | expect(some_namespace.a_bool); | |
| 7 | } else { | |
| 8 | expect(!some_namespace.a_bool); | |
| 9 | } | |
| 10 | } | |
| 11 | const some_namespace = switch (std.builtin.os.tag) { | |
| 12 | .linux => @import("namespace_depends_on_compile_var/a.zig"), | |
| 13 | else => @import("namespace_depends_on_compile_var/b.zig"), | |
| 14 | }; |
test/behavior/namespace_depends_on_compile_var/a.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub const a_bool = true; |
test/behavior/namespace_depends_on_compile_var/b.zig created+1| ... | ... | @@ -0,0 +1 @@ |
| 1 | pub const a_bool = false; |
test/behavior/null.zig created+162| ... | ... | @@ -0,0 +1,162 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "optional type" { | |
| 4 | const x: ?bool = true; | |
| 5 | ||
| 6 | if (x) |y| { | |
| 7 | if (y) { | |
| 8 | // OK | |
| 9 | } else { | |
| 10 | unreachable; | |
| 11 | } | |
| 12 | } else { | |
| 13 | unreachable; | |
| 14 | } | |
| 15 | ||
| 16 | const next_x: ?i32 = null; | |
| 17 | ||
| 18 | const z = next_x orelse 1234; | |
| 19 | ||
| 20 | expect(z == 1234); | |
| 21 | ||
| 22 | const final_x: ?i32 = 13; | |
| 23 | ||
| 24 | const num = final_x orelse unreachable; | |
| 25 | ||
| 26 | expect(num == 13); | |
| 27 | } | |
| 28 | ||
| 29 | test "test maybe object and get a pointer to the inner value" { | |
| 30 | var maybe_bool: ?bool = true; | |
| 31 | ||
| 32 | if (maybe_bool) |*b| { | |
| 33 | b.* = false; | |
| 34 | } | |
| 35 | ||
| 36 | expect(maybe_bool.? == false); | |
| 37 | } | |
| 38 | ||
| 39 | test "rhs maybe unwrap return" { | |
| 40 | const x: ?bool = true; | |
| 41 | const y = x orelse return; | |
| 42 | } | |
| 43 | ||
| 44 | test "maybe return" { | |
| 45 | maybeReturnImpl(); | |
| 46 | comptime maybeReturnImpl(); | |
| 47 | } | |
| 48 | ||
| 49 | fn maybeReturnImpl() void { | |
| 50 | expect(foo(1235).?); | |
| 51 | if (foo(null) != null) unreachable; | |
| 52 | expect(!foo(1234).?); | |
| 53 | } | |
| 54 | ||
| 55 | fn foo(x: ?i32) ?bool { | |
| 56 | const value = x orelse return null; | |
| 57 | return value > 1234; | |
| 58 | } | |
| 59 | ||
| 60 | test "if var maybe pointer" { | |
| 61 | expect(shouldBeAPlus1(Particle{ | |
| 62 | .a = 14, | |
| 63 | .b = 1, | |
| 64 | .c = 1, | |
| 65 | .d = 1, | |
| 66 | }) == 15); | |
| 67 | } | |
| 68 | fn shouldBeAPlus1(p: Particle) u64 { | |
| 69 | var maybe_particle: ?Particle = p; | |
| 70 | if (maybe_particle) |*particle| { | |
| 71 | particle.a += 1; | |
| 72 | } | |
| 73 | if (maybe_particle) |particle| { | |
| 74 | return particle.a; | |
| 75 | } | |
| 76 | return 0; | |
| 77 | } | |
| 78 | const Particle = struct { | |
| 79 | a: u64, | |
| 80 | b: u64, | |
| 81 | c: u64, | |
| 82 | d: u64, | |
| 83 | }; | |
| 84 | ||
| 85 | test "null literal outside function" { | |
| 86 | const is_null = here_is_a_null_literal.context == null; | |
| 87 | expect(is_null); | |
| 88 | ||
| 89 | const is_non_null = here_is_a_null_literal.context != null; | |
| 90 | expect(!is_non_null); | |
| 91 | } | |
| 92 | const SillyStruct = struct { | |
| 93 | context: ?i32, | |
| 94 | }; | |
| 95 | const here_is_a_null_literal = SillyStruct{ .context = null }; | |
| 96 | ||
| 97 | test "test null runtime" { | |
| 98 | testTestNullRuntime(null); | |
| 99 | } | |
| 100 | fn testTestNullRuntime(x: ?i32) void { | |
| 101 | expect(x == null); | |
| 102 | expect(!(x != null)); | |
| 103 | } | |
| 104 | ||
| 105 | test "optional void" { | |
| 106 | optionalVoidImpl(); | |
| 107 | comptime optionalVoidImpl(); | |
| 108 | } | |
| 109 | ||
| 110 | fn optionalVoidImpl() void { | |
| 111 | expect(bar(null) == null); | |
| 112 | expect(bar({}) != null); | |
| 113 | } | |
| 114 | ||
| 115 | fn bar(x: ?void) ?void { | |
| 116 | if (x) |_| { | |
| 117 | return {}; | |
| 118 | } else { | |
| 119 | return null; | |
| 120 | } | |
| 121 | } | |
| 122 | ||
| 123 | const StructWithOptional = struct { | |
| 124 | field: ?i32, | |
| 125 | }; | |
| 126 | ||
| 127 | var struct_with_optional: StructWithOptional = undefined; | |
| 128 | ||
| 129 | test "unwrap optional which is field of global var" { | |
| 130 | struct_with_optional.field = null; | |
| 131 | if (struct_with_optional.field) |payload| { | |
| 132 | unreachable; | |
| 133 | } | |
| 134 | struct_with_optional.field = 1234; | |
| 135 | if (struct_with_optional.field) |payload| { | |
| 136 | expect(payload == 1234); | |
| 137 | } else { | |
| 138 | unreachable; | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | test "null with default unwrap" { | |
| 143 | const x: i32 = null orelse 1; | |
| 144 | expect(x == 1); | |
| 145 | } | |
| 146 | ||
| 147 | test "optional types" { | |
| 148 | comptime { | |
| 149 | const opt_type_struct = StructWithOptionalType{ .t = u8 }; | |
| 150 | expect(opt_type_struct.t != null and opt_type_struct.t.? == u8); | |
| 151 | } | |
| 152 | } | |
| 153 | ||
| 154 | const StructWithOptionalType = struct { | |
| 155 | t: ?type, | |
| 156 | }; | |
| 157 | ||
| 158 | test "optional pointer to 0 bit type null value at runtime" { | |
| 159 | const EmptyStruct = struct {}; | |
| 160 | var x: ?*EmptyStruct = null; | |
| 161 | expect(x == null); | |
| 162 | } |
test/behavior/optional.zig created+269| ... | ... | @@ -0,0 +1,269 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | pub const EmptyStruct = struct {}; | |
| 7 | ||
| 8 | test "optional pointer to size zero struct" { | |
| 9 | var e = EmptyStruct{}; | |
| 10 | var o: ?*EmptyStruct = &e; | |
| 11 | expect(o != null); | |
| 12 | } | |
| 13 | ||
| 14 | test "equality compare nullable pointers" { | |
| 15 | testNullPtrsEql(); | |
| 16 | comptime testNullPtrsEql(); | |
| 17 | } | |
| 18 | ||
| 19 | fn testNullPtrsEql() void { | |
| 20 | var number: i32 = 1234; | |
| 21 | ||
| 22 | var x: ?*i32 = null; | |
| 23 | var y: ?*i32 = null; | |
| 24 | expect(x == y); | |
| 25 | y = &number; | |
| 26 | expect(x != y); | |
| 27 | expect(x != &number); | |
| 28 | expect(&number != x); | |
| 29 | x = &number; | |
| 30 | expect(x == y); | |
| 31 | expect(x == &number); | |
| 32 | expect(&number == x); | |
| 33 | } | |
| 34 | ||
| 35 | test "address of unwrap optional" { | |
| 36 | const S = struct { | |
| 37 | const Foo = struct { | |
| 38 | a: i32, | |
| 39 | }; | |
| 40 | ||
| 41 | var global: ?Foo = null; | |
| 42 | ||
| 43 | pub fn getFoo() anyerror!*Foo { | |
| 44 | return &global.?; | |
| 45 | } | |
| 46 | }; | |
| 47 | S.global = S.Foo{ .a = 1234 }; | |
| 48 | const foo = S.getFoo() catch unreachable; | |
| 49 | expect(foo.a == 1234); | |
| 50 | } | |
| 51 | ||
| 52 | test "equality compare optional with non-optional" { | |
| 53 | test_cmp_optional_non_optional(); | |
| 54 | comptime test_cmp_optional_non_optional(); | |
| 55 | } | |
| 56 | ||
| 57 | fn test_cmp_optional_non_optional() void { | |
| 58 | var ten: i32 = 10; | |
| 59 | var opt_ten: ?i32 = 10; | |
| 60 | var five: i32 = 5; | |
| 61 | var int_n: ?i32 = null; | |
| 62 | ||
| 63 | expect(int_n != ten); | |
| 64 | expect(opt_ten == ten); | |
| 65 | expect(opt_ten != five); | |
| 66 | ||
| 67 | // test evaluation is always lexical | |
| 68 | // ensure that the optional isn't always computed before the non-optional | |
| 69 | var mutable_state: i32 = 0; | |
| 70 | _ = blk1: { | |
| 71 | mutable_state += 1; | |
| 72 | break :blk1 @as(?f64, 10.0); | |
| 73 | } != blk2: { | |
| 74 | expect(mutable_state == 1); | |
| 75 | break :blk2 @as(f64, 5.0); | |
| 76 | }; | |
| 77 | _ = blk1: { | |
| 78 | mutable_state += 1; | |
| 79 | break :blk1 @as(f64, 10.0); | |
| 80 | } != blk2: { | |
| 81 | expect(mutable_state == 2); | |
| 82 | break :blk2 @as(?f64, 5.0); | |
| 83 | }; | |
| 84 | } | |
| 85 | ||
| 86 | test "passing an optional integer as a parameter" { | |
| 87 | const S = struct { | |
| 88 | fn entry() bool { | |
| 89 | var x: i32 = 1234; | |
| 90 | return foo(x); | |
| 91 | } | |
| 92 | ||
| 93 | fn foo(x: ?i32) bool { | |
| 94 | return x.? == 1234; | |
| 95 | } | |
| 96 | }; | |
| 97 | expect(S.entry()); | |
| 98 | comptime expect(S.entry()); | |
| 99 | } | |
| 100 | ||
| 101 | test "unwrap function call with optional pointer return value" { | |
| 102 | const S = struct { | |
| 103 | fn entry() void { | |
| 104 | expect(foo().?.* == 1234); | |
| 105 | expect(bar() == null); | |
| 106 | } | |
| 107 | const global: i32 = 1234; | |
| 108 | fn foo() ?*const i32 { | |
| 109 | return &global; | |
| 110 | } | |
| 111 | fn bar() ?*i32 { | |
| 112 | return null; | |
| 113 | } | |
| 114 | }; | |
| 115 | S.entry(); | |
| 116 | comptime S.entry(); | |
| 117 | } | |
| 118 | ||
| 119 | test "nested orelse" { | |
| 120 | const S = struct { | |
| 121 | fn entry() void { | |
| 122 | expect(func() == null); | |
| 123 | } | |
| 124 | fn maybe() ?Foo { | |
| 125 | return null; | |
| 126 | } | |
| 127 | fn func() ?Foo { | |
| 128 | const x = maybe() orelse | |
| 129 | maybe() orelse | |
| 130 | return null; | |
| 131 | unreachable; | |
| 132 | } | |
| 133 | const Foo = struct { | |
| 134 | field: i32, | |
| 135 | }; | |
| 136 | }; | |
| 137 | S.entry(); | |
| 138 | comptime S.entry(); | |
| 139 | } | |
| 140 | ||
| 141 | test "self-referential struct through a slice of optional" { | |
| 142 | const S = struct { | |
| 143 | const Node = struct { | |
| 144 | children: []?Node, | |
| 145 | data: ?u8, | |
| 146 | ||
| 147 | fn new() Node { | |
| 148 | return Node{ | |
| 149 | .children = undefined, | |
| 150 | .data = null, | |
| 151 | }; | |
| 152 | } | |
| 153 | }; | |
| 154 | }; | |
| 155 | ||
| 156 | var n = S.Node.new(); | |
| 157 | expect(n.data == null); | |
| 158 | } | |
| 159 | ||
| 160 | test "assigning to an unwrapped optional field in an inline loop" { | |
| 161 | comptime var maybe_pos_arg: ?comptime_int = null; | |
| 162 | inline for ("ab") |x| { | |
| 163 | maybe_pos_arg = 0; | |
| 164 | if (maybe_pos_arg.? != 0) { | |
| 165 | @compileError("bad"); | |
| 166 | } | |
| 167 | maybe_pos_arg.? = 10; | |
| 168 | } | |
| 169 | } | |
| 170 | ||
| 171 | test "coerce an anon struct literal to optional struct" { | |
| 172 | const S = struct { | |
| 173 | const Struct = struct { | |
| 174 | field: u32, | |
| 175 | }; | |
| 176 | export fn doTheTest() void { | |
| 177 | var maybe_dims: ?Struct = null; | |
| 178 | maybe_dims = .{ .field = 1 }; | |
| 179 | expect(maybe_dims.?.field == 1); | |
| 180 | } | |
| 181 | }; | |
| 182 | S.doTheTest(); | |
| 183 | comptime S.doTheTest(); | |
| 184 | } | |
| 185 | ||
| 186 | test "optional with void type" { | |
| 187 | const Foo = struct { | |
| 188 | x: ?void, | |
| 189 | }; | |
| 190 | var x = Foo{ .x = null }; | |
| 191 | expect(x.x == null); | |
| 192 | } | |
| 193 | ||
| 194 | test "0-bit child type coerced to optional return ptr result location" { | |
| 195 | const S = struct { | |
| 196 | fn doTheTest() void { | |
| 197 | var y = Foo{}; | |
| 198 | var z = y.thing(); | |
| 199 | expect(z != null); | |
| 200 | } | |
| 201 | ||
| 202 | const Foo = struct { | |
| 203 | pub const Bar = struct { | |
| 204 | field: *Foo, | |
| 205 | }; | |
| 206 | ||
| 207 | pub fn thing(self: *Foo) ?Bar { | |
| 208 | return Bar{ .field = self }; | |
| 209 | } | |
| 210 | }; | |
| 211 | }; | |
| 212 | S.doTheTest(); | |
| 213 | comptime S.doTheTest(); | |
| 214 | } | |
| 215 | ||
| 216 | test "0-bit child type coerced to optional" { | |
| 217 | const S = struct { | |
| 218 | fn doTheTest() void { | |
| 219 | var it: Foo = .{ | |
| 220 | .list = undefined, | |
| 221 | }; | |
| 222 | expect(it.foo() != null); | |
| 223 | } | |
| 224 | ||
| 225 | const Empty = struct {}; | |
| 226 | const Foo = struct { | |
| 227 | list: [10]Empty, | |
| 228 | ||
| 229 | fn foo(self: *Foo) ?*Empty { | |
| 230 | const data = &self.list[0]; | |
| 231 | return data; | |
| 232 | } | |
| 233 | }; | |
| 234 | }; | |
| 235 | S.doTheTest(); | |
| 236 | comptime S.doTheTest(); | |
| 237 | } | |
| 238 | ||
| 239 | test "array of optional unaligned types" { | |
| 240 | const Enum = enum { one, two, three }; | |
| 241 | ||
| 242 | const SomeUnion = union(enum) { | |
| 243 | Num: Enum, | |
| 244 | Other: u32, | |
| 245 | }; | |
| 246 | ||
| 247 | const values = [_]?SomeUnion{ | |
| 248 | SomeUnion{ .Num = .one }, | |
| 249 | SomeUnion{ .Num = .two }, | |
| 250 | SomeUnion{ .Num = .three }, | |
| 251 | SomeUnion{ .Num = .one }, | |
| 252 | SomeUnion{ .Num = .two }, | |
| 253 | SomeUnion{ .Num = .three }, | |
| 254 | }; | |
| 255 | ||
| 256 | // The index must be a runtime value | |
| 257 | var i: usize = 0; | |
| 258 | expectEqual(Enum.one, values[i].?.Num); | |
| 259 | i += 1; | |
| 260 | expectEqual(Enum.two, values[i].?.Num); | |
| 261 | i += 1; | |
| 262 | expectEqual(Enum.three, values[i].?.Num); | |
| 263 | i += 1; | |
| 264 | expectEqual(Enum.one, values[i].?.Num); | |
| 265 | i += 1; | |
| 266 | expectEqual(Enum.two, values[i].?.Num); | |
| 267 | i += 1; | |
| 268 | expectEqual(Enum.three, values[i].?.Num); | |
| 269 | } |
test/behavior/pointers.zig created+339| ... | ... | @@ -0,0 +1,339 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectError = testing.expectError; | |
| 5 | ||
| 6 | test "dereference pointer" { | |
| 7 | comptime testDerefPtr(); | |
| 8 | testDerefPtr(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testDerefPtr() void { | |
| 12 | var x: i32 = 1234; | |
| 13 | var y = &x; | |
| 14 | y.* += 1; | |
| 15 | expect(x == 1235); | |
| 16 | } | |
| 17 | ||
| 18 | const Foo1 = struct { | |
| 19 | x: void, | |
| 20 | }; | |
| 21 | ||
| 22 | test "dereference pointer again" { | |
| 23 | testDerefPtrOneVal(); | |
| 24 | comptime testDerefPtrOneVal(); | |
| 25 | } | |
| 26 | ||
| 27 | fn testDerefPtrOneVal() void { | |
| 28 | // Foo1 satisfies the OnePossibleValueYes criteria | |
| 29 | const x = &Foo1{ .x = {} }; | |
| 30 | const y = x.*; | |
| 31 | expect(@TypeOf(y.x) == void); | |
| 32 | } | |
| 33 | ||
| 34 | test "pointer arithmetic" { | |
| 35 | var ptr: [*]const u8 = "abcd"; | |
| 36 | ||
| 37 | expect(ptr[0] == 'a'); | |
| 38 | ptr += 1; | |
| 39 | expect(ptr[0] == 'b'); | |
| 40 | ptr += 1; | |
| 41 | expect(ptr[0] == 'c'); | |
| 42 | ptr += 1; | |
| 43 | expect(ptr[0] == 'd'); | |
| 44 | ptr += 1; | |
| 45 | expect(ptr[0] == 0); | |
| 46 | ptr -= 1; | |
| 47 | expect(ptr[0] == 'd'); | |
| 48 | ptr -= 1; | |
| 49 | expect(ptr[0] == 'c'); | |
| 50 | ptr -= 1; | |
| 51 | expect(ptr[0] == 'b'); | |
| 52 | ptr -= 1; | |
| 53 | expect(ptr[0] == 'a'); | |
| 54 | } | |
| 55 | ||
| 56 | test "double pointer parsing" { | |
| 57 | comptime expect(PtrOf(PtrOf(i32)) == **i32); | |
| 58 | } | |
| 59 | ||
| 60 | fn PtrOf(comptime T: type) type { | |
| 61 | return *T; | |
| 62 | } | |
| 63 | ||
| 64 | test "assigning integer to C pointer" { | |
| 65 | var x: i32 = 0; | |
| 66 | var ptr: [*c]u8 = 0; | |
| 67 | var ptr2: [*c]u8 = x; | |
| 68 | } | |
| 69 | ||
| 70 | test "implicit cast single item pointer to C pointer and back" { | |
| 71 | var y: u8 = 11; | |
| 72 | var x: [*c]u8 = &y; | |
| 73 | var z: *u8 = x; | |
| 74 | z.* += 1; | |
| 75 | expect(y == 12); | |
| 76 | } | |
| 77 | ||
| 78 | test "C pointer comparison and arithmetic" { | |
| 79 | const S = struct { | |
| 80 | fn doTheTest() void { | |
| 81 | var one: usize = 1; | |
| 82 | var ptr1: [*c]u32 = 0; | |
| 83 | var ptr2 = ptr1 + 10; | |
| 84 | expect(ptr1 == 0); | |
| 85 | expect(ptr1 >= 0); | |
| 86 | expect(ptr1 <= 0); | |
| 87 | // expect(ptr1 < 1); | |
| 88 | // expect(ptr1 < one); | |
| 89 | // expect(1 > ptr1); | |
| 90 | // expect(one > ptr1); | |
| 91 | expect(ptr1 < ptr2); | |
| 92 | expect(ptr2 > ptr1); | |
| 93 | expect(ptr2 >= 40); | |
| 94 | expect(ptr2 == 40); | |
| 95 | expect(ptr2 <= 40); | |
| 96 | ptr2 -= 10; | |
| 97 | expect(ptr1 == ptr2); | |
| 98 | } | |
| 99 | }; | |
| 100 | S.doTheTest(); | |
| 101 | comptime S.doTheTest(); | |
| 102 | } | |
| 103 | ||
| 104 | test "peer type resolution with C pointers" { | |
| 105 | var ptr_one: *u8 = undefined; | |
| 106 | var ptr_many: [*]u8 = undefined; | |
| 107 | var ptr_c: [*c]u8 = undefined; | |
| 108 | var t = true; | |
| 109 | var x1 = if (t) ptr_one else ptr_c; | |
| 110 | var x2 = if (t) ptr_many else ptr_c; | |
| 111 | var x3 = if (t) ptr_c else ptr_one; | |
| 112 | var x4 = if (t) ptr_c else ptr_many; | |
| 113 | expect(@TypeOf(x1) == [*c]u8); | |
| 114 | expect(@TypeOf(x2) == [*c]u8); | |
| 115 | expect(@TypeOf(x3) == [*c]u8); | |
| 116 | expect(@TypeOf(x4) == [*c]u8); | |
| 117 | } | |
| 118 | ||
| 119 | test "implicit casting between C pointer and optional non-C pointer" { | |
| 120 | var slice: []const u8 = "aoeu"; | |
| 121 | const opt_many_ptr: ?[*]const u8 = slice.ptr; | |
| 122 | var ptr_opt_many_ptr = &opt_many_ptr; | |
| 123 | var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr; | |
| 124 | expect(c_ptr.*.* == 'a'); | |
| 125 | ptr_opt_many_ptr = c_ptr; | |
| 126 | expect(ptr_opt_many_ptr.*.?[1] == 'o'); | |
| 127 | } | |
| 128 | ||
| 129 | test "implicit cast error unions with non-optional to optional pointer" { | |
| 130 | const S = struct { | |
| 131 | fn doTheTest() void { | |
| 132 | expectError(error.Fail, foo()); | |
| 133 | } | |
| 134 | fn foo() anyerror!?*u8 { | |
| 135 | return bar() orelse error.Fail; | |
| 136 | } | |
| 137 | fn bar() ?*u8 { | |
| 138 | return null; | |
| 139 | } | |
| 140 | }; | |
| 141 | S.doTheTest(); | |
| 142 | comptime S.doTheTest(); | |
| 143 | } | |
| 144 | ||
| 145 | test "initialize const optional C pointer to null" { | |
| 146 | const a: ?[*c]i32 = null; | |
| 147 | expect(a == null); | |
| 148 | comptime expect(a == null); | |
| 149 | } | |
| 150 | ||
| 151 | test "compare equality of optional and non-optional pointer" { | |
| 152 | const a = @intToPtr(*const usize, 0x12345678); | |
| 153 | const b = @intToPtr(?*usize, 0x12345678); | |
| 154 | expect(a == b); | |
| 155 | expect(b == a); | |
| 156 | } | |
| 157 | ||
| 158 | test "allowzero pointer and slice" { | |
| 159 | var ptr = @intToPtr([*]allowzero i32, 0); | |
| 160 | var opt_ptr: ?[*]allowzero i32 = ptr; | |
| 161 | expect(opt_ptr != null); | |
| 162 | expect(@ptrToInt(ptr) == 0); | |
| 163 | var runtime_zero: usize = 0; | |
| 164 | var slice = ptr[runtime_zero..10]; | |
| 165 | comptime expect(@TypeOf(slice) == []allowzero i32); | |
| 166 | expect(@ptrToInt(&slice[5]) == 20); | |
| 167 | ||
| 168 | comptime expect(@typeInfo(@TypeOf(ptr)).Pointer.is_allowzero); | |
| 169 | comptime expect(@typeInfo(@TypeOf(slice)).Pointer.is_allowzero); | |
| 170 | } | |
| 171 | ||
| 172 | test "assign null directly to C pointer and test null equality" { | |
| 173 | var x: [*c]i32 = null; | |
| 174 | expect(x == null); | |
| 175 | expect(null == x); | |
| 176 | expect(!(x != null)); | |
| 177 | expect(!(null != x)); | |
| 178 | if (x) |same_x| { | |
| 179 | @panic("fail"); | |
| 180 | } | |
| 181 | var otherx: i32 = undefined; | |
| 182 | expect((x orelse &otherx) == &otherx); | |
| 183 | ||
| 184 | const y: [*c]i32 = null; | |
| 185 | comptime expect(y == null); | |
| 186 | comptime expect(null == y); | |
| 187 | comptime expect(!(y != null)); | |
| 188 | comptime expect(!(null != y)); | |
| 189 | if (y) |same_y| @panic("fail"); | |
| 190 | const othery: i32 = undefined; | |
| 191 | comptime expect((y orelse &othery) == &othery); | |
| 192 | ||
| 193 | var n: i32 = 1234; | |
| 194 | var x1: [*c]i32 = &n; | |
| 195 | expect(!(x1 == null)); | |
| 196 | expect(!(null == x1)); | |
| 197 | expect(x1 != null); | |
| 198 | expect(null != x1); | |
| 199 | expect(x1.?.* == 1234); | |
| 200 | if (x1) |same_x1| { | |
| 201 | expect(same_x1.* == 1234); | |
| 202 | } else { | |
| 203 | @panic("fail"); | |
| 204 | } | |
| 205 | expect((x1 orelse &otherx) == x1); | |
| 206 | ||
| 207 | const nc: i32 = 1234; | |
| 208 | const y1: [*c]const i32 = &nc; | |
| 209 | comptime expect(!(y1 == null)); | |
| 210 | comptime expect(!(null == y1)); | |
| 211 | comptime expect(y1 != null); | |
| 212 | comptime expect(null != y1); | |
| 213 | comptime expect(y1.?.* == 1234); | |
| 214 | if (y1) |same_y1| { | |
| 215 | expect(same_y1.* == 1234); | |
| 216 | } else { | |
| 217 | @compileError("fail"); | |
| 218 | } | |
| 219 | comptime expect((y1 orelse &othery) == y1); | |
| 220 | } | |
| 221 | ||
| 222 | test "null terminated pointer" { | |
| 223 | const S = struct { | |
| 224 | fn doTheTest() void { | |
| 225 | var array_with_zero = [_:0]u8{ 'h', 'e', 'l', 'l', 'o' }; | |
| 226 | var zero_ptr: [*:0]const u8 = @ptrCast([*:0]const u8, &array_with_zero); | |
| 227 | var no_zero_ptr: [*]const u8 = zero_ptr; | |
| 228 | var zero_ptr_again = @ptrCast([*:0]const u8, no_zero_ptr); | |
| 229 | expect(std.mem.eql(u8, std.mem.spanZ(zero_ptr_again), "hello")); | |
| 230 | } | |
| 231 | }; | |
| 232 | S.doTheTest(); | |
| 233 | comptime S.doTheTest(); | |
| 234 | } | |
| 235 | ||
| 236 | test "allow any sentinel" { | |
| 237 | const S = struct { | |
| 238 | fn doTheTest() void { | |
| 239 | var array = [_:std.math.minInt(i32)]i32{ 1, 2, 3, 4 }; | |
| 240 | var ptr: [*:std.math.minInt(i32)]i32 = &array; | |
| 241 | expect(ptr[4] == std.math.minInt(i32)); | |
| 242 | } | |
| 243 | }; | |
| 244 | S.doTheTest(); | |
| 245 | comptime S.doTheTest(); | |
| 246 | } | |
| 247 | ||
| 248 | test "pointer sentinel with enums" { | |
| 249 | const S = struct { | |
| 250 | const Number = enum { | |
| 251 | one, | |
| 252 | two, | |
| 253 | sentinel, | |
| 254 | }; | |
| 255 | ||
| 256 | fn doTheTest() void { | |
| 257 | var ptr: [*:.sentinel]const Number = &[_:.sentinel]Number{ .one, .two, .two, .one }; | |
| 258 | expect(ptr[4] == .sentinel); // TODO this should be comptime expect, see #3731 | |
| 259 | } | |
| 260 | }; | |
| 261 | S.doTheTest(); | |
| 262 | comptime S.doTheTest(); | |
| 263 | } | |
| 264 | ||
| 265 | test "pointer sentinel with optional element" { | |
| 266 | const S = struct { | |
| 267 | fn doTheTest() void { | |
| 268 | var ptr: [*:null]const ?i32 = &[_:null]?i32{ 1, 2, 3, 4 }; | |
| 269 | expect(ptr[4] == null); // TODO this should be comptime expect, see #3731 | |
| 270 | } | |
| 271 | }; | |
| 272 | S.doTheTest(); | |
| 273 | comptime S.doTheTest(); | |
| 274 | } | |
| 275 | ||
| 276 | test "pointer sentinel with +inf" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | const inf = std.math.inf_f32; | |
| 280 | var ptr: [*:inf]const f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 281 | expect(ptr[4] == inf); // TODO this should be comptime expect, see #3731 | |
| 282 | } | |
| 283 | }; | |
| 284 | S.doTheTest(); | |
| 285 | comptime S.doTheTest(); | |
| 286 | } | |
| 287 | ||
| 288 | test "pointer to array at fixed address" { | |
| 289 | const array = @intToPtr(*volatile [1]u32, 0x10); | |
| 290 | // Silly check just to reference `array` | |
| 291 | expect(@ptrToInt(&array[0]) == 0x10); | |
| 292 | } | |
| 293 | ||
| 294 | test "pointer arithmetic affects the alignment" { | |
| 295 | { | |
| 296 | var ptr: [*]align(8) u32 = undefined; | |
| 297 | var x: usize = 1; | |
| 298 | ||
| 299 | expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 8); | |
| 300 | const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4 | |
| 301 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 4); | |
| 302 | const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8 | |
| 303 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 8); | |
| 304 | const ptr3 = ptr + 0; // no-op | |
| 305 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8); | |
| 306 | const ptr4 = ptr + x; // runtime-known addend | |
| 307 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4); | |
| 308 | } | |
| 309 | { | |
| 310 | var ptr: [*]align(8) [3]u8 = undefined; | |
| 311 | var x: usize = 1; | |
| 312 | ||
| 313 | const ptr1 = ptr + 17; // 3 * 17 = 51 | |
| 314 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1); | |
| 315 | const ptr2 = ptr + x; // runtime-known addend | |
| 316 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 1); | |
| 317 | const ptr3 = ptr + 8; // 3 * 8 = 24 -> lcd(8,24) = 8 | |
| 318 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8); | |
| 319 | const ptr4 = ptr + 4; // 3 * 4 = 12 -> lcd(8,12) = 4 | |
| 320 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4); | |
| 321 | } | |
| 322 | } | |
| 323 | ||
| 324 | test "@ptrToInt on null optional at comptime" { | |
| 325 | { | |
| 326 | const pointer = @intToPtr(?*u8, 0x000); | |
| 327 | const x = @ptrToInt(pointer); | |
| 328 | comptime expect(0 == @ptrToInt(pointer)); | |
| 329 | } | |
| 330 | { | |
| 331 | const pointer = @intToPtr(?*u8, 0xf00); | |
| 332 | comptime expect(0xf00 == @ptrToInt(pointer)); | |
| 333 | } | |
| 334 | } | |
| 335 | ||
| 336 | test "indexing array with sentinel returns correct type" { | |
| 337 | var s: [:0]const u8 = "abc"; | |
| 338 | testing.expectEqualSlices(u8, "*const u8", @typeName(@TypeOf(&s[0]))); | |
| 339 | } |
test/behavior/popcount.zig created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@popCount" { | |
| 4 | comptime testPopCount(); | |
| 5 | testPopCount(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testPopCount() void { | |
| 9 | { | |
| 10 | var x: u32 = 0xffffffff; | |
| 11 | expect(@popCount(u32, x) == 32); | |
| 12 | } | |
| 13 | { | |
| 14 | var x: u5 = 0x1f; | |
| 15 | expect(@popCount(u5, x) == 5); | |
| 16 | } | |
| 17 | { | |
| 18 | var x: u32 = 0xaa; | |
| 19 | expect(@popCount(u32, x) == 4); | |
| 20 | } | |
| 21 | { | |
| 22 | var x: u32 = 0xaaaaaaaa; | |
| 23 | expect(@popCount(u32, x) == 16); | |
| 24 | } | |
| 25 | { | |
| 26 | var x: u32 = 0xaaaaaaaa; | |
| 27 | expect(@popCount(u32, x) == 16); | |
| 28 | } | |
| 29 | { | |
| 30 | var x: i16 = -1; | |
| 31 | expect(@popCount(i16, x) == 16); | |
| 32 | } | |
| 33 | { | |
| 34 | var x: i8 = -120; | |
| 35 | expect(@popCount(i8, x) == 2); | |
| 36 | } | |
| 37 | comptime { | |
| 38 | expect(@popCount(u8, @bitCast(u8, @as(i8, -120))) == 2); | |
| 39 | } | |
| 40 | comptime { | |
| 41 | expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24); | |
| 42 | } | |
| 43 | } |
test/behavior/ptrcast.zig created+73| ... | ... | @@ -0,0 +1,73 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 5 | ||
| 6 | test "reinterpret bytes as integer with nonzero offset" { | |
| 7 | testReinterpretBytesAsInteger(); | |
| 8 | comptime testReinterpretBytesAsInteger(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testReinterpretBytesAsInteger() void { | |
| 12 | const bytes = "\x12\x34\x56\x78\xab"; | |
| 13 | const expected = switch (native_endian) { | |
| 14 | .Little => 0xab785634, | |
| 15 | .Big => 0x345678ab, | |
| 16 | }; | |
| 17 | expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected); | |
| 18 | } | |
| 19 | ||
| 20 | test "reinterpret bytes of an array into an extern struct" { | |
| 21 | testReinterpretBytesAsExternStruct(); | |
| 22 | comptime testReinterpretBytesAsExternStruct(); | |
| 23 | } | |
| 24 | ||
| 25 | fn testReinterpretBytesAsExternStruct() void { | |
| 26 | var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 }; | |
| 27 | ||
| 28 | const S = extern struct { | |
| 29 | a: u8, | |
| 30 | b: u16, | |
| 31 | c: u8, | |
| 32 | }; | |
| 33 | ||
| 34 | var ptr = @ptrCast(*const S, &bytes); | |
| 35 | var val = ptr.c; | |
| 36 | expect(val == 5); | |
| 37 | } | |
| 38 | ||
| 39 | test "reinterpret struct field at comptime" { | |
| 40 | const numNative = comptime Bytes.init(0x12345678); | |
| 41 | if (native_endian != .Little) { | |
| 42 | expect(std.mem.eql(u8, &[_]u8{ 0x12, 0x34, 0x56, 0x78 }, &numNative.bytes)); | |
| 43 | } else { | |
| 44 | expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numNative.bytes)); | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | const Bytes = struct { | |
| 49 | bytes: [4]u8, | |
| 50 | ||
| 51 | pub fn init(v: u32) Bytes { | |
| 52 | var res: Bytes = undefined; | |
| 53 | @ptrCast(*align(1) u32, &res.bytes).* = v; | |
| 54 | ||
| 55 | return res; | |
| 56 | } | |
| 57 | }; | |
| 58 | ||
| 59 | test "comptime ptrcast keeps larger alignment" { | |
| 60 | comptime { | |
| 61 | const a: u32 = 1234; | |
| 62 | const p = @ptrCast([*]const u8, &a); | |
| 63 | std.debug.assert(@TypeOf(p) == [*]align(@alignOf(u32)) const u8); | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | test "implicit optional pointer to optional c_void pointer" { | |
| 68 | var buf: [4]u8 = "aoeu".*; | |
| 69 | var x: ?[*]u8 = &buf; | |
| 70 | var y: ?*c_void = x; | |
| 71 | var z = @ptrCast(*[4]u8, y); | |
| 72 | expect(std.mem.eql(u8, z, "aoeu")); | |
| 73 | } |
test/behavior/pub_enum.zig created+13| ... | ... | @@ -0,0 +1,13 @@ |
| 1 | const other = @import("pub_enum/other.zig"); | |
| 2 | const expect = @import("std").testing.expect; | |
| 3 | ||
| 4 | test "pub enum" { | |
| 5 | pubEnumTest(other.APubEnum.Two); | |
| 6 | } | |
| 7 | fn pubEnumTest(foo: other.APubEnum) void { | |
| 8 | expect(foo == other.APubEnum.Two); | |
| 9 | } | |
| 10 | ||
| 11 | test "cast with imported symbol" { | |
| 12 | expect(@as(other.size_t, 42) == 42); | |
| 13 | } |
test/behavior/pub_enum/other.zig created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | pub const APubEnum = enum { | |
| 2 | One, | |
| 3 | Two, | |
| 4 | Three, | |
| 5 | }; | |
| 6 | pub const size_t = u64; |
test/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig created+37| ... | ... | @@ -0,0 +1,37 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | ||
| 4 | var ok: bool = false; | |
| 5 | test "reference a variable in an if after an if in the 2nd switch prong" { | |
| 6 | foo(true, Num.Two, false, "aoeu"); | |
| 7 | expect(!ok); | |
| 8 | foo(false, Num.One, false, "aoeu"); | |
| 9 | expect(!ok); | |
| 10 | foo(true, Num.One, false, "aoeu"); | |
| 11 | expect(ok); | |
| 12 | } | |
| 13 | ||
| 14 | const Num = enum { | |
| 15 | One, | |
| 16 | Two, | |
| 17 | }; | |
| 18 | ||
| 19 | fn foo(c: bool, k: Num, c2: bool, b: []const u8) void { | |
| 20 | switch (k) { | |
| 21 | Num.Two => {}, | |
| 22 | Num.One => { | |
| 23 | if (c) { | |
| 24 | const output_path = b; | |
| 25 | ||
| 26 | if (c2) {} | |
| 27 | ||
| 28 | a(output_path); | |
| 29 | } | |
| 30 | }, | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn a(x: []const u8) void { | |
| 35 | expect(mem.eql(u8, x, "aoeu")); | |
| 36 | ok = true; | |
| 37 | } |
test/behavior/reflection.zig created+55| ... | ... | @@ -0,0 +1,55 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const reflection = @This(); | |
| 4 | ||
| 5 | test "reflection: function return type, var args, and param types" { | |
| 6 | comptime { | |
| 7 | const info = @typeInfo(@TypeOf(dummy)).Fn; | |
| 8 | expect(info.return_type.? == i32); | |
| 9 | expect(!info.is_var_args); | |
| 10 | expect(info.args.len == 3); | |
| 11 | expect(info.args[0].arg_type.? == bool); | |
| 12 | expect(info.args[1].arg_type.? == i32); | |
| 13 | expect(info.args[2].arg_type.? == f32); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn dummy(a: bool, b: i32, c: f32) i32 { | |
| 18 | return 1234; | |
| 19 | } | |
| 20 | ||
| 21 | test "reflection: @field" { | |
| 22 | var f = Foo{ | |
| 23 | .one = 42, | |
| 24 | .two = true, | |
| 25 | .three = void{}, | |
| 26 | }; | |
| 27 | ||
| 28 | expect(f.one == f.one); | |
| 29 | expect(@field(f, "o" ++ "ne") == f.one); | |
| 30 | expect(@field(f, "t" ++ "wo") == f.two); | |
| 31 | expect(@field(f, "th" ++ "ree") == f.three); | |
| 32 | expect(@field(Foo, "const" ++ "ant") == Foo.constant); | |
| 33 | expect(@field(Bar, "O" ++ "ne") == Bar.One); | |
| 34 | expect(@field(Bar, "T" ++ "wo") == Bar.Two); | |
| 35 | expect(@field(Bar, "Th" ++ "ree") == Bar.Three); | |
| 36 | expect(@field(Bar, "F" ++ "our") == Bar.Four); | |
| 37 | expect(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2)); | |
| 38 | @field(f, "o" ++ "ne") = 4; | |
| 39 | expect(f.one == 4); | |
| 40 | } | |
| 41 | ||
| 42 | const Foo = struct { | |
| 43 | const constant = 52; | |
| 44 | ||
| 45 | one: i32, | |
| 46 | two: bool, | |
| 47 | three: void, | |
| 48 | }; | |
| 49 | ||
| 50 | const Bar = union(enum) { | |
| 51 | One: void, | |
| 52 | Two: i32, | |
| 53 | Three: bool, | |
| 54 | Four: f64, | |
| 55 | }; |
test/behavior/shuffle.zig created+63| ... | ... | @@ -0,0 +1,63 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const expect = std.testing.expect; | |
| 5 | const Vector = std.meta.Vector; | |
| 6 | ||
| 7 | test "@shuffle" { | |
| 8 | // TODO investigate why this fails when cross-compiling to wasm. | |
| 9 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | |
| 10 | ||
| 11 | const S = struct { | |
| 12 | fn doTheTest() void { | |
| 13 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 14 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; | |
| 15 | const mask: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }; | |
| 16 | var res = @shuffle(i32, v, x, mask); | |
| 17 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); | |
| 18 | ||
| 19 | // Implicit cast from array (of mask) | |
| 20 | res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }); | |
| 21 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); | |
| 22 | ||
| 23 | // Undefined | |
| 24 | const mask2: Vector(4, i32) = [4]i32{ 3, 1, 2, 0 }; | |
| 25 | res = @shuffle(i32, v, undefined, mask2); | |
| 26 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 40, -2, 30, 2147483647 })); | |
| 27 | ||
| 28 | // Upcasting of b | |
| 29 | var v2: Vector(2, i32) = [2]i32{ 2147483647, undefined }; | |
| 30 | const mask3: Vector(4, i32) = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 }; | |
| 31 | res = @shuffle(i32, x, v2, mask3); | |
| 32 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 2147483647, 4 })); | |
| 33 | ||
| 34 | // Upcasting of a | |
| 35 | var v3: Vector(2, i32) = [2]i32{ 2147483647, -2 }; | |
| 36 | const mask4: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) }; | |
| 37 | res = @shuffle(i32, v3, x, mask4); | |
| 38 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, -2, 4 })); | |
| 39 | ||
| 40 | // bool | |
| 41 | // https://github.com/ziglang/zig/issues/3317 | |
| 42 | if (builtin.target.cpu.arch != .mipsel and builtin.target.cpu.arch != .mips) { | |
| 43 | var x2: Vector(4, bool) = [4]bool{ false, true, false, true }; | |
| 44 | var v4: Vector(2, bool) = [2]bool{ true, false }; | |
| 45 | const mask5: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 46 | var res2 = @shuffle(bool, x2, v4, mask5); | |
| 47 | expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); | |
| 48 | } | |
| 49 | ||
| 50 | // TODO re-enable when LLVM codegen is fixed | |
| 51 | // https://github.com/ziglang/zig/issues/3246 | |
| 52 | if (false) { | |
| 53 | var x2: Vector(3, bool) = [3]bool{ false, true, false }; | |
| 54 | var v4: Vector(2, bool) = [2]bool{ true, false }; | |
| 55 | const mask5: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 56 | var res2 = @shuffle(bool, x2, v4, mask5); | |
| 57 | expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); | |
| 58 | } | |
| 59 | } | |
| 60 | }; | |
| 61 | S.doTheTest(); | |
| 62 | comptime S.doTheTest(); | |
| 63 | } |
test/behavior/sizeof_and_typeof.zig created+264| ... | ... | @@ -0,0 +1,264 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | ||
| 6 | test "@sizeOf and @TypeOf" { | |
| 7 | const y: @TypeOf(x) = 120; | |
| 8 | expect(@sizeOf(@TypeOf(y)) == 2); | |
| 9 | } | |
| 10 | const x: u16 = 13; | |
| 11 | const z: @TypeOf(x) = 19; | |
| 12 | ||
| 13 | const A = struct { | |
| 14 | a: u8, | |
| 15 | b: u32, | |
| 16 | c: u8, | |
| 17 | d: u3, | |
| 18 | e: u5, | |
| 19 | f: u16, | |
| 20 | g: u16, | |
| 21 | h: u9, | |
| 22 | i: u7, | |
| 23 | }; | |
| 24 | ||
| 25 | const P = packed struct { | |
| 26 | a: u8, | |
| 27 | b: u32, | |
| 28 | c: u8, | |
| 29 | d: u3, | |
| 30 | e: u5, | |
| 31 | f: u16, | |
| 32 | g: u16, | |
| 33 | h: u9, | |
| 34 | i: u7, | |
| 35 | }; | |
| 36 | ||
| 37 | test "@byteOffsetOf" { | |
| 38 | // Packed structs have fixed memory layout | |
| 39 | expect(@byteOffsetOf(P, "a") == 0); | |
| 40 | expect(@byteOffsetOf(P, "b") == 1); | |
| 41 | expect(@byteOffsetOf(P, "c") == 5); | |
| 42 | expect(@byteOffsetOf(P, "d") == 6); | |
| 43 | expect(@byteOffsetOf(P, "e") == 6); | |
| 44 | expect(@byteOffsetOf(P, "f") == 7); | |
| 45 | expect(@byteOffsetOf(P, "g") == 9); | |
| 46 | expect(@byteOffsetOf(P, "h") == 11); | |
| 47 | expect(@byteOffsetOf(P, "i") == 12); | |
| 48 | ||
| 49 | // Normal struct fields can be moved/padded | |
| 50 | var a: A = undefined; | |
| 51 | expect(@ptrToInt(&a.a) - @ptrToInt(&a) == @byteOffsetOf(A, "a")); | |
| 52 | expect(@ptrToInt(&a.b) - @ptrToInt(&a) == @byteOffsetOf(A, "b")); | |
| 53 | expect(@ptrToInt(&a.c) - @ptrToInt(&a) == @byteOffsetOf(A, "c")); | |
| 54 | expect(@ptrToInt(&a.d) - @ptrToInt(&a) == @byteOffsetOf(A, "d")); | |
| 55 | expect(@ptrToInt(&a.e) - @ptrToInt(&a) == @byteOffsetOf(A, "e")); | |
| 56 | expect(@ptrToInt(&a.f) - @ptrToInt(&a) == @byteOffsetOf(A, "f")); | |
| 57 | expect(@ptrToInt(&a.g) - @ptrToInt(&a) == @byteOffsetOf(A, "g")); | |
| 58 | expect(@ptrToInt(&a.h) - @ptrToInt(&a) == @byteOffsetOf(A, "h")); | |
| 59 | expect(@ptrToInt(&a.i) - @ptrToInt(&a) == @byteOffsetOf(A, "i")); | |
| 60 | } | |
| 61 | ||
| 62 | test "@byteOffsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" { | |
| 63 | const p3a_len = 3; | |
| 64 | const P3 = packed struct { | |
| 65 | a: [p3a_len]u8, | |
| 66 | b: usize, | |
| 67 | }; | |
| 68 | std.testing.expectEqual(0, @byteOffsetOf(P3, "a")); | |
| 69 | std.testing.expectEqual(p3a_len, @byteOffsetOf(P3, "b")); | |
| 70 | ||
| 71 | const p5a_len = 5; | |
| 72 | const P5 = packed struct { | |
| 73 | a: [p5a_len]u8, | |
| 74 | b: usize, | |
| 75 | }; | |
| 76 | std.testing.expectEqual(0, @byteOffsetOf(P5, "a")); | |
| 77 | std.testing.expectEqual(p5a_len, @byteOffsetOf(P5, "b")); | |
| 78 | ||
| 79 | const p6a_len = 6; | |
| 80 | const P6 = packed struct { | |
| 81 | a: [p6a_len]u8, | |
| 82 | b: usize, | |
| 83 | }; | |
| 84 | std.testing.expectEqual(0, @byteOffsetOf(P6, "a")); | |
| 85 | std.testing.expectEqual(p6a_len, @byteOffsetOf(P6, "b")); | |
| 86 | ||
| 87 | const p7a_len = 7; | |
| 88 | const P7 = packed struct { | |
| 89 | a: [p7a_len]u8, | |
| 90 | b: usize, | |
| 91 | }; | |
| 92 | std.testing.expectEqual(0, @byteOffsetOf(P7, "a")); | |
| 93 | std.testing.expectEqual(p7a_len, @byteOffsetOf(P7, "b")); | |
| 94 | ||
| 95 | const p9a_len = 9; | |
| 96 | const P9 = packed struct { | |
| 97 | a: [p9a_len]u8, | |
| 98 | b: usize, | |
| 99 | }; | |
| 100 | std.testing.expectEqual(0, @byteOffsetOf(P9, "a")); | |
| 101 | std.testing.expectEqual(p9a_len, @byteOffsetOf(P9, "b")); | |
| 102 | ||
| 103 | // 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25 etc. are further cases | |
| 104 | } | |
| 105 | ||
| 106 | test "@bitOffsetOf" { | |
| 107 | // Packed structs have fixed memory layout | |
| 108 | expect(@bitOffsetOf(P, "a") == 0); | |
| 109 | expect(@bitOffsetOf(P, "b") == 8); | |
| 110 | expect(@bitOffsetOf(P, "c") == 40); | |
| 111 | expect(@bitOffsetOf(P, "d") == 48); | |
| 112 | expect(@bitOffsetOf(P, "e") == 51); | |
| 113 | expect(@bitOffsetOf(P, "f") == 56); | |
| 114 | expect(@bitOffsetOf(P, "g") == 72); | |
| 115 | ||
| 116 | expect(@byteOffsetOf(A, "a") * 8 == @bitOffsetOf(A, "a")); | |
| 117 | expect(@byteOffsetOf(A, "b") * 8 == @bitOffsetOf(A, "b")); | |
| 118 | expect(@byteOffsetOf(A, "c") * 8 == @bitOffsetOf(A, "c")); | |
| 119 | expect(@byteOffsetOf(A, "d") * 8 == @bitOffsetOf(A, "d")); | |
| 120 | expect(@byteOffsetOf(A, "e") * 8 == @bitOffsetOf(A, "e")); | |
| 121 | expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f")); | |
| 122 | expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g")); | |
| 123 | } | |
| 124 | ||
| 125 | test "@sizeOf on compile-time types" { | |
| 126 | expect(@sizeOf(comptime_int) == 0); | |
| 127 | expect(@sizeOf(comptime_float) == 0); | |
| 128 | expect(@sizeOf(@TypeOf(.hi)) == 0); | |
| 129 | expect(@sizeOf(@TypeOf(type)) == 0); | |
| 130 | } | |
| 131 | ||
| 132 | test "@sizeOf(T) == 0 doesn't force resolving struct size" { | |
| 133 | const S = struct { | |
| 134 | const Foo = struct { | |
| 135 | y: if (@sizeOf(Foo) == 0) u64 else u32, | |
| 136 | }; | |
| 137 | const Bar = struct { | |
| 138 | x: i32, | |
| 139 | y: if (0 == @sizeOf(Bar)) u64 else u32, | |
| 140 | }; | |
| 141 | }; | |
| 142 | ||
| 143 | expect(@sizeOf(S.Foo) == 4); | |
| 144 | expect(@sizeOf(S.Bar) == 8); | |
| 145 | } | |
| 146 | ||
| 147 | test "@TypeOf() has no runtime side effects" { | |
| 148 | const S = struct { | |
| 149 | fn foo(comptime T: type, ptr: *T) T { | |
| 150 | ptr.* += 1; | |
| 151 | return ptr.*; | |
| 152 | } | |
| 153 | }; | |
| 154 | var data: i32 = 0; | |
| 155 | const T = @TypeOf(S.foo(i32, &data)); | |
| 156 | comptime expect(T == i32); | |
| 157 | expect(data == 0); | |
| 158 | } | |
| 159 | ||
| 160 | test "@TypeOf() with multiple arguments" { | |
| 161 | { | |
| 162 | var var_1: u32 = undefined; | |
| 163 | var var_2: u8 = undefined; | |
| 164 | var var_3: u64 = undefined; | |
| 165 | comptime expect(@TypeOf(var_1, var_2, var_3) == u64); | |
| 166 | } | |
| 167 | { | |
| 168 | var var_1: f16 = undefined; | |
| 169 | var var_2: f32 = undefined; | |
| 170 | var var_3: f64 = undefined; | |
| 171 | comptime expect(@TypeOf(var_1, var_2, var_3) == f64); | |
| 172 | } | |
| 173 | { | |
| 174 | var var_1: u16 = undefined; | |
| 175 | comptime expect(@TypeOf(var_1, 0xffff) == u16); | |
| 176 | } | |
| 177 | { | |
| 178 | var var_1: f32 = undefined; | |
| 179 | comptime expect(@TypeOf(var_1, 3.1415) == f32); | |
| 180 | } | |
| 181 | } | |
| 182 | ||
| 183 | test "branching logic inside @TypeOf" { | |
| 184 | const S = struct { | |
| 185 | var data: i32 = 0; | |
| 186 | fn foo() anyerror!i32 { | |
| 187 | data += 1; | |
| 188 | return undefined; | |
| 189 | } | |
| 190 | }; | |
| 191 | const T = @TypeOf(S.foo() catch undefined); | |
| 192 | comptime expect(T == i32); | |
| 193 | expect(S.data == 0); | |
| 194 | } | |
| 195 | ||
| 196 | fn fn1(alpha: bool) void { | |
| 197 | const n: usize = 7; | |
| 198 | const v = if (alpha) n else @sizeOf(usize); | |
| 199 | } | |
| 200 | ||
| 201 | test "lazy @sizeOf result is checked for definedness" { | |
| 202 | const f = fn1; | |
| 203 | } | |
| 204 | ||
| 205 | test "@bitSizeOf" { | |
| 206 | expect(@bitSizeOf(u2) == 2); | |
| 207 | expect(@bitSizeOf(u8) == @sizeOf(u8) * 8); | |
| 208 | expect(@bitSizeOf(struct { | |
| 209 | a: u2, | |
| 210 | }) == 8); | |
| 211 | expect(@bitSizeOf(packed struct { | |
| 212 | a: u2, | |
| 213 | }) == 2); | |
| 214 | } | |
| 215 | ||
| 216 | test "@sizeOf comparison against zero" { | |
| 217 | const S0 = struct { | |
| 218 | f: *@This(), | |
| 219 | }; | |
| 220 | const U0 = union { | |
| 221 | f: *@This(), | |
| 222 | }; | |
| 223 | const S1 = struct { | |
| 224 | fn H(comptime T: type) type { | |
| 225 | return struct { | |
| 226 | x: T, | |
| 227 | }; | |
| 228 | } | |
| 229 | f0: H(*@This()), | |
| 230 | f1: H(**@This()), | |
| 231 | f2: H(***@This()), | |
| 232 | }; | |
| 233 | const U1 = union { | |
| 234 | fn H(comptime T: type) type { | |
| 235 | return struct { | |
| 236 | x: T, | |
| 237 | }; | |
| 238 | } | |
| 239 | f0: H(*@This()), | |
| 240 | f1: H(**@This()), | |
| 241 | f2: H(***@This()), | |
| 242 | }; | |
| 243 | const S = struct { | |
| 244 | fn doTheTest(comptime T: type, comptime result: bool) void { | |
| 245 | expectEqual(result, @sizeOf(T) > 0); | |
| 246 | } | |
| 247 | }; | |
| 248 | // Zero-sized type | |
| 249 | S.doTheTest(u0, false); | |
| 250 | S.doTheTest(*u0, false); | |
| 251 | // Non byte-sized type | |
| 252 | S.doTheTest(u1, true); | |
| 253 | S.doTheTest(*u1, true); | |
| 254 | // Regular type | |
| 255 | S.doTheTest(u8, true); | |
| 256 | S.doTheTest(*u8, true); | |
| 257 | S.doTheTest(f32, true); | |
| 258 | S.doTheTest(*f32, true); | |
| 259 | // Container with ptr pointing to themselves | |
| 260 | S.doTheTest(S0, true); | |
| 261 | S.doTheTest(U0, true); | |
| 262 | S.doTheTest(S1, true); | |
| 263 | S.doTheTest(U1, true); | |
| 264 | } |
test/behavior/slice.zig created+337| ... | ... | @@ -0,0 +1,337 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const mem = std.mem; | |
| 6 | ||
| 7 | const x = @intToPtr([*]i32, 0x1000)[0..0x500]; | |
| 8 | const y = x[0x100..]; | |
| 9 | test "compile time slice of pointer to hard coded address" { | |
| 10 | expect(@ptrToInt(x) == 0x1000); | |
| 11 | expect(x.len == 0x500); | |
| 12 | ||
| 13 | expect(@ptrToInt(y) == 0x1100); | |
| 14 | expect(y.len == 0x400); | |
| 15 | } | |
| 16 | ||
| 17 | test "runtime safety lets us slice from len..len" { | |
| 18 | var an_array = [_]u8{ | |
| 19 | 1, | |
| 20 | 2, | |
| 21 | 3, | |
| 22 | }; | |
| 23 | expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), "")); | |
| 24 | } | |
| 25 | ||
| 26 | fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { | |
| 27 | return a_slice[start..end]; | |
| 28 | } | |
| 29 | ||
| 30 | test "implicitly cast array of size 0 to slice" { | |
| 31 | var msg = [_]u8{}; | |
| 32 | assertLenIsZero(&msg); | |
| 33 | } | |
| 34 | ||
| 35 | fn assertLenIsZero(msg: []const u8) void { | |
| 36 | expect(msg.len == 0); | |
| 37 | } | |
| 38 | ||
| 39 | test "C pointer" { | |
| 40 | var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; | |
| 41 | var len: u32 = 10; | |
| 42 | var slice = buf[0..len]; | |
| 43 | expectEqualSlices(u8, "kjdhfkjdhf", slice); | |
| 44 | } | |
| 45 | ||
| 46 | test "C pointer slice access" { | |
| 47 | var buf: [10]u32 = [1]u32{42} ** 10; | |
| 48 | const c_ptr = @ptrCast([*c]const u32, &buf); | |
| 49 | ||
| 50 | var runtime_zero: usize = 0; | |
| 51 | comptime expectEqual([]const u32, @TypeOf(c_ptr[runtime_zero..1])); | |
| 52 | comptime expectEqual(*const [1]u32, @TypeOf(c_ptr[0..1])); | |
| 53 | ||
| 54 | for (c_ptr[0..5]) |*cl| { | |
| 55 | expectEqual(@as(u32, 42), cl.*); | |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | fn sliceSum(comptime q: []const u8) i32 { | |
| 60 | comptime var result = 0; | |
| 61 | inline for (q) |item| { | |
| 62 | result += item; | |
| 63 | } | |
| 64 | return result; | |
| 65 | } | |
| 66 | ||
| 67 | test "comptime slices are disambiguated" { | |
| 68 | expect(sliceSum(&[_]u8{ 1, 2 }) == 3); | |
| 69 | expect(sliceSum(&[_]u8{ 3, 4 }) == 7); | |
| 70 | } | |
| 71 | ||
| 72 | test "slice type with custom alignment" { | |
| 73 | const LazilyResolvedType = struct { | |
| 74 | anything: i32, | |
| 75 | }; | |
| 76 | var slice: []align(32) LazilyResolvedType = undefined; | |
| 77 | var array: [10]LazilyResolvedType align(32) = undefined; | |
| 78 | slice = &array; | |
| 79 | slice[1].anything = 42; | |
| 80 | expect(array[1].anything == 42); | |
| 81 | } | |
| 82 | ||
| 83 | test "access len index of sentinel-terminated slice" { | |
| 84 | const S = struct { | |
| 85 | fn doTheTest() void { | |
| 86 | var slice: [:0]const u8 = "hello"; | |
| 87 | ||
| 88 | expect(slice.len == 5); | |
| 89 | expect(slice[5] == 0); | |
| 90 | } | |
| 91 | }; | |
| 92 | S.doTheTest(); | |
| 93 | comptime S.doTheTest(); | |
| 94 | } | |
| 95 | ||
| 96 | test "obtaining a null terminated slice" { | |
| 97 | // here we have a normal array | |
| 98 | var buf: [50]u8 = undefined; | |
| 99 | ||
| 100 | buf[0] = 'a'; | |
| 101 | buf[1] = 'b'; | |
| 102 | buf[2] = 'c'; | |
| 103 | buf[3] = 0; | |
| 104 | ||
| 105 | // now we obtain a null terminated slice: | |
| 106 | const ptr = buf[0..3 :0]; | |
| 107 | ||
| 108 | var runtime_len: usize = 3; | |
| 109 | const ptr2 = buf[0..runtime_len :0]; | |
| 110 | // ptr2 is a null-terminated slice | |
| 111 | comptime expect(@TypeOf(ptr2) == [:0]u8); | |
| 112 | comptime expect(@TypeOf(ptr2[0..2]) == *[2]u8); | |
| 113 | var runtime_zero: usize = 0; | |
| 114 | comptime expect(@TypeOf(ptr2[runtime_zero..2]) == []u8); | |
| 115 | } | |
| 116 | ||
| 117 | test "empty array to slice" { | |
| 118 | const S = struct { | |
| 119 | fn doTheTest() void { | |
| 120 | const empty: []align(16) u8 = &[_]u8{}; | |
| 121 | const align_1: []align(1) u8 = empty; | |
| 122 | const align_4: []align(4) u8 = empty; | |
| 123 | const align_16: []align(16) u8 = empty; | |
| 124 | expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment); | |
| 125 | expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment); | |
| 126 | expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment); | |
| 127 | } | |
| 128 | }; | |
| 129 | ||
| 130 | S.doTheTest(); | |
| 131 | comptime S.doTheTest(); | |
| 132 | } | |
| 133 | ||
| 134 | test "@ptrCast slice to pointer" { | |
| 135 | const S = struct { | |
| 136 | fn doTheTest() void { | |
| 137 | var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff }; | |
| 138 | var slice: []u8 = &array; | |
| 139 | var ptr = @ptrCast(*u16, slice); | |
| 140 | expect(ptr.* == 65535); | |
| 141 | } | |
| 142 | }; | |
| 143 | ||
| 144 | S.doTheTest(); | |
| 145 | comptime S.doTheTest(); | |
| 146 | } | |
| 147 | ||
| 148 | test "slice syntax resulting in pointer-to-array" { | |
| 149 | const S = struct { | |
| 150 | fn doTheTest() void { | |
| 151 | testArray(); | |
| 152 | testArrayZ(); | |
| 153 | testArray0(); | |
| 154 | testArrayAlign(); | |
| 155 | testPointer(); | |
| 156 | testPointerZ(); | |
| 157 | testPointer0(); | |
| 158 | testPointerAlign(); | |
| 159 | testSlice(); | |
| 160 | testSliceZ(); | |
| 161 | testSlice0(); | |
| 162 | testSliceOpt(); | |
| 163 | testSliceAlign(); | |
| 164 | } | |
| 165 | ||
| 166 | fn testArray() void { | |
| 167 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 168 | var slice = array[1..3]; | |
| 169 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 170 | expect(slice[0] == 2); | |
| 171 | expect(slice[1] == 3); | |
| 172 | } | |
| 173 | ||
| 174 | fn testArrayZ() void { | |
| 175 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 176 | comptime expect(@TypeOf(array[1..3]) == *[2]u8); | |
| 177 | comptime expect(@TypeOf(array[1..5]) == *[4:0]u8); | |
| 178 | comptime expect(@TypeOf(array[1..]) == *[4:0]u8); | |
| 179 | comptime expect(@TypeOf(array[1..3 :4]) == *[2:4]u8); | |
| 180 | } | |
| 181 | ||
| 182 | fn testArray0() void { | |
| 183 | { | |
| 184 | var array = [0]u8{}; | |
| 185 | var slice = array[0..0]; | |
| 186 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 187 | } | |
| 188 | { | |
| 189 | var array = [0:0]u8{}; | |
| 190 | var slice = array[0..0]; | |
| 191 | comptime expect(@TypeOf(slice) == *[0:0]u8); | |
| 192 | expect(slice[0] == 0); | |
| 193 | } | |
| 194 | } | |
| 195 | ||
| 196 | fn testArrayAlign() void { | |
| 197 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 198 | var slice = array[4..5]; | |
| 199 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 200 | expect(slice[0] == 5); | |
| 201 | comptime expect(@TypeOf(array[0..2]) == *align(4) [2]u8); | |
| 202 | } | |
| 203 | ||
| 204 | fn testPointer() void { | |
| 205 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 206 | var pointer: [*]u8 = &array; | |
| 207 | var slice = pointer[1..3]; | |
| 208 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 209 | expect(slice[0] == 2); | |
| 210 | expect(slice[1] == 3); | |
| 211 | } | |
| 212 | ||
| 213 | fn testPointerZ() void { | |
| 214 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 215 | var pointer: [*:0]u8 = &array; | |
| 216 | comptime expect(@TypeOf(pointer[1..3]) == *[2]u8); | |
| 217 | comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8); | |
| 218 | } | |
| 219 | ||
| 220 | fn testPointer0() void { | |
| 221 | var pointer: [*]const u0 = &[1]u0{0}; | |
| 222 | var slice = pointer[0..1]; | |
| 223 | comptime expect(@TypeOf(slice) == *const [1]u0); | |
| 224 | expect(slice[0] == 0); | |
| 225 | } | |
| 226 | ||
| 227 | fn testPointerAlign() void { | |
| 228 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 229 | var pointer: [*]align(4) u8 = &array; | |
| 230 | var slice = pointer[4..5]; | |
| 231 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 232 | expect(slice[0] == 5); | |
| 233 | comptime expect(@TypeOf(pointer[0..2]) == *align(4) [2]u8); | |
| 234 | } | |
| 235 | ||
| 236 | fn testSlice() void { | |
| 237 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 238 | var src_slice: []u8 = &array; | |
| 239 | var slice = src_slice[1..3]; | |
| 240 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 241 | expect(slice[0] == 2); | |
| 242 | expect(slice[1] == 3); | |
| 243 | } | |
| 244 | ||
| 245 | fn testSliceZ() void { | |
| 246 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 247 | var slice: [:0]u8 = &array; | |
| 248 | comptime expect(@TypeOf(slice[1..3]) == *[2]u8); | |
| 249 | comptime expect(@TypeOf(slice[1..]) == [:0]u8); | |
| 250 | comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8); | |
| 251 | } | |
| 252 | ||
| 253 | fn testSliceOpt() void { | |
| 254 | var array: [2]u8 = [2]u8{ 1, 2 }; | |
| 255 | var slice: ?[]u8 = &array; | |
| 256 | comptime expect(@TypeOf(&array, slice) == ?[]u8); | |
| 257 | comptime expect(@TypeOf(slice.?[0..2]) == *[2]u8); | |
| 258 | } | |
| 259 | ||
| 260 | fn testSlice0() void { | |
| 261 | { | |
| 262 | var array = [0]u8{}; | |
| 263 | var src_slice: []u8 = &array; | |
| 264 | var slice = src_slice[0..0]; | |
| 265 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 266 | } | |
| 267 | { | |
| 268 | var array = [0:0]u8{}; | |
| 269 | var src_slice: [:0]u8 = &array; | |
| 270 | var slice = src_slice[0..0]; | |
| 271 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 272 | } | |
| 273 | } | |
| 274 | ||
| 275 | fn testSliceAlign() void { | |
| 276 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 277 | var src_slice: []align(4) u8 = &array; | |
| 278 | var slice = src_slice[4..5]; | |
| 279 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 280 | expect(slice[0] == 5); | |
| 281 | comptime expect(@TypeOf(src_slice[0..2]) == *align(4) [2]u8); | |
| 282 | } | |
| 283 | ||
| 284 | fn testConcatStrLiterals() void { | |
| 285 | expectEqualSlices("a"[0..] ++ "b"[0..], "ab"); | |
| 286 | expectEqualSlices("a"[0..:0] ++ "b"[0..:0], "ab"); | |
| 287 | } | |
| 288 | }; | |
| 289 | ||
| 290 | S.doTheTest(); | |
| 291 | comptime S.doTheTest(); | |
| 292 | } | |
| 293 | ||
| 294 | test "slice of hardcoded address to pointer" { | |
| 295 | const S = struct { | |
| 296 | fn doTheTest() void { | |
| 297 | const pointer = @intToPtr([*]u8, 0x04)[0..2]; | |
| 298 | comptime expect(@TypeOf(pointer) == *[2]u8); | |
| 299 | const slice: []const u8 = pointer; | |
| 300 | expect(@ptrToInt(slice.ptr) == 4); | |
| 301 | expect(slice.len == 2); | |
| 302 | } | |
| 303 | }; | |
| 304 | ||
| 305 | S.doTheTest(); | |
| 306 | } | |
| 307 | ||
| 308 | test "type coercion of pointer to anon struct literal to pointer to slice" { | |
| 309 | const S = struct { | |
| 310 | const U = union{ | |
| 311 | a: u32, | |
| 312 | b: bool, | |
| 313 | c: []const u8, | |
| 314 | }; | |
| 315 | ||
| 316 | fn doTheTest() void { | |
| 317 | var x1: u8 = 42; | |
| 318 | const t1 = &.{ x1, 56, 54 }; | |
| 319 | var slice1: []const u8 = t1; | |
| 320 | expect(slice1.len == 3); | |
| 321 | expect(slice1[0] == 42); | |
| 322 | expect(slice1[1] == 56); | |
| 323 | expect(slice1[2] == 54); | |
| 324 | ||
| 325 | var x2: []const u8 = "hello"; | |
| 326 | const t2 = &.{ x2, ", ", "world!" }; | |
| 327 | // @compileLog(@TypeOf(t2)); | |
| 328 | var slice2: []const []const u8 = t2; | |
| 329 | expect(slice2.len == 3); | |
| 330 | expect(mem.eql(u8, slice2[0], "hello")); | |
| 331 | expect(mem.eql(u8, slice2[1], ", ")); | |
| 332 | expect(mem.eql(u8, slice2[2], "world!")); | |
| 333 | } | |
| 334 | }; | |
| 335 | // S.doTheTest(); | |
| 336 | comptime S.doTheTest(); | |
| 337 | } |
test/behavior/slice_sentinel_comptime.zig created+199| ... | ... | @@ -0,0 +1,199 @@ |
| 1 | test "comptime slice-sentinel in bounds (unterminated)" { | |
| 2 | // array | |
| 3 | comptime { | |
| 4 | var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 5 | const slice = target[0..3 :'d']; | |
| 6 | } | |
| 7 | ||
| 8 | // ptr_array | |
| 9 | comptime { | |
| 10 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 11 | var target = &buf; | |
| 12 | const slice = target[0..3 :'d']; | |
| 13 | } | |
| 14 | ||
| 15 | // vector_ConstPtrSpecialBaseArray | |
| 16 | comptime { | |
| 17 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 18 | var target: [*]u8 = &buf; | |
| 19 | const slice = target[0..3 :'d']; | |
| 20 | } | |
| 21 | ||
| 22 | // vector_ConstPtrSpecialRef | |
| 23 | comptime { | |
| 24 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 25 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 26 | const slice = target[0..3 :'d']; | |
| 27 | } | |
| 28 | ||
| 29 | // cvector_ConstPtrSpecialBaseArray | |
| 30 | comptime { | |
| 31 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 32 | var target: [*c]u8 = &buf; | |
| 33 | const slice = target[0..3 :'d']; | |
| 34 | } | |
| 35 | ||
| 36 | // cvector_ConstPtrSpecialRef | |
| 37 | comptime { | |
| 38 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 39 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 40 | const slice = target[0..3 :'d']; | |
| 41 | } | |
| 42 | ||
| 43 | // slice | |
| 44 | comptime { | |
| 45 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 46 | var target: []u8 = &buf; | |
| 47 | const slice = target[0..3 :'d']; | |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 51 | test "comptime slice-sentinel in bounds (end,unterminated)" { | |
| 52 | // array | |
| 53 | comptime { | |
| 54 | var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 55 | const slice = target[0..13 :0xff]; | |
| 56 | } | |
| 57 | ||
| 58 | // ptr_array | |
| 59 | comptime { | |
| 60 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 61 | var target = &buf; | |
| 62 | const slice = target[0..13 :0xff]; | |
| 63 | } | |
| 64 | ||
| 65 | // vector_ConstPtrSpecialBaseArray | |
| 66 | comptime { | |
| 67 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 68 | var target: [*]u8 = &buf; | |
| 69 | const slice = target[0..13 :0xff]; | |
| 70 | } | |
| 71 | ||
| 72 | // vector_ConstPtrSpecialRef | |
| 73 | comptime { | |
| 74 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 75 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 76 | const slice = target[0..13 :0xff]; | |
| 77 | } | |
| 78 | ||
| 79 | // cvector_ConstPtrSpecialBaseArray | |
| 80 | comptime { | |
| 81 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 82 | var target: [*c]u8 = &buf; | |
| 83 | const slice = target[0..13 :0xff]; | |
| 84 | } | |
| 85 | ||
| 86 | // cvector_ConstPtrSpecialRef | |
| 87 | comptime { | |
| 88 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 89 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 90 | const slice = target[0..13 :0xff]; | |
| 91 | } | |
| 92 | ||
| 93 | // slice | |
| 94 | comptime { | |
| 95 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 96 | var target: []u8 = &buf; | |
| 97 | const slice = target[0..13 :0xff]; | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | test "comptime slice-sentinel in bounds (terminated)" { | |
| 102 | // array | |
| 103 | comptime { | |
| 104 | var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 105 | const slice = target[0..3 :'d']; | |
| 106 | } | |
| 107 | ||
| 108 | // ptr_array | |
| 109 | comptime { | |
| 110 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 111 | var target = &buf; | |
| 112 | const slice = target[0..3 :'d']; | |
| 113 | } | |
| 114 | ||
| 115 | // vector_ConstPtrSpecialBaseArray | |
| 116 | comptime { | |
| 117 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 118 | var target: [*]u8 = &buf; | |
| 119 | const slice = target[0..3 :'d']; | |
| 120 | } | |
| 121 | ||
| 122 | // vector_ConstPtrSpecialRef | |
| 123 | comptime { | |
| 124 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 125 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 126 | const slice = target[0..3 :'d']; | |
| 127 | } | |
| 128 | ||
| 129 | // cvector_ConstPtrSpecialBaseArray | |
| 130 | comptime { | |
| 131 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 132 | var target: [*c]u8 = &buf; | |
| 133 | const slice = target[0..3 :'d']; | |
| 134 | } | |
| 135 | ||
| 136 | // cvector_ConstPtrSpecialRef | |
| 137 | comptime { | |
| 138 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 139 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 140 | const slice = target[0..3 :'d']; | |
| 141 | } | |
| 142 | ||
| 143 | // slice | |
| 144 | comptime { | |
| 145 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 146 | var target: []u8 = &buf; | |
| 147 | const slice = target[0..3 :'d']; | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | test "comptime slice-sentinel in bounds (on target sentinel)" { | |
| 152 | // array | |
| 153 | comptime { | |
| 154 | var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 155 | const slice = target[0..14 :0]; | |
| 156 | } | |
| 157 | ||
| 158 | // ptr_array | |
| 159 | comptime { | |
| 160 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 161 | var target = &buf; | |
| 162 | const slice = target[0..14 :0]; | |
| 163 | } | |
| 164 | ||
| 165 | // vector_ConstPtrSpecialBaseArray | |
| 166 | comptime { | |
| 167 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 168 | var target: [*]u8 = &buf; | |
| 169 | const slice = target[0..14 :0]; | |
| 170 | } | |
| 171 | ||
| 172 | // vector_ConstPtrSpecialRef | |
| 173 | comptime { | |
| 174 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 175 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 176 | const slice = target[0..14 :0]; | |
| 177 | } | |
| 178 | ||
| 179 | // cvector_ConstPtrSpecialBaseArray | |
| 180 | comptime { | |
| 181 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 182 | var target: [*c]u8 = &buf; | |
| 183 | const slice = target[0..14 :0]; | |
| 184 | } | |
| 185 | ||
| 186 | // cvector_ConstPtrSpecialRef | |
| 187 | comptime { | |
| 188 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 189 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 190 | const slice = target[0..14 :0]; | |
| 191 | } | |
| 192 | ||
| 193 | // slice | |
| 194 | comptime { | |
| 195 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 196 | var target: []u8 = &buf; | |
| 197 | const slice = target[0..14 :0]; | |
| 198 | } | |
| 199 | } |
test/behavior/src.zig created+17| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@src" { | |
| 5 | doTheTest(); | |
| 6 | } | |
| 7 | ||
| 8 | fn doTheTest() void { | |
| 9 | const src = @src(); | |
| 10 | ||
| 11 | expect(src.line == 9); | |
| 12 | expect(src.column == 17); | |
| 13 | expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); | |
| 14 | expect(std.mem.endsWith(u8, src.file, "src.zig")); | |
| 15 | expect(src.fn_name[src.fn_name.len] == 0); | |
| 16 | expect(src.file[src.file.len] == 0); | |
| 17 | } |
test/behavior/struct.zig created+945| ... | ... | @@ -0,0 +1,945 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 4 | const expect = std.testing.expect; | |
| 5 | const expectEqual = std.testing.expectEqual; | |
| 6 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 7 | const maxInt = std.math.maxInt; | |
| 8 | const StructWithNoFields = struct { | |
| 9 | fn add(a: i32, b: i32) i32 { | |
| 10 | return a + b; | |
| 11 | } | |
| 12 | }; | |
| 13 | const empty_global_instance = StructWithNoFields{}; | |
| 14 | ||
| 15 | top_level_field: i32, | |
| 16 | ||
| 17 | test "top level fields" { | |
| 18 | var instance = @This(){ | |
| 19 | .top_level_field = 1234, | |
| 20 | }; | |
| 21 | instance.top_level_field += 1; | |
| 22 | expectEqual(@as(i32, 1235), instance.top_level_field); | |
| 23 | } | |
| 24 | ||
| 25 | test "call struct static method" { | |
| 26 | const result = StructWithNoFields.add(3, 4); | |
| 27 | expect(result == 7); | |
| 28 | } | |
| 29 | ||
| 30 | test "return empty struct instance" { | |
| 31 | _ = returnEmptyStructInstance(); | |
| 32 | } | |
| 33 | fn returnEmptyStructInstance() StructWithNoFields { | |
| 34 | return empty_global_instance; | |
| 35 | } | |
| 36 | ||
| 37 | const should_be_11 = StructWithNoFields.add(5, 6); | |
| 38 | ||
| 39 | test "invoke static method in global scope" { | |
| 40 | expect(should_be_11 == 11); | |
| 41 | } | |
| 42 | ||
| 43 | test "void struct fields" { | |
| 44 | const foo = VoidStructFieldsFoo{ | |
| 45 | .a = void{}, | |
| 46 | .b = 1, | |
| 47 | .c = void{}, | |
| 48 | }; | |
| 49 | expect(foo.b == 1); | |
| 50 | expect(@sizeOf(VoidStructFieldsFoo) == 4); | |
| 51 | } | |
| 52 | const VoidStructFieldsFoo = struct { | |
| 53 | a: void, | |
| 54 | b: i32, | |
| 55 | c: void, | |
| 56 | }; | |
| 57 | ||
| 58 | test "structs" { | |
| 59 | var foo: StructFoo = undefined; | |
| 60 | @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); | |
| 61 | foo.a += 1; | |
| 62 | foo.b = foo.a == 1; | |
| 63 | testFoo(foo); | |
| 64 | testMutation(&foo); | |
| 65 | expect(foo.c == 100); | |
| 66 | } | |
| 67 | const StructFoo = struct { | |
| 68 | a: i32, | |
| 69 | b: bool, | |
| 70 | c: f32, | |
| 71 | }; | |
| 72 | fn testFoo(foo: StructFoo) void { | |
| 73 | expect(foo.b); | |
| 74 | } | |
| 75 | fn testMutation(foo: *StructFoo) void { | |
| 76 | foo.c = 100; | |
| 77 | } | |
| 78 | ||
| 79 | const Node = struct { | |
| 80 | val: Val, | |
| 81 | next: *Node, | |
| 82 | }; | |
| 83 | ||
| 84 | const Val = struct { | |
| 85 | x: i32, | |
| 86 | }; | |
| 87 | ||
| 88 | test "struct point to self" { | |
| 89 | var root: Node = undefined; | |
| 90 | root.val.x = 1; | |
| 91 | ||
| 92 | var node: Node = undefined; | |
| 93 | node.next = &root; | |
| 94 | node.val.x = 2; | |
| 95 | ||
| 96 | root.next = &node; | |
| 97 | ||
| 98 | expect(node.next.next.next.val.x == 1); | |
| 99 | } | |
| 100 | ||
| 101 | test "struct byval assign" { | |
| 102 | var foo1: StructFoo = undefined; | |
| 103 | var foo2: StructFoo = undefined; | |
| 104 | ||
| 105 | foo1.a = 1234; | |
| 106 | foo2.a = 0; | |
| 107 | expect(foo2.a == 0); | |
| 108 | foo2 = foo1; | |
| 109 | expect(foo2.a == 1234); | |
| 110 | } | |
| 111 | ||
| 112 | fn structInitializer() void { | |
| 113 | const val = Val{ .x = 42 }; | |
| 114 | expect(val.x == 42); | |
| 115 | } | |
| 116 | ||
| 117 | test "fn call of struct field" { | |
| 118 | const Foo = struct { | |
| 119 | ptr: fn () i32, | |
| 120 | }; | |
| 121 | const S = struct { | |
| 122 | fn aFunc() i32 { | |
| 123 | return 13; | |
| 124 | } | |
| 125 | ||
| 126 | fn callStructField(foo: Foo) i32 { | |
| 127 | return foo.ptr(); | |
| 128 | } | |
| 129 | }; | |
| 130 | ||
| 131 | expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13); | |
| 132 | } | |
| 133 | ||
| 134 | test "store member function in variable" { | |
| 135 | const instance = MemberFnTestFoo{ .x = 1234 }; | |
| 136 | const memberFn = MemberFnTestFoo.member; | |
| 137 | const result = memberFn(instance); | |
| 138 | expect(result == 1234); | |
| 139 | } | |
| 140 | const MemberFnTestFoo = struct { | |
| 141 | x: i32, | |
| 142 | fn member(foo: MemberFnTestFoo) i32 { | |
| 143 | return foo.x; | |
| 144 | } | |
| 145 | }; | |
| 146 | ||
| 147 | test "call member function directly" { | |
| 148 | const instance = MemberFnTestFoo{ .x = 1234 }; | |
| 149 | const result = MemberFnTestFoo.member(instance); | |
| 150 | expect(result == 1234); | |
| 151 | } | |
| 152 | ||
| 153 | test "member functions" { | |
| 154 | const r = MemberFnRand{ .seed = 1234 }; | |
| 155 | expect(r.getSeed() == 1234); | |
| 156 | } | |
| 157 | const MemberFnRand = struct { | |
| 158 | seed: u32, | |
| 159 | pub fn getSeed(r: *const MemberFnRand) u32 { | |
| 160 | return r.seed; | |
| 161 | } | |
| 162 | }; | |
| 163 | ||
| 164 | test "return struct byval from function" { | |
| 165 | const bar = makeBar(1234, 5678); | |
| 166 | expect(bar.y == 5678); | |
| 167 | } | |
| 168 | const Bar = struct { | |
| 169 | x: i32, | |
| 170 | y: i32, | |
| 171 | }; | |
| 172 | fn makeBar(x: i32, y: i32) Bar { | |
| 173 | return Bar{ | |
| 174 | .x = x, | |
| 175 | .y = y, | |
| 176 | }; | |
| 177 | } | |
| 178 | ||
| 179 | test "empty struct method call" { | |
| 180 | const es = EmptyStruct{}; | |
| 181 | expect(es.method() == 1234); | |
| 182 | } | |
| 183 | const EmptyStruct = struct { | |
| 184 | fn method(es: *const EmptyStruct) i32 { | |
| 185 | return 1234; | |
| 186 | } | |
| 187 | }; | |
| 188 | ||
| 189 | test "return empty struct from fn" { | |
| 190 | _ = testReturnEmptyStructFromFn(); | |
| 191 | } | |
| 192 | const EmptyStruct2 = struct {}; | |
| 193 | fn testReturnEmptyStructFromFn() EmptyStruct2 { | |
| 194 | return EmptyStruct2{}; | |
| 195 | } | |
| 196 | ||
| 197 | test "pass slice of empty struct to fn" { | |
| 198 | expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); | |
| 199 | } | |
| 200 | fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { | |
| 201 | return slice.len; | |
| 202 | } | |
| 203 | ||
| 204 | const APackedStruct = packed struct { | |
| 205 | x: u8, | |
| 206 | y: u8, | |
| 207 | }; | |
| 208 | ||
| 209 | test "packed struct" { | |
| 210 | var foo = APackedStruct{ | |
| 211 | .x = 1, | |
| 212 | .y = 2, | |
| 213 | }; | |
| 214 | foo.y += 1; | |
| 215 | const four = foo.x + foo.y; | |
| 216 | expect(four == 4); | |
| 217 | } | |
| 218 | ||
| 219 | const BitField1 = packed struct { | |
| 220 | a: u3, | |
| 221 | b: u3, | |
| 222 | c: u2, | |
| 223 | }; | |
| 224 | ||
| 225 | const bit_field_1 = BitField1{ | |
| 226 | .a = 1, | |
| 227 | .b = 2, | |
| 228 | .c = 3, | |
| 229 | }; | |
| 230 | ||
| 231 | test "bit field access" { | |
| 232 | var data = bit_field_1; | |
| 233 | expect(getA(&data) == 1); | |
| 234 | expect(getB(&data) == 2); | |
| 235 | expect(getC(&data) == 3); | |
| 236 | comptime expect(@sizeOf(BitField1) == 1); | |
| 237 | ||
| 238 | data.b += 1; | |
| 239 | expect(data.b == 3); | |
| 240 | ||
| 241 | data.a += 1; | |
| 242 | expect(data.a == 2); | |
| 243 | expect(data.b == 3); | |
| 244 | } | |
| 245 | ||
| 246 | fn getA(data: *const BitField1) u3 { | |
| 247 | return data.a; | |
| 248 | } | |
| 249 | ||
| 250 | fn getB(data: *const BitField1) u3 { | |
| 251 | return data.b; | |
| 252 | } | |
| 253 | ||
| 254 | fn getC(data: *const BitField1) u2 { | |
| 255 | return data.c; | |
| 256 | } | |
| 257 | ||
| 258 | const Foo24Bits = packed struct { | |
| 259 | field: u24, | |
| 260 | }; | |
| 261 | const Foo96Bits = packed struct { | |
| 262 | a: u24, | |
| 263 | b: u24, | |
| 264 | c: u24, | |
| 265 | d: u24, | |
| 266 | }; | |
| 267 | ||
| 268 | test "packed struct 24bits" { | |
| 269 | comptime { | |
| 270 | expect(@sizeOf(Foo24Bits) == 4); | |
| 271 | if (@sizeOf(usize) == 4) { | |
| 272 | expect(@sizeOf(Foo96Bits) == 12); | |
| 273 | } else { | |
| 274 | expect(@sizeOf(Foo96Bits) == 16); | |
| 275 | } | |
| 276 | } | |
| 277 | ||
| 278 | var value = Foo96Bits{ | |
| 279 | .a = 0, | |
| 280 | .b = 0, | |
| 281 | .c = 0, | |
| 282 | .d = 0, | |
| 283 | }; | |
| 284 | value.a += 1; | |
| 285 | expect(value.a == 1); | |
| 286 | expect(value.b == 0); | |
| 287 | expect(value.c == 0); | |
| 288 | expect(value.d == 0); | |
| 289 | ||
| 290 | value.b += 1; | |
| 291 | expect(value.a == 1); | |
| 292 | expect(value.b == 1); | |
| 293 | expect(value.c == 0); | |
| 294 | expect(value.d == 0); | |
| 295 | ||
| 296 | value.c += 1; | |
| 297 | expect(value.a == 1); | |
| 298 | expect(value.b == 1); | |
| 299 | expect(value.c == 1); | |
| 300 | expect(value.d == 0); | |
| 301 | ||
| 302 | value.d += 1; | |
| 303 | expect(value.a == 1); | |
| 304 | expect(value.b == 1); | |
| 305 | expect(value.c == 1); | |
| 306 | expect(value.d == 1); | |
| 307 | } | |
| 308 | ||
| 309 | const Foo32Bits = packed struct { | |
| 310 | field: u24, | |
| 311 | pad: u8, | |
| 312 | }; | |
| 313 | ||
| 314 | const FooArray24Bits = packed struct { | |
| 315 | a: u16, | |
| 316 | b: [2]Foo32Bits, | |
| 317 | c: u16, | |
| 318 | }; | |
| 319 | ||
| 320 | // TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512 | |
| 321 | test "packed array 24bits" { | |
| 322 | comptime { | |
| 323 | expect(@sizeOf([9]Foo32Bits) == 9 * 4); | |
| 324 | expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2); | |
| 325 | } | |
| 326 | ||
| 327 | var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); | |
| 328 | bytes[bytes.len - 1] = 0xaa; | |
| 329 | const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; | |
| 330 | expect(ptr.a == 0); | |
| 331 | expect(ptr.b[0].field == 0); | |
| 332 | expect(ptr.b[1].field == 0); | |
| 333 | expect(ptr.c == 0); | |
| 334 | ||
| 335 | ptr.a = maxInt(u16); | |
| 336 | expect(ptr.a == maxInt(u16)); | |
| 337 | expect(ptr.b[0].field == 0); | |
| 338 | expect(ptr.b[1].field == 0); | |
| 339 | expect(ptr.c == 0); | |
| 340 | ||
| 341 | ptr.b[0].field = maxInt(u24); | |
| 342 | expect(ptr.a == maxInt(u16)); | |
| 343 | expect(ptr.b[0].field == maxInt(u24)); | |
| 344 | expect(ptr.b[1].field == 0); | |
| 345 | expect(ptr.c == 0); | |
| 346 | ||
| 347 | ptr.b[1].field = maxInt(u24); | |
| 348 | expect(ptr.a == maxInt(u16)); | |
| 349 | expect(ptr.b[0].field == maxInt(u24)); | |
| 350 | expect(ptr.b[1].field == maxInt(u24)); | |
| 351 | expect(ptr.c == 0); | |
| 352 | ||
| 353 | ptr.c = maxInt(u16); | |
| 354 | expect(ptr.a == maxInt(u16)); | |
| 355 | expect(ptr.b[0].field == maxInt(u24)); | |
| 356 | expect(ptr.b[1].field == maxInt(u24)); | |
| 357 | expect(ptr.c == maxInt(u16)); | |
| 358 | ||
| 359 | expect(bytes[bytes.len - 1] == 0xaa); | |
| 360 | } | |
| 361 | ||
| 362 | const FooStructAligned = packed struct { | |
| 363 | a: u8, | |
| 364 | b: u8, | |
| 365 | }; | |
| 366 | ||
| 367 | const FooArrayOfAligned = packed struct { | |
| 368 | a: [2]FooStructAligned, | |
| 369 | }; | |
| 370 | ||
| 371 | test "aligned array of packed struct" { | |
| 372 | comptime { | |
| 373 | expect(@sizeOf(FooStructAligned) == 2); | |
| 374 | expect(@sizeOf(FooArrayOfAligned) == 2 * 2); | |
| 375 | } | |
| 376 | ||
| 377 | var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned); | |
| 378 | const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0]; | |
| 379 | ||
| 380 | expect(ptr.a[0].a == 0xbb); | |
| 381 | expect(ptr.a[0].b == 0xbb); | |
| 382 | expect(ptr.a[1].a == 0xbb); | |
| 383 | expect(ptr.a[1].b == 0xbb); | |
| 384 | } | |
| 385 | ||
| 386 | test "runtime struct initialization of bitfield" { | |
| 387 | const s1 = Nibbles{ | |
| 388 | .x = x1, | |
| 389 | .y = x1, | |
| 390 | }; | |
| 391 | const s2 = Nibbles{ | |
| 392 | .x = @intCast(u4, x2), | |
| 393 | .y = @intCast(u4, x2), | |
| 394 | }; | |
| 395 | ||
| 396 | expect(s1.x == x1); | |
| 397 | expect(s1.y == x1); | |
| 398 | expect(s2.x == @intCast(u4, x2)); | |
| 399 | expect(s2.y == @intCast(u4, x2)); | |
| 400 | } | |
| 401 | ||
| 402 | var x1 = @as(u4, 1); | |
| 403 | var x2 = @as(u8, 2); | |
| 404 | ||
| 405 | const Nibbles = packed struct { | |
| 406 | x: u4, | |
| 407 | y: u4, | |
| 408 | }; | |
| 409 | ||
| 410 | const Bitfields = packed struct { | |
| 411 | f1: u16, | |
| 412 | f2: u16, | |
| 413 | f3: u8, | |
| 414 | f4: u8, | |
| 415 | f5: u4, | |
| 416 | f6: u4, | |
| 417 | f7: u8, | |
| 418 | }; | |
| 419 | ||
| 420 | test "native bit field understands endianness" { | |
| 421 | var all: u64 = if (native_endian != .Little) | |
| 422 | 0x1111222233445677 | |
| 423 | else | |
| 424 | 0x7765443322221111; | |
| 425 | var bytes: [8]u8 = undefined; | |
| 426 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); | |
| 427 | var bitfields = @ptrCast(*Bitfields, &bytes).*; | |
| 428 | ||
| 429 | expect(bitfields.f1 == 0x1111); | |
| 430 | expect(bitfields.f2 == 0x2222); | |
| 431 | expect(bitfields.f3 == 0x33); | |
| 432 | expect(bitfields.f4 == 0x44); | |
| 433 | expect(bitfields.f5 == 0x5); | |
| 434 | expect(bitfields.f6 == 0x6); | |
| 435 | expect(bitfields.f7 == 0x77); | |
| 436 | } | |
| 437 | ||
| 438 | test "align 1 field before self referential align 8 field as slice return type" { | |
| 439 | const result = alloc(Expr); | |
| 440 | expect(result.len == 0); | |
| 441 | } | |
| 442 | ||
| 443 | const Expr = union(enum) { | |
| 444 | Literal: u8, | |
| 445 | Question: *Expr, | |
| 446 | }; | |
| 447 | ||
| 448 | fn alloc(comptime T: type) []T { | |
| 449 | return &[_]T{}; | |
| 450 | } | |
| 451 | ||
| 452 | test "call method with mutable reference to struct with no fields" { | |
| 453 | const S = struct { | |
| 454 | fn doC(s: *const @This()) bool { | |
| 455 | return true; | |
| 456 | } | |
| 457 | fn do(s: *@This()) bool { | |
| 458 | return true; | |
| 459 | } | |
| 460 | }; | |
| 461 | ||
| 462 | var s = S{}; | |
| 463 | expect(S.doC(&s)); | |
| 464 | expect(s.doC()); | |
| 465 | expect(S.do(&s)); | |
| 466 | expect(s.do()); | |
| 467 | } | |
| 468 | ||
| 469 | test "implicit cast packed struct field to const ptr" { | |
| 470 | const LevelUpMove = packed struct { | |
| 471 | move_id: u9, | |
| 472 | level: u7, | |
| 473 | ||
| 474 | fn toInt(value: u7) u7 { | |
| 475 | return value; | |
| 476 | } | |
| 477 | }; | |
| 478 | ||
| 479 | var lup: LevelUpMove = undefined; | |
| 480 | lup.level = 12; | |
| 481 | const res = LevelUpMove.toInt(lup.level); | |
| 482 | expect(res == 12); | |
| 483 | } | |
| 484 | ||
| 485 | test "pointer to packed struct member in a stack variable" { | |
| 486 | const S = packed struct { | |
| 487 | a: u2, | |
| 488 | b: u2, | |
| 489 | }; | |
| 490 | ||
| 491 | var s = S{ .a = 2, .b = 0 }; | |
| 492 | var b_ptr = &s.b; | |
| 493 | expect(s.b == 0); | |
| 494 | b_ptr.* = 2; | |
| 495 | expect(s.b == 2); | |
| 496 | } | |
| 497 | ||
| 498 | test "non-byte-aligned array inside packed struct" { | |
| 499 | const Foo = packed struct { | |
| 500 | a: bool, | |
| 501 | b: [0x16]u8, | |
| 502 | }; | |
| 503 | const S = struct { | |
| 504 | fn bar(slice: []const u8) void { | |
| 505 | expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu"); | |
| 506 | } | |
| 507 | fn doTheTest() void { | |
| 508 | var foo = Foo{ | |
| 509 | .a = true, | |
| 510 | .b = "abcdefghijklmnopqurstu".*, | |
| 511 | }; | |
| 512 | const value = foo.b; | |
| 513 | bar(&value); | |
| 514 | } | |
| 515 | }; | |
| 516 | S.doTheTest(); | |
| 517 | comptime S.doTheTest(); | |
| 518 | } | |
| 519 | ||
| 520 | test "packed struct with u0 field access" { | |
| 521 | const S = packed struct { | |
| 522 | f0: u0, | |
| 523 | }; | |
| 524 | var s = S{ .f0 = 0 }; | |
| 525 | comptime expect(s.f0 == 0); | |
| 526 | } | |
| 527 | ||
| 528 | const S0 = struct { | |
| 529 | bar: S1, | |
| 530 | ||
| 531 | pub const S1 = struct { | |
| 532 | value: u8, | |
| 533 | }; | |
| 534 | ||
| 535 | fn init() @This() { | |
| 536 | return S0{ .bar = S1{ .value = 123 } }; | |
| 537 | } | |
| 538 | }; | |
| 539 | ||
| 540 | var g_foo: S0 = S0.init(); | |
| 541 | ||
| 542 | test "access to global struct fields" { | |
| 543 | g_foo.bar.value = 42; | |
| 544 | expect(g_foo.bar.value == 42); | |
| 545 | } | |
| 546 | ||
| 547 | test "packed struct with fp fields" { | |
| 548 | const S = packed struct { | |
| 549 | data: [3]f32, | |
| 550 | ||
| 551 | pub fn frob(self: *@This()) void { | |
| 552 | self.data[0] += self.data[1] + self.data[2]; | |
| 553 | self.data[1] += self.data[0] + self.data[2]; | |
| 554 | self.data[2] += self.data[0] + self.data[1]; | |
| 555 | } | |
| 556 | }; | |
| 557 | ||
| 558 | var s: S = undefined; | |
| 559 | s.data[0] = 1.0; | |
| 560 | s.data[1] = 2.0; | |
| 561 | s.data[2] = 3.0; | |
| 562 | s.frob(); | |
| 563 | expectEqual(@as(f32, 6.0), s.data[0]); | |
| 564 | expectEqual(@as(f32, 11.0), s.data[1]); | |
| 565 | expectEqual(@as(f32, 20.0), s.data[2]); | |
| 566 | } | |
| 567 | ||
| 568 | test "use within struct scope" { | |
| 569 | const S = struct { | |
| 570 | usingnamespace struct { | |
| 571 | pub fn inner() i32 { | |
| 572 | return 42; | |
| 573 | } | |
| 574 | }; | |
| 575 | }; | |
| 576 | expectEqual(@as(i32, 42), S.inner()); | |
| 577 | } | |
| 578 | ||
| 579 | test "default struct initialization fields" { | |
| 580 | const S = struct { | |
| 581 | a: i32 = 1234, | |
| 582 | b: i32, | |
| 583 | }; | |
| 584 | const x = S{ | |
| 585 | .b = 5, | |
| 586 | }; | |
| 587 | if (x.a + x.b != 1239) { | |
| 588 | @compileError("it should be comptime known"); | |
| 589 | } | |
| 590 | var five: i32 = 5; | |
| 591 | const y = S{ | |
| 592 | .b = five, | |
| 593 | }; | |
| 594 | expectEqual(1239, x.a + x.b); | |
| 595 | } | |
| 596 | ||
| 597 | test "fn with C calling convention returns struct by value" { | |
| 598 | const S = struct { | |
| 599 | fn entry() void { | |
| 600 | var x = makeBar(10); | |
| 601 | expectEqual(@as(i32, 10), x.handle); | |
| 602 | } | |
| 603 | ||
| 604 | const ExternBar = extern struct { | |
| 605 | handle: i32, | |
| 606 | }; | |
| 607 | ||
| 608 | fn makeBar(t: i32) callconv(.C) ExternBar { | |
| 609 | return ExternBar{ | |
| 610 | .handle = t, | |
| 611 | }; | |
| 612 | } | |
| 613 | }; | |
| 614 | S.entry(); | |
| 615 | comptime S.entry(); | |
| 616 | } | |
| 617 | ||
| 618 | test "for loop over pointers to struct, getting field from struct pointer" { | |
| 619 | const S = struct { | |
| 620 | const Foo = struct { | |
| 621 | name: []const u8, | |
| 622 | }; | |
| 623 | ||
| 624 | var ok = true; | |
| 625 | ||
| 626 | fn eql(a: []const u8) bool { | |
| 627 | return true; | |
| 628 | } | |
| 629 | ||
| 630 | const ArrayList = struct { | |
| 631 | fn toSlice(self: *ArrayList) []*Foo { | |
| 632 | return @as([*]*Foo, undefined)[0..0]; | |
| 633 | } | |
| 634 | }; | |
| 635 | ||
| 636 | fn doTheTest() void { | |
| 637 | var objects: ArrayList = undefined; | |
| 638 | ||
| 639 | for (objects.toSlice()) |obj| { | |
| 640 | if (eql(obj.name)) { | |
| 641 | ok = false; | |
| 642 | } | |
| 643 | } | |
| 644 | ||
| 645 | expect(ok); | |
| 646 | } | |
| 647 | }; | |
| 648 | S.doTheTest(); | |
| 649 | } | |
| 650 | ||
| 651 | test "zero-bit field in packed struct" { | |
| 652 | const S = packed struct { | |
| 653 | x: u10, | |
| 654 | y: void, | |
| 655 | }; | |
| 656 | var x: S = undefined; | |
| 657 | } | |
| 658 | ||
| 659 | test "struct field init with catch" { | |
| 660 | const S = struct { | |
| 661 | fn doTheTest() void { | |
| 662 | var x: anyerror!isize = 1; | |
| 663 | var req = Foo{ | |
| 664 | .field = x catch undefined, | |
| 665 | }; | |
| 666 | expect(req.field == 1); | |
| 667 | } | |
| 668 | ||
| 669 | pub const Foo = extern struct { | |
| 670 | field: isize, | |
| 671 | }; | |
| 672 | }; | |
| 673 | S.doTheTest(); | |
| 674 | comptime S.doTheTest(); | |
| 675 | } | |
| 676 | ||
| 677 | test "packed struct with non-ABI-aligned field" { | |
| 678 | const S = packed struct { | |
| 679 | x: u9, | |
| 680 | y: u183, | |
| 681 | }; | |
| 682 | var s: S = undefined; | |
| 683 | s.x = 1; | |
| 684 | s.y = 42; | |
| 685 | expect(s.x == 1); | |
| 686 | expect(s.y == 42); | |
| 687 | } | |
| 688 | ||
| 689 | test "non-packed struct with u128 entry in union" { | |
| 690 | const U = union(enum) { | |
| 691 | Num: u128, | |
| 692 | Void, | |
| 693 | }; | |
| 694 | ||
| 695 | const S = struct { | |
| 696 | f1: U, | |
| 697 | f2: U, | |
| 698 | }; | |
| 699 | ||
| 700 | var sx: S = undefined; | |
| 701 | var s = &sx; | |
| 702 | std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @byteOffsetOf(S, "f2")); | |
| 703 | var v2 = U{ .Num = 123 }; | |
| 704 | s.f2 = v2; | |
| 705 | std.testing.expect(s.f2.Num == 123); | |
| 706 | } | |
| 707 | ||
| 708 | test "packed struct field passed to generic function" { | |
| 709 | const S = struct { | |
| 710 | const P = packed struct { | |
| 711 | b: u5, | |
| 712 | g: u5, | |
| 713 | r: u5, | |
| 714 | a: u1, | |
| 715 | }; | |
| 716 | ||
| 717 | fn genericReadPackedField(ptr: anytype) u5 { | |
| 718 | return ptr.*; | |
| 719 | } | |
| 720 | }; | |
| 721 | ||
| 722 | var p: S.P = undefined; | |
| 723 | p.b = 29; | |
| 724 | var loaded = S.genericReadPackedField(&p.b); | |
| 725 | expect(loaded == 29); | |
| 726 | } | |
| 727 | ||
| 728 | test "anonymous struct literal syntax" { | |
| 729 | const S = struct { | |
| 730 | const Point = struct { | |
| 731 | x: i32, | |
| 732 | y: i32, | |
| 733 | }; | |
| 734 | ||
| 735 | fn doTheTest() void { | |
| 736 | var p: Point = .{ | |
| 737 | .x = 1, | |
| 738 | .y = 2, | |
| 739 | }; | |
| 740 | expect(p.x == 1); | |
| 741 | expect(p.y == 2); | |
| 742 | } | |
| 743 | }; | |
| 744 | S.doTheTest(); | |
| 745 | comptime S.doTheTest(); | |
| 746 | } | |
| 747 | ||
| 748 | test "fully anonymous struct" { | |
| 749 | const S = struct { | |
| 750 | fn doTheTest() void { | |
| 751 | dump(.{ | |
| 752 | .int = @as(u32, 1234), | |
| 753 | .float = @as(f64, 12.34), | |
| 754 | .b = true, | |
| 755 | .s = "hi", | |
| 756 | }); | |
| 757 | } | |
| 758 | fn dump(args: anytype) void { | |
| 759 | expect(args.int == 1234); | |
| 760 | expect(args.float == 12.34); | |
| 761 | expect(args.b); | |
| 762 | expect(args.s[0] == 'h'); | |
| 763 | expect(args.s[1] == 'i'); | |
| 764 | } | |
| 765 | }; | |
| 766 | S.doTheTest(); | |
| 767 | comptime S.doTheTest(); | |
| 768 | } | |
| 769 | ||
| 770 | test "fully anonymous list literal" { | |
| 771 | const S = struct { | |
| 772 | fn doTheTest() void { | |
| 773 | dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); | |
| 774 | } | |
| 775 | fn dump(args: anytype) void { | |
| 776 | expect(args.@"0" == 1234); | |
| 777 | expect(args.@"1" == 12.34); | |
| 778 | expect(args.@"2"); | |
| 779 | expect(args.@"3"[0] == 'h'); | |
| 780 | expect(args.@"3"[1] == 'i'); | |
| 781 | } | |
| 782 | }; | |
| 783 | S.doTheTest(); | |
| 784 | comptime S.doTheTest(); | |
| 785 | } | |
| 786 | ||
| 787 | test "anonymous struct literal assigned to variable" { | |
| 788 | var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) }; | |
| 789 | expect(vec.@"0" == 22); | |
| 790 | expect(vec.@"1" == 55); | |
| 791 | expect(vec.@"2" == 99); | |
| 792 | } | |
| 793 | ||
| 794 | test "struct with var field" { | |
| 795 | const Point = struct { | |
| 796 | x: anytype, | |
| 797 | y: anytype, | |
| 798 | }; | |
| 799 | const pt = Point{ | |
| 800 | .x = 1, | |
| 801 | .y = 2, | |
| 802 | }; | |
| 803 | expect(pt.x == 1); | |
| 804 | expect(pt.y == 2); | |
| 805 | } | |
| 806 | ||
| 807 | test "comptime struct field" { | |
| 808 | const T = struct { | |
| 809 | a: i32, | |
| 810 | comptime b: i32 = 1234, | |
| 811 | }; | |
| 812 | ||
| 813 | var foo: T = undefined; | |
| 814 | comptime expect(foo.b == 1234); | |
| 815 | } | |
| 816 | ||
| 817 | test "anon struct literal field value initialized with fn call" { | |
| 818 | const S = struct { | |
| 819 | fn doTheTest() void { | |
| 820 | var x = .{foo()}; | |
| 821 | expectEqualSlices(u8, x[0], "hi"); | |
| 822 | } | |
| 823 | fn foo() []const u8 { | |
| 824 | return "hi"; | |
| 825 | } | |
| 826 | }; | |
| 827 | S.doTheTest(); | |
| 828 | comptime S.doTheTest(); | |
| 829 | } | |
| 830 | ||
| 831 | test "self-referencing struct via array member" { | |
| 832 | const T = struct { | |
| 833 | children: [1]*@This(), | |
| 834 | }; | |
| 835 | var x: T = undefined; | |
| 836 | x = T{ .children = .{&x} }; | |
| 837 | expect(x.children[0] == &x); | |
| 838 | } | |
| 839 | ||
| 840 | test "struct with union field" { | |
| 841 | const Value = struct { | |
| 842 | ref: u32 = 2, | |
| 843 | kind: union(enum) { | |
| 844 | None: usize, | |
| 845 | Bool: bool, | |
| 846 | }, | |
| 847 | }; | |
| 848 | ||
| 849 | var True = Value{ | |
| 850 | .kind = .{ .Bool = true }, | |
| 851 | }; | |
| 852 | expectEqual(@as(u32, 2), True.ref); | |
| 853 | expectEqual(true, True.kind.Bool); | |
| 854 | } | |
| 855 | ||
| 856 | test "type coercion of anon struct literal to struct" { | |
| 857 | const S = struct { | |
| 858 | const S2 = struct { | |
| 859 | A: u32, | |
| 860 | B: []const u8, | |
| 861 | C: void, | |
| 862 | D: Foo = .{}, | |
| 863 | }; | |
| 864 | ||
| 865 | const Foo = struct { | |
| 866 | field: i32 = 1234, | |
| 867 | }; | |
| 868 | ||
| 869 | fn doTheTest() void { | |
| 870 | var y: u32 = 42; | |
| 871 | const t0 = .{ .A = 123, .B = "foo", .C = {} }; | |
| 872 | const t1 = .{ .A = y, .B = "foo", .C = {} }; | |
| 873 | const y0: S2 = t0; | |
| 874 | var y1: S2 = t1; | |
| 875 | expect(y0.A == 123); | |
| 876 | expect(std.mem.eql(u8, y0.B, "foo")); | |
| 877 | expect(y0.C == {}); | |
| 878 | expect(y0.D.field == 1234); | |
| 879 | expect(y1.A == y); | |
| 880 | expect(std.mem.eql(u8, y1.B, "foo")); | |
| 881 | expect(y1.C == {}); | |
| 882 | expect(y1.D.field == 1234); | |
| 883 | } | |
| 884 | }; | |
| 885 | S.doTheTest(); | |
| 886 | comptime S.doTheTest(); | |
| 887 | } | |
| 888 | ||
| 889 | test "type coercion of pointer to anon struct literal to pointer to struct" { | |
| 890 | const S = struct { | |
| 891 | const S2 = struct { | |
| 892 | A: u32, | |
| 893 | B: []const u8, | |
| 894 | C: void, | |
| 895 | D: Foo = .{}, | |
| 896 | }; | |
| 897 | ||
| 898 | const Foo = struct { | |
| 899 | field: i32 = 1234, | |
| 900 | }; | |
| 901 | ||
| 902 | fn doTheTest() void { | |
| 903 | var y: u32 = 42; | |
| 904 | const t0 = &.{ .A = 123, .B = "foo", .C = {} }; | |
| 905 | const t1 = &.{ .A = y, .B = "foo", .C = {} }; | |
| 906 | const y0: *const S2 = t0; | |
| 907 | var y1: *const S2 = t1; | |
| 908 | expect(y0.A == 123); | |
| 909 | expect(std.mem.eql(u8, y0.B, "foo")); | |
| 910 | expect(y0.C == {}); | |
| 911 | expect(y0.D.field == 1234); | |
| 912 | expect(y1.A == y); | |
| 913 | expect(std.mem.eql(u8, y1.B, "foo")); | |
| 914 | expect(y1.C == {}); | |
| 915 | expect(y1.D.field == 1234); | |
| 916 | } | |
| 917 | }; | |
| 918 | S.doTheTest(); | |
| 919 | comptime S.doTheTest(); | |
| 920 | } | |
| 921 | ||
| 922 | test "packed struct with undefined initializers" { | |
| 923 | const S = struct { | |
| 924 | const P = packed struct { | |
| 925 | a: u3, | |
| 926 | _a: u3 = undefined, | |
| 927 | b: u3, | |
| 928 | _b: u3 = undefined, | |
| 929 | c: u3, | |
| 930 | _c: u3 = undefined, | |
| 931 | }; | |
| 932 | ||
| 933 | fn doTheTest() void { | |
| 934 | var p: P = undefined; | |
| 935 | p = P{ .a = 2, .b = 4, .c = 6 }; | |
| 936 | // Make sure the compiler doesn't touch the unprefixed fields. | |
| 937 | expectEqual(@as(u3, 2), p.a); | |
| 938 | expectEqual(@as(u3, 4), p.b); | |
| 939 | expectEqual(@as(u3, 6), p.c); | |
| 940 | } | |
| 941 | }; | |
| 942 | ||
| 943 | S.doTheTest(); | |
| 944 | comptime S.doTheTest(); | |
| 945 | } |
test/behavior/struct_contains_null_ptr_itself.zig created+21| ... | ... | @@ -0,0 +1,21 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "struct contains null pointer which contains original struct" { | |
| 5 | var x: ?*NodeLineComment = null; | |
| 6 | expect(x == null); | |
| 7 | } | |
| 8 | ||
| 9 | pub const Node = struct { | |
| 10 | id: Id, | |
| 11 | comment: ?*NodeLineComment, | |
| 12 | ||
| 13 | pub const Id = enum { | |
| 14 | Root, | |
| 15 | LineComment, | |
| 16 | }; | |
| 17 | }; | |
| 18 | ||
| 19 | pub const NodeLineComment = struct { | |
| 20 | base: Node, | |
| 21 | }; |
test/behavior/struct_contains_slice_of_itself.zig created+85| ... | ... | @@ -0,0 +1,85 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Node = struct { | |
| 4 | payload: i32, | |
| 5 | children: []Node, | |
| 6 | }; | |
| 7 | ||
| 8 | const NodeAligned = struct { | |
| 9 | payload: i32, | |
| 10 | children: []align(@alignOf(NodeAligned)) NodeAligned, | |
| 11 | }; | |
| 12 | ||
| 13 | test "struct contains slice of itself" { | |
| 14 | var other_nodes = [_]Node{ | |
| 15 | Node{ | |
| 16 | .payload = 31, | |
| 17 | .children = &[_]Node{}, | |
| 18 | }, | |
| 19 | Node{ | |
| 20 | .payload = 32, | |
| 21 | .children = &[_]Node{}, | |
| 22 | }, | |
| 23 | }; | |
| 24 | var nodes = [_]Node{ | |
| 25 | Node{ | |
| 26 | .payload = 1, | |
| 27 | .children = &[_]Node{}, | |
| 28 | }, | |
| 29 | Node{ | |
| 30 | .payload = 2, | |
| 31 | .children = &[_]Node{}, | |
| 32 | }, | |
| 33 | Node{ | |
| 34 | .payload = 3, | |
| 35 | .children = other_nodes[0..], | |
| 36 | }, | |
| 37 | }; | |
| 38 | const root = Node{ | |
| 39 | .payload = 1234, | |
| 40 | .children = nodes[0..], | |
| 41 | }; | |
| 42 | expect(root.payload == 1234); | |
| 43 | expect(root.children[0].payload == 1); | |
| 44 | expect(root.children[1].payload == 2); | |
| 45 | expect(root.children[2].payload == 3); | |
| 46 | expect(root.children[2].children[0].payload == 31); | |
| 47 | expect(root.children[2].children[1].payload == 32); | |
| 48 | } | |
| 49 | ||
| 50 | test "struct contains aligned slice of itself" { | |
| 51 | var other_nodes = [_]NodeAligned{ | |
| 52 | NodeAligned{ | |
| 53 | .payload = 31, | |
| 54 | .children = &[_]NodeAligned{}, | |
| 55 | }, | |
| 56 | NodeAligned{ | |
| 57 | .payload = 32, | |
| 58 | .children = &[_]NodeAligned{}, | |
| 59 | }, | |
| 60 | }; | |
| 61 | var nodes = [_]NodeAligned{ | |
| 62 | NodeAligned{ | |
| 63 | .payload = 1, | |
| 64 | .children = &[_]NodeAligned{}, | |
| 65 | }, | |
| 66 | NodeAligned{ | |
| 67 | .payload = 2, | |
| 68 | .children = &[_]NodeAligned{}, | |
| 69 | }, | |
| 70 | NodeAligned{ | |
| 71 | .payload = 3, | |
| 72 | .children = other_nodes[0..], | |
| 73 | }, | |
| 74 | }; | |
| 75 | const root = NodeAligned{ | |
| 76 | .payload = 1234, | |
| 77 | .children = nodes[0..], | |
| 78 | }; | |
| 79 | expect(root.payload == 1234); | |
| 80 | expect(root.children[0].payload == 1); | |
| 81 | expect(root.children[1].payload == 2); | |
| 82 | expect(root.children[2].payload == 3); | |
| 83 | expect(root.children[2].children[0].payload == 31); | |
| 84 | expect(root.children[2].children[1].payload == 32); | |
| 85 | } |
test/behavior/switch.zig created+537| ... | ... | @@ -0,0 +1,537 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectError = std.testing.expectError; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | ||
| 6 | test "switch with numbers" { | |
| 7 | testSwitchWithNumbers(13); | |
| 8 | } | |
| 9 | ||
| 10 | fn testSwitchWithNumbers(x: u32) void { | |
| 11 | const result = switch (x) { | |
| 12 | 1, 2, 3, 4...8 => false, | |
| 13 | 13 => true, | |
| 14 | else => false, | |
| 15 | }; | |
| 16 | expect(result); | |
| 17 | } | |
| 18 | ||
| 19 | test "switch with all ranges" { | |
| 20 | expect(testSwitchWithAllRanges(50, 3) == 1); | |
| 21 | expect(testSwitchWithAllRanges(101, 0) == 2); | |
| 22 | expect(testSwitchWithAllRanges(300, 5) == 3); | |
| 23 | expect(testSwitchWithAllRanges(301, 6) == 6); | |
| 24 | } | |
| 25 | ||
| 26 | fn testSwitchWithAllRanges(x: u32, y: u32) u32 { | |
| 27 | return switch (x) { | |
| 28 | 0...100 => 1, | |
| 29 | 101...200 => 2, | |
| 30 | 201...300 => 3, | |
| 31 | else => y, | |
| 32 | }; | |
| 33 | } | |
| 34 | ||
| 35 | test "implicit comptime switch" { | |
| 36 | const x = 3 + 4; | |
| 37 | const result = switch (x) { | |
| 38 | 3 => 10, | |
| 39 | 4 => 11, | |
| 40 | 5, 6 => 12, | |
| 41 | 7, 8 => 13, | |
| 42 | else => 14, | |
| 43 | }; | |
| 44 | ||
| 45 | comptime { | |
| 46 | expect(result + 1 == 14); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | test "switch on enum" { | |
| 51 | const fruit = Fruit.Orange; | |
| 52 | nonConstSwitchOnEnum(fruit); | |
| 53 | } | |
| 54 | const Fruit = enum { | |
| 55 | Apple, | |
| 56 | Orange, | |
| 57 | Banana, | |
| 58 | }; | |
| 59 | fn nonConstSwitchOnEnum(fruit: Fruit) void { | |
| 60 | switch (fruit) { | |
| 61 | Fruit.Apple => unreachable, | |
| 62 | Fruit.Orange => {}, | |
| 63 | Fruit.Banana => unreachable, | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | test "switch statement" { | |
| 68 | nonConstSwitch(SwitchStatmentFoo.C); | |
| 69 | } | |
| 70 | fn nonConstSwitch(foo: SwitchStatmentFoo) void { | |
| 71 | const val = switch (foo) { | |
| 72 | SwitchStatmentFoo.A => @as(i32, 1), | |
| 73 | SwitchStatmentFoo.B => 2, | |
| 74 | SwitchStatmentFoo.C => 3, | |
| 75 | SwitchStatmentFoo.D => 4, | |
| 76 | }; | |
| 77 | expect(val == 3); | |
| 78 | } | |
| 79 | const SwitchStatmentFoo = enum { | |
| 80 | A, | |
| 81 | B, | |
| 82 | C, | |
| 83 | D, | |
| 84 | }; | |
| 85 | ||
| 86 | test "switch prong with variable" { | |
| 87 | switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 }); | |
| 88 | switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 }); | |
| 89 | switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} }); | |
| 90 | } | |
| 91 | const SwitchProngWithVarEnum = union(enum) { | |
| 92 | One: i32, | |
| 93 | Two: f32, | |
| 94 | Meh: void, | |
| 95 | }; | |
| 96 | fn switchProngWithVarFn(a: SwitchProngWithVarEnum) void { | |
| 97 | switch (a) { | |
| 98 | SwitchProngWithVarEnum.One => |x| { | |
| 99 | expect(x == 13); | |
| 100 | }, | |
| 101 | SwitchProngWithVarEnum.Two => |x| { | |
| 102 | expect(x == 13.0); | |
| 103 | }, | |
| 104 | SwitchProngWithVarEnum.Meh => |x| { | |
| 105 | const v: void = x; | |
| 106 | }, | |
| 107 | } | |
| 108 | } | |
| 109 | ||
| 110 | test "switch on enum using pointer capture" { | |
| 111 | testSwitchEnumPtrCapture(); | |
| 112 | comptime testSwitchEnumPtrCapture(); | |
| 113 | } | |
| 114 | ||
| 115 | fn testSwitchEnumPtrCapture() void { | |
| 116 | var value = SwitchProngWithVarEnum{ .One = 1234 }; | |
| 117 | switch (value) { | |
| 118 | SwitchProngWithVarEnum.One => |*x| x.* += 1, | |
| 119 | else => unreachable, | |
| 120 | } | |
| 121 | switch (value) { | |
| 122 | SwitchProngWithVarEnum.One => |x| expect(x == 1235), | |
| 123 | else => unreachable, | |
| 124 | } | |
| 125 | } | |
| 126 | ||
| 127 | test "switch with multiple expressions" { | |
| 128 | const x = switch (returnsFive()) { | |
| 129 | 1, 2, 3 => 1, | |
| 130 | 4, 5, 6 => 2, | |
| 131 | else => @as(i32, 3), | |
| 132 | }; | |
| 133 | expect(x == 2); | |
| 134 | } | |
| 135 | fn returnsFive() i32 { | |
| 136 | return 5; | |
| 137 | } | |
| 138 | ||
| 139 | const Number = union(enum) { | |
| 140 | One: u64, | |
| 141 | Two: u8, | |
| 142 | Three: f32, | |
| 143 | }; | |
| 144 | ||
| 145 | const number = Number{ .Three = 1.23 }; | |
| 146 | ||
| 147 | fn returnsFalse() bool { | |
| 148 | switch (number) { | |
| 149 | Number.One => |x| return x > 1234, | |
| 150 | Number.Two => |x| return x == 'a', | |
| 151 | Number.Three => |x| return x > 12.34, | |
| 152 | } | |
| 153 | } | |
| 154 | test "switch on const enum with var" { | |
| 155 | expect(!returnsFalse()); | |
| 156 | } | |
| 157 | ||
| 158 | test "switch on type" { | |
| 159 | expect(trueIfBoolFalseOtherwise(bool)); | |
| 160 | expect(!trueIfBoolFalseOtherwise(i32)); | |
| 161 | } | |
| 162 | ||
| 163 | fn trueIfBoolFalseOtherwise(comptime T: type) bool { | |
| 164 | return switch (T) { | |
| 165 | bool => true, | |
| 166 | else => false, | |
| 167 | }; | |
| 168 | } | |
| 169 | ||
| 170 | test "switch handles all cases of number" { | |
| 171 | testSwitchHandleAllCases(); | |
| 172 | comptime testSwitchHandleAllCases(); | |
| 173 | } | |
| 174 | ||
| 175 | fn testSwitchHandleAllCases() void { | |
| 176 | expect(testSwitchHandleAllCasesExhaustive(0) == 3); | |
| 177 | expect(testSwitchHandleAllCasesExhaustive(1) == 2); | |
| 178 | expect(testSwitchHandleAllCasesExhaustive(2) == 1); | |
| 179 | expect(testSwitchHandleAllCasesExhaustive(3) == 0); | |
| 180 | ||
| 181 | expect(testSwitchHandleAllCasesRange(100) == 0); | |
| 182 | expect(testSwitchHandleAllCasesRange(200) == 1); | |
| 183 | expect(testSwitchHandleAllCasesRange(201) == 2); | |
| 184 | expect(testSwitchHandleAllCasesRange(202) == 4); | |
| 185 | expect(testSwitchHandleAllCasesRange(230) == 3); | |
| 186 | } | |
| 187 | ||
| 188 | fn testSwitchHandleAllCasesExhaustive(x: u2) u2 { | |
| 189 | return switch (x) { | |
| 190 | 0 => @as(u2, 3), | |
| 191 | 1 => 2, | |
| 192 | 2 => 1, | |
| 193 | 3 => 0, | |
| 194 | }; | |
| 195 | } | |
| 196 | ||
| 197 | fn testSwitchHandleAllCasesRange(x: u8) u8 { | |
| 198 | return switch (x) { | |
| 199 | 0...100 => @as(u8, 0), | |
| 200 | 101...200 => 1, | |
| 201 | 201, 203 => 2, | |
| 202 | 202 => 4, | |
| 203 | 204...255 => 3, | |
| 204 | }; | |
| 205 | } | |
| 206 | ||
| 207 | test "switch all prongs unreachable" { | |
| 208 | testAllProngsUnreachable(); | |
| 209 | comptime testAllProngsUnreachable(); | |
| 210 | } | |
| 211 | ||
| 212 | fn testAllProngsUnreachable() void { | |
| 213 | expect(switchWithUnreachable(1) == 2); | |
| 214 | expect(switchWithUnreachable(2) == 10); | |
| 215 | } | |
| 216 | ||
| 217 | fn switchWithUnreachable(x: i32) i32 { | |
| 218 | while (true) { | |
| 219 | switch (x) { | |
| 220 | 1 => return 2, | |
| 221 | 2 => break, | |
| 222 | else => continue, | |
| 223 | } | |
| 224 | } | |
| 225 | return 10; | |
| 226 | } | |
| 227 | ||
| 228 | fn return_a_number() anyerror!i32 { | |
| 229 | return 1; | |
| 230 | } | |
| 231 | ||
| 232 | test "capture value of switch with all unreachable prongs" { | |
| 233 | const x = return_a_number() catch |err| switch (err) { | |
| 234 | else => unreachable, | |
| 235 | }; | |
| 236 | expect(x == 1); | |
| 237 | } | |
| 238 | ||
| 239 | test "switching on booleans" { | |
| 240 | testSwitchOnBools(); | |
| 241 | comptime testSwitchOnBools(); | |
| 242 | } | |
| 243 | ||
| 244 | fn testSwitchOnBools() void { | |
| 245 | expect(testSwitchOnBoolsTrueAndFalse(true) == false); | |
| 246 | expect(testSwitchOnBoolsTrueAndFalse(false) == true); | |
| 247 | ||
| 248 | expect(testSwitchOnBoolsTrueWithElse(true) == false); | |
| 249 | expect(testSwitchOnBoolsTrueWithElse(false) == true); | |
| 250 | ||
| 251 | expect(testSwitchOnBoolsFalseWithElse(true) == false); | |
| 252 | expect(testSwitchOnBoolsFalseWithElse(false) == true); | |
| 253 | } | |
| 254 | ||
| 255 | fn testSwitchOnBoolsTrueAndFalse(x: bool) bool { | |
| 256 | return switch (x) { | |
| 257 | true => false, | |
| 258 | false => true, | |
| 259 | }; | |
| 260 | } | |
| 261 | ||
| 262 | fn testSwitchOnBoolsTrueWithElse(x: bool) bool { | |
| 263 | return switch (x) { | |
| 264 | true => false, | |
| 265 | else => true, | |
| 266 | }; | |
| 267 | } | |
| 268 | ||
| 269 | fn testSwitchOnBoolsFalseWithElse(x: bool) bool { | |
| 270 | return switch (x) { | |
| 271 | false => true, | |
| 272 | else => false, | |
| 273 | }; | |
| 274 | } | |
| 275 | ||
| 276 | test "u0" { | |
| 277 | var val: u0 = 0; | |
| 278 | switch (val) { | |
| 279 | 0 => expect(val == 0), | |
| 280 | } | |
| 281 | } | |
| 282 | ||
| 283 | test "undefined.u0" { | |
| 284 | var val: u0 = undefined; | |
| 285 | switch (val) { | |
| 286 | 0 => expect(val == 0), | |
| 287 | } | |
| 288 | } | |
| 289 | ||
| 290 | test "anon enum literal used in switch on union enum" { | |
| 291 | const Foo = union(enum) { | |
| 292 | a: i32, | |
| 293 | }; | |
| 294 | ||
| 295 | var foo = Foo{ .a = 1234 }; | |
| 296 | switch (foo) { | |
| 297 | .a => |x| { | |
| 298 | expect(x == 1234); | |
| 299 | }, | |
| 300 | } | |
| 301 | } | |
| 302 | ||
| 303 | test "else prong of switch on error set excludes other cases" { | |
| 304 | const S = struct { | |
| 305 | fn doTheTest() void { | |
| 306 | expectError(error.C, bar()); | |
| 307 | } | |
| 308 | const E = error{ | |
| 309 | A, | |
| 310 | B, | |
| 311 | } || E2; | |
| 312 | ||
| 313 | const E2 = error{ | |
| 314 | C, | |
| 315 | D, | |
| 316 | }; | |
| 317 | ||
| 318 | fn foo() E!void { | |
| 319 | return error.C; | |
| 320 | } | |
| 321 | ||
| 322 | fn bar() E2!void { | |
| 323 | foo() catch |err| switch (err) { | |
| 324 | error.A, error.B => {}, | |
| 325 | else => |e| return e, | |
| 326 | }; | |
| 327 | } | |
| 328 | }; | |
| 329 | S.doTheTest(); | |
| 330 | comptime S.doTheTest(); | |
| 331 | } | |
| 332 | ||
| 333 | test "switch prongs with error set cases make a new error set type for capture value" { | |
| 334 | const S = struct { | |
| 335 | fn doTheTest() void { | |
| 336 | expectError(error.B, bar()); | |
| 337 | } | |
| 338 | const E = E1 || E2; | |
| 339 | ||
| 340 | const E1 = error{ | |
| 341 | A, | |
| 342 | B, | |
| 343 | }; | |
| 344 | ||
| 345 | const E2 = error{ | |
| 346 | C, | |
| 347 | D, | |
| 348 | }; | |
| 349 | ||
| 350 | fn foo() E!void { | |
| 351 | return error.B; | |
| 352 | } | |
| 353 | ||
| 354 | fn bar() E1!void { | |
| 355 | foo() catch |err| switch (err) { | |
| 356 | error.A, error.B => |e| return e, | |
| 357 | else => {}, | |
| 358 | }; | |
| 359 | } | |
| 360 | }; | |
| 361 | S.doTheTest(); | |
| 362 | comptime S.doTheTest(); | |
| 363 | } | |
| 364 | ||
| 365 | test "return result loc and then switch with range implicit casted to error union" { | |
| 366 | const S = struct { | |
| 367 | fn doTheTest() void { | |
| 368 | expect((func(0xb) catch unreachable) == 0xb); | |
| 369 | } | |
| 370 | fn func(d: u8) anyerror!u8 { | |
| 371 | return switch (d) { | |
| 372 | 0xa...0xf => d, | |
| 373 | else => unreachable, | |
| 374 | }; | |
| 375 | } | |
| 376 | }; | |
| 377 | S.doTheTest(); | |
| 378 | comptime S.doTheTest(); | |
| 379 | } | |
| 380 | ||
| 381 | test "switch with null and T peer types and inferred result location type" { | |
| 382 | const S = struct { | |
| 383 | fn doTheTest(c: u8) void { | |
| 384 | if (switch (c) { | |
| 385 | 0 => true, | |
| 386 | else => null, | |
| 387 | }) |v| { | |
| 388 | @panic("fail"); | |
| 389 | } | |
| 390 | } | |
| 391 | }; | |
| 392 | S.doTheTest(1); | |
| 393 | comptime S.doTheTest(1); | |
| 394 | } | |
| 395 | ||
| 396 | test "switch prongs with cases with identical payload types" { | |
| 397 | const Union = union(enum) { | |
| 398 | A: usize, | |
| 399 | B: isize, | |
| 400 | C: usize, | |
| 401 | }; | |
| 402 | const S = struct { | |
| 403 | fn doTheTest() void { | |
| 404 | doTheSwitch1(Union{ .A = 8 }); | |
| 405 | doTheSwitch2(Union{ .B = -8 }); | |
| 406 | } | |
| 407 | fn doTheSwitch1(u: Union) void { | |
| 408 | switch (u) { | |
| 409 | .A, .C => |e| { | |
| 410 | expect(@TypeOf(e) == usize); | |
| 411 | expect(e == 8); | |
| 412 | }, | |
| 413 | .B => |e| @panic("fail"), | |
| 414 | } | |
| 415 | } | |
| 416 | fn doTheSwitch2(u: Union) void { | |
| 417 | switch (u) { | |
| 418 | .A, .C => |e| @panic("fail"), | |
| 419 | .B => |e| { | |
| 420 | expect(@TypeOf(e) == isize); | |
| 421 | expect(e == -8); | |
| 422 | }, | |
| 423 | } | |
| 424 | } | |
| 425 | }; | |
| 426 | S.doTheTest(); | |
| 427 | comptime S.doTheTest(); | |
| 428 | } | |
| 429 | ||
| 430 | test "switch with disjoint range" { | |
| 431 | var q: u8 = 0; | |
| 432 | switch (q) { | |
| 433 | 0...125 => {}, | |
| 434 | 127...255 => {}, | |
| 435 | 126...126 => {}, | |
| 436 | } | |
| 437 | } | |
| 438 | ||
| 439 | test "switch variable for range and multiple prongs" { | |
| 440 | const S = struct { | |
| 441 | fn doTheTest() void { | |
| 442 | var u: u8 = 16; | |
| 443 | doTheSwitch(u); | |
| 444 | comptime doTheSwitch(u); | |
| 445 | var v: u8 = 42; | |
| 446 | doTheSwitch(v); | |
| 447 | comptime doTheSwitch(v); | |
| 448 | } | |
| 449 | fn doTheSwitch(q: u8) void { | |
| 450 | switch (q) { | |
| 451 | 0...40 => |x| expect(x == 16), | |
| 452 | 41, 42, 43 => |x| expect(x == 42), | |
| 453 | else => expect(false), | |
| 454 | } | |
| 455 | } | |
| 456 | }; | |
| 457 | } | |
| 458 | ||
| 459 | var state: u32 = 0; | |
| 460 | fn poll() void { | |
| 461 | switch (state) { | |
| 462 | 0 => { | |
| 463 | state = 1; | |
| 464 | }, | |
| 465 | else => { | |
| 466 | state += 1; | |
| 467 | }, | |
| 468 | } | |
| 469 | } | |
| 470 | ||
| 471 | test "switch on global mutable var isn't constant-folded" { | |
| 472 | while (state < 2) { | |
| 473 | poll(); | |
| 474 | } | |
| 475 | } | |
| 476 | ||
| 477 | test "switch on pointer type" { | |
| 478 | const S = struct { | |
| 479 | const X = struct { | |
| 480 | field: u32, | |
| 481 | }; | |
| 482 | ||
| 483 | const P1 = @intToPtr(*X, 0x400); | |
| 484 | const P2 = @intToPtr(*X, 0x800); | |
| 485 | const P3 = @intToPtr(*X, 0xC00); | |
| 486 | ||
| 487 | fn doTheTest(arg: *X) i32 { | |
| 488 | switch (arg) { | |
| 489 | P1 => return 1, | |
| 490 | P2 => return 2, | |
| 491 | else => return 3, | |
| 492 | } | |
| 493 | } | |
| 494 | }; | |
| 495 | ||
| 496 | expect(1 == S.doTheTest(S.P1)); | |
| 497 | expect(2 == S.doTheTest(S.P2)); | |
| 498 | expect(3 == S.doTheTest(S.P3)); | |
| 499 | comptime expect(1 == S.doTheTest(S.P1)); | |
| 500 | comptime expect(2 == S.doTheTest(S.P2)); | |
| 501 | comptime expect(3 == S.doTheTest(S.P3)); | |
| 502 | } | |
| 503 | ||
| 504 | test "switch on error set with single else" { | |
| 505 | const S = struct { | |
| 506 | fn doTheTest() void { | |
| 507 | var some: error{Foo} = error.Foo; | |
| 508 | expect(switch (some) { | |
| 509 | else => |a| true, | |
| 510 | }); | |
| 511 | } | |
| 512 | }; | |
| 513 | ||
| 514 | S.doTheTest(); | |
| 515 | comptime S.doTheTest(); | |
| 516 | } | |
| 517 | ||
| 518 | test "while copies its payload" { | |
| 519 | const S = struct { | |
| 520 | fn doTheTest() void { | |
| 521 | var tmp: union(enum) { | |
| 522 | A: u8, | |
| 523 | B: u32, | |
| 524 | } = .{ .A = 42 }; | |
| 525 | switch (tmp) { | |
| 526 | .A => |value| { | |
| 527 | // Modify the original union | |
| 528 | tmp = .{ .B = 0x10101010 }; | |
| 529 | expectEqual(@as(u8, 42), value); | |
| 530 | }, | |
| 531 | else => unreachable, | |
| 532 | } | |
| 533 | } | |
| 534 | }; | |
| 535 | S.doTheTest(); | |
| 536 | comptime S.doTheTest(); | |
| 537 | } |
test/behavior/switch_prong_err_enum.zig created+30| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | var read_count: u64 = 0; | |
| 4 | ||
| 5 | fn readOnce() anyerror!u64 { | |
| 6 | read_count += 1; | |
| 7 | return read_count; | |
| 8 | } | |
| 9 | ||
| 10 | const FormValue = union(enum) { | |
| 11 | Address: u64, | |
| 12 | Other: bool, | |
| 13 | }; | |
| 14 | ||
| 15 | fn doThing(form_id: u64) anyerror!FormValue { | |
| 16 | return switch (form_id) { | |
| 17 | 17 => FormValue{ .Address = try readOnce() }, | |
| 18 | else => error.InvalidDebugInfo, | |
| 19 | }; | |
| 20 | } | |
| 21 | ||
| 22 | test "switch prong returns error enum" { | |
| 23 | switch (doThing(17) catch unreachable) { | |
| 24 | FormValue.Address => |payload| { | |
| 25 | expect(payload == 1); | |
| 26 | }, | |
| 27 | else => unreachable, | |
| 28 | } | |
| 29 | expect(read_count == 1); | |
| 30 | } |
test/behavior/switch_prong_implicit_cast.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const FormValue = union(enum) { | |
| 4 | One: void, | |
| 5 | Two: bool, | |
| 6 | }; | |
| 7 | ||
| 8 | fn foo(id: u64) !FormValue { | |
| 9 | return switch (id) { | |
| 10 | 2 => FormValue{ .Two = true }, | |
| 11 | 1 => FormValue{ .One = {} }, | |
| 12 | else => return error.Whatever, | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | test "switch prong implicit cast" { | |
| 17 | const result = switch (foo(2) catch unreachable) { | |
| 18 | FormValue.One => false, | |
| 19 | FormValue.Two => |x| x, | |
| 20 | }; | |
| 21 | expect(result); | |
| 22 | } |
test/behavior/syntax.zig created+68| ... | ... | @@ -0,0 +1,68 @@ |
| 1 | // Test trailing comma syntax | |
| 2 | // zig fmt: off | |
| 3 | ||
| 4 | extern var a: c_int; | |
| 5 | extern "c" var b: c_int; | |
| 6 | export var c: c_int = 0; | |
| 7 | threadlocal var d: c_int; | |
| 8 | extern threadlocal var e: c_int; | |
| 9 | extern "c" threadlocal var f: c_int; | |
| 10 | export threadlocal var g: c_int = 0; | |
| 11 | ||
| 12 | const struct_trailing_comma = struct { x: i32, y: i32, }; | |
| 13 | const struct_no_comma = struct { x: i32, y: i32 }; | |
| 14 | const struct_fn_no_comma = struct { fn m() void {} y: i32 }; | |
| 15 | ||
| 16 | const enum_no_comma = enum { A, B }; | |
| 17 | ||
| 18 | fn container_init() void { | |
| 19 | const S = struct { x: i32, y: i32 }; | |
| 20 | _ = S { .x = 1, .y = 2 }; | |
| 21 | _ = S { .x = 1, .y = 2, }; | |
| 22 | } | |
| 23 | ||
| 24 | fn type_expr_return1() if (true) A {} | |
| 25 | fn type_expr_return2() for (true) |_| A {} | |
| 26 | fn type_expr_return3() while (true) A {} | |
| 27 | fn type_expr_return4() comptime A {} | |
| 28 | ||
| 29 | fn switch_cases(x: i32) void { | |
| 30 | switch (x) { | |
| 31 | 1,2,3 => {}, | |
| 32 | 4,5, => {}, | |
| 33 | 6...8, => {}, | |
| 34 | else => {}, | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | fn switch_prongs(x: i32) void { | |
| 39 | switch (x) { | |
| 40 | 0 => {}, | |
| 41 | else => {}, | |
| 42 | } | |
| 43 | switch (x) { | |
| 44 | 0 => {}, | |
| 45 | else => {} | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | const fn_no_comma = fn(i32, i32)void; | |
| 50 | const fn_trailing_comma = fn(i32, i32,)void; | |
| 51 | ||
| 52 | fn fn_calls() void { | |
| 53 | fn add(x: i32, y: i32,) i32 { x + y }; | |
| 54 | _ = add(1, 2); | |
| 55 | _ = add(1, 2,); | |
| 56 | } | |
| 57 | ||
| 58 | fn asm_lists() void { | |
| 59 | if (false) { // Build AST but don't analyze | |
| 60 | asm ("not real assembly" | |
| 61 | :[a] "x" (x),); | |
| 62 | asm ("not real assembly" | |
| 63 | :[a] "x" (->i32),:[a] "x" (1),); | |
| 64 | asm ("still not real assembly" | |
| 65 | :::"a","b",); | |
| 66 | } | |
| 67 | } | |
| 68 |
test/behavior/this.zig created+34| ... | ... | @@ -0,0 +1,34 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const module = @This(); | |
| 4 | ||
| 5 | fn Point(comptime T: type) type { | |
| 6 | return struct { | |
| 7 | const Self = @This(); | |
| 8 | x: T, | |
| 9 | y: T, | |
| 10 | ||
| 11 | fn addOne(self: *Self) void { | |
| 12 | self.x += 1; | |
| 13 | self.y += 1; | |
| 14 | } | |
| 15 | }; | |
| 16 | } | |
| 17 | ||
| 18 | fn add(x: i32, y: i32) i32 { | |
| 19 | return x + y; | |
| 20 | } | |
| 21 | ||
| 22 | test "this refer to module call private fn" { | |
| 23 | expect(module.add(1, 2) == 3); | |
| 24 | } | |
| 25 | ||
| 26 | test "this refer to container" { | |
| 27 | var pt = Point(i32){ | |
| 28 | .x = 12, | |
| 29 | .y = 34, | |
| 30 | }; | |
| 31 | pt.addOne(); | |
| 32 | expect(pt.x == 13); | |
| 33 | expect(pt.y == 35); | |
| 34 | } |
test/behavior/translate_c_macros.h created+18| ... | ... | @@ -0,0 +1,18 @@ |
| 1 | // initializer list expression | |
| 2 | typedef struct Color { | |
| 3 | unsigned char r; | |
| 4 | unsigned char g; | |
| 5 | unsigned char b; | |
| 6 | unsigned char a; | |
| 7 | } Color; | |
| 8 | #define CLITERAL(type) (type) | |
| 9 | #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray | |
| 10 | ||
| 11 | #define MY_SIZEOF(x) ((int)sizeof(x)) | |
| 12 | #define MY_SIZEOF2(x) ((int)sizeof x) | |
| 13 | ||
| 14 | struct Foo { | |
| 15 | int a; | |
| 16 | }; | |
| 17 | ||
| 18 | #define SIZE_OF_FOO sizeof(struct Foo) |
test/behavior/translate_c_macros.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const expectEqual = @import("std").testing.expectEqual; | |
| 3 | ||
| 4 | const h = @cImport(@cInclude("behavior/translate_c_macros.h")); | |
| 5 | ||
| 6 | test "initializer list expression" { | |
| 7 | expectEqual(h.Color{ | |
| 8 | .r = 200, | |
| 9 | .g = 200, | |
| 10 | .b = 200, | |
| 11 | .a = 255, | |
| 12 | }, h.LIGHTGRAY); | |
| 13 | } | |
| 14 | ||
| 15 | test "sizeof in macros" { | |
| 16 | expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32)); | |
| 17 | expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32)); | |
| 18 | } | |
| 19 | ||
| 20 | test "reference to a struct type" { | |
| 21 | expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO); | |
| 22 | } |
test/behavior/truncate.zig created+36| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "truncate u0 to larger integer allowed and has comptime known result" { | |
| 5 | var x: u0 = 0; | |
| 6 | const y = @truncate(u8, x); | |
| 7 | comptime expect(y == 0); | |
| 8 | } | |
| 9 | ||
| 10 | test "truncate.u0.literal" { | |
| 11 | var z = @truncate(u0, 0); | |
| 12 | expect(z == 0); | |
| 13 | } | |
| 14 | ||
| 15 | test "truncate.u0.const" { | |
| 16 | const c0: usize = 0; | |
| 17 | var z = @truncate(u0, c0); | |
| 18 | expect(z == 0); | |
| 19 | } | |
| 20 | ||
| 21 | test "truncate.u0.var" { | |
| 22 | var d: u8 = 2; | |
| 23 | var z = @truncate(u0, d); | |
| 24 | expect(z == 0); | |
| 25 | } | |
| 26 | ||
| 27 | test "truncate sign mismatch but comptime known so it works anyway" { | |
| 28 | const x: u32 = 10; | |
| 29 | var result = @truncate(i8, x); | |
| 30 | expect(result == 10); | |
| 31 | } | |
| 32 | ||
| 33 | test "truncate on comptime integer" { | |
| 34 | var x = @truncate(u16, 9999); | |
| 35 | expect(x == 9999); | |
| 36 | } |
test/behavior/try.zig created+43| ... | ... | @@ -0,0 +1,43 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "try on error union" { | |
| 4 | tryOnErrorUnionImpl(); | |
| 5 | comptime tryOnErrorUnionImpl(); | |
| 6 | } | |
| 7 | ||
| 8 | fn tryOnErrorUnionImpl() void { | |
| 9 | const x = if (returnsTen()) |val| val + 1 else |err| switch (err) { | |
| 10 | error.ItBroke, error.NoMem => 1, | |
| 11 | error.CrappedOut => @as(i32, 2), | |
| 12 | else => unreachable, | |
| 13 | }; | |
| 14 | expect(x == 11); | |
| 15 | } | |
| 16 | ||
| 17 | fn returnsTen() anyerror!i32 { | |
| 18 | return 10; | |
| 19 | } | |
| 20 | ||
| 21 | test "try without vars" { | |
| 22 | const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2); | |
| 23 | expect(result1 == 2); | |
| 24 | ||
| 25 | const result2 = if (failIfTrue(false)) 1 else |_| @as(i32, 2); | |
| 26 | expect(result2 == 1); | |
| 27 | } | |
| 28 | ||
| 29 | fn failIfTrue(ok: bool) anyerror!void { | |
| 30 | if (ok) { | |
| 31 | return error.ItBroke; | |
| 32 | } else { | |
| 33 | return; | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | test "try then not executed with assignment" { | |
| 38 | if (failIfTrue(true)) { | |
| 39 | unreachable; | |
| 40 | } else |err| { | |
| 41 | expect(err == error.ItBroke); | |
| 42 | } | |
| 43 | } |
test/behavior/tuple.zig created+113| ... | ... | @@ -0,0 +1,113 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | test "tuple concatenation" { | |
| 7 | const S = struct { | |
| 8 | fn doTheTest() void { | |
| 9 | var a: i32 = 1; | |
| 10 | var b: i32 = 2; | |
| 11 | var x = .{a}; | |
| 12 | var y = .{b}; | |
| 13 | var c = x ++ y; | |
| 14 | expectEqual(@as(i32, 1), c[0]); | |
| 15 | expectEqual(@as(i32, 2), c[1]); | |
| 16 | } | |
| 17 | }; | |
| 18 | S.doTheTest(); | |
| 19 | comptime S.doTheTest(); | |
| 20 | } | |
| 21 | ||
| 22 | test "tuple multiplication" { | |
| 23 | const S = struct { | |
| 24 | fn doTheTest() void { | |
| 25 | { | |
| 26 | const t = .{} ** 4; | |
| 27 | expectEqual(0, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 28 | } | |
| 29 | { | |
| 30 | const t = .{'a'} ** 4; | |
| 31 | expectEqual(4, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 32 | inline for (t) |x| expectEqual('a', x); | |
| 33 | } | |
| 34 | { | |
| 35 | const t = .{ 1, 2, 3 } ** 4; | |
| 36 | expectEqual(12, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 37 | inline for (t) |x, i| expectEqual(1 + i % 3, x); | |
| 38 | } | |
| 39 | } | |
| 40 | }; | |
| 41 | S.doTheTest(); | |
| 42 | comptime S.doTheTest(); | |
| 43 | ||
| 44 | const T = struct { | |
| 45 | fn consume_tuple(tuple: anytype, len: usize) void { | |
| 46 | expect(tuple.len == len); | |
| 47 | } | |
| 48 | ||
| 49 | fn doTheTest() void { | |
| 50 | const t1 = .{}; | |
| 51 | ||
| 52 | var rt_var: u8 = 42; | |
| 53 | const t2 = .{rt_var} ++ .{}; | |
| 54 | ||
| 55 | expect(t2.len == 1); | |
| 56 | expect(t2.@"0" == rt_var); | |
| 57 | expect(t2.@"0" == 42); | |
| 58 | expect(&t2.@"0" != &rt_var); | |
| 59 | ||
| 60 | consume_tuple(t1 ++ t1, 0); | |
| 61 | consume_tuple(.{} ++ .{}, 0); | |
| 62 | consume_tuple(.{0} ++ .{}, 1); | |
| 63 | consume_tuple(.{0} ++ .{1}, 2); | |
| 64 | consume_tuple(.{ 0, 1, 2 } ++ .{ u8, 1, noreturn }, 6); | |
| 65 | consume_tuple(t2 ++ t1, 1); | |
| 66 | consume_tuple(t1 ++ t2, 1); | |
| 67 | consume_tuple(t2 ++ t2, 2); | |
| 68 | consume_tuple(.{rt_var} ++ .{}, 1); | |
| 69 | consume_tuple(.{rt_var} ++ t1, 1); | |
| 70 | consume_tuple(.{} ++ .{rt_var}, 1); | |
| 71 | consume_tuple(t2 ++ .{void}, 2); | |
| 72 | consume_tuple(t2 ++ .{0}, 2); | |
| 73 | consume_tuple(.{0} ++ t2, 2); | |
| 74 | consume_tuple(.{void} ++ t2, 2); | |
| 75 | consume_tuple(.{u8} ++ .{rt_var} ++ .{true}, 3); | |
| 76 | } | |
| 77 | }; | |
| 78 | ||
| 79 | T.doTheTest(); | |
| 80 | comptime T.doTheTest(); | |
| 81 | } | |
| 82 | ||
| 83 | test "pass tuple to comptime var parameter" { | |
| 84 | const S = struct { | |
| 85 | fn Foo(comptime args: anytype) void { | |
| 86 | expect(args[0] == 1); | |
| 87 | } | |
| 88 | ||
| 89 | fn doTheTest() void { | |
| 90 | Foo(.{1}); | |
| 91 | } | |
| 92 | }; | |
| 93 | S.doTheTest(); | |
| 94 | comptime S.doTheTest(); | |
| 95 | } | |
| 96 | ||
| 97 | test "tuple initializer for var" { | |
| 98 | const S = struct { | |
| 99 | fn doTheTest() void { | |
| 100 | const Bytes = struct { | |
| 101 | id: usize, | |
| 102 | }; | |
| 103 | ||
| 104 | var tmp = .{ | |
| 105 | .id = @as(usize, 2), | |
| 106 | .name = Bytes{ .id = 20 }, | |
| 107 | }; | |
| 108 | } | |
| 109 | }; | |
| 110 | ||
| 111 | S.doTheTest(); | |
| 112 | comptime S.doTheTest(); | |
| 113 | } |
test/behavior/type.zig created+453| ... | ... | @@ -0,0 +1,453 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const TypeInfo = std.builtin.TypeInfo; | |
| 4 | const testing = std.testing; | |
| 5 | ||
| 6 | fn testTypes(comptime types: []const type) void { | |
| 7 | inline for (types) |testType| { | |
| 8 | testing.expect(testType == @Type(@typeInfo(testType))); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | test "Type.MetaType" { | |
| 13 | testing.expect(type == @Type(TypeInfo{ .Type = undefined })); | |
| 14 | testTypes(&[_]type{type}); | |
| 15 | } | |
| 16 | ||
| 17 | test "Type.Void" { | |
| 18 | testing.expect(void == @Type(TypeInfo{ .Void = undefined })); | |
| 19 | testTypes(&[_]type{void}); | |
| 20 | } | |
| 21 | ||
| 22 | test "Type.Bool" { | |
| 23 | testing.expect(bool == @Type(TypeInfo{ .Bool = undefined })); | |
| 24 | testTypes(&[_]type{bool}); | |
| 25 | } | |
| 26 | ||
| 27 | test "Type.NoReturn" { | |
| 28 | testing.expect(noreturn == @Type(TypeInfo{ .NoReturn = undefined })); | |
| 29 | testTypes(&[_]type{noreturn}); | |
| 30 | } | |
| 31 | ||
| 32 | test "Type.Int" { | |
| 33 | testing.expect(u1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 1 } })); | |
| 34 | testing.expect(i1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 1 } })); | |
| 35 | testing.expect(u8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 8 } })); | |
| 36 | testing.expect(i8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 8 } })); | |
| 37 | testing.expect(u64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 64 } })); | |
| 38 | testing.expect(i64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 64 } })); | |
| 39 | testTypes(&[_]type{ u8, u32, i64 }); | |
| 40 | } | |
| 41 | ||
| 42 | test "Type.Float" { | |
| 43 | testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } })); | |
| 44 | testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); | |
| 45 | testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); | |
| 46 | testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); | |
| 47 | testTypes(&[_]type{ f16, f32, f64, f128 }); | |
| 48 | } | |
| 49 | ||
| 50 | test "Type.Pointer" { | |
| 51 | testTypes(&[_]type{ | |
| 52 | // One Value Pointer Types | |
| 53 | *u8, *const u8, | |
| 54 | *volatile u8, *const volatile u8, | |
| 55 | *align(4) u8, *align(4) const u8, | |
| 56 | *align(4) volatile u8, *align(4) const volatile u8, | |
| 57 | *align(8) u8, *align(8) const u8, | |
| 58 | *align(8) volatile u8, *align(8) const volatile u8, | |
| 59 | *allowzero u8, *allowzero const u8, | |
| 60 | *allowzero volatile u8, *allowzero const volatile u8, | |
| 61 | *allowzero align(4) u8, *allowzero align(4) const u8, | |
| 62 | *allowzero align(4) volatile u8, *allowzero align(4) const volatile u8, | |
| 63 | // Many Values Pointer Types | |
| 64 | [*]u8, [*]const u8, | |
| 65 | [*]volatile u8, [*]const volatile u8, | |
| 66 | [*]align(4) u8, [*]align(4) const u8, | |
| 67 | [*]align(4) volatile u8, [*]align(4) const volatile u8, | |
| 68 | [*]align(8) u8, [*]align(8) const u8, | |
| 69 | [*]align(8) volatile u8, [*]align(8) const volatile u8, | |
| 70 | [*]allowzero u8, [*]allowzero const u8, | |
| 71 | [*]allowzero volatile u8, [*]allowzero const volatile u8, | |
| 72 | [*]allowzero align(4) u8, [*]allowzero align(4) const u8, | |
| 73 | [*]allowzero align(4) volatile u8, [*]allowzero align(4) const volatile u8, | |
| 74 | // Slice Types | |
| 75 | []u8, []const u8, | |
| 76 | []volatile u8, []const volatile u8, | |
| 77 | []align(4) u8, []align(4) const u8, | |
| 78 | []align(4) volatile u8, []align(4) const volatile u8, | |
| 79 | []align(8) u8, []align(8) const u8, | |
| 80 | []align(8) volatile u8, []align(8) const volatile u8, | |
| 81 | []allowzero u8, []allowzero const u8, | |
| 82 | []allowzero volatile u8, []allowzero const volatile u8, | |
| 83 | []allowzero align(4) u8, []allowzero align(4) const u8, | |
| 84 | []allowzero align(4) volatile u8, []allowzero align(4) const volatile u8, | |
| 85 | // C Pointer Types | |
| 86 | [*c]u8, [*c]const u8, | |
| 87 | [*c]volatile u8, [*c]const volatile u8, | |
| 88 | [*c]align(4) u8, [*c]align(4) const u8, | |
| 89 | [*c]align(4) volatile u8, [*c]align(4) const volatile u8, | |
| 90 | [*c]align(8) u8, [*c]align(8) const u8, | |
| 91 | [*c]align(8) volatile u8, [*c]align(8) const volatile u8, | |
| 92 | }); | |
| 93 | } | |
| 94 | ||
| 95 | test "Type.Array" { | |
| 96 | testing.expect([123]u8 == @Type(TypeInfo{ | |
| 97 | .Array = TypeInfo.Array{ | |
| 98 | .len = 123, | |
| 99 | .child = u8, | |
| 100 | .sentinel = null, | |
| 101 | }, | |
| 102 | })); | |
| 103 | testing.expect([2]u32 == @Type(TypeInfo{ | |
| 104 | .Array = TypeInfo.Array{ | |
| 105 | .len = 2, | |
| 106 | .child = u32, | |
| 107 | .sentinel = null, | |
| 108 | }, | |
| 109 | })); | |
| 110 | testing.expect([2:0]u32 == @Type(TypeInfo{ | |
| 111 | .Array = TypeInfo.Array{ | |
| 112 | .len = 2, | |
| 113 | .child = u32, | |
| 114 | .sentinel = 0, | |
| 115 | }, | |
| 116 | })); | |
| 117 | testTypes(&[_]type{ [1]u8, [30]usize, [7]bool }); | |
| 118 | } | |
| 119 | ||
| 120 | test "Type.ComptimeFloat" { | |
| 121 | testTypes(&[_]type{comptime_float}); | |
| 122 | } | |
| 123 | test "Type.ComptimeInt" { | |
| 124 | testTypes(&[_]type{comptime_int}); | |
| 125 | } | |
| 126 | test "Type.Undefined" { | |
| 127 | testTypes(&[_]type{@TypeOf(undefined)}); | |
| 128 | } | |
| 129 | test "Type.Null" { | |
| 130 | testTypes(&[_]type{@TypeOf(null)}); | |
| 131 | } | |
| 132 | test "@Type create slice with null sentinel" { | |
| 133 | const Slice = @Type(TypeInfo{ | |
| 134 | .Pointer = .{ | |
| 135 | .size = .Slice, | |
| 136 | .is_const = true, | |
| 137 | .is_volatile = false, | |
| 138 | .is_allowzero = false, | |
| 139 | .alignment = 8, | |
| 140 | .child = *i32, | |
| 141 | .sentinel = null, | |
| 142 | }, | |
| 143 | }); | |
| 144 | testing.expect(Slice == []align(8) const *i32); | |
| 145 | } | |
| 146 | test "@Type picks up the sentinel value from TypeInfo" { | |
| 147 | testTypes(&[_]type{ | |
| 148 | [11:0]u8, [4:10]u8, | |
| 149 | [*:0]u8, [*:0]const u8, | |
| 150 | [*:0]volatile u8, [*:0]const volatile u8, | |
| 151 | [*:0]align(4) u8, [*:0]align(4) const u8, | |
| 152 | [*:0]align(4) volatile u8, [*:0]align(4) const volatile u8, | |
| 153 | [*:0]align(8) u8, [*:0]align(8) const u8, | |
| 154 | [*:0]align(8) volatile u8, [*:0]align(8) const volatile u8, | |
| 155 | [*:0]allowzero u8, [*:0]allowzero const u8, | |
| 156 | [*:0]allowzero volatile u8, [*:0]allowzero const volatile u8, | |
| 157 | [*:0]allowzero align(4) u8, [*:0]allowzero align(4) const u8, | |
| 158 | [*:0]allowzero align(4) volatile u8, [*:0]allowzero align(4) const volatile u8, | |
| 159 | [*:5]allowzero align(4) volatile u8, [*:5]allowzero align(4) const volatile u8, | |
| 160 | [:0]u8, [:0]const u8, | |
| 161 | [:0]volatile u8, [:0]const volatile u8, | |
| 162 | [:0]align(4) u8, [:0]align(4) const u8, | |
| 163 | [:0]align(4) volatile u8, [:0]align(4) const volatile u8, | |
| 164 | [:0]align(8) u8, [:0]align(8) const u8, | |
| 165 | [:0]align(8) volatile u8, [:0]align(8) const volatile u8, | |
| 166 | [:0]allowzero u8, [:0]allowzero const u8, | |
| 167 | [:0]allowzero volatile u8, [:0]allowzero const volatile u8, | |
| 168 | [:0]allowzero align(4) u8, [:0]allowzero align(4) const u8, | |
| 169 | [:0]allowzero align(4) volatile u8, [:0]allowzero align(4) const volatile u8, | |
| 170 | [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8, | |
| 171 | }); | |
| 172 | } | |
| 173 | ||
| 174 | test "Type.Optional" { | |
| 175 | testTypes(&[_]type{ | |
| 176 | ?u8, | |
| 177 | ?*u8, | |
| 178 | ?[]u8, | |
| 179 | ?[*]u8, | |
| 180 | ?[*c]u8, | |
| 181 | }); | |
| 182 | } | |
| 183 | ||
| 184 | test "Type.ErrorUnion" { | |
| 185 | testTypes(&[_]type{ | |
| 186 | error{}!void, | |
| 187 | error{Error}!void, | |
| 188 | }); | |
| 189 | } | |
| 190 | ||
| 191 | test "Type.Opaque" { | |
| 192 | const Opaque = @Type(.{ | |
| 193 | .Opaque = .{ | |
| 194 | .decls = &[_]TypeInfo.Declaration{}, | |
| 195 | }, | |
| 196 | }); | |
| 197 | testing.expect(Opaque != opaque {}); | |
| 198 | testing.expectEqualSlices( | |
| 199 | TypeInfo.Declaration, | |
| 200 | &[_]TypeInfo.Declaration{}, | |
| 201 | @typeInfo(Opaque).Opaque.decls, | |
| 202 | ); | |
| 203 | } | |
| 204 | ||
| 205 | test "Type.Vector" { | |
| 206 | testTypes(&[_]type{ | |
| 207 | @Vector(0, u8), | |
| 208 | @Vector(4, u8), | |
| 209 | @Vector(8, *u8), | |
| 210 | std.meta.Vector(0, u8), | |
| 211 | std.meta.Vector(4, u8), | |
| 212 | std.meta.Vector(8, *u8), | |
| 213 | }); | |
| 214 | } | |
| 215 | ||
| 216 | test "Type.AnyFrame" { | |
| 217 | testTypes(&[_]type{ | |
| 218 | anyframe, | |
| 219 | anyframe->u8, | |
| 220 | anyframe->anyframe->u8, | |
| 221 | }); | |
| 222 | } | |
| 223 | ||
| 224 | test "Type.EnumLiteral" { | |
| 225 | testTypes(&[_]type{ | |
| 226 | @TypeOf(.Dummy), | |
| 227 | }); | |
| 228 | } | |
| 229 | ||
| 230 | fn add(a: i32, b: i32) i32 { | |
| 231 | return a + b; | |
| 232 | } | |
| 233 | ||
| 234 | test "Type.Frame" { | |
| 235 | testTypes(&[_]type{ | |
| 236 | @Frame(add), | |
| 237 | }); | |
| 238 | } | |
| 239 | ||
| 240 | test "Type.ErrorSet" { | |
| 241 | // error sets don't compare equal so just check if they compile | |
| 242 | _ = @Type(@typeInfo(error{})); | |
| 243 | _ = @Type(@typeInfo(error{A})); | |
| 244 | _ = @Type(@typeInfo(error{ A, B, C })); | |
| 245 | } | |
| 246 | ||
| 247 | test "Type.Struct" { | |
| 248 | const A = @Type(@typeInfo(struct { x: u8, y: u32 })); | |
| 249 | const infoA = @typeInfo(A).Struct; | |
| 250 | testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout); | |
| 251 | testing.expectEqualSlices(u8, "x", infoA.fields[0].name); | |
| 252 | testing.expectEqual(u8, infoA.fields[0].field_type); | |
| 253 | testing.expectEqual(@as(?u8, null), infoA.fields[0].default_value); | |
| 254 | testing.expectEqualSlices(u8, "y", infoA.fields[1].name); | |
| 255 | testing.expectEqual(u32, infoA.fields[1].field_type); | |
| 256 | testing.expectEqual(@as(?u32, null), infoA.fields[1].default_value); | |
| 257 | testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls); | |
| 258 | testing.expectEqual(@as(bool, false), infoA.is_tuple); | |
| 259 | ||
| 260 | var a = A{ .x = 0, .y = 1 }; | |
| 261 | testing.expectEqual(@as(u8, 0), a.x); | |
| 262 | testing.expectEqual(@as(u32, 1), a.y); | |
| 263 | a.y += 1; | |
| 264 | testing.expectEqual(@as(u32, 2), a.y); | |
| 265 | ||
| 266 | const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 })); | |
| 267 | const infoB = @typeInfo(B).Struct; | |
| 268 | testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout); | |
| 269 | testing.expectEqualSlices(u8, "x", infoB.fields[0].name); | |
| 270 | testing.expectEqual(u8, infoB.fields[0].field_type); | |
| 271 | testing.expectEqual(@as(?u8, null), infoB.fields[0].default_value); | |
| 272 | testing.expectEqualSlices(u8, "y", infoB.fields[1].name); | |
| 273 | testing.expectEqual(u32, infoB.fields[1].field_type); | |
| 274 | testing.expectEqual(@as(?u32, 5), infoB.fields[1].default_value); | |
| 275 | testing.expectEqual(@as(usize, 0), infoB.decls.len); | |
| 276 | testing.expectEqual(@as(bool, false), infoB.is_tuple); | |
| 277 | ||
| 278 | const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 })); | |
| 279 | const infoC = @typeInfo(C).Struct; | |
| 280 | testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout); | |
| 281 | testing.expectEqualSlices(u8, "x", infoC.fields[0].name); | |
| 282 | testing.expectEqual(u8, infoC.fields[0].field_type); | |
| 283 | testing.expectEqual(@as(?u8, 3), infoC.fields[0].default_value); | |
| 284 | testing.expectEqualSlices(u8, "y", infoC.fields[1].name); | |
| 285 | testing.expectEqual(u32, infoC.fields[1].field_type); | |
| 286 | testing.expectEqual(@as(?u32, 5), infoC.fields[1].default_value); | |
| 287 | testing.expectEqual(@as(usize, 0), infoC.decls.len); | |
| 288 | testing.expectEqual(@as(bool, false), infoC.is_tuple); | |
| 289 | } | |
| 290 | ||
| 291 | test "Type.Enum" { | |
| 292 | const Foo = @Type(.{ | |
| 293 | .Enum = .{ | |
| 294 | .layout = .Auto, | |
| 295 | .tag_type = u8, | |
| 296 | .fields = &[_]TypeInfo.EnumField{ | |
| 297 | .{ .name = "a", .value = 1 }, | |
| 298 | .{ .name = "b", .value = 5 }, | |
| 299 | }, | |
| 300 | .decls = &[_]TypeInfo.Declaration{}, | |
| 301 | .is_exhaustive = true, | |
| 302 | }, | |
| 303 | }); | |
| 304 | testing.expectEqual(true, @typeInfo(Foo).Enum.is_exhaustive); | |
| 305 | testing.expectEqual(@as(u8, 1), @enumToInt(Foo.a)); | |
| 306 | testing.expectEqual(@as(u8, 5), @enumToInt(Foo.b)); | |
| 307 | const Bar = @Type(.{ | |
| 308 | .Enum = .{ | |
| 309 | .layout = .Extern, | |
| 310 | .tag_type = u32, | |
| 311 | .fields = &[_]TypeInfo.EnumField{ | |
| 312 | .{ .name = "a", .value = 1 }, | |
| 313 | .{ .name = "b", .value = 5 }, | |
| 314 | }, | |
| 315 | .decls = &[_]TypeInfo.Declaration{}, | |
| 316 | .is_exhaustive = false, | |
| 317 | }, | |
| 318 | }); | |
| 319 | testing.expectEqual(false, @typeInfo(Bar).Enum.is_exhaustive); | |
| 320 | testing.expectEqual(@as(u32, 1), @enumToInt(Bar.a)); | |
| 321 | testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b)); | |
| 322 | testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6))); | |
| 323 | } | |
| 324 | ||
| 325 | test "Type.Union" { | |
| 326 | const Untagged = @Type(.{ | |
| 327 | .Union = .{ | |
| 328 | .layout = .Auto, | |
| 329 | .tag_type = null, | |
| 330 | .fields = &[_]TypeInfo.UnionField{ | |
| 331 | .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) }, | |
| 332 | .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) }, | |
| 333 | }, | |
| 334 | .decls = &[_]TypeInfo.Declaration{}, | |
| 335 | }, | |
| 336 | }); | |
| 337 | var untagged = Untagged{ .int = 1 }; | |
| 338 | untagged.float = 2.0; | |
| 339 | untagged.int = 3; | |
| 340 | testing.expectEqual(@as(i32, 3), untagged.int); | |
| 341 | ||
| 342 | const PackedUntagged = @Type(.{ | |
| 343 | .Union = .{ | |
| 344 | .layout = .Packed, | |
| 345 | .tag_type = null, | |
| 346 | .fields = &[_]TypeInfo.UnionField{ | |
| 347 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 348 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 349 | }, | |
| 350 | .decls = &[_]TypeInfo.Declaration{}, | |
| 351 | }, | |
| 352 | }); | |
| 353 | var packed_untagged = PackedUntagged{ .signed = -1 }; | |
| 354 | testing.expectEqual(@as(i32, -1), packed_untagged.signed); | |
| 355 | testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned); | |
| 356 | ||
| 357 | const Tag = @Type(.{ | |
| 358 | .Enum = .{ | |
| 359 | .layout = .Auto, | |
| 360 | .tag_type = u1, | |
| 361 | .fields = &[_]TypeInfo.EnumField{ | |
| 362 | .{ .name = "signed", .value = 0 }, | |
| 363 | .{ .name = "unsigned", .value = 1 }, | |
| 364 | }, | |
| 365 | .decls = &[_]TypeInfo.Declaration{}, | |
| 366 | .is_exhaustive = true, | |
| 367 | }, | |
| 368 | }); | |
| 369 | const Tagged = @Type(.{ | |
| 370 | .Union = .{ | |
| 371 | .layout = .Auto, | |
| 372 | .tag_type = Tag, | |
| 373 | .fields = &[_]TypeInfo.UnionField{ | |
| 374 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 375 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 376 | }, | |
| 377 | .decls = &[_]TypeInfo.Declaration{}, | |
| 378 | }, | |
| 379 | }); | |
| 380 | var tagged = Tagged{ .signed = -1 }; | |
| 381 | testing.expectEqual(Tag.signed, tagged); | |
| 382 | tagged = .{ .unsigned = 1 }; | |
| 383 | testing.expectEqual(Tag.unsigned, tagged); | |
| 384 | } | |
| 385 | ||
| 386 | test "Type.Union from Type.Enum" { | |
| 387 | const Tag = @Type(.{ | |
| 388 | .Enum = .{ | |
| 389 | .layout = .Auto, | |
| 390 | .tag_type = u0, | |
| 391 | .fields = &[_]TypeInfo.EnumField{ | |
| 392 | .{ .name = "working_as_expected", .value = 0 }, | |
| 393 | }, | |
| 394 | .decls = &[_]TypeInfo.Declaration{}, | |
| 395 | .is_exhaustive = true, | |
| 396 | }, | |
| 397 | }); | |
| 398 | const T = @Type(.{ | |
| 399 | .Union = .{ | |
| 400 | .layout = .Auto, | |
| 401 | .tag_type = Tag, | |
| 402 | .fields = &[_]TypeInfo.UnionField{ | |
| 403 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 404 | }, | |
| 405 | .decls = &[_]TypeInfo.Declaration{}, | |
| 406 | }, | |
| 407 | }); | |
| 408 | _ = T; | |
| 409 | _ = @typeInfo(T).Union; | |
| 410 | } | |
| 411 | ||
| 412 | test "Type.Union from regular enum" { | |
| 413 | const E = enum { working_as_expected = 0 }; | |
| 414 | const T = @Type(.{ | |
| 415 | .Union = .{ | |
| 416 | .layout = .Auto, | |
| 417 | .tag_type = E, | |
| 418 | .fields = &[_]TypeInfo.UnionField{ | |
| 419 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 420 | }, | |
| 421 | .decls = &[_]TypeInfo.Declaration{}, | |
| 422 | }, | |
| 423 | }); | |
| 424 | _ = T; | |
| 425 | _ = @typeInfo(T).Union; | |
| 426 | } | |
| 427 | ||
| 428 | test "Type.Fn" { | |
| 429 | // wasm doesn't support align attributes on functions | |
| 430 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 431 | ||
| 432 | const foo = struct { | |
| 433 | fn func(a: usize, b: bool) align(4) callconv(.C) usize { | |
| 434 | return 0; | |
| 435 | } | |
| 436 | }.func; | |
| 437 | const Foo = @Type(@typeInfo(@TypeOf(foo))); | |
| 438 | const foo_2: Foo = foo; | |
| 439 | } | |
| 440 | ||
| 441 | test "Type.BoundFn" { | |
| 442 | // wasm doesn't support align attributes on functions | |
| 443 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 444 | ||
| 445 | const TestStruct = packed struct { | |
| 446 | pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void {} | |
| 447 | }; | |
| 448 | const test_instance: TestStruct = undefined; | |
| 449 | testing.expect(std.meta.eql( | |
| 450 | @typeName(@TypeOf(test_instance.foo)), | |
| 451 | @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))), | |
| 452 | )); | |
| 453 | } |
test/behavior/type_info.zig created+485| ... | ... | @@ -0,0 +1,485 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | const TypeInfo = std.builtin.TypeInfo; | |
| 6 | const TypeId = std.builtin.TypeId; | |
| 7 | ||
| 8 | const expect = std.testing.expect; | |
| 9 | const expectEqualStrings = std.testing.expectEqualStrings; | |
| 10 | ||
| 11 | test "type info: tag type, void info" { | |
| 12 | testBasic(); | |
| 13 | comptime testBasic(); | |
| 14 | } | |
| 15 | ||
| 16 | fn testBasic() void { | |
| 17 | expect(@typeInfo(TypeInfo).Union.tag_type == TypeId); | |
| 18 | const void_info = @typeInfo(void); | |
| 19 | expect(void_info == TypeId.Void); | |
| 20 | expect(void_info.Void == {}); | |
| 21 | } | |
| 22 | ||
| 23 | test "type info: integer, floating point type info" { | |
| 24 | testIntFloat(); | |
| 25 | comptime testIntFloat(); | |
| 26 | } | |
| 27 | ||
| 28 | fn testIntFloat() void { | |
| 29 | const u8_info = @typeInfo(u8); | |
| 30 | expect(u8_info == .Int); | |
| 31 | expect(u8_info.Int.signedness == .unsigned); | |
| 32 | expect(u8_info.Int.bits == 8); | |
| 33 | ||
| 34 | const f64_info = @typeInfo(f64); | |
| 35 | expect(f64_info == .Float); | |
| 36 | expect(f64_info.Float.bits == 64); | |
| 37 | } | |
| 38 | ||
| 39 | test "type info: pointer type info" { | |
| 40 | testPointer(); | |
| 41 | comptime testPointer(); | |
| 42 | } | |
| 43 | ||
| 44 | fn testPointer() void { | |
| 45 | const u32_ptr_info = @typeInfo(*u32); | |
| 46 | expect(u32_ptr_info == .Pointer); | |
| 47 | expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One); | |
| 48 | expect(u32_ptr_info.Pointer.is_const == false); | |
| 49 | expect(u32_ptr_info.Pointer.is_volatile == false); | |
| 50 | expect(u32_ptr_info.Pointer.alignment == @alignOf(u32)); | |
| 51 | expect(u32_ptr_info.Pointer.child == u32); | |
| 52 | expect(u32_ptr_info.Pointer.sentinel == null); | |
| 53 | } | |
| 54 | ||
| 55 | test "type info: unknown length pointer type info" { | |
| 56 | testUnknownLenPtr(); | |
| 57 | comptime testUnknownLenPtr(); | |
| 58 | } | |
| 59 | ||
| 60 | fn testUnknownLenPtr() void { | |
| 61 | const u32_ptr_info = @typeInfo([*]const volatile f64); | |
| 62 | expect(u32_ptr_info == .Pointer); | |
| 63 | expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); | |
| 64 | expect(u32_ptr_info.Pointer.is_const == true); | |
| 65 | expect(u32_ptr_info.Pointer.is_volatile == true); | |
| 66 | expect(u32_ptr_info.Pointer.sentinel == null); | |
| 67 | expect(u32_ptr_info.Pointer.alignment == @alignOf(f64)); | |
| 68 | expect(u32_ptr_info.Pointer.child == f64); | |
| 69 | } | |
| 70 | ||
| 71 | test "type info: null terminated pointer type info" { | |
| 72 | testNullTerminatedPtr(); | |
| 73 | comptime testNullTerminatedPtr(); | |
| 74 | } | |
| 75 | ||
| 76 | fn testNullTerminatedPtr() void { | |
| 77 | const ptr_info = @typeInfo([*:0]u8); | |
| 78 | expect(ptr_info == .Pointer); | |
| 79 | expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); | |
| 80 | expect(ptr_info.Pointer.is_const == false); | |
| 81 | expect(ptr_info.Pointer.is_volatile == false); | |
| 82 | expect(ptr_info.Pointer.sentinel.? == 0); | |
| 83 | ||
| 84 | expect(@typeInfo([:0]u8).Pointer.sentinel != null); | |
| 85 | } | |
| 86 | ||
| 87 | test "type info: C pointer type info" { | |
| 88 | testCPtr(); | |
| 89 | comptime testCPtr(); | |
| 90 | } | |
| 91 | ||
| 92 | fn testCPtr() void { | |
| 93 | const ptr_info = @typeInfo([*c]align(4) const i8); | |
| 94 | expect(ptr_info == .Pointer); | |
| 95 | expect(ptr_info.Pointer.size == .C); | |
| 96 | expect(ptr_info.Pointer.is_const); | |
| 97 | expect(!ptr_info.Pointer.is_volatile); | |
| 98 | expect(ptr_info.Pointer.alignment == 4); | |
| 99 | expect(ptr_info.Pointer.child == i8); | |
| 100 | } | |
| 101 | ||
| 102 | test "type info: slice type info" { | |
| 103 | testSlice(); | |
| 104 | comptime testSlice(); | |
| 105 | } | |
| 106 | ||
| 107 | fn testSlice() void { | |
| 108 | const u32_slice_info = @typeInfo([]u32); | |
| 109 | expect(u32_slice_info == .Pointer); | |
| 110 | expect(u32_slice_info.Pointer.size == .Slice); | |
| 111 | expect(u32_slice_info.Pointer.is_const == false); | |
| 112 | expect(u32_slice_info.Pointer.is_volatile == false); | |
| 113 | expect(u32_slice_info.Pointer.alignment == 4); | |
| 114 | expect(u32_slice_info.Pointer.child == u32); | |
| 115 | } | |
| 116 | ||
| 117 | test "type info: array type info" { | |
| 118 | testArray(); | |
| 119 | comptime testArray(); | |
| 120 | } | |
| 121 | ||
| 122 | fn testArray() void { | |
| 123 | { | |
| 124 | const info = @typeInfo([42]u8); | |
| 125 | expect(info == .Array); | |
| 126 | expect(info.Array.len == 42); | |
| 127 | expect(info.Array.child == u8); | |
| 128 | expect(info.Array.sentinel == null); | |
| 129 | } | |
| 130 | ||
| 131 | { | |
| 132 | const info = @typeInfo([10:0]u8); | |
| 133 | expect(info.Array.len == 10); | |
| 134 | expect(info.Array.child == u8); | |
| 135 | expect(info.Array.sentinel.? == @as(u8, 0)); | |
| 136 | expect(@sizeOf([10:0]u8) == info.Array.len + 1); | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 | test "type info: optional type info" { | |
| 141 | testOptional(); | |
| 142 | comptime testOptional(); | |
| 143 | } | |
| 144 | ||
| 145 | fn testOptional() void { | |
| 146 | const null_info = @typeInfo(?void); | |
| 147 | expect(null_info == .Optional); | |
| 148 | expect(null_info.Optional.child == void); | |
| 149 | } | |
| 150 | ||
| 151 | test "type info: error set, error union info" { | |
| 152 | testErrorSet(); | |
| 153 | comptime testErrorSet(); | |
| 154 | } | |
| 155 | ||
| 156 | fn testErrorSet() void { | |
| 157 | const TestErrorSet = error{ | |
| 158 | First, | |
| 159 | Second, | |
| 160 | Third, | |
| 161 | }; | |
| 162 | ||
| 163 | const error_set_info = @typeInfo(TestErrorSet); | |
| 164 | expect(error_set_info == .ErrorSet); | |
| 165 | expect(error_set_info.ErrorSet.?.len == 3); | |
| 166 | expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "First")); | |
| 167 | ||
| 168 | const error_union_info = @typeInfo(TestErrorSet!usize); | |
| 169 | expect(error_union_info == .ErrorUnion); | |
| 170 | expect(error_union_info.ErrorUnion.error_set == TestErrorSet); | |
| 171 | expect(error_union_info.ErrorUnion.payload == usize); | |
| 172 | ||
| 173 | const global_info = @typeInfo(anyerror); | |
| 174 | expect(global_info == .ErrorSet); | |
| 175 | expect(global_info.ErrorSet == null); | |
| 176 | } | |
| 177 | ||
| 178 | test "type info: enum info" { | |
| 179 | testEnum(); | |
| 180 | comptime testEnum(); | |
| 181 | } | |
| 182 | ||
| 183 | fn testEnum() void { | |
| 184 | const Os = enum { | |
| 185 | Windows, | |
| 186 | Macos, | |
| 187 | Linux, | |
| 188 | FreeBSD, | |
| 189 | }; | |
| 190 | ||
| 191 | const os_info = @typeInfo(Os); | |
| 192 | expect(os_info == .Enum); | |
| 193 | expect(os_info.Enum.layout == .Auto); | |
| 194 | expect(os_info.Enum.fields.len == 4); | |
| 195 | expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos")); | |
| 196 | expect(os_info.Enum.fields[3].value == 3); | |
| 197 | expect(os_info.Enum.tag_type == u2); | |
| 198 | expect(os_info.Enum.decls.len == 0); | |
| 199 | } | |
| 200 | ||
| 201 | test "type info: union info" { | |
| 202 | testUnion(); | |
| 203 | comptime testUnion(); | |
| 204 | } | |
| 205 | ||
| 206 | fn testUnion() void { | |
| 207 | const typeinfo_info = @typeInfo(TypeInfo); | |
| 208 | expect(typeinfo_info == .Union); | |
| 209 | expect(typeinfo_info.Union.layout == .Auto); | |
| 210 | expect(typeinfo_info.Union.tag_type.? == TypeId); | |
| 211 | expect(typeinfo_info.Union.fields.len == 25); | |
| 212 | expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int)); | |
| 213 | expect(typeinfo_info.Union.decls.len == 22); | |
| 214 | ||
| 215 | const TestNoTagUnion = union { | |
| 216 | Foo: void, | |
| 217 | Bar: u32, | |
| 218 | }; | |
| 219 | ||
| 220 | const notag_union_info = @typeInfo(TestNoTagUnion); | |
| 221 | expect(notag_union_info == .Union); | |
| 222 | expect(notag_union_info.Union.tag_type == null); | |
| 223 | expect(notag_union_info.Union.layout == .Auto); | |
| 224 | expect(notag_union_info.Union.fields.len == 2); | |
| 225 | expect(notag_union_info.Union.fields[0].alignment == @alignOf(void)); | |
| 226 | expect(notag_union_info.Union.fields[1].field_type == u32); | |
| 227 | expect(notag_union_info.Union.fields[1].alignment == @alignOf(u32)); | |
| 228 | ||
| 229 | const TestExternUnion = extern union { | |
| 230 | foo: *c_void, | |
| 231 | }; | |
| 232 | ||
| 233 | const extern_union_info = @typeInfo(TestExternUnion); | |
| 234 | expect(extern_union_info.Union.layout == .Extern); | |
| 235 | expect(extern_union_info.Union.tag_type == null); | |
| 236 | expect(extern_union_info.Union.fields[0].field_type == *c_void); | |
| 237 | } | |
| 238 | ||
| 239 | test "type info: struct info" { | |
| 240 | testStruct(); | |
| 241 | comptime testStruct(); | |
| 242 | } | |
| 243 | ||
| 244 | fn testStruct() void { | |
| 245 | const unpacked_struct_info = @typeInfo(TestUnpackedStruct); | |
| 246 | expect(unpacked_struct_info.Struct.is_tuple == false); | |
| 247 | expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); | |
| 248 | expect(unpacked_struct_info.Struct.fields[0].default_value.? == 4); | |
| 249 | expectEqualStrings("foobar", unpacked_struct_info.Struct.fields[1].default_value.?); | |
| 250 | ||
| 251 | const struct_info = @typeInfo(TestStruct); | |
| 252 | expect(struct_info == .Struct); | |
| 253 | expect(struct_info.Struct.is_tuple == false); | |
| 254 | expect(struct_info.Struct.layout == .Packed); | |
| 255 | expect(struct_info.Struct.fields.len == 4); | |
| 256 | expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize)); | |
| 257 | expect(struct_info.Struct.fields[2].field_type == *TestStruct); | |
| 258 | expect(struct_info.Struct.fields[2].default_value == null); | |
| 259 | expect(struct_info.Struct.fields[3].default_value.? == 4); | |
| 260 | expect(struct_info.Struct.fields[3].alignment == 1); | |
| 261 | expect(struct_info.Struct.decls.len == 2); | |
| 262 | expect(struct_info.Struct.decls[0].is_pub); | |
| 263 | expect(!struct_info.Struct.decls[0].data.Fn.is_extern); | |
| 264 | expect(struct_info.Struct.decls[0].data.Fn.lib_name == null); | |
| 265 | expect(struct_info.Struct.decls[0].data.Fn.return_type == void); | |
| 266 | expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void); | |
| 267 | } | |
| 268 | ||
| 269 | const TestUnpackedStruct = struct { | |
| 270 | fieldA: u32 = 4, | |
| 271 | fieldB: *const [6:0]u8 = "foobar", | |
| 272 | }; | |
| 273 | ||
| 274 | const TestStruct = packed struct { | |
| 275 | fieldA: usize align(2 * @alignOf(usize)), | |
| 276 | fieldB: void, | |
| 277 | fieldC: *Self, | |
| 278 | fieldD: u32 = 4, | |
| 279 | ||
| 280 | pub fn foo(self: *const Self) void {} | |
| 281 | const Self = @This(); | |
| 282 | }; | |
| 283 | ||
| 284 | test "type info: opaque info" { | |
| 285 | testOpaque(); | |
| 286 | comptime testOpaque(); | |
| 287 | } | |
| 288 | ||
| 289 | fn testOpaque() void { | |
| 290 | const Foo = opaque { | |
| 291 | const A = 1; | |
| 292 | fn b() void {} | |
| 293 | }; | |
| 294 | ||
| 295 | const foo_info = @typeInfo(Foo); | |
| 296 | expect(foo_info.Opaque.decls.len == 2); | |
| 297 | } | |
| 298 | ||
| 299 | test "type info: function type info" { | |
| 300 | // wasm doesn't support align attributes on functions | |
| 301 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 302 | testFunction(); | |
| 303 | comptime testFunction(); | |
| 304 | } | |
| 305 | ||
| 306 | fn testFunction() void { | |
| 307 | const fn_info = @typeInfo(@TypeOf(foo)); | |
| 308 | expect(fn_info == .Fn); | |
| 309 | // TODO Fix this before merging the branch | |
| 310 | //expect(fn_info.Fn.alignment > 0); | |
| 311 | expect(fn_info.Fn.calling_convention == .C); | |
| 312 | expect(!fn_info.Fn.is_generic); | |
| 313 | expect(fn_info.Fn.args.len == 2); | |
| 314 | expect(fn_info.Fn.is_var_args); | |
| 315 | expect(fn_info.Fn.return_type.? == usize); | |
| 316 | const fn_aligned_info = @typeInfo(@TypeOf(fooAligned)); | |
| 317 | expect(fn_aligned_info.Fn.alignment == 4); | |
| 318 | ||
| 319 | const test_instance: TestStruct = undefined; | |
| 320 | const bound_fn_info = @typeInfo(@TypeOf(test_instance.foo)); | |
| 321 | expect(bound_fn_info == .BoundFn); | |
| 322 | expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct); | |
| 323 | } | |
| 324 | ||
| 325 | extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; | |
| 326 | extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; | |
| 327 | ||
| 328 | test "typeInfo with comptime parameter in struct fn def" { | |
| 329 | const S = struct { | |
| 330 | pub fn func(comptime x: f32) void {} | |
| 331 | }; | |
| 332 | comptime var info = @typeInfo(S); | |
| 333 | } | |
| 334 | ||
| 335 | test "type info: vectors" { | |
| 336 | testVector(); | |
| 337 | comptime testVector(); | |
| 338 | } | |
| 339 | ||
| 340 | fn testVector() void { | |
| 341 | const vec_info = @typeInfo(std.meta.Vector(4, i32)); | |
| 342 | expect(vec_info == .Vector); | |
| 343 | expect(vec_info.Vector.len == 4); | |
| 344 | expect(vec_info.Vector.child == i32); | |
| 345 | } | |
| 346 | ||
| 347 | test "type info: anyframe and anyframe->T" { | |
| 348 | testAnyFrame(); | |
| 349 | comptime testAnyFrame(); | |
| 350 | } | |
| 351 | ||
| 352 | fn testAnyFrame() void { | |
| 353 | { | |
| 354 | const anyframe_info = @typeInfo(anyframe->i32); | |
| 355 | expect(anyframe_info == .AnyFrame); | |
| 356 | expect(anyframe_info.AnyFrame.child.? == i32); | |
| 357 | } | |
| 358 | ||
| 359 | { | |
| 360 | const anyframe_info = @typeInfo(anyframe); | |
| 361 | expect(anyframe_info == .AnyFrame); | |
| 362 | expect(anyframe_info.AnyFrame.child == null); | |
| 363 | } | |
| 364 | } | |
| 365 | ||
| 366 | test "type info: pass to function" { | |
| 367 | _ = passTypeInfo(@typeInfo(void)); | |
| 368 | _ = comptime passTypeInfo(@typeInfo(void)); | |
| 369 | } | |
| 370 | ||
| 371 | fn passTypeInfo(comptime info: TypeInfo) type { | |
| 372 | return void; | |
| 373 | } | |
| 374 | ||
| 375 | test "type info: TypeId -> TypeInfo impl cast" { | |
| 376 | _ = passTypeInfo(TypeId.Void); | |
| 377 | _ = comptime passTypeInfo(TypeId.Void); | |
| 378 | } | |
| 379 | ||
| 380 | test "type info: extern fns with and without lib names" { | |
| 381 | const S = struct { | |
| 382 | extern fn bar1() void; | |
| 383 | extern "cool" fn bar2() void; | |
| 384 | }; | |
| 385 | const info = @typeInfo(S); | |
| 386 | comptime { | |
| 387 | for (info.Struct.decls) |decl| { | |
| 388 | if (std.mem.eql(u8, decl.name, "bar1")) { | |
| 389 | expect(decl.data.Fn.lib_name == null); | |
| 390 | } else { | |
| 391 | expectEqualStrings("cool", decl.data.Fn.lib_name.?); | |
| 392 | } | |
| 393 | } | |
| 394 | } | |
| 395 | } | |
| 396 | ||
| 397 | test "data field is a compile-time value" { | |
| 398 | const S = struct { | |
| 399 | const Bar = @as(isize, -1); | |
| 400 | }; | |
| 401 | comptime expect(@typeInfo(S).Struct.decls[0].data.Var == isize); | |
| 402 | } | |
| 403 | ||
| 404 | test "sentinel of opaque pointer type" { | |
| 405 | const c_void_info = @typeInfo(*c_void); | |
| 406 | expect(c_void_info.Pointer.sentinel == null); | |
| 407 | } | |
| 408 | ||
| 409 | test "@typeInfo does not force declarations into existence" { | |
| 410 | const S = struct { | |
| 411 | x: i32, | |
| 412 | ||
| 413 | fn doNotReferenceMe() void { | |
| 414 | @compileError("test failed"); | |
| 415 | } | |
| 416 | }; | |
| 417 | comptime expect(@typeInfo(S).Struct.fields.len == 1); | |
| 418 | } | |
| 419 | ||
| 420 | test "defaut value for a var-typed field" { | |
| 421 | const S = struct { x: anytype }; | |
| 422 | expect(@typeInfo(S).Struct.fields[0].default_value == null); | |
| 423 | } | |
| 424 | ||
| 425 | fn add(a: i32, b: i32) i32 { | |
| 426 | return a + b; | |
| 427 | } | |
| 428 | ||
| 429 | test "type info for async frames" { | |
| 430 | switch (@typeInfo(@Frame(add))) { | |
| 431 | .Frame => |frame| { | |
| 432 | expect(frame.function == add); | |
| 433 | }, | |
| 434 | else => unreachable, | |
| 435 | } | |
| 436 | } | |
| 437 | ||
| 438 | test "type info: value is correctly copied" { | |
| 439 | comptime { | |
| 440 | var ptrInfo = @typeInfo([]u32); | |
| 441 | ptrInfo.Pointer.size = .One; | |
| 442 | expect(@typeInfo([]u32).Pointer.size == .Slice); | |
| 443 | } | |
| 444 | } | |
| 445 | ||
| 446 | test "Declarations are returned in declaration order" { | |
| 447 | const S = struct { | |
| 448 | const a = 1; | |
| 449 | const b = 2; | |
| 450 | const c = 3; | |
| 451 | const d = 4; | |
| 452 | const e = 5; | |
| 453 | }; | |
| 454 | const d = @typeInfo(S).Struct.decls; | |
| 455 | expect(std.mem.eql(u8, d[0].name, "a")); | |
| 456 | expect(std.mem.eql(u8, d[1].name, "b")); | |
| 457 | expect(std.mem.eql(u8, d[2].name, "c")); | |
| 458 | expect(std.mem.eql(u8, d[3].name, "d")); | |
| 459 | expect(std.mem.eql(u8, d[4].name, "e")); | |
| 460 | } | |
| 461 | ||
| 462 | test "Struct.is_tuple" { | |
| 463 | expect(@typeInfo(@TypeOf(.{0})).Struct.is_tuple); | |
| 464 | expect(!@typeInfo(@TypeOf(.{ .a = 0 })).Struct.is_tuple); | |
| 465 | } | |
| 466 | ||
| 467 | test "StructField.is_comptime" { | |
| 468 | const info = @typeInfo(struct { x: u8 = 3, comptime y: u32 = 5 }).Struct; | |
| 469 | expect(!info.fields[0].is_comptime); | |
| 470 | expect(info.fields[1].is_comptime); | |
| 471 | } | |
| 472 | ||
| 473 | test "typeInfo resolves usingnamespace declarations" { | |
| 474 | const A = struct { | |
| 475 | pub const f1 = 42; | |
| 476 | }; | |
| 477 | ||
| 478 | const B = struct { | |
| 479 | const f0 = 42; | |
| 480 | usingnamespace A; | |
| 481 | }; | |
| 482 | ||
| 483 | expect(@typeInfo(B).Struct.decls.len == 2); | |
| 484 | //a | |
| 485 | } |
test/behavior/typename.zig created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | ||
| 5 | test "slice" { | |
| 6 | expectEqualSlices(u8, "[]u8", @typeName([]u8)); | |
| 7 | } |
test/behavior/undefined.zig created+69| ... | ... | @@ -0,0 +1,69 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | fn initStaticArray() [10]i32 { | |
| 6 | var array: [10]i32 = undefined; | |
| 7 | array[0] = 1; | |
| 8 | array[4] = 2; | |
| 9 | array[7] = 3; | |
| 10 | array[9] = 4; | |
| 11 | return array; | |
| 12 | } | |
| 13 | const static_array = initStaticArray(); | |
| 14 | test "init static array to undefined" { | |
| 15 | expect(static_array[0] == 1); | |
| 16 | expect(static_array[4] == 2); | |
| 17 | expect(static_array[7] == 3); | |
| 18 | expect(static_array[9] == 4); | |
| 19 | ||
| 20 | comptime { | |
| 21 | expect(static_array[0] == 1); | |
| 22 | expect(static_array[4] == 2); | |
| 23 | expect(static_array[7] == 3); | |
| 24 | expect(static_array[9] == 4); | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | const Foo = struct { | |
| 29 | x: i32, | |
| 30 | ||
| 31 | fn setFooXMethod(foo: *Foo) void { | |
| 32 | foo.x = 3; | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | fn setFooX(foo: *Foo) void { | |
| 37 | foo.x = 2; | |
| 38 | } | |
| 39 | ||
| 40 | test "assign undefined to struct" { | |
| 41 | comptime { | |
| 42 | var foo: Foo = undefined; | |
| 43 | setFooX(&foo); | |
| 44 | expect(foo.x == 2); | |
| 45 | } | |
| 46 | { | |
| 47 | var foo: Foo = undefined; | |
| 48 | setFooX(&foo); | |
| 49 | expect(foo.x == 2); | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | test "assign undefined to struct with method" { | |
| 54 | comptime { | |
| 55 | var foo: Foo = undefined; | |
| 56 | foo.setFooXMethod(); | |
| 57 | expect(foo.x == 3); | |
| 58 | } | |
| 59 | { | |
| 60 | var foo: Foo = undefined; | |
| 61 | foo.setFooXMethod(); | |
| 62 | expect(foo.x == 3); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | test "type name of undefined" { | |
| 67 | const x = undefined; | |
| 68 | expect(mem.eql(u8, @typeName(@TypeOf(x)), "(undefined)")); | |
| 69 | } |
test/behavior/underscore.zig created+28| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "ignore lval with underscore" { | |
| 5 | _ = false; | |
| 6 | } | |
| 7 | ||
| 8 | test "ignore lval with underscore (for loop)" { | |
| 9 | for ([_]void{}) |_, i| { | |
| 10 | for ([_]void{}) |_, j| { | |
| 11 | break; | |
| 12 | } | |
| 13 | break; | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | test "ignore lval with underscore (while loop)" { | |
| 18 | while (optionalReturnError()) |_| { | |
| 19 | while (optionalReturnError()) |_| { | |
| 20 | break; | |
| 21 | } else |_| {} | |
| 22 | break; | |
| 23 | } else |_| {} | |
| 24 | } | |
| 25 | ||
| 26 | fn optionalReturnError() !?u32 { | |
| 27 | return error.optionalReturnError; | |
| 28 | } |
test/behavior/union.zig created+806| ... | ... | @@ -0,0 +1,806 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const Tag = std.meta.Tag; | |
| 5 | ||
| 6 | const Value = union(enum) { | |
| 7 | Int: u64, | |
| 8 | Array: [9]u8, | |
| 9 | }; | |
| 10 | ||
| 11 | const Agg = struct { | |
| 12 | val1: Value, | |
| 13 | val2: Value, | |
| 14 | }; | |
| 15 | ||
| 16 | const v1 = Value{ .Int = 1234 }; | |
| 17 | const v2 = Value{ .Array = [_]u8{3} ** 9 }; | |
| 18 | ||
| 19 | const err = @as(anyerror!Agg, Agg{ | |
| 20 | .val1 = v1, | |
| 21 | .val2 = v2, | |
| 22 | }); | |
| 23 | ||
| 24 | const array = [_]Value{ | |
| 25 | v1, | |
| 26 | v2, | |
| 27 | v1, | |
| 28 | v2, | |
| 29 | }; | |
| 30 | ||
| 31 | test "unions embedded in aggregate types" { | |
| 32 | switch (array[1]) { | |
| 33 | Value.Array => |arr| expect(arr[4] == 3), | |
| 34 | else => unreachable, | |
| 35 | } | |
| 36 | switch ((err catch unreachable).val1) { | |
| 37 | Value.Int => |x| expect(x == 1234), | |
| 38 | else => unreachable, | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | const Foo = union { | |
| 43 | float: f64, | |
| 44 | int: i32, | |
| 45 | }; | |
| 46 | ||
| 47 | test "basic unions" { | |
| 48 | var foo = Foo{ .int = 1 }; | |
| 49 | expect(foo.int == 1); | |
| 50 | foo = Foo{ .float = 12.34 }; | |
| 51 | expect(foo.float == 12.34); | |
| 52 | } | |
| 53 | ||
| 54 | test "comptime union field access" { | |
| 55 | comptime { | |
| 56 | var foo = Foo{ .int = 0 }; | |
| 57 | expect(foo.int == 0); | |
| 58 | ||
| 59 | foo = Foo{ .float = 42.42 }; | |
| 60 | expect(foo.float == 42.42); | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | test "init union with runtime value" { | |
| 65 | var foo: Foo = undefined; | |
| 66 | ||
| 67 | setFloat(&foo, 12.34); | |
| 68 | expect(foo.float == 12.34); | |
| 69 | ||
| 70 | setInt(&foo, 42); | |
| 71 | expect(foo.int == 42); | |
| 72 | } | |
| 73 | ||
| 74 | fn setFloat(foo: *Foo, x: f64) void { | |
| 75 | foo.* = Foo{ .float = x }; | |
| 76 | } | |
| 77 | ||
| 78 | fn setInt(foo: *Foo, x: i32) void { | |
| 79 | foo.* = Foo{ .int = x }; | |
| 80 | } | |
| 81 | ||
| 82 | const FooExtern = extern union { | |
| 83 | float: f64, | |
| 84 | int: i32, | |
| 85 | }; | |
| 86 | ||
| 87 | test "basic extern unions" { | |
| 88 | var foo = FooExtern{ .int = 1 }; | |
| 89 | expect(foo.int == 1); | |
| 90 | foo.float = 12.34; | |
| 91 | expect(foo.float == 12.34); | |
| 92 | } | |
| 93 | ||
| 94 | const Letter = enum { | |
| 95 | A, | |
| 96 | B, | |
| 97 | C, | |
| 98 | }; | |
| 99 | const Payload = union(Letter) { | |
| 100 | A: i32, | |
| 101 | B: f64, | |
| 102 | C: bool, | |
| 103 | }; | |
| 104 | ||
| 105 | test "union with specified enum tag" { | |
| 106 | doTest(); | |
| 107 | comptime doTest(); | |
| 108 | } | |
| 109 | ||
| 110 | fn doTest() void { | |
| 111 | expect(bar(Payload{ .A = 1234 }) == -10); | |
| 112 | } | |
| 113 | ||
| 114 | fn bar(value: Payload) i32 { | |
| 115 | expect(@as(Letter, value) == Letter.A); | |
| 116 | return switch (value) { | |
| 117 | Payload.A => |x| return x - 1244, | |
| 118 | Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21, | |
| 119 | Payload.C => |x| if (x) @as(i32, 30) else 31, | |
| 120 | }; | |
| 121 | } | |
| 122 | ||
| 123 | const MultipleChoice = union(enum(u32)) { | |
| 124 | A = 20, | |
| 125 | B = 40, | |
| 126 | C = 60, | |
| 127 | D = 1000, | |
| 128 | }; | |
| 129 | test "simple union(enum(u32))" { | |
| 130 | var x = MultipleChoice.C; | |
| 131 | expect(x == MultipleChoice.C); | |
| 132 | expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60); | |
| 133 | } | |
| 134 | ||
| 135 | const MultipleChoice2 = union(enum(u32)) { | |
| 136 | Unspecified1: i32, | |
| 137 | A: f32 = 20, | |
| 138 | Unspecified2: void, | |
| 139 | B: bool = 40, | |
| 140 | Unspecified3: i32, | |
| 141 | C: i8 = 60, | |
| 142 | Unspecified4: void, | |
| 143 | D: void = 1000, | |
| 144 | Unspecified5: i32, | |
| 145 | }; | |
| 146 | ||
| 147 | test "union(enum(u32)) with specified and unspecified tag values" { | |
| 148 | comptime expect(Tag(Tag(MultipleChoice2)) == u32); | |
| 149 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 150 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 151 | } | |
| 152 | ||
| 153 | fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void { | |
| 154 | expect(@enumToInt(@as(Tag(MultipleChoice2), x)) == 60); | |
| 155 | expect(1123 == switch (x) { | |
| 156 | MultipleChoice2.A => 1, | |
| 157 | MultipleChoice2.B => 2, | |
| 158 | MultipleChoice2.C => |v| @as(i32, 1000) + v, | |
| 159 | MultipleChoice2.D => 4, | |
| 160 | MultipleChoice2.Unspecified1 => 5, | |
| 161 | MultipleChoice2.Unspecified2 => 6, | |
| 162 | MultipleChoice2.Unspecified3 => 7, | |
| 163 | MultipleChoice2.Unspecified4 => 8, | |
| 164 | MultipleChoice2.Unspecified5 => 9, | |
| 165 | }); | |
| 166 | } | |
| 167 | ||
| 168 | const ExternPtrOrInt = extern union { | |
| 169 | ptr: *u8, | |
| 170 | int: u64, | |
| 171 | }; | |
| 172 | test "extern union size" { | |
| 173 | comptime expect(@sizeOf(ExternPtrOrInt) == 8); | |
| 174 | } | |
| 175 | ||
| 176 | const PackedPtrOrInt = packed union { | |
| 177 | ptr: *u8, | |
| 178 | int: u64, | |
| 179 | }; | |
| 180 | test "extern union size" { | |
| 181 | comptime expect(@sizeOf(PackedPtrOrInt) == 8); | |
| 182 | } | |
| 183 | ||
| 184 | const ZeroBits = union { | |
| 185 | OnlyField: void, | |
| 186 | }; | |
| 187 | test "union with only 1 field which is void should be zero bits" { | |
| 188 | comptime expect(@sizeOf(ZeroBits) == 0); | |
| 189 | } | |
| 190 | ||
| 191 | const TheTag = enum { | |
| 192 | A, | |
| 193 | B, | |
| 194 | C, | |
| 195 | }; | |
| 196 | const TheUnion = union(TheTag) { | |
| 197 | A: i32, | |
| 198 | B: i32, | |
| 199 | C: i32, | |
| 200 | }; | |
| 201 | test "union field access gives the enum values" { | |
| 202 | expect(TheUnion.A == TheTag.A); | |
| 203 | expect(TheUnion.B == TheTag.B); | |
| 204 | expect(TheUnion.C == TheTag.C); | |
| 205 | } | |
| 206 | ||
| 207 | test "cast union to tag type of union" { | |
| 208 | testCastUnionToTag(TheUnion{ .B = 1234 }); | |
| 209 | comptime testCastUnionToTag(TheUnion{ .B = 1234 }); | |
| 210 | } | |
| 211 | ||
| 212 | fn testCastUnionToTag(x: TheUnion) void { | |
| 213 | expect(@as(TheTag, x) == TheTag.B); | |
| 214 | } | |
| 215 | ||
| 216 | test "cast tag type of union to union" { | |
| 217 | var x: Value2 = Letter2.B; | |
| 218 | expect(@as(Letter2, x) == Letter2.B); | |
| 219 | } | |
| 220 | const Letter2 = enum { | |
| 221 | A, | |
| 222 | B, | |
| 223 | C, | |
| 224 | }; | |
| 225 | const Value2 = union(Letter2) { | |
| 226 | A: i32, | |
| 227 | B, | |
| 228 | C, | |
| 229 | }; | |
| 230 | ||
| 231 | test "implicit cast union to its tag type" { | |
| 232 | var x: Value2 = Letter2.B; | |
| 233 | expect(x == Letter2.B); | |
| 234 | giveMeLetterB(x); | |
| 235 | } | |
| 236 | fn giveMeLetterB(x: Letter2) void { | |
| 237 | expect(x == Value2.B); | |
| 238 | } | |
| 239 | ||
| 240 | pub const PackThis = union(enum) { | |
| 241 | Invalid: bool, | |
| 242 | StringLiteral: u2, | |
| 243 | }; | |
| 244 | ||
| 245 | test "constant packed union" { | |
| 246 | testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }}); | |
| 247 | } | |
| 248 | ||
| 249 | fn testConstPackedUnion(expected_tokens: []const PackThis) void { | |
| 250 | expect(expected_tokens[0].StringLiteral == 1); | |
| 251 | } | |
| 252 | ||
| 253 | test "switch on union with only 1 field" { | |
| 254 | var r: PartialInst = undefined; | |
| 255 | r = PartialInst.Compiled; | |
| 256 | switch (r) { | |
| 257 | PartialInst.Compiled => { | |
| 258 | var z: PartialInstWithPayload = undefined; | |
| 259 | z = PartialInstWithPayload{ .Compiled = 1234 }; | |
| 260 | switch (z) { | |
| 261 | PartialInstWithPayload.Compiled => |x| { | |
| 262 | expect(x == 1234); | |
| 263 | return; | |
| 264 | }, | |
| 265 | } | |
| 266 | }, | |
| 267 | } | |
| 268 | unreachable; | |
| 269 | } | |
| 270 | ||
| 271 | const PartialInst = union(enum) { | |
| 272 | Compiled, | |
| 273 | }; | |
| 274 | ||
| 275 | const PartialInstWithPayload = union(enum) { | |
| 276 | Compiled: i32, | |
| 277 | }; | |
| 278 | ||
| 279 | test "access a member of tagged union with conflicting enum tag name" { | |
| 280 | const Bar = union(enum) { | |
| 281 | A: A, | |
| 282 | B: B, | |
| 283 | ||
| 284 | const A = u8; | |
| 285 | const B = void; | |
| 286 | }; | |
| 287 | ||
| 288 | comptime expect(Bar.A == u8); | |
| 289 | } | |
| 290 | ||
| 291 | test "tagged union initialization with runtime void" { | |
| 292 | expect(testTaggedUnionInit({})); | |
| 293 | } | |
| 294 | ||
| 295 | const TaggedUnionWithAVoid = union(enum) { | |
| 296 | A, | |
| 297 | B: i32, | |
| 298 | }; | |
| 299 | ||
| 300 | fn testTaggedUnionInit(x: anytype) bool { | |
| 301 | const y = TaggedUnionWithAVoid{ .A = x }; | |
| 302 | return @as(Tag(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A; | |
| 303 | } | |
| 304 | ||
| 305 | pub const UnionEnumNoPayloads = union(enum) { | |
| 306 | A, | |
| 307 | B, | |
| 308 | }; | |
| 309 | ||
| 310 | test "tagged union with no payloads" { | |
| 311 | const a = UnionEnumNoPayloads{ .B = {} }; | |
| 312 | switch (a) { | |
| 313 | Tag(UnionEnumNoPayloads).A => @panic("wrong"), | |
| 314 | Tag(UnionEnumNoPayloads).B => {}, | |
| 315 | } | |
| 316 | } | |
| 317 | ||
| 318 | test "union with only 1 field casted to its enum type" { | |
| 319 | const Literal = union(enum) { | |
| 320 | Number: f64, | |
| 321 | Bool: bool, | |
| 322 | }; | |
| 323 | ||
| 324 | const Expr = union(enum) { | |
| 325 | Literal: Literal, | |
| 326 | }; | |
| 327 | ||
| 328 | var e = Expr{ .Literal = Literal{ .Bool = true } }; | |
| 329 | const ExprTag = Tag(Expr); | |
| 330 | comptime expect(Tag(ExprTag) == u0); | |
| 331 | var t = @as(ExprTag, e); | |
| 332 | expect(t == Expr.Literal); | |
| 333 | } | |
| 334 | ||
| 335 | test "union with only 1 field casted to its enum type which has enum value specified" { | |
| 336 | const Literal = union(enum) { | |
| 337 | Number: f64, | |
| 338 | Bool: bool, | |
| 339 | }; | |
| 340 | ||
| 341 | const ExprTag = enum(comptime_int) { | |
| 342 | Literal = 33, | |
| 343 | }; | |
| 344 | ||
| 345 | const Expr = union(ExprTag) { | |
| 346 | Literal: Literal, | |
| 347 | }; | |
| 348 | ||
| 349 | var e = Expr{ .Literal = Literal{ .Bool = true } }; | |
| 350 | comptime expect(Tag(ExprTag) == comptime_int); | |
| 351 | var t = @as(ExprTag, e); | |
| 352 | expect(t == Expr.Literal); | |
| 353 | expect(@enumToInt(t) == 33); | |
| 354 | comptime expect(@enumToInt(t) == 33); | |
| 355 | } | |
| 356 | ||
| 357 | test "@enumToInt works on unions" { | |
| 358 | const Bar = union(enum) { | |
| 359 | A: bool, | |
| 360 | B: u8, | |
| 361 | C, | |
| 362 | }; | |
| 363 | ||
| 364 | const a = Bar{ .A = true }; | |
| 365 | var b = Bar{ .B = undefined }; | |
| 366 | var c = Bar.C; | |
| 367 | expect(@enumToInt(a) == 0); | |
| 368 | expect(@enumToInt(b) == 1); | |
| 369 | expect(@enumToInt(c) == 2); | |
| 370 | } | |
| 371 | ||
| 372 | const Attribute = union(enum) { | |
| 373 | A: bool, | |
| 374 | B: u8, | |
| 375 | }; | |
| 376 | ||
| 377 | fn setAttribute(attr: Attribute) void {} | |
| 378 | ||
| 379 | fn Setter(attr: Attribute) type { | |
| 380 | return struct { | |
| 381 | fn set() void { | |
| 382 | setAttribute(attr); | |
| 383 | } | |
| 384 | }; | |
| 385 | } | |
| 386 | ||
| 387 | test "comptime union field value equality" { | |
| 388 | const a0 = Setter(Attribute{ .A = false }); | |
| 389 | const a1 = Setter(Attribute{ .A = true }); | |
| 390 | const a2 = Setter(Attribute{ .A = false }); | |
| 391 | ||
| 392 | const b0 = Setter(Attribute{ .B = 5 }); | |
| 393 | const b1 = Setter(Attribute{ .B = 9 }); | |
| 394 | const b2 = Setter(Attribute{ .B = 5 }); | |
| 395 | ||
| 396 | expect(a0 == a0); | |
| 397 | expect(a1 == a1); | |
| 398 | expect(a0 == a2); | |
| 399 | ||
| 400 | expect(b0 == b0); | |
| 401 | expect(b1 == b1); | |
| 402 | expect(b0 == b2); | |
| 403 | ||
| 404 | expect(a0 != b0); | |
| 405 | expect(a0 != a1); | |
| 406 | expect(b0 != b1); | |
| 407 | } | |
| 408 | ||
| 409 | test "return union init with void payload" { | |
| 410 | const S = struct { | |
| 411 | fn entry() void { | |
| 412 | expect(func().state == State.one); | |
| 413 | } | |
| 414 | const Outer = union(enum) { | |
| 415 | state: State, | |
| 416 | }; | |
| 417 | const State = union(enum) { | |
| 418 | one: void, | |
| 419 | two: u32, | |
| 420 | }; | |
| 421 | fn func() Outer { | |
| 422 | return Outer{ .state = State{ .one = {} } }; | |
| 423 | } | |
| 424 | }; | |
| 425 | S.entry(); | |
| 426 | comptime S.entry(); | |
| 427 | } | |
| 428 | ||
| 429 | test "@unionInit can modify a union type" { | |
| 430 | const UnionInitEnum = union(enum) { | |
| 431 | Boolean: bool, | |
| 432 | Byte: u8, | |
| 433 | }; | |
| 434 | ||
| 435 | var value: UnionInitEnum = undefined; | |
| 436 | ||
| 437 | value = @unionInit(UnionInitEnum, "Boolean", true); | |
| 438 | expect(value.Boolean == true); | |
| 439 | value.Boolean = false; | |
| 440 | expect(value.Boolean == false); | |
| 441 | ||
| 442 | value = @unionInit(UnionInitEnum, "Byte", 2); | |
| 443 | expect(value.Byte == 2); | |
| 444 | value.Byte = 3; | |
| 445 | expect(value.Byte == 3); | |
| 446 | } | |
| 447 | ||
| 448 | test "@unionInit can modify a pointer value" { | |
| 449 | const UnionInitEnum = union(enum) { | |
| 450 | Boolean: bool, | |
| 451 | Byte: u8, | |
| 452 | }; | |
| 453 | ||
| 454 | var value: UnionInitEnum = undefined; | |
| 455 | var value_ptr = &value; | |
| 456 | ||
| 457 | value_ptr.* = @unionInit(UnionInitEnum, "Boolean", true); | |
| 458 | expect(value.Boolean == true); | |
| 459 | ||
| 460 | value_ptr.* = @unionInit(UnionInitEnum, "Byte", 2); | |
| 461 | expect(value.Byte == 2); | |
| 462 | } | |
| 463 | ||
| 464 | test "union no tag with struct member" { | |
| 465 | const Struct = struct {}; | |
| 466 | const Union = union { | |
| 467 | s: Struct, | |
| 468 | pub fn foo(self: *@This()) void {} | |
| 469 | }; | |
| 470 | var u = Union{ .s = Struct{} }; | |
| 471 | u.foo(); | |
| 472 | } | |
| 473 | ||
| 474 | fn testComparison() void { | |
| 475 | var x = Payload{ .A = 42 }; | |
| 476 | expect(x == .A); | |
| 477 | expect(x != .B); | |
| 478 | expect(x != .C); | |
| 479 | expect((x == .B) == false); | |
| 480 | expect((x == .C) == false); | |
| 481 | expect((x != .A) == false); | |
| 482 | } | |
| 483 | ||
| 484 | test "comparison between union and enum literal" { | |
| 485 | testComparison(); | |
| 486 | comptime testComparison(); | |
| 487 | } | |
| 488 | ||
| 489 | test "packed union generates correctly aligned LLVM type" { | |
| 490 | const U = packed union { | |
| 491 | f1: fn () void, | |
| 492 | f2: u32, | |
| 493 | }; | |
| 494 | var foo = [_]U{ | |
| 495 | U{ .f1 = doTest }, | |
| 496 | U{ .f2 = 0 }, | |
| 497 | }; | |
| 498 | foo[0].f1(); | |
| 499 | } | |
| 500 | ||
| 501 | test "union with one member defaults to u0 tag type" { | |
| 502 | const U0 = union(enum) { | |
| 503 | X: u32, | |
| 504 | }; | |
| 505 | comptime expect(Tag(Tag(U0)) == u0); | |
| 506 | } | |
| 507 | ||
| 508 | test "union with comptime_int tag" { | |
| 509 | const Union = union(enum(comptime_int)) { | |
| 510 | X: u32, | |
| 511 | Y: u16, | |
| 512 | Z: u8, | |
| 513 | }; | |
| 514 | comptime expect(Tag(Tag(Union)) == comptime_int); | |
| 515 | } | |
| 516 | ||
| 517 | test "extern union doesn't trigger field check at comptime" { | |
| 518 | const U = extern union { | |
| 519 | x: u32, | |
| 520 | y: u8, | |
| 521 | }; | |
| 522 | ||
| 523 | const x = U{ .x = 0x55AAAA55 }; | |
| 524 | comptime expect(x.y == 0x55); | |
| 525 | } | |
| 526 | ||
| 527 | const Foo1 = union(enum) { | |
| 528 | f: struct { | |
| 529 | x: usize, | |
| 530 | }, | |
| 531 | }; | |
| 532 | var glbl: Foo1 = undefined; | |
| 533 | ||
| 534 | test "global union with single field is correctly initialized" { | |
| 535 | glbl = Foo1{ | |
| 536 | .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 }, | |
| 537 | }; | |
| 538 | expect(glbl.f.x == 123); | |
| 539 | } | |
| 540 | ||
| 541 | pub const FooUnion = union(enum) { | |
| 542 | U0: usize, | |
| 543 | U1: u8, | |
| 544 | }; | |
| 545 | ||
| 546 | var glbl_array: [2]FooUnion = undefined; | |
| 547 | ||
| 548 | test "initialize global array of union" { | |
| 549 | glbl_array[1] = FooUnion{ .U1 = 2 }; | |
| 550 | glbl_array[0] = FooUnion{ .U0 = 1 }; | |
| 551 | expect(glbl_array[0].U0 == 1); | |
| 552 | expect(glbl_array[1].U1 == 2); | |
| 553 | } | |
| 554 | ||
| 555 | test "anonymous union literal syntax" { | |
| 556 | const S = struct { | |
| 557 | const Number = union { | |
| 558 | int: i32, | |
| 559 | float: f64, | |
| 560 | }; | |
| 561 | ||
| 562 | fn doTheTest() void { | |
| 563 | var i: Number = .{ .int = 42 }; | |
| 564 | var f = makeNumber(); | |
| 565 | expect(i.int == 42); | |
| 566 | expect(f.float == 12.34); | |
| 567 | } | |
| 568 | ||
| 569 | fn makeNumber() Number { | |
| 570 | return .{ .float = 12.34 }; | |
| 571 | } | |
| 572 | }; | |
| 573 | S.doTheTest(); | |
| 574 | comptime S.doTheTest(); | |
| 575 | } | |
| 576 | ||
| 577 | test "update the tag value for zero-sized unions" { | |
| 578 | const S = union(enum) { | |
| 579 | U0: void, | |
| 580 | U1: void, | |
| 581 | }; | |
| 582 | var x = S{ .U0 = {} }; | |
| 583 | expect(x == .U0); | |
| 584 | x = S{ .U1 = {} }; | |
| 585 | expect(x == .U1); | |
| 586 | } | |
| 587 | ||
| 588 | test "function call result coerces from tagged union to the tag" { | |
| 589 | const S = struct { | |
| 590 | const Arch = union(enum) { | |
| 591 | One, | |
| 592 | Two: usize, | |
| 593 | }; | |
| 594 | ||
| 595 | const ArchTag = Tag(Arch); | |
| 596 | ||
| 597 | fn doTheTest() void { | |
| 598 | var x: ArchTag = getArch1(); | |
| 599 | expect(x == .One); | |
| 600 | ||
| 601 | var y: ArchTag = getArch2(); | |
| 602 | expect(y == .Two); | |
| 603 | } | |
| 604 | ||
| 605 | pub fn getArch1() Arch { | |
| 606 | return .One; | |
| 607 | } | |
| 608 | ||
| 609 | pub fn getArch2() Arch { | |
| 610 | return .{ .Two = 99 }; | |
| 611 | } | |
| 612 | }; | |
| 613 | S.doTheTest(); | |
| 614 | comptime S.doTheTest(); | |
| 615 | } | |
| 616 | ||
| 617 | test "0-sized extern union definition" { | |
| 618 | const U = extern union { | |
| 619 | a: void, | |
| 620 | const f = 1; | |
| 621 | }; | |
| 622 | ||
| 623 | expect(U.f == 1); | |
| 624 | } | |
| 625 | ||
| 626 | test "union initializer generates padding only if needed" { | |
| 627 | const U = union(enum) { | |
| 628 | A: u24, | |
| 629 | }; | |
| 630 | ||
| 631 | var v = U{ .A = 532 }; | |
| 632 | expect(v.A == 532); | |
| 633 | } | |
| 634 | ||
| 635 | test "runtime tag name with single field" { | |
| 636 | const U = union(enum) { | |
| 637 | A: i32, | |
| 638 | }; | |
| 639 | ||
| 640 | var v = U{ .A = 42 }; | |
| 641 | expect(std.mem.eql(u8, @tagName(v), "A")); | |
| 642 | } | |
| 643 | ||
| 644 | test "cast from anonymous struct to union" { | |
| 645 | const S = struct { | |
| 646 | const U = union(enum) { | |
| 647 | A: u32, | |
| 648 | B: []const u8, | |
| 649 | C: void, | |
| 650 | }; | |
| 651 | fn doTheTest() void { | |
| 652 | var y: u32 = 42; | |
| 653 | const t0 = .{ .A = 123 }; | |
| 654 | const t1 = .{ .B = "foo" }; | |
| 655 | const t2 = .{ .C = {} }; | |
| 656 | const t3 = .{ .A = y }; | |
| 657 | const x0: U = t0; | |
| 658 | var x1: U = t1; | |
| 659 | const x2: U = t2; | |
| 660 | var x3: U = t3; | |
| 661 | expect(x0.A == 123); | |
| 662 | expect(std.mem.eql(u8, x1.B, "foo")); | |
| 663 | expect(x2 == .C); | |
| 664 | expect(x3.A == y); | |
| 665 | } | |
| 666 | }; | |
| 667 | S.doTheTest(); | |
| 668 | comptime S.doTheTest(); | |
| 669 | } | |
| 670 | ||
| 671 | test "cast from pointer to anonymous struct to pointer to union" { | |
| 672 | const S = struct { | |
| 673 | const U = union(enum) { | |
| 674 | A: u32, | |
| 675 | B: []const u8, | |
| 676 | C: void, | |
| 677 | }; | |
| 678 | fn doTheTest() void { | |
| 679 | var y: u32 = 42; | |
| 680 | const t0 = &.{ .A = 123 }; | |
| 681 | const t1 = &.{ .B = "foo" }; | |
| 682 | const t2 = &.{ .C = {} }; | |
| 683 | const t3 = &.{ .A = y }; | |
| 684 | const x0: *const U = t0; | |
| 685 | var x1: *const U = t1; | |
| 686 | const x2: *const U = t2; | |
| 687 | var x3: *const U = t3; | |
| 688 | expect(x0.A == 123); | |
| 689 | expect(std.mem.eql(u8, x1.B, "foo")); | |
| 690 | expect(x2.* == .C); | |
| 691 | expect(x3.A == y); | |
| 692 | } | |
| 693 | }; | |
| 694 | S.doTheTest(); | |
| 695 | comptime S.doTheTest(); | |
| 696 | } | |
| 697 | ||
| 698 | test "method call on an empty union" { | |
| 699 | const S = struct { | |
| 700 | const MyUnion = union(MyUnionTag) { | |
| 701 | pub const MyUnionTag = enum { X1, X2 }; | |
| 702 | X1: [0]u8, | |
| 703 | X2: [0]u8, | |
| 704 | ||
| 705 | pub fn useIt(self: *@This()) bool { | |
| 706 | return true; | |
| 707 | } | |
| 708 | }; | |
| 709 | ||
| 710 | fn doTheTest() void { | |
| 711 | var u = MyUnion{ .X1 = [0]u8{} }; | |
| 712 | expect(u.useIt()); | |
| 713 | } | |
| 714 | }; | |
| 715 | S.doTheTest(); | |
| 716 | comptime S.doTheTest(); | |
| 717 | } | |
| 718 | ||
| 719 | test "switching on non exhaustive union" { | |
| 720 | const S = struct { | |
| 721 | const E = enum(u8) { | |
| 722 | a, | |
| 723 | b, | |
| 724 | _, | |
| 725 | }; | |
| 726 | const U = union(E) { | |
| 727 | a: i32, | |
| 728 | b: u32, | |
| 729 | }; | |
| 730 | fn doTheTest() void { | |
| 731 | var a = U{ .a = 2 }; | |
| 732 | switch (a) { | |
| 733 | .a => |val| expect(val == 2), | |
| 734 | .b => unreachable, | |
| 735 | } | |
| 736 | } | |
| 737 | }; | |
| 738 | S.doTheTest(); | |
| 739 | comptime S.doTheTest(); | |
| 740 | } | |
| 741 | ||
| 742 | test "containers with single-field enums" { | |
| 743 | const S = struct { | |
| 744 | const A = union(enum) { f1 }; | |
| 745 | const B = union(enum) { f1: void }; | |
| 746 | const C = struct { a: A }; | |
| 747 | const D = struct { a: B }; | |
| 748 | ||
| 749 | fn doTheTest() void { | |
| 750 | var array1 = [1]A{A{ .f1 = {} }}; | |
| 751 | var array2 = [1]B{B{ .f1 = {} }}; | |
| 752 | expect(array1[0] == .f1); | |
| 753 | expect(array2[0] == .f1); | |
| 754 | ||
| 755 | var struct1 = C{ .a = A{ .f1 = {} } }; | |
| 756 | var struct2 = D{ .a = B{ .f1 = {} } }; | |
| 757 | expect(struct1.a == .f1); | |
| 758 | expect(struct2.a == .f1); | |
| 759 | } | |
| 760 | }; | |
| 761 | ||
| 762 | S.doTheTest(); | |
| 763 | comptime S.doTheTest(); | |
| 764 | } | |
| 765 | ||
| 766 | test "@unionInit on union w/ tag but no fields" { | |
| 767 | const S = struct { | |
| 768 | const Type = enum(u8) { no_op = 105 }; | |
| 769 | ||
| 770 | const Data = union(Type) { | |
| 771 | no_op: void, | |
| 772 | ||
| 773 | pub fn decode(buf: []const u8) Data { | |
| 774 | return @unionInit(Data, "no_op", {}); | |
| 775 | } | |
| 776 | }; | |
| 777 | ||
| 778 | comptime { | |
| 779 | expect(@sizeOf(Data) != 0); | |
| 780 | } | |
| 781 | ||
| 782 | fn doTheTest() void { | |
| 783 | var data: Data = .{ .no_op = .{} }; | |
| 784 | var o = Data.decode(&[_]u8{}); | |
| 785 | expectEqual(Type.no_op, o); | |
| 786 | } | |
| 787 | }; | |
| 788 | ||
| 789 | S.doTheTest(); | |
| 790 | comptime S.doTheTest(); | |
| 791 | } | |
| 792 | ||
| 793 | test "union enum type gets a separate scope" { | |
| 794 | const S = struct { | |
| 795 | const U = union(enum) { | |
| 796 | a: u8, | |
| 797 | const foo = 1; | |
| 798 | }; | |
| 799 | ||
| 800 | fn doTheTest() void { | |
| 801 | expect(!@hasDecl(Tag(U), "foo")); | |
| 802 | } | |
| 803 | }; | |
| 804 | ||
| 805 | S.doTheTest(); | |
| 806 | } |
test/behavior/usingnamespace.zig created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | fn Foo(comptime T: type) type { | |
| 4 | return struct { | |
| 5 | usingnamespace T; | |
| 6 | }; | |
| 7 | } | |
| 8 | ||
| 9 | test "usingnamespace inside a generic struct" { | |
| 10 | const std2 = Foo(std); | |
| 11 | const testing2 = Foo(std.testing); | |
| 12 | std2.testing.expect(true); | |
| 13 | testing2.expect(true); | |
| 14 | } | |
| 15 | ||
| 16 | usingnamespace struct { | |
| 17 | pub const foo = 42; | |
| 18 | }; | |
| 19 | ||
| 20 | test "usingnamespace does not redeclare an imported variable" { | |
| 21 | comptime std.testing.expect(foo == 42); | |
| 22 | } |
test/behavior/var_args.zig created+83| ... | ... | @@ -0,0 +1,83 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn add(args: anytype) i32 { | |
| 4 | var sum = @as(i32, 0); | |
| 5 | { | |
| 6 | comptime var i: usize = 0; | |
| 7 | inline while (i < args.len) : (i += 1) { | |
| 8 | sum += args[i]; | |
| 9 | } | |
| 10 | } | |
| 11 | return sum; | |
| 12 | } | |
| 13 | ||
| 14 | test "add arbitrary args" { | |
| 15 | expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); | |
| 16 | expect(add(.{@as(i32, 1234)}) == 1234); | |
| 17 | expect(add(.{}) == 0); | |
| 18 | } | |
| 19 | ||
| 20 | fn readFirstVarArg(args: anytype) void { | |
| 21 | const value = args[0]; | |
| 22 | } | |
| 23 | ||
| 24 | test "send void arg to var args" { | |
| 25 | readFirstVarArg(.{{}}); | |
| 26 | } | |
| 27 | ||
| 28 | test "pass args directly" { | |
| 29 | expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); | |
| 30 | expect(addSomeStuff(.{@as(i32, 1234)}) == 1234); | |
| 31 | expect(addSomeStuff(.{}) == 0); | |
| 32 | } | |
| 33 | ||
| 34 | fn addSomeStuff(args: anytype) i32 { | |
| 35 | return add(args); | |
| 36 | } | |
| 37 | ||
| 38 | test "runtime parameter before var args" { | |
| 39 | expect(extraFn(10, .{}) == 0); | |
| 40 | expect(extraFn(10, .{false}) == 1); | |
| 41 | expect(extraFn(10, .{ false, true }) == 2); | |
| 42 | ||
| 43 | comptime { | |
| 44 | expect(extraFn(10, .{}) == 0); | |
| 45 | expect(extraFn(10, .{false}) == 1); | |
| 46 | expect(extraFn(10, .{ false, true }) == 2); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | fn extraFn(extra: u32, args: anytype) usize { | |
| 51 | if (args.len >= 1) { | |
| 52 | expect(args[0] == false); | |
| 53 | } | |
| 54 | if (args.len >= 2) { | |
| 55 | expect(args[1] == true); | |
| 56 | } | |
| 57 | return args.len; | |
| 58 | } | |
| 59 | ||
| 60 | const foos = [_]fn (anytype) bool{ | |
| 61 | foo1, | |
| 62 | foo2, | |
| 63 | }; | |
| 64 | ||
| 65 | fn foo1(args: anytype) bool { | |
| 66 | return true; | |
| 67 | } | |
| 68 | fn foo2(args: anytype) bool { | |
| 69 | return false; | |
| 70 | } | |
| 71 | ||
| 72 | test "array of var args functions" { | |
| 73 | expect(foos[0](.{})); | |
| 74 | expect(!foos[1](.{})); | |
| 75 | } | |
| 76 | ||
| 77 | test "pass zero length array to var args param" { | |
| 78 | doNothingWithFirstArg(.{""}); | |
| 79 | } | |
| 80 | ||
| 81 | fn doNothingWithFirstArg(args: anytype) void { | |
| 82 | const a = args[0]; | |
| 83 | } |
test/behavior/vector.zig created+655| ... | ... | @@ -0,0 +1,655 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const math = std.math; | |
| 5 | const expect = std.testing.expect; | |
| 6 | const expectEqual = std.testing.expectEqual; | |
| 7 | const expectApproxEqRel = std.testing.expectApproxEqRel; | |
| 8 | const Vector = std.meta.Vector; | |
| 9 | ||
| 10 | test "implicit cast vector to array - bool" { | |
| 11 | const S = struct { | |
| 12 | fn doTheTest() void { | |
| 13 | const a: Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 14 | const result_array: [4]bool = a; | |
| 15 | expect(mem.eql(bool, &result_array, &[4]bool{ true, false, true, false })); | |
| 16 | } | |
| 17 | }; | |
| 18 | S.doTheTest(); | |
| 19 | comptime S.doTheTest(); | |
| 20 | } | |
| 21 | ||
| 22 | test "vector wrap operators" { | |
| 23 | const S = struct { | |
| 24 | fn doTheTest() void { | |
| 25 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 26 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; | |
| 27 | expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 })); | |
| 28 | expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 })); | |
| 29 | expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 })); | |
| 30 | var z: Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 }; | |
| 31 | expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 })); | |
| 32 | } | |
| 33 | }; | |
| 34 | S.doTheTest(); | |
| 35 | comptime S.doTheTest(); | |
| 36 | } | |
| 37 | ||
| 38 | test "vector bin compares with mem.eql" { | |
| 39 | const S = struct { | |
| 40 | fn doTheTest() void { | |
| 41 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 42 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 }; | |
| 43 | expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false })); | |
| 44 | expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true })); | |
| 45 | expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false })); | |
| 46 | expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true })); | |
| 47 | expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false })); | |
| 48 | expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true })); | |
| 49 | } | |
| 50 | }; | |
| 51 | S.doTheTest(); | |
| 52 | comptime S.doTheTest(); | |
| 53 | } | |
| 54 | ||
| 55 | test "vector int operators" { | |
| 56 | const S = struct { | |
| 57 | fn doTheTest() void { | |
| 58 | var v: Vector(4, i32) = [4]i32{ 10, 20, 30, 40 }; | |
| 59 | var x: Vector(4, i32) = [4]i32{ 1, 2, 3, 4 }; | |
| 60 | expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 })); | |
| 61 | expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 })); | |
| 62 | expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 })); | |
| 63 | expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 })); | |
| 64 | } | |
| 65 | }; | |
| 66 | S.doTheTest(); | |
| 67 | comptime S.doTheTest(); | |
| 68 | } | |
| 69 | ||
| 70 | test "vector float operators" { | |
| 71 | const S = struct { | |
| 72 | fn doTheTest() void { | |
| 73 | var v: Vector(4, f32) = [4]f32{ 10, 20, 30, 40 }; | |
| 74 | var x: Vector(4, f32) = [4]f32{ 1, 2, 3, 4 }; | |
| 75 | expect(mem.eql(f32, &@as([4]f32, v + x), &[4]f32{ 11, 22, 33, 44 })); | |
| 76 | expect(mem.eql(f32, &@as([4]f32, v - x), &[4]f32{ 9, 18, 27, 36 })); | |
| 77 | expect(mem.eql(f32, &@as([4]f32, v * x), &[4]f32{ 10, 40, 90, 160 })); | |
| 78 | expect(mem.eql(f32, &@as([4]f32, -x), &[4]f32{ -1, -2, -3, -4 })); | |
| 79 | } | |
| 80 | }; | |
| 81 | S.doTheTest(); | |
| 82 | comptime S.doTheTest(); | |
| 83 | } | |
| 84 | ||
| 85 | test "vector bit operators" { | |
| 86 | const S = struct { | |
| 87 | fn doTheTest() void { | |
| 88 | var v: Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 }; | |
| 89 | var x: Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 }; | |
| 90 | expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 })); | |
| 91 | expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 })); | |
| 92 | expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 })); | |
| 93 | } | |
| 94 | }; | |
| 95 | S.doTheTest(); | |
| 96 | comptime S.doTheTest(); | |
| 97 | } | |
| 98 | ||
| 99 | test "implicit cast vector to array" { | |
| 100 | const S = struct { | |
| 101 | fn doTheTest() void { | |
| 102 | var a: Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; | |
| 103 | var result_array: [4]i32 = a; | |
| 104 | result_array = a; | |
| 105 | expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 })); | |
| 106 | } | |
| 107 | }; | |
| 108 | S.doTheTest(); | |
| 109 | comptime S.doTheTest(); | |
| 110 | } | |
| 111 | ||
| 112 | test "array to vector" { | |
| 113 | var foo: f32 = 3.14; | |
| 114 | var arr = [4]f32{ foo, 1.5, 0.0, 0.0 }; | |
| 115 | var vec: Vector(4, f32) = arr; | |
| 116 | } | |
| 117 | ||
| 118 | test "vector casts of sizes not divisable by 8" { | |
| 119 | // https://github.com/ziglang/zig/issues/3563 | |
| 120 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; | |
| 121 | ||
| 122 | const S = struct { | |
| 123 | fn doTheTest() void { | |
| 124 | { | |
| 125 | var v: Vector(4, u3) = [4]u3{ 5, 2, 3, 0 }; | |
| 126 | var x: [4]u3 = v; | |
| 127 | expect(mem.eql(u3, &x, &@as([4]u3, v))); | |
| 128 | } | |
| 129 | { | |
| 130 | var v: Vector(4, u2) = [4]u2{ 1, 2, 3, 0 }; | |
| 131 | var x: [4]u2 = v; | |
| 132 | expect(mem.eql(u2, &x, &@as([4]u2, v))); | |
| 133 | } | |
| 134 | { | |
| 135 | var v: Vector(4, u1) = [4]u1{ 1, 0, 1, 0 }; | |
| 136 | var x: [4]u1 = v; | |
| 137 | expect(mem.eql(u1, &x, &@as([4]u1, v))); | |
| 138 | } | |
| 139 | { | |
| 140 | var v: Vector(4, bool) = [4]bool{ false, false, true, false }; | |
| 141 | var x: [4]bool = v; | |
| 142 | expect(mem.eql(bool, &x, &@as([4]bool, v))); | |
| 143 | } | |
| 144 | } | |
| 145 | }; | |
| 146 | S.doTheTest(); | |
| 147 | comptime S.doTheTest(); | |
| 148 | } | |
| 149 | ||
| 150 | test "vector @splat" { | |
| 151 | const S = struct { | |
| 152 | fn testForT(comptime N: comptime_int, v: anytype) void { | |
| 153 | const T = @TypeOf(v); | |
| 154 | var vec = @splat(N, v); | |
| 155 | expectEqual(Vector(N, T), @TypeOf(vec)); | |
| 156 | var as_array = @as([N]T, vec); | |
| 157 | for (as_array) |elem| expectEqual(v, elem); | |
| 158 | } | |
| 159 | fn doTheTest() void { | |
| 160 | // Splats with multiple-of-8 bit types that fill a 128bit vector. | |
| 161 | testForT(16, @as(u8, 0xEE)); | |
| 162 | testForT(8, @as(u16, 0xBEEF)); | |
| 163 | testForT(4, @as(u32, 0xDEADBEEF)); | |
| 164 | testForT(2, @as(u64, 0xCAFEF00DDEADBEEF)); | |
| 165 | ||
| 166 | testForT(8, @as(f16, 3.1415)); | |
| 167 | testForT(4, @as(f32, 3.1415)); | |
| 168 | testForT(2, @as(f64, 3.1415)); | |
| 169 | ||
| 170 | // Same but fill more than 128 bits. | |
| 171 | testForT(16 * 2, @as(u8, 0xEE)); | |
| 172 | testForT(8 * 2, @as(u16, 0xBEEF)); | |
| 173 | testForT(4 * 2, @as(u32, 0xDEADBEEF)); | |
| 174 | testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF)); | |
| 175 | ||
| 176 | testForT(8 * 2, @as(f16, 3.1415)); | |
| 177 | testForT(4 * 2, @as(f32, 3.1415)); | |
| 178 | testForT(2 * 2, @as(f64, 3.1415)); | |
| 179 | } | |
| 180 | }; | |
| 181 | S.doTheTest(); | |
| 182 | comptime S.doTheTest(); | |
| 183 | } | |
| 184 | ||
| 185 | test "load vector elements via comptime index" { | |
| 186 | const S = struct { | |
| 187 | fn doTheTest() void { | |
| 188 | var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined }; | |
| 189 | expect(v[0] == 1); | |
| 190 | expect(v[1] == 2); | |
| 191 | expect(loadv(&v[2]) == 3); | |
| 192 | } | |
| 193 | fn loadv(ptr: anytype) i32 { | |
| 194 | return ptr.*; | |
| 195 | } | |
| 196 | }; | |
| 197 | ||
| 198 | S.doTheTest(); | |
| 199 | comptime S.doTheTest(); | |
| 200 | } | |
| 201 | ||
| 202 | test "store vector elements via comptime index" { | |
| 203 | const S = struct { | |
| 204 | fn doTheTest() void { | |
| 205 | var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; | |
| 206 | ||
| 207 | v[2] = 42; | |
| 208 | expect(v[1] == 5); | |
| 209 | v[3] = -364; | |
| 210 | expect(v[2] == 42); | |
| 211 | expect(-364 == v[3]); | |
| 212 | ||
| 213 | storev(&v[0], 100); | |
| 214 | expect(v[0] == 100); | |
| 215 | } | |
| 216 | fn storev(ptr: anytype, x: i32) void { | |
| 217 | ptr.* = x; | |
| 218 | } | |
| 219 | }; | |
| 220 | ||
| 221 | S.doTheTest(); | |
| 222 | comptime S.doTheTest(); | |
| 223 | } | |
| 224 | ||
| 225 | test "load vector elements via runtime index" { | |
| 226 | const S = struct { | |
| 227 | fn doTheTest() void { | |
| 228 | var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined }; | |
| 229 | var i: u32 = 0; | |
| 230 | expect(v[i] == 1); | |
| 231 | i += 1; | |
| 232 | expect(v[i] == 2); | |
| 233 | i += 1; | |
| 234 | expect(v[i] == 3); | |
| 235 | } | |
| 236 | }; | |
| 237 | ||
| 238 | S.doTheTest(); | |
| 239 | comptime S.doTheTest(); | |
| 240 | } | |
| 241 | ||
| 242 | test "store vector elements via runtime index" { | |
| 243 | const S = struct { | |
| 244 | fn doTheTest() void { | |
| 245 | var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; | |
| 246 | var i: u32 = 2; | |
| 247 | v[i] = 1; | |
| 248 | expect(v[1] == 5); | |
| 249 | expect(v[2] == 1); | |
| 250 | i += 1; | |
| 251 | v[i] = -364; | |
| 252 | expect(-364 == v[3]); | |
| 253 | } | |
| 254 | }; | |
| 255 | ||
| 256 | S.doTheTest(); | |
| 257 | comptime S.doTheTest(); | |
| 258 | } | |
| 259 | ||
| 260 | test "initialize vector which is a struct field" { | |
| 261 | const Vec4Obj = struct { | |
| 262 | data: Vector(4, f32), | |
| 263 | }; | |
| 264 | ||
| 265 | const S = struct { | |
| 266 | fn doTheTest() void { | |
| 267 | var foo = Vec4Obj{ | |
| 268 | .data = [_]f32{ 1, 2, 3, 4 }, | |
| 269 | }; | |
| 270 | } | |
| 271 | }; | |
| 272 | S.doTheTest(); | |
| 273 | comptime S.doTheTest(); | |
| 274 | } | |
| 275 | ||
| 276 | test "vector comparison operators" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | { | |
| 280 | const v1: Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 281 | const v2: Vector(4, bool) = [_]bool{ false, true, false, true }; | |
| 282 | expectEqual(@splat(4, true), v1 == v1); | |
| 283 | expectEqual(@splat(4, false), v1 == v2); | |
| 284 | expectEqual(@splat(4, true), v1 != v2); | |
| 285 | expectEqual(@splat(4, false), v2 != v2); | |
| 286 | } | |
| 287 | { | |
| 288 | const v1 = @splat(4, @as(u32, 0xc0ffeeee)); | |
| 289 | const v2: Vector(4, c_uint) = v1; | |
| 290 | const v3 = @splat(4, @as(u32, 0xdeadbeef)); | |
| 291 | expectEqual(@splat(4, true), v1 == v2); | |
| 292 | expectEqual(@splat(4, false), v1 == v3); | |
| 293 | expectEqual(@splat(4, true), v1 != v3); | |
| 294 | expectEqual(@splat(4, false), v1 != v2); | |
| 295 | } | |
| 296 | { | |
| 297 | // Comptime-known LHS/RHS | |
| 298 | var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 }; | |
| 299 | const v2 = @splat(4, @as(u32, 2)); | |
| 300 | const v3: @Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 301 | expectEqual(v3, v1 == v2); | |
| 302 | expectEqual(v3, v2 == v1); | |
| 303 | } | |
| 304 | } | |
| 305 | }; | |
| 306 | S.doTheTest(); | |
| 307 | comptime S.doTheTest(); | |
| 308 | } | |
| 309 | ||
| 310 | test "vector division operators" { | |
| 311 | const S = struct { | |
| 312 | fn doTheTestDiv(comptime T: type, x: Vector(4, T), y: Vector(4, T)) void { | |
| 313 | if (!comptime std.meta.trait.isSignedInt(T)) { | |
| 314 | const d0 = x / y; | |
| 315 | for (@as([4]T, d0)) |v, i| { | |
| 316 | expectEqual(x[i] / y[i], v); | |
| 317 | } | |
| 318 | } | |
| 319 | const d1 = @divExact(x, y); | |
| 320 | for (@as([4]T, d1)) |v, i| { | |
| 321 | expectEqual(@divExact(x[i], y[i]), v); | |
| 322 | } | |
| 323 | const d2 = @divFloor(x, y); | |
| 324 | for (@as([4]T, d2)) |v, i| { | |
| 325 | expectEqual(@divFloor(x[i], y[i]), v); | |
| 326 | } | |
| 327 | const d3 = @divTrunc(x, y); | |
| 328 | for (@as([4]T, d3)) |v, i| { | |
| 329 | expectEqual(@divTrunc(x[i], y[i]), v); | |
| 330 | } | |
| 331 | } | |
| 332 | ||
| 333 | fn doTheTestMod(comptime T: type, x: Vector(4, T), y: Vector(4, T)) void { | |
| 334 | if ((!comptime std.meta.trait.isSignedInt(T)) and @typeInfo(T) != .Float) { | |
| 335 | const r0 = x % y; | |
| 336 | for (@as([4]T, r0)) |v, i| { | |
| 337 | expectEqual(x[i] % y[i], v); | |
| 338 | } | |
| 339 | } | |
| 340 | const r1 = @mod(x, y); | |
| 341 | for (@as([4]T, r1)) |v, i| { | |
| 342 | expectEqual(@mod(x[i], y[i]), v); | |
| 343 | } | |
| 344 | const r2 = @rem(x, y); | |
| 345 | for (@as([4]T, r2)) |v, i| { | |
| 346 | expectEqual(@rem(x[i], y[i]), v); | |
| 347 | } | |
| 348 | } | |
| 349 | ||
| 350 | fn doTheTest() void { | |
| 351 | // https://github.com/ziglang/zig/issues/4952 | |
| 352 | if (builtin.target.os.tag != .windows) { | |
| 353 | doTheTestDiv(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, -1.0, -2.0 }); | |
| 354 | } | |
| 355 | ||
| 356 | doTheTestDiv(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, -1.0, -2.0 }); | |
| 357 | doTheTestDiv(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, -1.0, -2.0 }); | |
| 358 | ||
| 359 | // https://github.com/ziglang/zig/issues/4952 | |
| 360 | if (builtin.target.os.tag != .windows) { | |
| 361 | doTheTestMod(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, 0.5, 3.0 }); | |
| 362 | } | |
| 363 | doTheTestMod(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, 0.5, 3.0 }); | |
| 364 | doTheTestMod(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, 0.5, 3.0 }); | |
| 365 | ||
| 366 | doTheTestDiv(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, -1, -2 }); | |
| 367 | doTheTestDiv(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, -1, -2 }); | |
| 368 | doTheTestDiv(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, -1, -2 }); | |
| 369 | doTheTestDiv(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, -1, -2 }); | |
| 370 | ||
| 371 | doTheTestMod(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, 4, 8 }); | |
| 372 | doTheTestMod(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, 4, 8 }); | |
| 373 | doTheTestMod(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, 4, 8 }); | |
| 374 | doTheTestMod(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, 4, 8 }); | |
| 375 | ||
| 376 | doTheTestDiv(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 }); | |
| 377 | doTheTestDiv(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 }); | |
| 378 | doTheTestDiv(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 }); | |
| 379 | doTheTestDiv(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 }); | |
| 380 | ||
| 381 | doTheTestMod(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 }); | |
| 382 | doTheTestMod(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 }); | |
| 383 | doTheTestMod(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 }); | |
| 384 | doTheTestMod(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 }); | |
| 385 | } | |
| 386 | }; | |
| 387 | ||
| 388 | S.doTheTest(); | |
| 389 | comptime S.doTheTest(); | |
| 390 | } | |
| 391 | ||
| 392 | test "vector bitwise not operator" { | |
| 393 | const S = struct { | |
| 394 | fn doTheTestNot(comptime T: type, x: Vector(4, T)) void { | |
| 395 | var y = ~x; | |
| 396 | for (@as([4]T, y)) |v, i| { | |
| 397 | expectEqual(~x[i], v); | |
| 398 | } | |
| 399 | } | |
| 400 | fn doTheTest() void { | |
| 401 | doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 }); | |
| 402 | doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 }); | |
| 403 | doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 }); | |
| 404 | doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 }); | |
| 405 | ||
| 406 | doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 }); | |
| 407 | doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 }); | |
| 408 | doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 }); | |
| 409 | doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 }); | |
| 410 | } | |
| 411 | }; | |
| 412 | ||
| 413 | S.doTheTest(); | |
| 414 | comptime S.doTheTest(); | |
| 415 | } | |
| 416 | ||
| 417 | test "vector shift operators" { | |
| 418 | // TODO investigate why this fails when cross-compiled to wasm. | |
| 419 | if (builtin.target.os.tag == .wasi) return error.SkipZigTest; | |
| 420 | ||
| 421 | const S = struct { | |
| 422 | fn doTheTestShift(x: anytype, y: anytype) void { | |
| 423 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 424 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 425 | const TY = @typeInfo(@TypeOf(y)).Array.child; | |
| 426 | ||
| 427 | var xv = @as(Vector(N, TX), x); | |
| 428 | var yv = @as(Vector(N, TY), y); | |
| 429 | ||
| 430 | var z0 = xv >> yv; | |
| 431 | for (@as([N]TX, z0)) |v, i| { | |
| 432 | expectEqual(x[i] >> y[i], v); | |
| 433 | } | |
| 434 | var z1 = xv << yv; | |
| 435 | for (@as([N]TX, z1)) |v, i| { | |
| 436 | expectEqual(x[i] << y[i], v); | |
| 437 | } | |
| 438 | } | |
| 439 | fn doTheTestShiftExact(x: anytype, y: anytype, dir: enum { Left, Right }) void { | |
| 440 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 441 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 442 | const TY = @typeInfo(@TypeOf(y)).Array.child; | |
| 443 | ||
| 444 | var xv = @as(Vector(N, TX), x); | |
| 445 | var yv = @as(Vector(N, TY), y); | |
| 446 | ||
| 447 | var z = if (dir == .Left) @shlExact(xv, yv) else @shrExact(xv, yv); | |
| 448 | for (@as([N]TX, z)) |v, i| { | |
| 449 | const check = if (dir == .Left) x[i] << y[i] else x[i] >> y[i]; | |
| 450 | expectEqual(check, v); | |
| 451 | } | |
| 452 | } | |
| 453 | fn doTheTest() void { | |
| 454 | doTheTestShift([_]u8{ 0, 2, 4, math.maxInt(u8) }, [_]u3{ 2, 0, 2, 7 }); | |
| 455 | doTheTestShift([_]u16{ 0, 2, 4, math.maxInt(u16) }, [_]u4{ 2, 0, 2, 15 }); | |
| 456 | doTheTestShift([_]u24{ 0, 2, 4, math.maxInt(u24) }, [_]u5{ 2, 0, 2, 23 }); | |
| 457 | doTheTestShift([_]u32{ 0, 2, 4, math.maxInt(u32) }, [_]u5{ 2, 0, 2, 31 }); | |
| 458 | doTheTestShift([_]u64{ 0xfe, math.maxInt(u64) }, [_]u6{ 0, 63 }); | |
| 459 | ||
| 460 | doTheTestShift([_]i8{ 0, 2, 4, math.maxInt(i8) }, [_]u3{ 2, 0, 2, 7 }); | |
| 461 | doTheTestShift([_]i16{ 0, 2, 4, math.maxInt(i16) }, [_]u4{ 2, 0, 2, 7 }); | |
| 462 | doTheTestShift([_]i24{ 0, 2, 4, math.maxInt(i24) }, [_]u5{ 2, 0, 2, 7 }); | |
| 463 | doTheTestShift([_]i32{ 0, 2, 4, math.maxInt(i32) }, [_]u5{ 2, 0, 2, 7 }); | |
| 464 | doTheTestShift([_]i64{ 0xfe, math.maxInt(i64) }, [_]u6{ 0, 63 }); | |
| 465 | ||
| 466 | doTheTestShiftExact([_]u8{ 0, 1, 1 << 7, math.maxInt(u8) ^ 1 }, [_]u3{ 4, 0, 7, 1 }, .Right); | |
| 467 | doTheTestShiftExact([_]u16{ 0, 1, 1 << 15, math.maxInt(u16) ^ 1 }, [_]u4{ 4, 0, 15, 1 }, .Right); | |
| 468 | doTheTestShiftExact([_]u24{ 0, 1, 1 << 23, math.maxInt(u24) ^ 1 }, [_]u5{ 4, 0, 23, 1 }, .Right); | |
| 469 | doTheTestShiftExact([_]u32{ 0, 1, 1 << 31, math.maxInt(u32) ^ 1 }, [_]u5{ 4, 0, 31, 1 }, .Right); | |
| 470 | doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 63, 0 }, .Right); | |
| 471 | ||
| 472 | doTheTestShiftExact([_]u8{ 0, 1, 1, math.maxInt(u8) ^ (1 << 7) }, [_]u3{ 4, 0, 7, 1 }, .Left); | |
| 473 | doTheTestShiftExact([_]u16{ 0, 1, 1, math.maxInt(u16) ^ (1 << 15) }, [_]u4{ 4, 0, 15, 1 }, .Left); | |
| 474 | doTheTestShiftExact([_]u24{ 0, 1, 1, math.maxInt(u24) ^ (1 << 23) }, [_]u5{ 4, 0, 23, 1 }, .Left); | |
| 475 | doTheTestShiftExact([_]u32{ 0, 1, 1, math.maxInt(u32) ^ (1 << 31) }, [_]u5{ 4, 0, 31, 1 }, .Left); | |
| 476 | doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 0, 63 }, .Left); | |
| 477 | } | |
| 478 | }; | |
| 479 | ||
| 480 | switch (builtin.target.cpu.arch) { | |
| 481 | .i386, | |
| 482 | .aarch64, | |
| 483 | .aarch64_be, | |
| 484 | .aarch64_32, | |
| 485 | .arm, | |
| 486 | .armeb, | |
| 487 | .thumb, | |
| 488 | .thumbeb, | |
| 489 | .mips, | |
| 490 | .mipsel, | |
| 491 | .mips64, | |
| 492 | .mips64el, | |
| 493 | .riscv64, | |
| 494 | .sparcv9, | |
| 495 | => { | |
| 496 | // LLVM miscompiles on this architecture | |
| 497 | // https://github.com/ziglang/zig/issues/4951 | |
| 498 | return error.SkipZigTest; | |
| 499 | }, | |
| 500 | else => {}, | |
| 501 | } | |
| 502 | ||
| 503 | S.doTheTest(); | |
| 504 | comptime S.doTheTest(); | |
| 505 | } | |
| 506 | ||
| 507 | test "vector reduce operation" { | |
| 508 | const S = struct { | |
| 509 | fn doTheTestReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) void { | |
| 510 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 511 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 512 | ||
| 513 | // wasmtime: unknown import: `env::fminf` has not been defined | |
| 514 | // https://github.com/ziglang/zig/issues/8131 | |
| 515 | switch (builtin.target.cpu.arch) { | |
| 516 | .wasm32 => switch (@typeInfo(TX)) { | |
| 517 | .Float => switch (op) { | |
| 518 | .Min, | |
| 519 | .Max, | |
| 520 | => return, | |
| 521 | else => {}, | |
| 522 | }, | |
| 523 | else => {}, | |
| 524 | }, | |
| 525 | else => {}, | |
| 526 | } | |
| 527 | ||
| 528 | var r = @reduce(op, @as(Vector(N, TX), x)); | |
| 529 | switch (@typeInfo(TX)) { | |
| 530 | .Int, .Bool => expectEqual(expected, r), | |
| 531 | .Float => { | |
| 532 | const expected_nan = math.isNan(expected); | |
| 533 | const got_nan = math.isNan(r); | |
| 534 | ||
| 535 | if (expected_nan and got_nan) { | |
| 536 | // Do this check explicitly as two NaN values are never | |
| 537 | // equal. | |
| 538 | } else { | |
| 539 | expectApproxEqRel(expected, r, math.sqrt(math.epsilon(TX))); | |
| 540 | } | |
| 541 | }, | |
| 542 | else => unreachable, | |
| 543 | } | |
| 544 | } | |
| 545 | fn doTheTest() void { | |
| 546 | doTheTestReduce(.Add, [4]i16{ -9, -99, -999, -9999 }, @as(i32, -11106)); | |
| 547 | doTheTestReduce(.Add, [4]u16{ 9, 99, 999, 9999 }, @as(u32, 11106)); | |
| 548 | doTheTestReduce(.Add, [4]i32{ -9, -99, -999, -9999 }, @as(i32, -11106)); | |
| 549 | doTheTestReduce(.Add, [4]u32{ 9, 99, 999, 9999 }, @as(u32, 11106)); | |
| 550 | doTheTestReduce(.Add, [4]i64{ -9, -99, -999, -9999 }, @as(i64, -11106)); | |
| 551 | doTheTestReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106)); | |
| 552 | doTheTestReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106)); | |
| 553 | doTheTestReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106)); | |
| 554 | doTheTestReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9)); | |
| 555 | doTheTestReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9)); | |
| 556 | doTheTestReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9)); | |
| 557 | ||
| 558 | doTheTestReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false)); | |
| 559 | doTheTestReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0)); | |
| 560 | doTheTestReduce(.And, [4]u16{ 0xffff, 0xff55, 0xaaff, 0x1010 }, @as(u16, 0x10)); | |
| 561 | doTheTestReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010)); | |
| 562 | doTheTestReduce(.And, [4]u64{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u64, 0x1010)); | |
| 563 | ||
| 564 | doTheTestReduce(.Min, [4]i16{ -1, 2, 3, 4 }, @as(i16, -1)); | |
| 565 | doTheTestReduce(.Min, [4]u16{ 1, 2, 3, 4 }, @as(u16, 1)); | |
| 566 | doTheTestReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386)); | |
| 567 | doTheTestReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9)); | |
| 568 | ||
| 569 | // LLVM 11 ERROR: Cannot select type | |
| 570 | // https://github.com/ziglang/zig/issues/7138 | |
| 571 | if (builtin.target.cpu.arch != .aarch64) { | |
| 572 | doTheTestReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386)); | |
| 573 | doTheTestReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9)); | |
| 574 | } | |
| 575 | ||
| 576 | doTheTestReduce(.Min, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, -386)); | |
| 577 | doTheTestReduce(.Min, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 9)); | |
| 578 | doTheTestReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0)); | |
| 579 | doTheTestReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0)); | |
| 580 | doTheTestReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0)); | |
| 581 | ||
| 582 | doTheTestReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4)); | |
| 583 | doTheTestReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4)); | |
| 584 | doTheTestReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567)); | |
| 585 | doTheTestReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999)); | |
| 586 | ||
| 587 | // LLVM 11 ERROR: Cannot select type | |
| 588 | // https://github.com/ziglang/zig/issues/7138 | |
| 589 | if (builtin.target.cpu.arch != .aarch64) { | |
| 590 | doTheTestReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567)); | |
| 591 | doTheTestReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999)); | |
| 592 | } | |
| 593 | ||
| 594 | doTheTestReduce(.Max, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, 1234567)); | |
| 595 | doTheTestReduce(.Max, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 99999)); | |
| 596 | doTheTestReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9)); | |
| 597 | doTheTestReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9)); | |
| 598 | doTheTestReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9)); | |
| 599 | ||
| 600 | doTheTestReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24)); | |
| 601 | doTheTestReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24)); | |
| 602 | doTheTestReduce(.Mul, [4]i32{ -9, -99, -999, 999 }, @as(i32, -889218891)); | |
| 603 | doTheTestReduce(.Mul, [4]u32{ 1, 2, 3, 4 }, @as(u32, 24)); | |
| 604 | doTheTestReduce(.Mul, [4]i64{ 9, 99, 999, 9999 }, @as(i64, 8900199891)); | |
| 605 | doTheTestReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891)); | |
| 606 | doTheTestReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891)); | |
| 607 | doTheTestReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891)); | |
| 608 | doTheTestReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7)); | |
| 609 | doTheTestReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7)); | |
| 610 | doTheTestReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7)); | |
| 611 | ||
| 612 | doTheTestReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true)); | |
| 613 | doTheTestReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1)); | |
| 614 | doTheTestReduce(.Or, [4]u16{ 0xff00, 0xff00, 0xf0, 0xf }, ~@as(u16, 0)); | |
| 615 | doTheTestReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0)); | |
| 616 | doTheTestReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff)); | |
| 617 | doTheTestReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff)); | |
| 618 | ||
| 619 | doTheTestReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true)); | |
| 620 | doTheTestReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1)); | |
| 621 | doTheTestReduce(.Xor, [4]u16{ 0x0000, 0x3333, 0x8888, 0x4444 }, ~@as(u16, 0)); | |
| 622 | doTheTestReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0)); | |
| 623 | doTheTestReduce(.Xor, [4]u64{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u64, 0xffffffff)); | |
| 624 | doTheTestReduce(.Xor, [4]u128{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u128, 0xffffffff)); | |
| 625 | ||
| 626 | // Test the reduction on vectors containing NaNs. | |
| 627 | const f16_nan = math.nan(f16); | |
| 628 | const f32_nan = math.nan(f32); | |
| 629 | const f64_nan = math.nan(f64); | |
| 630 | ||
| 631 | doTheTestReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 632 | doTheTestReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 633 | doTheTestReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 634 | ||
| 635 | // LLVM 11 ERROR: Cannot select type | |
| 636 | // https://github.com/ziglang/zig/issues/7138 | |
| 637 | if (false) { | |
| 638 | doTheTestReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 639 | doTheTestReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 640 | doTheTestReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 641 | ||
| 642 | doTheTestReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 643 | doTheTestReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 644 | doTheTestReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 645 | } | |
| 646 | ||
| 647 | doTheTestReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 648 | doTheTestReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 649 | doTheTestReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 650 | } | |
| 651 | }; | |
| 652 | ||
| 653 | S.doTheTest(); | |
| 654 | comptime S.doTheTest(); | |
| 655 | } |
test/behavior/void.zig created+40| ... | ... | @@ -0,0 +1,40 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | a: void, | |
| 5 | b: i32, | |
| 6 | c: void, | |
| 7 | }; | |
| 8 | ||
| 9 | test "compare void with void compile time known" { | |
| 10 | comptime { | |
| 11 | const foo = Foo{ | |
| 12 | .a = {}, | |
| 13 | .b = 1, | |
| 14 | .c = {}, | |
| 15 | }; | |
| 16 | expect(foo.a == {}); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | test "iterate over a void slice" { | |
| 21 | var j: usize = 0; | |
| 22 | for (times(10)) |_, i| { | |
| 23 | expect(i == j); | |
| 24 | j += 1; | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn times(n: usize) []const void { | |
| 29 | return @as([*]void, undefined)[0..n]; | |
| 30 | } | |
| 31 | ||
| 32 | test "void optional" { | |
| 33 | var x: ?void = {}; | |
| 34 | expect(x != null); | |
| 35 | } | |
| 36 | ||
| 37 | test "void array as a local variable initializer" { | |
| 38 | var x = [_]void{{}} ** 1004; | |
| 39 | var y = x[0]; | |
| 40 | } |
test/behavior/wasm.zig created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "memory size and grow" { | |
| 5 | var prev = @wasmMemorySize(0); | |
| 6 | expect(prev == @wasmMemoryGrow(0, 1)); | |
| 7 | expect(prev + 1 == @wasmMemorySize(0)); | |
| 8 | } |
test/behavior/while.zig created+289| ... | ... | @@ -0,0 +1,289 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "while loop" { | |
| 5 | var i: i32 = 0; | |
| 6 | while (i < 4) { | |
| 7 | i += 1; | |
| 8 | } | |
| 9 | expect(i == 4); | |
| 10 | expect(whileLoop1() == 1); | |
| 11 | } | |
| 12 | fn whileLoop1() i32 { | |
| 13 | return whileLoop2(); | |
| 14 | } | |
| 15 | fn whileLoop2() i32 { | |
| 16 | while (true) { | |
| 17 | return 1; | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | test "static eval while" { | |
| 22 | expect(static_eval_while_number == 1); | |
| 23 | } | |
| 24 | const static_eval_while_number = staticWhileLoop1(); | |
| 25 | fn staticWhileLoop1() i32 { | |
| 26 | return whileLoop2(); | |
| 27 | } | |
| 28 | fn staticWhileLoop2() i32 { | |
| 29 | while (true) { | |
| 30 | return 1; | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | test "continue and break" { | |
| 35 | runContinueAndBreakTest(); | |
| 36 | expect(continue_and_break_counter == 8); | |
| 37 | } | |
| 38 | var continue_and_break_counter: i32 = 0; | |
| 39 | fn runContinueAndBreakTest() void { | |
| 40 | var i: i32 = 0; | |
| 41 | while (true) { | |
| 42 | continue_and_break_counter += 2; | |
| 43 | i += 1; | |
| 44 | if (i < 4) { | |
| 45 | continue; | |
| 46 | } | |
| 47 | break; | |
| 48 | } | |
| 49 | expect(i == 4); | |
| 50 | } | |
| 51 | ||
| 52 | test "return with implicit cast from while loop" { | |
| 53 | returnWithImplicitCastFromWhileLoopTest() catch unreachable; | |
| 54 | } | |
| 55 | fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { | |
| 56 | while (true) { | |
| 57 | return; | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | test "while with continue expression" { | |
| 62 | var sum: i32 = 0; | |
| 63 | { | |
| 64 | var i: i32 = 0; | |
| 65 | while (i < 10) : (i += 1) { | |
| 66 | if (i == 5) continue; | |
| 67 | sum += i; | |
| 68 | } | |
| 69 | } | |
| 70 | expect(sum == 40); | |
| 71 | } | |
| 72 | ||
| 73 | test "while with else" { | |
| 74 | var sum: i32 = 0; | |
| 75 | var i: i32 = 0; | |
| 76 | var got_else: i32 = 0; | |
| 77 | while (i < 10) : (i += 1) { | |
| 78 | sum += 1; | |
| 79 | } else { | |
| 80 | got_else += 1; | |
| 81 | } | |
| 82 | expect(sum == 10); | |
| 83 | expect(got_else == 1); | |
| 84 | } | |
| 85 | ||
| 86 | test "while with optional as condition" { | |
| 87 | numbers_left = 10; | |
| 88 | var sum: i32 = 0; | |
| 89 | while (getNumberOrNull()) |value| { | |
| 90 | sum += value; | |
| 91 | } | |
| 92 | expect(sum == 45); | |
| 93 | } | |
| 94 | ||
| 95 | test "while with optional as condition with else" { | |
| 96 | numbers_left = 10; | |
| 97 | var sum: i32 = 0; | |
| 98 | var got_else: i32 = 0; | |
| 99 | while (getNumberOrNull()) |value| { | |
| 100 | sum += value; | |
| 101 | expect(got_else == 0); | |
| 102 | } else { | |
| 103 | got_else += 1; | |
| 104 | } | |
| 105 | expect(sum == 45); | |
| 106 | expect(got_else == 1); | |
| 107 | } | |
| 108 | ||
| 109 | test "while with error union condition" { | |
| 110 | numbers_left = 10; | |
| 111 | var sum: i32 = 0; | |
| 112 | var got_else: i32 = 0; | |
| 113 | while (getNumberOrErr()) |value| { | |
| 114 | sum += value; | |
| 115 | } else |err| { | |
| 116 | expect(err == error.OutOfNumbers); | |
| 117 | got_else += 1; | |
| 118 | } | |
| 119 | expect(sum == 45); | |
| 120 | expect(got_else == 1); | |
| 121 | } | |
| 122 | ||
| 123 | var numbers_left: i32 = undefined; | |
| 124 | fn getNumberOrErr() anyerror!i32 { | |
| 125 | return if (numbers_left == 0) error.OutOfNumbers else x: { | |
| 126 | numbers_left -= 1; | |
| 127 | break :x numbers_left; | |
| 128 | }; | |
| 129 | } | |
| 130 | fn getNumberOrNull() ?i32 { | |
| 131 | return if (numbers_left == 0) null else x: { | |
| 132 | numbers_left -= 1; | |
| 133 | break :x numbers_left; | |
| 134 | }; | |
| 135 | } | |
| 136 | ||
| 137 | test "while on optional with else result follow else prong" { | |
| 138 | const result = while (returnNull()) |value| { | |
| 139 | break value; | |
| 140 | } else | |
| 141 | @as(i32, 2); | |
| 142 | expect(result == 2); | |
| 143 | } | |
| 144 | ||
| 145 | test "while on optional with else result follow break prong" { | |
| 146 | const result = while (returnOptional(10)) |value| { | |
| 147 | break value; | |
| 148 | } else | |
| 149 | @as(i32, 2); | |
| 150 | expect(result == 10); | |
| 151 | } | |
| 152 | ||
| 153 | test "while on error union with else result follow else prong" { | |
| 154 | const result = while (returnError()) |value| { | |
| 155 | break value; | |
| 156 | } else |err| | |
| 157 | @as(i32, 2); | |
| 158 | expect(result == 2); | |
| 159 | } | |
| 160 | ||
| 161 | test "while on error union with else result follow break prong" { | |
| 162 | const result = while (returnSuccess(10)) |value| { | |
| 163 | break value; | |
| 164 | } else |err| | |
| 165 | @as(i32, 2); | |
| 166 | expect(result == 10); | |
| 167 | } | |
| 168 | ||
| 169 | test "while on bool with else result follow else prong" { | |
| 170 | const result = while (returnFalse()) { | |
| 171 | break @as(i32, 10); | |
| 172 | } else | |
| 173 | @as(i32, 2); | |
| 174 | expect(result == 2); | |
| 175 | } | |
| 176 | ||
| 177 | test "while on bool with else result follow break prong" { | |
| 178 | const result = while (returnTrue()) { | |
| 179 | break @as(i32, 10); | |
| 180 | } else | |
| 181 | @as(i32, 2); | |
| 182 | expect(result == 10); | |
| 183 | } | |
| 184 | ||
| 185 | test "break from outer while loop" { | |
| 186 | testBreakOuter(); | |
| 187 | comptime testBreakOuter(); | |
| 188 | } | |
| 189 | ||
| 190 | fn testBreakOuter() void { | |
| 191 | outer: while (true) { | |
| 192 | while (true) { | |
| 193 | break :outer; | |
| 194 | } | |
| 195 | } | |
| 196 | } | |
| 197 | ||
| 198 | test "continue outer while loop" { | |
| 199 | testContinueOuter(); | |
| 200 | comptime testContinueOuter(); | |
| 201 | } | |
| 202 | ||
| 203 | fn testContinueOuter() void { | |
| 204 | var i: usize = 0; | |
| 205 | outer: while (i < 10) : (i += 1) { | |
| 206 | while (true) { | |
| 207 | continue :outer; | |
| 208 | } | |
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | fn returnNull() ?i32 { | |
| 213 | return null; | |
| 214 | } | |
| 215 | fn returnOptional(x: i32) ?i32 { | |
| 216 | return x; | |
| 217 | } | |
| 218 | fn returnError() anyerror!i32 { | |
| 219 | return error.YouWantedAnError; | |
| 220 | } | |
| 221 | fn returnSuccess(x: i32) anyerror!i32 { | |
| 222 | return x; | |
| 223 | } | |
| 224 | fn returnFalse() bool { | |
| 225 | return false; | |
| 226 | } | |
| 227 | fn returnTrue() bool { | |
| 228 | return true; | |
| 229 | } | |
| 230 | ||
| 231 | test "while bool 2 break statements and an else" { | |
| 232 | const S = struct { | |
| 233 | fn entry(t: bool, f: bool) void { | |
| 234 | var ok = false; | |
| 235 | ok = while (t) { | |
| 236 | if (f) break false; | |
| 237 | if (t) break true; | |
| 238 | } else false; | |
| 239 | expect(ok); | |
| 240 | } | |
| 241 | }; | |
| 242 | S.entry(true, false); | |
| 243 | comptime S.entry(true, false); | |
| 244 | } | |
| 245 | ||
| 246 | test "while optional 2 break statements and an else" { | |
| 247 | const S = struct { | |
| 248 | fn entry(opt_t: ?bool, f: bool) void { | |
| 249 | var ok = false; | |
| 250 | ok = while (opt_t) |t| { | |
| 251 | if (f) break false; | |
| 252 | if (t) break true; | |
| 253 | } else false; | |
| 254 | expect(ok); | |
| 255 | } | |
| 256 | }; | |
| 257 | S.entry(true, false); | |
| 258 | comptime S.entry(true, false); | |
| 259 | } | |
| 260 | ||
| 261 | test "while error 2 break statements and an else" { | |
| 262 | const S = struct { | |
| 263 | fn entry(opt_t: anyerror!bool, f: bool) void { | |
| 264 | var ok = false; | |
| 265 | ok = while (opt_t) |t| { | |
| 266 | if (f) break false; | |
| 267 | if (t) break true; | |
| 268 | } else |_| false; | |
| 269 | expect(ok); | |
| 270 | } | |
| 271 | }; | |
| 272 | S.entry(true, false); | |
| 273 | comptime S.entry(true, false); | |
| 274 | } | |
| 275 | ||
| 276 | test "while copies its payload" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | var tmp: ?i32 = 10; | |
| 280 | while (tmp) |value| { | |
| 281 | // Modify the original variable | |
| 282 | tmp = null; | |
| 283 | expect(value == 10); | |
| 284 | } | |
| 285 | } | |
| 286 | }; | |
| 287 | S.doTheTest(); | |
| 288 | comptime S.doTheTest(); | |
| 289 | } |
test/behavior/widening.zig created+39| ... | ... | @@ -0,0 +1,39 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | test "integer widening" { | |
| 6 | var a: u8 = 250; | |
| 7 | var b: u16 = a; | |
| 8 | var c: u32 = b; | |
| 9 | var d: u64 = c; | |
| 10 | var e: u64 = d; | |
| 11 | var f: u128 = e; | |
| 12 | expect(f == a); | |
| 13 | } | |
| 14 | ||
| 15 | test "implicit unsigned integer to signed integer" { | |
| 16 | var a: u8 = 250; | |
| 17 | var b: i16 = a; | |
| 18 | expect(b == 250); | |
| 19 | } | |
| 20 | ||
| 21 | test "float widening" { | |
| 22 | var a: f16 = 12.34; | |
| 23 | var b: f32 = a; | |
| 24 | var c: f64 = b; | |
| 25 | var d: f128 = c; | |
| 26 | expect(a == b); | |
| 27 | expect(b == c); | |
| 28 | expect(c == d); | |
| 29 | } | |
| 30 | ||
| 31 | test "float widening f16 to f128" { | |
| 32 | // TODO https://github.com/ziglang/zig/issues/3282 | |
| 33 | if (@import("builtin").target.cpu.arch == .aarch64) return error.SkipZigTest; | |
| 34 | if (@import("builtin").target.cpu.arch == .powerpc64le) return error.SkipZigTest; | |
| 35 | ||
| 36 | var x: f16 = 12.34; | |
| 37 | var y: f128 = x; | |
| 38 | expect(x == y); | |
| 39 | } |
test/stage1/behavior.zig deleted-153| ... | ... | @@ -1,153 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | ||
| 3 | comptime { | |
| 4 | // Tests that pass for both. | |
| 5 | {} | |
| 6 | ||
| 7 | if (builtin.zig_is_stage2) { | |
| 8 | // Tests that only pass for stage2. | |
| 9 | } else { | |
| 10 | // Tests that only pass for stage1. | |
| 11 | _ = @import("behavior/align.zig"); | |
| 12 | _ = @import("behavior/alignof.zig"); | |
| 13 | _ = @import("behavior/array.zig"); | |
| 14 | if (builtin.os.tag != .wasi) { | |
| 15 | _ = @import("behavior/asm.zig"); | |
| 16 | _ = @import("behavior/async_fn.zig"); | |
| 17 | } | |
| 18 | _ = @import("behavior/atomics.zig"); | |
| 19 | _ = @import("behavior/await_struct.zig"); | |
| 20 | _ = @import("behavior/bit_shifting.zig"); | |
| 21 | _ = @import("behavior/bitcast.zig"); | |
| 22 | _ = @import("behavior/bitreverse.zig"); | |
| 23 | _ = @import("behavior/bool.zig"); | |
| 24 | _ = @import("behavior/bugs/1025.zig"); | |
| 25 | _ = @import("behavior/bugs/1076.zig"); | |
| 26 | _ = @import("behavior/bugs/1111.zig"); | |
| 27 | _ = @import("behavior/bugs/1120.zig"); | |
| 28 | _ = @import("behavior/bugs/1277.zig"); | |
| 29 | _ = @import("behavior/bugs/1310.zig"); | |
| 30 | _ = @import("behavior/bugs/1322.zig"); | |
| 31 | _ = @import("behavior/bugs/1381.zig"); | |
| 32 | _ = @import("behavior/bugs/1421.zig"); | |
| 33 | _ = @import("behavior/bugs/1442.zig"); | |
| 34 | _ = @import("behavior/bugs/1486.zig"); | |
| 35 | _ = @import("behavior/bugs/1500.zig"); | |
| 36 | _ = @import("behavior/bugs/1607.zig"); | |
| 37 | _ = @import("behavior/bugs/1735.zig"); | |
| 38 | _ = @import("behavior/bugs/1741.zig"); | |
| 39 | _ = @import("behavior/bugs/1851.zig"); | |
| 40 | _ = @import("behavior/bugs/1914.zig"); | |
| 41 | _ = @import("behavior/bugs/2006.zig"); | |
| 42 | _ = @import("behavior/bugs/2114.zig"); | |
| 43 | _ = @import("behavior/bugs/2346.zig"); | |
| 44 | _ = @import("behavior/bugs/2578.zig"); | |
| 45 | _ = @import("behavior/bugs/2692.zig"); | |
| 46 | _ = @import("behavior/bugs/2889.zig"); | |
| 47 | _ = @import("behavior/bugs/3007.zig"); | |
| 48 | _ = @import("behavior/bugs/3046.zig"); | |
| 49 | _ = @import("behavior/bugs/3112.zig"); | |
| 50 | _ = @import("behavior/bugs/3367.zig"); | |
| 51 | _ = @import("behavior/bugs/3384.zig"); | |
| 52 | _ = @import("behavior/bugs/3586.zig"); | |
| 53 | _ = @import("behavior/bugs/3742.zig"); | |
| 54 | _ = @import("behavior/bugs/4328.zig"); | |
| 55 | _ = @import("behavior/bugs/4560.zig"); | |
| 56 | _ = @import("behavior/bugs/4769_a.zig"); | |
| 57 | _ = @import("behavior/bugs/4769_b.zig"); | |
| 58 | _ = @import("behavior/bugs/4769_c.zig"); | |
| 59 | _ = @import("behavior/bugs/4954.zig"); | |
| 60 | _ = @import("behavior/bugs/5398.zig"); | |
| 61 | _ = @import("behavior/bugs/5413.zig"); | |
| 62 | _ = @import("behavior/bugs/5474.zig"); | |
| 63 | _ = @import("behavior/bugs/5487.zig"); | |
| 64 | _ = @import("behavior/bugs/6456.zig"); | |
| 65 | _ = @import("behavior/bugs/6781.zig"); | |
| 66 | _ = @import("behavior/bugs/6850.zig"); | |
| 67 | _ = @import("behavior/bugs/7027.zig"); | |
| 68 | _ = @import("behavior/bugs/7047.zig"); | |
| 69 | _ = @import("behavior/bugs/7003.zig"); | |
| 70 | _ = @import("behavior/bugs/7250.zig"); | |
| 71 | _ = @import("behavior/bugs/394.zig"); | |
| 72 | _ = @import("behavior/bugs/421.zig"); | |
| 73 | _ = @import("behavior/bugs/529.zig"); | |
| 74 | _ = @import("behavior/bugs/624.zig"); | |
| 75 | _ = @import("behavior/bugs/655.zig"); | |
| 76 | _ = @import("behavior/bugs/656.zig"); | |
| 77 | _ = @import("behavior/bugs/679.zig"); | |
| 78 | _ = @import("behavior/bugs/704.zig"); | |
| 79 | _ = @import("behavior/bugs/718.zig"); | |
| 80 | _ = @import("behavior/bugs/726.zig"); | |
| 81 | _ = @import("behavior/bugs/828.zig"); | |
| 82 | _ = @import("behavior/bugs/920.zig"); | |
| 83 | _ = @import("behavior/byteswap.zig"); | |
| 84 | _ = @import("behavior/byval_arg_var.zig"); | |
| 85 | _ = @import("behavior/call.zig"); | |
| 86 | _ = @import("behavior/cast.zig"); | |
| 87 | _ = @import("behavior/const_slice_child.zig"); | |
| 88 | _ = @import("behavior/defer.zig"); | |
| 89 | _ = @import("behavior/enum.zig"); | |
| 90 | _ = @import("behavior/enum_with_members.zig"); | |
| 91 | _ = @import("behavior/error.zig"); | |
| 92 | _ = @import("behavior/eval.zig"); | |
| 93 | _ = @import("behavior/field_parent_ptr.zig"); | |
| 94 | _ = @import("behavior/floatop.zig"); | |
| 95 | _ = @import("behavior/fn.zig"); | |
| 96 | _ = @import("behavior/fn_in_struct_in_comptime.zig"); | |
| 97 | _ = @import("behavior/fn_delegation.zig"); | |
| 98 | _ = @import("behavior/for.zig"); | |
| 99 | _ = @import("behavior/generics.zig"); | |
| 100 | _ = @import("behavior/hasdecl.zig"); | |
| 101 | _ = @import("behavior/hasfield.zig"); | |
| 102 | _ = @import("behavior/if.zig"); | |
| 103 | _ = @import("behavior/import.zig"); | |
| 104 | _ = @import("behavior/incomplete_struct_param_tld.zig"); | |
| 105 | _ = @import("behavior/inttoptr.zig"); | |
| 106 | _ = @import("behavior/ir_block_deps.zig"); | |
| 107 | _ = @import("behavior/math.zig"); | |
| 108 | _ = @import("behavior/merge_error_sets.zig"); | |
| 109 | _ = @import("behavior/misc.zig"); | |
| 110 | _ = @import("behavior/muladd.zig"); | |
| 111 | _ = @import("behavior/namespace_depends_on_compile_var.zig"); | |
| 112 | _ = @import("behavior/null.zig"); | |
| 113 | _ = @import("behavior/optional.zig"); | |
| 114 | _ = @import("behavior/pointers.zig"); | |
| 115 | _ = @import("behavior/popcount.zig"); | |
| 116 | _ = @import("behavior/ptrcast.zig"); | |
| 117 | _ = @import("behavior/pub_enum.zig"); | |
| 118 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); | |
| 119 | _ = @import("behavior/reflection.zig"); | |
| 120 | _ = @import("behavior/shuffle.zig"); | |
| 121 | _ = @import("behavior/sizeof_and_typeof.zig"); | |
| 122 | _ = @import("behavior/slice.zig"); | |
| 123 | _ = @import("behavior/slice_sentinel_comptime.zig"); | |
| 124 | _ = @import("behavior/struct.zig"); | |
| 125 | _ = @import("behavior/struct_contains_null_ptr_itself.zig"); | |
| 126 | _ = @import("behavior/struct_contains_slice_of_itself.zig"); | |
| 127 | _ = @import("behavior/switch.zig"); | |
| 128 | _ = @import("behavior/switch_prong_err_enum.zig"); | |
| 129 | _ = @import("behavior/switch_prong_implicit_cast.zig"); | |
| 130 | _ = @import("behavior/syntax.zig"); | |
| 131 | _ = @import("behavior/this.zig"); | |
| 132 | _ = @import("behavior/truncate.zig"); | |
| 133 | _ = @import("behavior/try.zig"); | |
| 134 | _ = @import("behavior/tuple.zig"); | |
| 135 | _ = @import("behavior/type.zig"); | |
| 136 | _ = @import("behavior/type_info.zig"); | |
| 137 | _ = @import("behavior/typename.zig"); | |
| 138 | _ = @import("behavior/undefined.zig"); | |
| 139 | _ = @import("behavior/underscore.zig"); | |
| 140 | _ = @import("behavior/union.zig"); | |
| 141 | _ = @import("behavior/usingnamespace.zig"); | |
| 142 | _ = @import("behavior/var_args.zig"); | |
| 143 | _ = @import("behavior/vector.zig"); | |
| 144 | _ = @import("behavior/void.zig"); | |
| 145 | if (builtin.target.cpu.arch == .wasm32) { | |
| 146 | _ = @import("behavior/wasm.zig"); | |
| 147 | } | |
| 148 | _ = @import("behavior/while.zig"); | |
| 149 | _ = @import("behavior/widening.zig"); | |
| 150 | _ = @import("behavior/src.zig"); | |
| 151 | _ = @import("behavior/translate_c_macros.zig"); | |
| 152 | } | |
| 153 | } |
test/stage1/behavior/align.zig deleted-347| ... | ... | @@ -1,347 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const builtin = @import("builtin"); | |
| 4 | const native_arch = builtin.target.cpu.arch; | |
| 5 | ||
| 6 | var foo: u8 align(4) = 100; | |
| 7 | ||
| 8 | test "global variable alignment" { | |
| 9 | comptime expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); | |
| 10 | comptime expect(@TypeOf(&foo) == *align(4) u8); | |
| 11 | { | |
| 12 | const slice = @as(*[1]u8, &foo)[0..]; | |
| 13 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 14 | } | |
| 15 | { | |
| 16 | var runtime_zero: usize = 0; | |
| 17 | const slice = @as(*[1]u8, &foo)[runtime_zero..]; | |
| 18 | comptime expect(@TypeOf(slice) == []align(4) u8); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | fn derp() align(@sizeOf(usize) * 2) i32 { | |
| 23 | return 1234; | |
| 24 | } | |
| 25 | fn noop1() align(1) void {} | |
| 26 | fn noop4() align(4) void {} | |
| 27 | ||
| 28 | test "function alignment" { | |
| 29 | // function alignment is a compile error on wasm32/wasm64 | |
| 30 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 31 | ||
| 32 | expect(derp() == 1234); | |
| 33 | expect(@TypeOf(noop1) == fn () align(1) void); | |
| 34 | expect(@TypeOf(noop4) == fn () align(4) void); | |
| 35 | noop1(); | |
| 36 | noop4(); | |
| 37 | } | |
| 38 | ||
| 39 | var baz: packed struct { | |
| 40 | a: u32, | |
| 41 | b: u32, | |
| 42 | } = undefined; | |
| 43 | ||
| 44 | test "packed struct alignment" { | |
| 45 | expect(@TypeOf(&baz.b) == *align(1) u32); | |
| 46 | } | |
| 47 | ||
| 48 | const blah: packed struct { | |
| 49 | a: u3, | |
| 50 | b: u3, | |
| 51 | c: u2, | |
| 52 | } = undefined; | |
| 53 | ||
| 54 | test "bit field alignment" { | |
| 55 | expect(@TypeOf(&blah.b) == *align(1:3:1) const u3); | |
| 56 | } | |
| 57 | ||
| 58 | test "default alignment allows unspecified in type syntax" { | |
| 59 | expect(*u32 == *align(@alignOf(u32)) u32); | |
| 60 | } | |
| 61 | ||
| 62 | test "implicitly decreasing pointer alignment" { | |
| 63 | const a: u32 align(4) = 3; | |
| 64 | const b: u32 align(8) = 4; | |
| 65 | expect(addUnaligned(&a, &b) == 7); | |
| 66 | } | |
| 67 | ||
| 68 | fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 { | |
| 69 | return a.* + b.*; | |
| 70 | } | |
| 71 | ||
| 72 | test "implicitly decreasing slice alignment" { | |
| 73 | const a: u32 align(4) = 3; | |
| 74 | const b: u32 align(8) = 4; | |
| 75 | expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7); | |
| 76 | } | |
| 77 | fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { | |
| 78 | return a[0] + b[0]; | |
| 79 | } | |
| 80 | ||
| 81 | test "specifying alignment allows pointer cast" { | |
| 82 | testBytesAlign(0x33); | |
| 83 | } | |
| 84 | fn testBytesAlign(b: u8) void { | |
| 85 | var bytes align(4) = [_]u8{ | |
| 86 | b, | |
| 87 | b, | |
| 88 | b, | |
| 89 | b, | |
| 90 | }; | |
| 91 | const ptr = @ptrCast(*u32, &bytes[0]); | |
| 92 | expect(ptr.* == 0x33333333); | |
| 93 | } | |
| 94 | ||
| 95 | test "@alignCast pointers" { | |
| 96 | var x: u32 align(4) = 1; | |
| 97 | expectsOnly1(&x); | |
| 98 | expect(x == 2); | |
| 99 | } | |
| 100 | fn expectsOnly1(x: *align(1) u32) void { | |
| 101 | expects4(@alignCast(4, x)); | |
| 102 | } | |
| 103 | fn expects4(x: *align(4) u32) void { | |
| 104 | x.* += 1; | |
| 105 | } | |
| 106 | ||
| 107 | test "@alignCast slices" { | |
| 108 | var array align(4) = [_]u32{ | |
| 109 | 1, | |
| 110 | 1, | |
| 111 | }; | |
| 112 | const slice = array[0..]; | |
| 113 | sliceExpectsOnly1(slice); | |
| 114 | expect(slice[0] == 2); | |
| 115 | } | |
| 116 | fn sliceExpectsOnly1(slice: []align(1) u32) void { | |
| 117 | sliceExpects4(@alignCast(4, slice)); | |
| 118 | } | |
| 119 | fn sliceExpects4(slice: []align(4) u32) void { | |
| 120 | slice[0] += 1; | |
| 121 | } | |
| 122 | ||
| 123 | test "implicitly decreasing fn alignment" { | |
| 124 | // function alignment is a compile error on wasm32/wasm64 | |
| 125 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 126 | ||
| 127 | testImplicitlyDecreaseFnAlign(alignedSmall, 1234); | |
| 128 | testImplicitlyDecreaseFnAlign(alignedBig, 5678); | |
| 129 | } | |
| 130 | ||
| 131 | fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void { | |
| 132 | expect(ptr() == answer); | |
| 133 | } | |
| 134 | ||
| 135 | fn alignedSmall() align(8) i32 { | |
| 136 | return 1234; | |
| 137 | } | |
| 138 | fn alignedBig() align(16) i32 { | |
| 139 | return 5678; | |
| 140 | } | |
| 141 | ||
| 142 | test "@alignCast functions" { | |
| 143 | // function alignment is a compile error on wasm32/wasm64 | |
| 144 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 145 | ||
| 146 | expect(fnExpectsOnly1(simple4) == 0x19); | |
| 147 | } | |
| 148 | fn fnExpectsOnly1(ptr: fn () align(1) i32) i32 { | |
| 149 | return fnExpects4(@alignCast(4, ptr)); | |
| 150 | } | |
| 151 | fn fnExpects4(ptr: fn () align(4) i32) i32 { | |
| 152 | return ptr(); | |
| 153 | } | |
| 154 | fn simple4() align(4) i32 { | |
| 155 | return 0x19; | |
| 156 | } | |
| 157 | ||
| 158 | test "generic function with align param" { | |
| 159 | // function alignment is a compile error on wasm32/wasm64 | |
| 160 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 161 | ||
| 162 | expect(whyWouldYouEverDoThis(1) == 0x1); | |
| 163 | expect(whyWouldYouEverDoThis(4) == 0x1); | |
| 164 | expect(whyWouldYouEverDoThis(8) == 0x1); | |
| 165 | } | |
| 166 | ||
| 167 | fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { | |
| 168 | return 0x1; | |
| 169 | } | |
| 170 | ||
| 171 | test "@ptrCast preserves alignment of bigger source" { | |
| 172 | var x: u32 align(16) = 1234; | |
| 173 | const ptr = @ptrCast(*u8, &x); | |
| 174 | expect(@TypeOf(ptr) == *align(16) u8); | |
| 175 | } | |
| 176 | ||
| 177 | test "runtime known array index has best alignment possible" { | |
| 178 | // take full advantage of over-alignment | |
| 179 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; | |
| 180 | expect(@TypeOf(&array[0]) == *align(4) u8); | |
| 181 | expect(@TypeOf(&array[1]) == *u8); | |
| 182 | expect(@TypeOf(&array[2]) == *align(2) u8); | |
| 183 | expect(@TypeOf(&array[3]) == *u8); | |
| 184 | ||
| 185 | // because align is too small but we still figure out to use 2 | |
| 186 | var bigger align(2) = [_]u64{ 1, 2, 3, 4 }; | |
| 187 | expect(@TypeOf(&bigger[0]) == *align(2) u64); | |
| 188 | expect(@TypeOf(&bigger[1]) == *align(2) u64); | |
| 189 | expect(@TypeOf(&bigger[2]) == *align(2) u64); | |
| 190 | expect(@TypeOf(&bigger[3]) == *align(2) u64); | |
| 191 | ||
| 192 | // because pointer is align 2 and u32 align % 2 == 0 we can assume align 2 | |
| 193 | var smaller align(2) = [_]u32{ 1, 2, 3, 4 }; | |
| 194 | var runtime_zero: usize = 0; | |
| 195 | comptime expect(@TypeOf(smaller[runtime_zero..]) == []align(2) u32); | |
| 196 | comptime expect(@TypeOf(smaller[runtime_zero..].ptr) == [*]align(2) u32); | |
| 197 | testIndex(smaller[runtime_zero..].ptr, 0, *align(2) u32); | |
| 198 | testIndex(smaller[runtime_zero..].ptr, 1, *align(2) u32); | |
| 199 | testIndex(smaller[runtime_zero..].ptr, 2, *align(2) u32); | |
| 200 | testIndex(smaller[runtime_zero..].ptr, 3, *align(2) u32); | |
| 201 | ||
| 202 | // has to use ABI alignment because index known at runtime only | |
| 203 | testIndex2(array[runtime_zero..].ptr, 0, *u8); | |
| 204 | testIndex2(array[runtime_zero..].ptr, 1, *u8); | |
| 205 | testIndex2(array[runtime_zero..].ptr, 2, *u8); | |
| 206 | testIndex2(array[runtime_zero..].ptr, 3, *u8); | |
| 207 | } | |
| 208 | fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void { | |
| 209 | comptime expect(@TypeOf(&smaller[index]) == T); | |
| 210 | } | |
| 211 | fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) void { | |
| 212 | comptime expect(@TypeOf(&ptr[index]) == T); | |
| 213 | } | |
| 214 | ||
| 215 | test "alignstack" { | |
| 216 | expect(fnWithAlignedStack() == 1234); | |
| 217 | } | |
| 218 | ||
| 219 | fn fnWithAlignedStack() i32 { | |
| 220 | @setAlignStack(256); | |
| 221 | return 1234; | |
| 222 | } | |
| 223 | ||
| 224 | test "alignment of structs" { | |
| 225 | expect(@alignOf(struct { | |
| 226 | a: i32, | |
| 227 | b: *i32, | |
| 228 | }) == @alignOf(usize)); | |
| 229 | } | |
| 230 | ||
| 231 | test "alignment of function with c calling convention" { | |
| 232 | var runtime_nothing = nothing; | |
| 233 | const casted1 = @ptrCast(*const u8, runtime_nothing); | |
| 234 | const casted2 = @ptrCast(fn () callconv(.C) void, casted1); | |
| 235 | casted2(); | |
| 236 | } | |
| 237 | ||
| 238 | fn nothing() callconv(.C) void {} | |
| 239 | ||
| 240 | test "return error union with 128-bit integer" { | |
| 241 | expect(3 == try give()); | |
| 242 | } | |
| 243 | fn give() anyerror!u128 { | |
| 244 | return 3; | |
| 245 | } | |
| 246 | ||
| 247 | test "alignment of >= 128-bit integer type" { | |
| 248 | expect(@alignOf(u128) == 16); | |
| 249 | expect(@alignOf(u129) == 16); | |
| 250 | } | |
| 251 | ||
| 252 | test "alignment of struct with 128-bit field" { | |
| 253 | expect(@alignOf(struct { | |
| 254 | x: u128, | |
| 255 | }) == 16); | |
| 256 | ||
| 257 | comptime { | |
| 258 | expect(@alignOf(struct { | |
| 259 | x: u128, | |
| 260 | }) == 16); | |
| 261 | } | |
| 262 | } | |
| 263 | ||
| 264 | test "size of extern struct with 128-bit field" { | |
| 265 | expect(@sizeOf(extern struct { | |
| 266 | x: u128, | |
| 267 | y: u8, | |
| 268 | }) == 32); | |
| 269 | ||
| 270 | comptime { | |
| 271 | expect(@sizeOf(extern struct { | |
| 272 | x: u128, | |
| 273 | y: u8, | |
| 274 | }) == 32); | |
| 275 | } | |
| 276 | } | |
| 277 | ||
| 278 | const DefaultAligned = struct { | |
| 279 | nevermind: u32, | |
| 280 | badguy: i128, | |
| 281 | }; | |
| 282 | ||
| 283 | test "read 128-bit field from default aligned struct in stack memory" { | |
| 284 | var default_aligned = DefaultAligned{ | |
| 285 | .nevermind = 1, | |
| 286 | .badguy = 12, | |
| 287 | }; | |
| 288 | expect((@ptrToInt(&default_aligned.badguy) % 16) == 0); | |
| 289 | expect(12 == default_aligned.badguy); | |
| 290 | } | |
| 291 | ||
| 292 | var default_aligned_global = DefaultAligned{ | |
| 293 | .nevermind = 1, | |
| 294 | .badguy = 12, | |
| 295 | }; | |
| 296 | ||
| 297 | test "read 128-bit field from default aligned struct in global memory" { | |
| 298 | expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0); | |
| 299 | expect(12 == default_aligned_global.badguy); | |
| 300 | } | |
| 301 | ||
| 302 | test "struct field explicit alignment" { | |
| 303 | const S = struct { | |
| 304 | const Node = struct { | |
| 305 | next: *Node, | |
| 306 | massive_byte: u8 align(64), | |
| 307 | }; | |
| 308 | }; | |
| 309 | ||
| 310 | var node: S.Node = undefined; | |
| 311 | node.massive_byte = 100; | |
| 312 | expect(node.massive_byte == 100); | |
| 313 | comptime expect(@TypeOf(&node.massive_byte) == *align(64) u8); | |
| 314 | expect(@ptrToInt(&node.massive_byte) % 64 == 0); | |
| 315 | } | |
| 316 | ||
| 317 | test "align(@alignOf(T)) T does not force resolution of T" { | |
| 318 | const S = struct { | |
| 319 | const A = struct { | |
| 320 | a: *align(@alignOf(A)) A, | |
| 321 | }; | |
| 322 | fn doTheTest() void { | |
| 323 | suspend { | |
| 324 | resume @frame(); | |
| 325 | } | |
| 326 | _ = bar(@Frame(doTheTest)); | |
| 327 | } | |
| 328 | fn bar(comptime T: type) *align(@alignOf(T)) T { | |
| 329 | ok = true; | |
| 330 | return undefined; | |
| 331 | } | |
| 332 | ||
| 333 | var ok = false; | |
| 334 | }; | |
| 335 | _ = async S.doTheTest(); | |
| 336 | expect(S.ok); | |
| 337 | } | |
| 338 | ||
| 339 | test "align(N) on functions" { | |
| 340 | // function alignment is a compile error on wasm32/wasm64 | |
| 341 | if (native_arch == .wasm32 or native_arch == .wasm64) return error.SkipZigTest; | |
| 342 | ||
| 343 | expect((@ptrToInt(overaligned_fn) & (0x1000 - 1)) == 0); | |
| 344 | } | |
| 345 | fn overaligned_fn() align(0x1000) i32 { | |
| 346 | return 42; | |
| 347 | } |
test/stage1/behavior/alignof.zig deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const builtin = @import("builtin"); | |
| 4 | const native_arch = builtin.target.cpu.arch; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | ||
| 7 | const Foo = struct { | |
| 8 | x: u32, | |
| 9 | y: u32, | |
| 10 | z: u32, | |
| 11 | }; | |
| 12 | ||
| 13 | test "@alignOf(T) before referencing T" { | |
| 14 | comptime expect(@alignOf(Foo) != maxInt(usize)); | |
| 15 | if (native_arch == .x86_64) { | |
| 16 | comptime expect(@alignOf(Foo) == 4); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | test "comparison of @alignOf(T) against zero" { | |
| 21 | { | |
| 22 | const T = struct { x: u32 }; | |
| 23 | expect(!(@alignOf(T) == 0)); | |
| 24 | expect(@alignOf(T) != 0); | |
| 25 | expect(!(@alignOf(T) < 0)); | |
| 26 | expect(!(@alignOf(T) <= 0)); | |
| 27 | expect(@alignOf(T) > 0); | |
| 28 | expect(@alignOf(T) >= 0); | |
| 29 | } | |
| 30 | { | |
| 31 | const T = struct {}; | |
| 32 | expect(@alignOf(T) == 0); | |
| 33 | expect(!(@alignOf(T) != 0)); | |
| 34 | expect(!(@alignOf(T) < 0)); | |
| 35 | expect(@alignOf(T) <= 0); | |
| 36 | expect(!(@alignOf(T) > 0)); | |
| 37 | expect(@alignOf(T) >= 0); | |
| 38 | } | |
| 39 | } |
test/stage1/behavior/array.zig deleted-489| ... | ... | @@ -1,489 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const mem = std.mem; | |
| 4 | const expect = testing.expect; | |
| 5 | const expectEqual = testing.expectEqual; | |
| 6 | ||
| 7 | test "arrays" { | |
| 8 | var array: [5]u32 = undefined; | |
| 9 | ||
| 10 | var i: u32 = 0; | |
| 11 | while (i < 5) { | |
| 12 | array[i] = i + 1; | |
| 13 | i = array[i]; | |
| 14 | } | |
| 15 | ||
| 16 | i = 0; | |
| 17 | var accumulator = @as(u32, 0); | |
| 18 | while (i < 5) { | |
| 19 | accumulator += array[i]; | |
| 20 | ||
| 21 | i += 1; | |
| 22 | } | |
| 23 | ||
| 24 | expect(accumulator == 15); | |
| 25 | expect(getArrayLen(&array) == 5); | |
| 26 | } | |
| 27 | fn getArrayLen(a: []const u32) usize { | |
| 28 | return a.len; | |
| 29 | } | |
| 30 | ||
| 31 | test "array with sentinels" { | |
| 32 | const S = struct { | |
| 33 | fn doTheTest(is_ct: bool) void { | |
| 34 | if (is_ct) { | |
| 35 | var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; | |
| 36 | // Disabled at runtime because of | |
| 37 | // https://github.com/ziglang/zig/issues/4372 | |
| 38 | expectEqual(@as(u8, 0xde), zero_sized[0]); | |
| 39 | var reinterpreted = @ptrCast(*[1]u8, &zero_sized); | |
| 40 | expectEqual(@as(u8, 0xde), reinterpreted[0]); | |
| 41 | } | |
| 42 | var arr: [3:0x55]u8 = undefined; | |
| 43 | // Make sure the sentinel pointer is pointing after the last element | |
| 44 | if (!is_ct) { | |
| 45 | const sentinel_ptr = @ptrToInt(&arr[3]); | |
| 46 | const last_elem_ptr = @ptrToInt(&arr[2]); | |
| 47 | expectEqual(@as(usize, 1), sentinel_ptr - last_elem_ptr); | |
| 48 | } | |
| 49 | // Make sure the sentinel is writeable | |
| 50 | arr[3] = 0x55; | |
| 51 | } | |
| 52 | }; | |
| 53 | ||
| 54 | S.doTheTest(false); | |
| 55 | comptime S.doTheTest(true); | |
| 56 | } | |
| 57 | ||
| 58 | test "void arrays" { | |
| 59 | var array: [4]void = undefined; | |
| 60 | array[0] = void{}; | |
| 61 | array[1] = array[2]; | |
| 62 | expect(@sizeOf(@TypeOf(array)) == 0); | |
| 63 | expect(array.len == 4); | |
| 64 | } | |
| 65 | ||
| 66 | test "array literal" { | |
| 67 | const hex_mult = [_]u16{ | |
| 68 | 4096, | |
| 69 | 256, | |
| 70 | 16, | |
| 71 | 1, | |
| 72 | }; | |
| 73 | ||
| 74 | expect(hex_mult.len == 4); | |
| 75 | expect(hex_mult[1] == 256); | |
| 76 | } | |
| 77 | ||
| 78 | test "array dot len const expr" { | |
| 79 | expect(comptime x: { | |
| 80 | break :x some_array.len == 4; | |
| 81 | }); | |
| 82 | } | |
| 83 | ||
| 84 | const ArrayDotLenConstExpr = struct { | |
| 85 | y: [some_array.len]u8, | |
| 86 | }; | |
| 87 | const some_array = [_]u8{ | |
| 88 | 0, | |
| 89 | 1, | |
| 90 | 2, | |
| 91 | 3, | |
| 92 | }; | |
| 93 | ||
| 94 | test "nested arrays" { | |
| 95 | const array_of_strings = [_][]const u8{ | |
| 96 | "hello", | |
| 97 | "this", | |
| 98 | "is", | |
| 99 | "my", | |
| 100 | "thing", | |
| 101 | }; | |
| 102 | for (array_of_strings) |s, i| { | |
| 103 | if (i == 0) expect(mem.eql(u8, s, "hello")); | |
| 104 | if (i == 1) expect(mem.eql(u8, s, "this")); | |
| 105 | if (i == 2) expect(mem.eql(u8, s, "is")); | |
| 106 | if (i == 3) expect(mem.eql(u8, s, "my")); | |
| 107 | if (i == 4) expect(mem.eql(u8, s, "thing")); | |
| 108 | } | |
| 109 | } | |
| 110 | ||
| 111 | var s_array: [8]Sub = undefined; | |
| 112 | const Sub = struct { | |
| 113 | b: u8, | |
| 114 | }; | |
| 115 | const Str = struct { | |
| 116 | a: []Sub, | |
| 117 | }; | |
| 118 | test "set global var array via slice embedded in struct" { | |
| 119 | var s = Str{ .a = s_array[0..] }; | |
| 120 | ||
| 121 | s.a[0].b = 1; | |
| 122 | s.a[1].b = 2; | |
| 123 | s.a[2].b = 3; | |
| 124 | ||
| 125 | expect(s_array[0].b == 1); | |
| 126 | expect(s_array[1].b == 2); | |
| 127 | expect(s_array[2].b == 3); | |
| 128 | } | |
| 129 | ||
| 130 | test "array literal with specified size" { | |
| 131 | var array = [2]u8{ | |
| 132 | 1, | |
| 133 | 2, | |
| 134 | }; | |
| 135 | expect(array[0] == 1); | |
| 136 | expect(array[1] == 2); | |
| 137 | } | |
| 138 | ||
| 139 | test "array len field" { | |
| 140 | var arr = [4]u8{ 0, 0, 0, 0 }; | |
| 141 | var ptr = &arr; | |
| 142 | expect(arr.len == 4); | |
| 143 | comptime expect(arr.len == 4); | |
| 144 | expect(ptr.len == 4); | |
| 145 | comptime expect(ptr.len == 4); | |
| 146 | } | |
| 147 | ||
| 148 | test "single-item pointer to array indexing and slicing" { | |
| 149 | testSingleItemPtrArrayIndexSlice(); | |
| 150 | comptime testSingleItemPtrArrayIndexSlice(); | |
| 151 | } | |
| 152 | ||
| 153 | fn testSingleItemPtrArrayIndexSlice() void { | |
| 154 | { | |
| 155 | var array: [4]u8 = "aaaa".*; | |
| 156 | doSomeMangling(&array); | |
| 157 | expect(mem.eql(u8, "azya", &array)); | |
| 158 | } | |
| 159 | { | |
| 160 | var array = "aaaa".*; | |
| 161 | doSomeMangling(&array); | |
| 162 | expect(mem.eql(u8, "azya", &array)); | |
| 163 | } | |
| 164 | } | |
| 165 | ||
| 166 | fn doSomeMangling(array: *[4]u8) void { | |
| 167 | array[1] = 'z'; | |
| 168 | array[2..3][0] = 'y'; | |
| 169 | } | |
| 170 | ||
| 171 | test "implicit cast single-item pointer" { | |
| 172 | testImplicitCastSingleItemPtr(); | |
| 173 | comptime testImplicitCastSingleItemPtr(); | |
| 174 | } | |
| 175 | ||
| 176 | fn testImplicitCastSingleItemPtr() void { | |
| 177 | var byte: u8 = 100; | |
| 178 | const slice = @as(*[1]u8, &byte)[0..]; | |
| 179 | slice[0] += 1; | |
| 180 | expect(byte == 101); | |
| 181 | } | |
| 182 | ||
| 183 | fn testArrayByValAtComptime(b: [2]u8) u8 { | |
| 184 | return b[0]; | |
| 185 | } | |
| 186 | ||
| 187 | test "comptime evalutating function that takes array by value" { | |
| 188 | const arr = [_]u8{ 0, 1 }; | |
| 189 | _ = comptime testArrayByValAtComptime(arr); | |
| 190 | _ = comptime testArrayByValAtComptime(arr); | |
| 191 | } | |
| 192 | ||
| 193 | test "implicit comptime in array type size" { | |
| 194 | var arr: [plusOne(10)]bool = undefined; | |
| 195 | expect(arr.len == 11); | |
| 196 | } | |
| 197 | ||
| 198 | fn plusOne(x: u32) u32 { | |
| 199 | return x + 1; | |
| 200 | } | |
| 201 | ||
| 202 | test "runtime initialize array elem and then implicit cast to slice" { | |
| 203 | var two: i32 = 2; | |
| 204 | const x: []const i32 = &[_]i32{two}; | |
| 205 | expect(x[0] == 2); | |
| 206 | } | |
| 207 | ||
| 208 | test "array literal as argument to function" { | |
| 209 | const S = struct { | |
| 210 | fn entry(two: i32) void { | |
| 211 | foo(&[_]i32{ | |
| 212 | 1, | |
| 213 | 2, | |
| 214 | 3, | |
| 215 | }); | |
| 216 | foo(&[_]i32{ | |
| 217 | 1, | |
| 218 | two, | |
| 219 | 3, | |
| 220 | }); | |
| 221 | foo2(true, &[_]i32{ | |
| 222 | 1, | |
| 223 | 2, | |
| 224 | 3, | |
| 225 | }); | |
| 226 | foo2(true, &[_]i32{ | |
| 227 | 1, | |
| 228 | two, | |
| 229 | 3, | |
| 230 | }); | |
| 231 | } | |
| 232 | fn foo(x: []const i32) void { | |
| 233 | expect(x[0] == 1); | |
| 234 | expect(x[1] == 2); | |
| 235 | expect(x[2] == 3); | |
| 236 | } | |
| 237 | fn foo2(trash: bool, x: []const i32) void { | |
| 238 | expect(trash); | |
| 239 | expect(x[0] == 1); | |
| 240 | expect(x[1] == 2); | |
| 241 | expect(x[2] == 3); | |
| 242 | } | |
| 243 | }; | |
| 244 | S.entry(2); | |
| 245 | comptime S.entry(2); | |
| 246 | } | |
| 247 | ||
| 248 | test "double nested array to const slice cast in array literal" { | |
| 249 | const S = struct { | |
| 250 | fn entry(two: i32) void { | |
| 251 | const cases = [_][]const []const i32{ | |
| 252 | &[_][]const i32{&[_]i32{1}}, | |
| 253 | &[_][]const i32{&[_]i32{ 2, 3 }}, | |
| 254 | &[_][]const i32{ | |
| 255 | &[_]i32{4}, | |
| 256 | &[_]i32{ 5, 6, 7 }, | |
| 257 | }, | |
| 258 | }; | |
| 259 | check(&cases); | |
| 260 | ||
| 261 | const cases2 = [_][]const i32{ | |
| 262 | &[_]i32{1}, | |
| 263 | &[_]i32{ two, 3 }, | |
| 264 | }; | |
| 265 | expect(cases2.len == 2); | |
| 266 | expect(cases2[0].len == 1); | |
| 267 | expect(cases2[0][0] == 1); | |
| 268 | expect(cases2[1].len == 2); | |
| 269 | expect(cases2[1][0] == 2); | |
| 270 | expect(cases2[1][1] == 3); | |
| 271 | ||
| 272 | const cases3 = [_][]const []const i32{ | |
| 273 | &[_][]const i32{&[_]i32{1}}, | |
| 274 | &[_][]const i32{&[_]i32{ two, 3 }}, | |
| 275 | &[_][]const i32{ | |
| 276 | &[_]i32{4}, | |
| 277 | &[_]i32{ 5, 6, 7 }, | |
| 278 | }, | |
| 279 | }; | |
| 280 | check(&cases3); | |
| 281 | } | |
| 282 | ||
| 283 | fn check(cases: []const []const []const i32) void { | |
| 284 | expect(cases.len == 3); | |
| 285 | expect(cases[0].len == 1); | |
| 286 | expect(cases[0][0].len == 1); | |
| 287 | expect(cases[0][0][0] == 1); | |
| 288 | expect(cases[1].len == 1); | |
| 289 | expect(cases[1][0].len == 2); | |
| 290 | expect(cases[1][0][0] == 2); | |
| 291 | expect(cases[1][0][1] == 3); | |
| 292 | expect(cases[2].len == 2); | |
| 293 | expect(cases[2][0].len == 1); | |
| 294 | expect(cases[2][0][0] == 4); | |
| 295 | expect(cases[2][1].len == 3); | |
| 296 | expect(cases[2][1][0] == 5); | |
| 297 | expect(cases[2][1][1] == 6); | |
| 298 | expect(cases[2][1][2] == 7); | |
| 299 | } | |
| 300 | }; | |
| 301 | S.entry(2); | |
| 302 | comptime S.entry(2); | |
| 303 | } | |
| 304 | ||
| 305 | test "read/write through global variable array of struct fields initialized via array mult" { | |
| 306 | const S = struct { | |
| 307 | fn doTheTest() void { | |
| 308 | expect(storage[0].term == 1); | |
| 309 | storage[0] = MyStruct{ .term = 123 }; | |
| 310 | expect(storage[0].term == 123); | |
| 311 | } | |
| 312 | ||
| 313 | pub const MyStruct = struct { | |
| 314 | term: usize, | |
| 315 | }; | |
| 316 | ||
| 317 | var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; | |
| 318 | }; | |
| 319 | S.doTheTest(); | |
| 320 | } | |
| 321 | ||
| 322 | test "implicit cast zero sized array ptr to slice" { | |
| 323 | { | |
| 324 | var b = "".*; | |
| 325 | const c: []const u8 = &b; | |
| 326 | expect(c.len == 0); | |
| 327 | } | |
| 328 | { | |
| 329 | var b: [0]u8 = "".*; | |
| 330 | const c: []const u8 = &b; | |
| 331 | expect(c.len == 0); | |
| 332 | } | |
| 333 | } | |
| 334 | ||
| 335 | test "anonymous list literal syntax" { | |
| 336 | const S = struct { | |
| 337 | fn doTheTest() void { | |
| 338 | var array: [4]u8 = .{ 1, 2, 3, 4 }; | |
| 339 | expect(array[0] == 1); | |
| 340 | expect(array[1] == 2); | |
| 341 | expect(array[2] == 3); | |
| 342 | expect(array[3] == 4); | |
| 343 | } | |
| 344 | }; | |
| 345 | S.doTheTest(); | |
| 346 | comptime S.doTheTest(); | |
| 347 | } | |
| 348 | ||
| 349 | test "anonymous literal in array" { | |
| 350 | const S = struct { | |
| 351 | const Foo = struct { | |
| 352 | a: usize = 2, | |
| 353 | b: usize = 4, | |
| 354 | }; | |
| 355 | fn doTheTest() void { | |
| 356 | var array: [2]Foo = .{ | |
| 357 | .{ .a = 3 }, | |
| 358 | .{ .b = 3 }, | |
| 359 | }; | |
| 360 | expect(array[0].a == 3); | |
| 361 | expect(array[0].b == 4); | |
| 362 | expect(array[1].a == 2); | |
| 363 | expect(array[1].b == 3); | |
| 364 | } | |
| 365 | }; | |
| 366 | S.doTheTest(); | |
| 367 | comptime S.doTheTest(); | |
| 368 | } | |
| 369 | ||
| 370 | test "access the null element of a null terminated array" { | |
| 371 | const S = struct { | |
| 372 | fn doTheTest() void { | |
| 373 | var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; | |
| 374 | expect(array[4] == 0); | |
| 375 | var len: usize = 4; | |
| 376 | expect(array[len] == 0); | |
| 377 | } | |
| 378 | }; | |
| 379 | S.doTheTest(); | |
| 380 | comptime S.doTheTest(); | |
| 381 | } | |
| 382 | ||
| 383 | test "type deduction for array subscript expression" { | |
| 384 | const S = struct { | |
| 385 | fn doTheTest() void { | |
| 386 | var array = [_]u8{ 0x55, 0xAA }; | |
| 387 | var v0 = true; | |
| 388 | expectEqual(@as(u8, 0xAA), array[if (v0) 1 else 0]); | |
| 389 | var v1 = false; | |
| 390 | expectEqual(@as(u8, 0x55), array[if (v1) 1 else 0]); | |
| 391 | } | |
| 392 | }; | |
| 393 | S.doTheTest(); | |
| 394 | comptime S.doTheTest(); | |
| 395 | } | |
| 396 | ||
| 397 | test "sentinel element count towards the ABI size calculation" { | |
| 398 | const S = struct { | |
| 399 | fn doTheTest() void { | |
| 400 | const T = packed struct { | |
| 401 | fill_pre: u8 = 0x55, | |
| 402 | data: [0:0]u8 = undefined, | |
| 403 | fill_post: u8 = 0xAA, | |
| 404 | }; | |
| 405 | var x = T{}; | |
| 406 | var as_slice = mem.asBytes(&x); | |
| 407 | expectEqual(@as(usize, 3), as_slice.len); | |
| 408 | expectEqual(@as(u8, 0x55), as_slice[0]); | |
| 409 | expectEqual(@as(u8, 0xAA), as_slice[2]); | |
| 410 | } | |
| 411 | }; | |
| 412 | ||
| 413 | S.doTheTest(); | |
| 414 | comptime S.doTheTest(); | |
| 415 | } | |
| 416 | ||
| 417 | test "zero-sized array with recursive type definition" { | |
| 418 | const U = struct { | |
| 419 | fn foo(comptime T: type, comptime n: usize) type { | |
| 420 | return struct { | |
| 421 | s: [n]T, | |
| 422 | x: usize = n, | |
| 423 | }; | |
| 424 | } | |
| 425 | }; | |
| 426 | ||
| 427 | const S = struct { | |
| 428 | list: U.foo(@This(), 0), | |
| 429 | }; | |
| 430 | ||
| 431 | var t: S = .{ .list = .{ .s = undefined } }; | |
| 432 | expectEqual(@as(usize, 0), t.list.x); | |
| 433 | } | |
| 434 | ||
| 435 | test "type coercion of anon struct literal to array" { | |
| 436 | const S = struct { | |
| 437 | const U = union{ | |
| 438 | a: u32, | |
| 439 | b: bool, | |
| 440 | c: []const u8, | |
| 441 | }; | |
| 442 | ||
| 443 | fn doTheTest() void { | |
| 444 | var x1: u8 = 42; | |
| 445 | const t1 = .{ x1, 56, 54 }; | |
| 446 | var arr1: [3]u8 = t1; | |
| 447 | expect(arr1[0] == 42); | |
| 448 | expect(arr1[1] == 56); | |
| 449 | expect(arr1[2] == 54); | |
| 450 | ||
| 451 | var x2: U = .{ .a = 42 }; | |
| 452 | const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; | |
| 453 | var arr2: [3]U = t2; | |
| 454 | expect(arr2[0].a == 42); | |
| 455 | expect(arr2[1].b == true); | |
| 456 | expect(mem.eql(u8, arr2[2].c, "hello")); | |
| 457 | } | |
| 458 | }; | |
| 459 | S.doTheTest(); | |
| 460 | comptime S.doTheTest(); | |
| 461 | } | |
| 462 | ||
| 463 | test "type coercion of pointer to anon struct literal to pointer to array" { | |
| 464 | const S = struct { | |
| 465 | const U = union{ | |
| 466 | a: u32, | |
| 467 | b: bool, | |
| 468 | c: []const u8, | |
| 469 | }; | |
| 470 | ||
| 471 | fn doTheTest() void { | |
| 472 | var x1: u8 = 42; | |
| 473 | const t1 = &.{ x1, 56, 54 }; | |
| 474 | var arr1: *const[3]u8 = t1; | |
| 475 | expect(arr1[0] == 42); | |
| 476 | expect(arr1[1] == 56); | |
| 477 | expect(arr1[2] == 54); | |
| 478 | ||
| 479 | var x2: U = .{ .a = 42 }; | |
| 480 | const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } }; | |
| 481 | var arr2: *const [3]U = t2; | |
| 482 | expect(arr2[0].a == 42); | |
| 483 | expect(arr2[1].b == true); | |
| 484 | expect(mem.eql(u8, arr2[2].c, "hello")); | |
| 485 | } | |
| 486 | }; | |
| 487 | S.doTheTest(); | |
| 488 | comptime S.doTheTest(); | |
| 489 | } |
test/stage1/behavior/asm.zig deleted-94| ... | ... | @@ -1,94 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const is_x86_64_linux = std.Target.current.cpu.arch == .x86_64 and std.Target.current.os.tag == .linux; | |
| 5 | ||
| 6 | comptime { | |
| 7 | if (is_x86_64_linux) { | |
| 8 | asm ( | |
| 9 | \\.globl this_is_my_alias; | |
| 10 | \\.type this_is_my_alias, @function; | |
| 11 | \\.set this_is_my_alias, derp; | |
| 12 | ); | |
| 13 | } | |
| 14 | } | |
| 15 | ||
| 16 | test "module level assembly" { | |
| 17 | if (is_x86_64_linux) { | |
| 18 | expect(this_is_my_alias() == 1234); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | test "output constraint modifiers" { | |
| 23 | // This is only testing compilation. | |
| 24 | var a: u32 = 3; | |
| 25 | asm volatile ("" | |
| 26 | : [_] "=m,r" (a) | |
| 27 | : | |
| 28 | : "" | |
| 29 | ); | |
| 30 | asm volatile ("" | |
| 31 | : [_] "=r,m" (a) | |
| 32 | : | |
| 33 | : "" | |
| 34 | ); | |
| 35 | } | |
| 36 | ||
| 37 | test "alternative constraints" { | |
| 38 | // Make sure we allow commas as a separator for alternative constraints. | |
| 39 | var a: u32 = 3; | |
| 40 | asm volatile ("" | |
| 41 | : [_] "=r,m" (a) | |
| 42 | : [_] "r,m" (a) | |
| 43 | : "" | |
| 44 | ); | |
| 45 | } | |
| 46 | ||
| 47 | test "sized integer/float in asm input" { | |
| 48 | asm volatile ("" | |
| 49 | : | |
| 50 | : [_] "m" (@as(usize, 3)) | |
| 51 | : "" | |
| 52 | ); | |
| 53 | asm volatile ("" | |
| 54 | : | |
| 55 | : [_] "m" (@as(i15, -3)) | |
| 56 | : "" | |
| 57 | ); | |
| 58 | asm volatile ("" | |
| 59 | : | |
| 60 | : [_] "m" (@as(u3, 3)) | |
| 61 | : "" | |
| 62 | ); | |
| 63 | asm volatile ("" | |
| 64 | : | |
| 65 | : [_] "m" (@as(i3, 3)) | |
| 66 | : "" | |
| 67 | ); | |
| 68 | asm volatile ("" | |
| 69 | : | |
| 70 | : [_] "m" (@as(u121, 3)) | |
| 71 | : "" | |
| 72 | ); | |
| 73 | asm volatile ("" | |
| 74 | : | |
| 75 | : [_] "m" (@as(i121, 3)) | |
| 76 | : "" | |
| 77 | ); | |
| 78 | asm volatile ("" | |
| 79 | : | |
| 80 | : [_] "m" (@as(f32, 3.17)) | |
| 81 | : "" | |
| 82 | ); | |
| 83 | asm volatile ("" | |
| 84 | : | |
| 85 | : [_] "m" (@as(f64, 3.17)) | |
| 86 | : "" | |
| 87 | ); | |
| 88 | } | |
| 89 | ||
| 90 | extern fn this_is_my_alias() i32; | |
| 91 | ||
| 92 | export fn derp() i32 { | |
| 93 | return 1234; | |
| 94 | } |
test/stage1/behavior/async_fn.zig deleted-1673| ... | ... | @@ -1,1673 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const expectEqualStrings = std.testing.expectEqualStrings; | |
| 6 | const expectError = std.testing.expectError; | |
| 7 | ||
| 8 | var global_x: i32 = 1; | |
| 9 | ||
| 10 | test "simple coroutine suspend and resume" { | |
| 11 | var frame = async simpleAsyncFn(); | |
| 12 | expect(global_x == 2); | |
| 13 | resume frame; | |
| 14 | expect(global_x == 3); | |
| 15 | const af: anyframe->void = &frame; | |
| 16 | resume frame; | |
| 17 | expect(global_x == 4); | |
| 18 | } | |
| 19 | fn simpleAsyncFn() void { | |
| 20 | global_x += 1; | |
| 21 | suspend {} | |
| 22 | global_x += 1; | |
| 23 | suspend {} | |
| 24 | global_x += 1; | |
| 25 | } | |
| 26 | ||
| 27 | var global_y: i32 = 1; | |
| 28 | ||
| 29 | test "pass parameter to coroutine" { | |
| 30 | var p = async simpleAsyncFnWithArg(2); | |
| 31 | expect(global_y == 3); | |
| 32 | resume p; | |
| 33 | expect(global_y == 5); | |
| 34 | } | |
| 35 | fn simpleAsyncFnWithArg(delta: i32) void { | |
| 36 | global_y += delta; | |
| 37 | suspend {} | |
| 38 | global_y += delta; | |
| 39 | } | |
| 40 | ||
| 41 | test "suspend at end of function" { | |
| 42 | const S = struct { | |
| 43 | var x: i32 = 1; | |
| 44 | ||
| 45 | fn doTheTest() void { | |
| 46 | expect(x == 1); | |
| 47 | const p = async suspendAtEnd(); | |
| 48 | expect(x == 2); | |
| 49 | } | |
| 50 | ||
| 51 | fn suspendAtEnd() void { | |
| 52 | x += 1; | |
| 53 | suspend {} | |
| 54 | } | |
| 55 | }; | |
| 56 | S.doTheTest(); | |
| 57 | } | |
| 58 | ||
| 59 | test "local variable in async function" { | |
| 60 | const S = struct { | |
| 61 | var x: i32 = 0; | |
| 62 | ||
| 63 | fn doTheTest() void { | |
| 64 | expect(x == 0); | |
| 65 | var p = async add(1, 2); | |
| 66 | expect(x == 0); | |
| 67 | resume p; | |
| 68 | expect(x == 0); | |
| 69 | resume p; | |
| 70 | expect(x == 0); | |
| 71 | resume p; | |
| 72 | expect(x == 3); | |
| 73 | } | |
| 74 | ||
| 75 | fn add(a: i32, b: i32) void { | |
| 76 | var accum: i32 = 0; | |
| 77 | suspend {} | |
| 78 | accum += a; | |
| 79 | suspend {} | |
| 80 | accum += b; | |
| 81 | suspend {} | |
| 82 | x = accum; | |
| 83 | } | |
| 84 | }; | |
| 85 | S.doTheTest(); | |
| 86 | } | |
| 87 | ||
| 88 | test "calling an inferred async function" { | |
| 89 | const S = struct { | |
| 90 | var x: i32 = 1; | |
| 91 | var other_frame: *@Frame(other) = undefined; | |
| 92 | ||
| 93 | fn doTheTest() void { | |
| 94 | _ = async first(); | |
| 95 | expect(x == 1); | |
| 96 | resume other_frame.*; | |
| 97 | expect(x == 2); | |
| 98 | } | |
| 99 | ||
| 100 | fn first() void { | |
| 101 | other(); | |
| 102 | } | |
| 103 | fn other() void { | |
| 104 | other_frame = @frame(); | |
| 105 | suspend {} | |
| 106 | x += 1; | |
| 107 | } | |
| 108 | }; | |
| 109 | S.doTheTest(); | |
| 110 | } | |
| 111 | ||
| 112 | test "@frameSize" { | |
| 113 | const S = struct { | |
| 114 | fn doTheTest() void { | |
| 115 | { | |
| 116 | var ptr = @ptrCast(fn (i32) callconv(.Async) void, other); | |
| 117 | const size = @frameSize(ptr); | |
| 118 | expect(size == @sizeOf(@Frame(other))); | |
| 119 | } | |
| 120 | { | |
| 121 | var ptr = @ptrCast(fn () callconv(.Async) void, first); | |
| 122 | const size = @frameSize(ptr); | |
| 123 | expect(size == @sizeOf(@Frame(first))); | |
| 124 | } | |
| 125 | } | |
| 126 | ||
| 127 | fn first() void { | |
| 128 | other(1); | |
| 129 | } | |
| 130 | fn other(param: i32) void { | |
| 131 | var local: i32 = undefined; | |
| 132 | suspend {} | |
| 133 | } | |
| 134 | }; | |
| 135 | S.doTheTest(); | |
| 136 | } | |
| 137 | ||
| 138 | test "coroutine suspend, resume" { | |
| 139 | const S = struct { | |
| 140 | var frame: anyframe = undefined; | |
| 141 | ||
| 142 | fn doTheTest() void { | |
| 143 | _ = async amain(); | |
| 144 | seq('d'); | |
| 145 | resume frame; | |
| 146 | seq('h'); | |
| 147 | ||
| 148 | expect(std.mem.eql(u8, &points, "abcdefgh")); | |
| 149 | } | |
| 150 | ||
| 151 | fn amain() void { | |
| 152 | seq('a'); | |
| 153 | var f = async testAsyncSeq(); | |
| 154 | seq('c'); | |
| 155 | await f; | |
| 156 | seq('g'); | |
| 157 | } | |
| 158 | ||
| 159 | fn testAsyncSeq() void { | |
| 160 | defer seq('f'); | |
| 161 | ||
| 162 | seq('b'); | |
| 163 | suspend { | |
| 164 | frame = @frame(); | |
| 165 | } | |
| 166 | seq('e'); | |
| 167 | } | |
| 168 | var points = [_]u8{'x'} ** "abcdefgh".len; | |
| 169 | var index: usize = 0; | |
| 170 | ||
| 171 | fn seq(c: u8) void { | |
| 172 | points[index] = c; | |
| 173 | index += 1; | |
| 174 | } | |
| 175 | }; | |
| 176 | S.doTheTest(); | |
| 177 | } | |
| 178 | ||
| 179 | test "coroutine suspend with block" { | |
| 180 | const p = async testSuspendBlock(); | |
| 181 | expect(!global_result); | |
| 182 | resume a_promise; | |
| 183 | expect(global_result); | |
| 184 | } | |
| 185 | ||
| 186 | var a_promise: anyframe = undefined; | |
| 187 | var global_result = false; | |
| 188 | fn testSuspendBlock() callconv(.Async) void { | |
| 189 | suspend { | |
| 190 | comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock)); | |
| 191 | a_promise = @frame(); | |
| 192 | } | |
| 193 | ||
| 194 | // Test to make sure that @frame() works as advertised (issue #1296) | |
| 195 | // var our_handle: anyframe = @frame(); | |
| 196 | expect(a_promise == @as(anyframe, @frame())); | |
| 197 | ||
| 198 | global_result = true; | |
| 199 | } | |
| 200 | ||
| 201 | var await_a_promise: anyframe = undefined; | |
| 202 | var await_final_result: i32 = 0; | |
| 203 | ||
| 204 | test "coroutine await" { | |
| 205 | await_seq('a'); | |
| 206 | var p = async await_amain(); | |
| 207 | await_seq('f'); | |
| 208 | resume await_a_promise; | |
| 209 | await_seq('i'); | |
| 210 | expect(await_final_result == 1234); | |
| 211 | expect(std.mem.eql(u8, &await_points, "abcdefghi")); | |
| 212 | } | |
| 213 | fn await_amain() callconv(.Async) void { | |
| 214 | await_seq('b'); | |
| 215 | var p = async await_another(); | |
| 216 | await_seq('e'); | |
| 217 | await_final_result = await p; | |
| 218 | await_seq('h'); | |
| 219 | } | |
| 220 | fn await_another() callconv(.Async) i32 { | |
| 221 | await_seq('c'); | |
| 222 | suspend { | |
| 223 | await_seq('d'); | |
| 224 | await_a_promise = @frame(); | |
| 225 | } | |
| 226 | await_seq('g'); | |
| 227 | return 1234; | |
| 228 | } | |
| 229 | ||
| 230 | var await_points = [_]u8{0} ** "abcdefghi".len; | |
| 231 | var await_seq_index: usize = 0; | |
| 232 | ||
| 233 | fn await_seq(c: u8) void { | |
| 234 | await_points[await_seq_index] = c; | |
| 235 | await_seq_index += 1; | |
| 236 | } | |
| 237 | ||
| 238 | var early_final_result: i32 = 0; | |
| 239 | ||
| 240 | test "coroutine await early return" { | |
| 241 | early_seq('a'); | |
| 242 | var p = async early_amain(); | |
| 243 | early_seq('f'); | |
| 244 | expect(early_final_result == 1234); | |
| 245 | expect(std.mem.eql(u8, &early_points, "abcdef")); | |
| 246 | } | |
| 247 | fn early_amain() callconv(.Async) void { | |
| 248 | early_seq('b'); | |
| 249 | var p = async early_another(); | |
| 250 | early_seq('d'); | |
| 251 | early_final_result = await p; | |
| 252 | early_seq('e'); | |
| 253 | } | |
| 254 | fn early_another() callconv(.Async) i32 { | |
| 255 | early_seq('c'); | |
| 256 | return 1234; | |
| 257 | } | |
| 258 | ||
| 259 | var early_points = [_]u8{0} ** "abcdef".len; | |
| 260 | var early_seq_index: usize = 0; | |
| 261 | ||
| 262 | fn early_seq(c: u8) void { | |
| 263 | early_points[early_seq_index] = c; | |
| 264 | early_seq_index += 1; | |
| 265 | } | |
| 266 | ||
| 267 | test "async function with dot syntax" { | |
| 268 | const S = struct { | |
| 269 | var y: i32 = 1; | |
| 270 | fn foo() callconv(.Async) void { | |
| 271 | y += 1; | |
| 272 | suspend {} | |
| 273 | } | |
| 274 | }; | |
| 275 | const p = async S.foo(); | |
| 276 | expect(S.y == 2); | |
| 277 | } | |
| 278 | ||
| 279 | test "async fn pointer in a struct field" { | |
| 280 | var data: i32 = 1; | |
| 281 | const Foo = struct { | |
| 282 | bar: fn (*i32) callconv(.Async) void, | |
| 283 | }; | |
| 284 | var foo = Foo{ .bar = simpleAsyncFn2 }; | |
| 285 | var bytes: [64]u8 align(16) = undefined; | |
| 286 | const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); | |
| 287 | comptime expect(@TypeOf(f) == anyframe->void); | |
| 288 | expect(data == 2); | |
| 289 | resume f; | |
| 290 | expect(data == 4); | |
| 291 | _ = async doTheAwait(f); | |
| 292 | expect(data == 4); | |
| 293 | } | |
| 294 | ||
| 295 | fn doTheAwait(f: anyframe->void) void { | |
| 296 | await f; | |
| 297 | } | |
| 298 | fn simpleAsyncFn2(y: *i32) callconv(.Async) void { | |
| 299 | defer y.* += 2; | |
| 300 | y.* += 1; | |
| 301 | suspend {} | |
| 302 | } | |
| 303 | ||
| 304 | test "@asyncCall with return type" { | |
| 305 | const Foo = struct { | |
| 306 | bar: fn () callconv(.Async) i32, | |
| 307 | ||
| 308 | var global_frame: anyframe = undefined; | |
| 309 | fn middle() callconv(.Async) i32 { | |
| 310 | return afunc(); | |
| 311 | } | |
| 312 | ||
| 313 | fn afunc() i32 { | |
| 314 | global_frame = @frame(); | |
| 315 | suspend {} | |
| 316 | return 1234; | |
| 317 | } | |
| 318 | }; | |
| 319 | var foo = Foo{ .bar = Foo.middle }; | |
| 320 | var bytes: [150]u8 align(16) = undefined; | |
| 321 | var aresult: i32 = 0; | |
| 322 | _ = @asyncCall(&bytes, &aresult, foo.bar, .{}); | |
| 323 | expect(aresult == 0); | |
| 324 | resume Foo.global_frame; | |
| 325 | expect(aresult == 1234); | |
| 326 | } | |
| 327 | ||
| 328 | test "async fn with inferred error set" { | |
| 329 | const S = struct { | |
| 330 | var global_frame: anyframe = undefined; | |
| 331 | ||
| 332 | fn doTheTest() void { | |
| 333 | var frame: [1]@Frame(middle) = undefined; | |
| 334 | var fn_ptr = middle; | |
| 335 | var result: @typeInfo(@typeInfo(@TypeOf(fn_ptr)).Fn.return_type.?).ErrorUnion.error_set!void = undefined; | |
| 336 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr, .{}); | |
| 337 | resume global_frame; | |
| 338 | std.testing.expectError(error.Fail, result); | |
| 339 | } | |
| 340 | fn middle() callconv(.Async) !void { | |
| 341 | var f = async middle2(); | |
| 342 | return await f; | |
| 343 | } | |
| 344 | ||
| 345 | fn middle2() !void { | |
| 346 | return failing(); | |
| 347 | } | |
| 348 | ||
| 349 | fn failing() !void { | |
| 350 | global_frame = @frame(); | |
| 351 | suspend {} | |
| 352 | return error.Fail; | |
| 353 | } | |
| 354 | }; | |
| 355 | S.doTheTest(); | |
| 356 | } | |
| 357 | ||
| 358 | test "error return trace across suspend points - early return" { | |
| 359 | const p = nonFailing(); | |
| 360 | resume p; | |
| 361 | const p2 = async printTrace(p); | |
| 362 | } | |
| 363 | ||
| 364 | test "error return trace across suspend points - async return" { | |
| 365 | const p = nonFailing(); | |
| 366 | const p2 = async printTrace(p); | |
| 367 | resume p; | |
| 368 | } | |
| 369 | ||
| 370 | fn nonFailing() (anyframe->anyerror!void) { | |
| 371 | const Static = struct { | |
| 372 | var frame: @Frame(suspendThenFail) = undefined; | |
| 373 | }; | |
| 374 | Static.frame = async suspendThenFail(); | |
| 375 | return &Static.frame; | |
| 376 | } | |
| 377 | fn suspendThenFail() callconv(.Async) anyerror!void { | |
| 378 | suspend {} | |
| 379 | return error.Fail; | |
| 380 | } | |
| 381 | fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void { | |
| 382 | (await p) catch |e| { | |
| 383 | std.testing.expect(e == error.Fail); | |
| 384 | if (@errorReturnTrace()) |trace| { | |
| 385 | expect(trace.index == 1); | |
| 386 | } else switch (builtin.mode) { | |
| 387 | .Debug, .ReleaseSafe => @panic("expected return trace"), | |
| 388 | .ReleaseFast, .ReleaseSmall => {}, | |
| 389 | } | |
| 390 | }; | |
| 391 | } | |
| 392 | ||
| 393 | test "break from suspend" { | |
| 394 | var my_result: i32 = 1; | |
| 395 | const p = async testBreakFromSuspend(&my_result); | |
| 396 | std.testing.expect(my_result == 2); | |
| 397 | } | |
| 398 | fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void { | |
| 399 | suspend { | |
| 400 | resume @frame(); | |
| 401 | } | |
| 402 | my_result.* += 1; | |
| 403 | suspend {} | |
| 404 | my_result.* += 1; | |
| 405 | } | |
| 406 | ||
| 407 | test "heap allocated async function frame" { | |
| 408 | const S = struct { | |
| 409 | var x: i32 = 42; | |
| 410 | ||
| 411 | fn doTheTest() !void { | |
| 412 | const frame = try std.testing.allocator.create(@Frame(someFunc)); | |
| 413 | defer std.testing.allocator.destroy(frame); | |
| 414 | ||
| 415 | expect(x == 42); | |
| 416 | frame.* = async someFunc(); | |
| 417 | expect(x == 43); | |
| 418 | resume frame; | |
| 419 | expect(x == 44); | |
| 420 | } | |
| 421 | ||
| 422 | fn someFunc() void { | |
| 423 | x += 1; | |
| 424 | suspend {} | |
| 425 | x += 1; | |
| 426 | } | |
| 427 | }; | |
| 428 | try S.doTheTest(); | |
| 429 | } | |
| 430 | ||
| 431 | test "async function call return value" { | |
| 432 | const S = struct { | |
| 433 | var frame: anyframe = undefined; | |
| 434 | var pt = Point{ .x = 10, .y = 11 }; | |
| 435 | ||
| 436 | fn doTheTest() void { | |
| 437 | expectEqual(pt.x, 10); | |
| 438 | expectEqual(pt.y, 11); | |
| 439 | _ = async first(); | |
| 440 | expectEqual(pt.x, 10); | |
| 441 | expectEqual(pt.y, 11); | |
| 442 | resume frame; | |
| 443 | expectEqual(pt.x, 1); | |
| 444 | expectEqual(pt.y, 2); | |
| 445 | } | |
| 446 | ||
| 447 | fn first() void { | |
| 448 | pt = second(1, 2); | |
| 449 | } | |
| 450 | ||
| 451 | fn second(x: i32, y: i32) Point { | |
| 452 | return other(x, y); | |
| 453 | } | |
| 454 | ||
| 455 | fn other(x: i32, y: i32) Point { | |
| 456 | frame = @frame(); | |
| 457 | suspend {} | |
| 458 | return Point{ | |
| 459 | .x = x, | |
| 460 | .y = y, | |
| 461 | }; | |
| 462 | } | |
| 463 | ||
| 464 | const Point = struct { | |
| 465 | x: i32, | |
| 466 | y: i32, | |
| 467 | }; | |
| 468 | }; | |
| 469 | S.doTheTest(); | |
| 470 | } | |
| 471 | ||
| 472 | test "suspension points inside branching control flow" { | |
| 473 | const S = struct { | |
| 474 | var result: i32 = 10; | |
| 475 | ||
| 476 | fn doTheTest() void { | |
| 477 | expect(10 == result); | |
| 478 | var frame = async func(true); | |
| 479 | expect(10 == result); | |
| 480 | resume frame; | |
| 481 | expect(11 == result); | |
| 482 | resume frame; | |
| 483 | expect(12 == result); | |
| 484 | resume frame; | |
| 485 | expect(13 == result); | |
| 486 | } | |
| 487 | ||
| 488 | fn func(b: bool) void { | |
| 489 | while (b) { | |
| 490 | suspend {} | |
| 491 | result += 1; | |
| 492 | } | |
| 493 | } | |
| 494 | }; | |
| 495 | S.doTheTest(); | |
| 496 | } | |
| 497 | ||
| 498 | test "call async function which has struct return type" { | |
| 499 | const S = struct { | |
| 500 | var frame: anyframe = undefined; | |
| 501 | ||
| 502 | fn doTheTest() void { | |
| 503 | _ = async atest(); | |
| 504 | resume frame; | |
| 505 | } | |
| 506 | ||
| 507 | fn atest() void { | |
| 508 | const result = func(); | |
| 509 | expect(result.x == 5); | |
| 510 | expect(result.y == 6); | |
| 511 | } | |
| 512 | ||
| 513 | const Point = struct { | |
| 514 | x: usize, | |
| 515 | y: usize, | |
| 516 | }; | |
| 517 | ||
| 518 | fn func() Point { | |
| 519 | suspend { | |
| 520 | frame = @frame(); | |
| 521 | } | |
| 522 | return Point{ | |
| 523 | .x = 5, | |
| 524 | .y = 6, | |
| 525 | }; | |
| 526 | } | |
| 527 | }; | |
| 528 | S.doTheTest(); | |
| 529 | } | |
| 530 | ||
| 531 | test "pass string literal to async function" { | |
| 532 | const S = struct { | |
| 533 | var frame: anyframe = undefined; | |
| 534 | var ok: bool = false; | |
| 535 | ||
| 536 | fn doTheTest() void { | |
| 537 | _ = async hello("hello"); | |
| 538 | resume frame; | |
| 539 | expect(ok); | |
| 540 | } | |
| 541 | ||
| 542 | fn hello(msg: []const u8) void { | |
| 543 | frame = @frame(); | |
| 544 | suspend {} | |
| 545 | expectEqualStrings("hello", msg); | |
| 546 | ok = true; | |
| 547 | } | |
| 548 | }; | |
| 549 | S.doTheTest(); | |
| 550 | } | |
| 551 | ||
| 552 | test "await inside an errdefer" { | |
| 553 | const S = struct { | |
| 554 | var frame: anyframe = undefined; | |
| 555 | ||
| 556 | fn doTheTest() void { | |
| 557 | _ = async amainWrap(); | |
| 558 | resume frame; | |
| 559 | } | |
| 560 | ||
| 561 | fn amainWrap() !void { | |
| 562 | var foo = async func(); | |
| 563 | errdefer await foo; | |
| 564 | return error.Bad; | |
| 565 | } | |
| 566 | ||
| 567 | fn func() void { | |
| 568 | frame = @frame(); | |
| 569 | suspend {} | |
| 570 | } | |
| 571 | }; | |
| 572 | S.doTheTest(); | |
| 573 | } | |
| 574 | ||
| 575 | test "try in an async function with error union and non-zero-bit payload" { | |
| 576 | const S = struct { | |
| 577 | var frame: anyframe = undefined; | |
| 578 | var ok = false; | |
| 579 | ||
| 580 | fn doTheTest() void { | |
| 581 | _ = async amain(); | |
| 582 | resume frame; | |
| 583 | expect(ok); | |
| 584 | } | |
| 585 | ||
| 586 | fn amain() void { | |
| 587 | std.testing.expectError(error.Bad, theProblem()); | |
| 588 | ok = true; | |
| 589 | } | |
| 590 | ||
| 591 | fn theProblem() ![]u8 { | |
| 592 | frame = @frame(); | |
| 593 | suspend {} | |
| 594 | const result = try other(); | |
| 595 | return result; | |
| 596 | } | |
| 597 | ||
| 598 | fn other() ![]u8 { | |
| 599 | return error.Bad; | |
| 600 | } | |
| 601 | }; | |
| 602 | S.doTheTest(); | |
| 603 | } | |
| 604 | ||
| 605 | test "returning a const error from async function" { | |
| 606 | const S = struct { | |
| 607 | var frame: anyframe = undefined; | |
| 608 | var ok = false; | |
| 609 | ||
| 610 | fn doTheTest() void { | |
| 611 | _ = async amain(); | |
| 612 | resume frame; | |
| 613 | expect(ok); | |
| 614 | } | |
| 615 | ||
| 616 | fn amain() !void { | |
| 617 | var download_frame = async fetchUrl(10, "a string"); | |
| 618 | const download_text = try await download_frame; | |
| 619 | ||
| 620 | @panic("should not get here"); | |
| 621 | } | |
| 622 | ||
| 623 | fn fetchUrl(unused: i32, url: []const u8) ![]u8 { | |
| 624 | frame = @frame(); | |
| 625 | suspend {} | |
| 626 | ok = true; | |
| 627 | return error.OutOfMemory; | |
| 628 | } | |
| 629 | }; | |
| 630 | S.doTheTest(); | |
| 631 | } | |
| 632 | ||
| 633 | test "async/await typical usage" { | |
| 634 | inline for ([_]bool{ false, true }) |b1| { | |
| 635 | inline for ([_]bool{ false, true }) |b2| { | |
| 636 | inline for ([_]bool{ false, true }) |b3| { | |
| 637 | inline for ([_]bool{ false, true }) |b4| { | |
| 638 | testAsyncAwaitTypicalUsage(b1, b2, b3, b4).doTheTest(); | |
| 639 | } | |
| 640 | } | |
| 641 | } | |
| 642 | } | |
| 643 | } | |
| 644 | ||
| 645 | fn testAsyncAwaitTypicalUsage( | |
| 646 | comptime simulate_fail_download: bool, | |
| 647 | comptime simulate_fail_file: bool, | |
| 648 | comptime suspend_download: bool, | |
| 649 | comptime suspend_file: bool, | |
| 650 | ) type { | |
| 651 | return struct { | |
| 652 | fn doTheTest() void { | |
| 653 | _ = async amainWrap(); | |
| 654 | if (suspend_file) { | |
| 655 | resume global_file_frame; | |
| 656 | } | |
| 657 | if (suspend_download) { | |
| 658 | resume global_download_frame; | |
| 659 | } | |
| 660 | } | |
| 661 | fn amainWrap() void { | |
| 662 | if (amain()) |_| { | |
| 663 | expect(!simulate_fail_download); | |
| 664 | expect(!simulate_fail_file); | |
| 665 | } else |e| switch (e) { | |
| 666 | error.NoResponse => expect(simulate_fail_download), | |
| 667 | error.FileNotFound => expect(simulate_fail_file), | |
| 668 | else => @panic("test failure"), | |
| 669 | } | |
| 670 | } | |
| 671 | ||
| 672 | fn amain() !void { | |
| 673 | const allocator = std.testing.allocator; | |
| 674 | var download_frame = async fetchUrl(allocator, "https://example.com/"); | |
| 675 | var download_awaited = false; | |
| 676 | errdefer if (!download_awaited) { | |
| 677 | if (await download_frame) |x| allocator.free(x) else |_| {} | |
| 678 | }; | |
| 679 | ||
| 680 | var file_frame = async readFile(allocator, "something.txt"); | |
| 681 | var file_awaited = false; | |
| 682 | errdefer if (!file_awaited) { | |
| 683 | if (await file_frame) |x| allocator.free(x) else |_| {} | |
| 684 | }; | |
| 685 | ||
| 686 | download_awaited = true; | |
| 687 | const download_text = try await download_frame; | |
| 688 | defer allocator.free(download_text); | |
| 689 | ||
| 690 | file_awaited = true; | |
| 691 | const file_text = try await file_frame; | |
| 692 | defer allocator.free(file_text); | |
| 693 | ||
| 694 | expect(std.mem.eql(u8, "expected download text", download_text)); | |
| 695 | expect(std.mem.eql(u8, "expected file text", file_text)); | |
| 696 | } | |
| 697 | ||
| 698 | var global_download_frame: anyframe = undefined; | |
| 699 | fn fetchUrl(allocator: *std.mem.Allocator, url: []const u8) anyerror![]u8 { | |
| 700 | const result = try std.mem.dupe(allocator, u8, "expected download text"); | |
| 701 | errdefer allocator.free(result); | |
| 702 | if (suspend_download) { | |
| 703 | suspend { | |
| 704 | global_download_frame = @frame(); | |
| 705 | } | |
| 706 | } | |
| 707 | if (simulate_fail_download) return error.NoResponse; | |
| 708 | return result; | |
| 709 | } | |
| 710 | ||
| 711 | var global_file_frame: anyframe = undefined; | |
| 712 | fn readFile(allocator: *std.mem.Allocator, filename: []const u8) anyerror![]u8 { | |
| 713 | const result = try std.mem.dupe(allocator, u8, "expected file text"); | |
| 714 | errdefer allocator.free(result); | |
| 715 | if (suspend_file) { | |
| 716 | suspend { | |
| 717 | global_file_frame = @frame(); | |
| 718 | } | |
| 719 | } | |
| 720 | if (simulate_fail_file) return error.FileNotFound; | |
| 721 | return result; | |
| 722 | } | |
| 723 | }; | |
| 724 | } | |
| 725 | ||
| 726 | test "alignment of local variables in async functions" { | |
| 727 | const S = struct { | |
| 728 | fn doTheTest() void { | |
| 729 | var y: u8 = 123; | |
| 730 | var x: u8 align(128) = 1; | |
| 731 | expect(@ptrToInt(&x) % 128 == 0); | |
| 732 | } | |
| 733 | }; | |
| 734 | S.doTheTest(); | |
| 735 | } | |
| 736 | ||
| 737 | test "no reason to resolve frame still works" { | |
| 738 | _ = async simpleNothing(); | |
| 739 | } | |
| 740 | fn simpleNothing() void { | |
| 741 | var x: i32 = 1234; | |
| 742 | } | |
| 743 | ||
| 744 | test "async call a generic function" { | |
| 745 | const S = struct { | |
| 746 | fn doTheTest() void { | |
| 747 | var f = async func(i32, 2); | |
| 748 | const result = await f; | |
| 749 | expect(result == 3); | |
| 750 | } | |
| 751 | ||
| 752 | fn func(comptime T: type, inc: T) T { | |
| 753 | var x: T = 1; | |
| 754 | suspend { | |
| 755 | resume @frame(); | |
| 756 | } | |
| 757 | x += inc; | |
| 758 | return x; | |
| 759 | } | |
| 760 | }; | |
| 761 | _ = async S.doTheTest(); | |
| 762 | } | |
| 763 | ||
| 764 | test "return from suspend block" { | |
| 765 | const S = struct { | |
| 766 | fn doTheTest() void { | |
| 767 | expect(func() == 1234); | |
| 768 | } | |
| 769 | fn func() i32 { | |
| 770 | suspend { | |
| 771 | return 1234; | |
| 772 | } | |
| 773 | } | |
| 774 | }; | |
| 775 | _ = async S.doTheTest(); | |
| 776 | } | |
| 777 | ||
| 778 | test "struct parameter to async function is copied to the frame" { | |
| 779 | const S = struct { | |
| 780 | const Point = struct { | |
| 781 | x: i32, | |
| 782 | y: i32, | |
| 783 | }; | |
| 784 | ||
| 785 | var frame: anyframe = undefined; | |
| 786 | ||
| 787 | fn doTheTest() void { | |
| 788 | _ = async atest(); | |
| 789 | resume frame; | |
| 790 | } | |
| 791 | ||
| 792 | fn atest() void { | |
| 793 | var f: @Frame(foo) = undefined; | |
| 794 | bar(&f); | |
| 795 | clobberStack(10); | |
| 796 | } | |
| 797 | ||
| 798 | fn clobberStack(x: i32) void { | |
| 799 | if (x == 0) return; | |
| 800 | clobberStack(x - 1); | |
| 801 | var y: i32 = x; | |
| 802 | } | |
| 803 | ||
| 804 | fn bar(f: *@Frame(foo)) void { | |
| 805 | var pt = Point{ .x = 1, .y = 2 }; | |
| 806 | f.* = async foo(pt); | |
| 807 | var result = await f; | |
| 808 | expect(result == 1); | |
| 809 | } | |
| 810 | ||
| 811 | fn foo(point: Point) i32 { | |
| 812 | suspend { | |
| 813 | frame = @frame(); | |
| 814 | } | |
| 815 | return point.x; | |
| 816 | } | |
| 817 | }; | |
| 818 | S.doTheTest(); | |
| 819 | } | |
| 820 | ||
| 821 | test "cast fn to async fn when it is inferred to be async" { | |
| 822 | const S = struct { | |
| 823 | var frame: anyframe = undefined; | |
| 824 | var ok = false; | |
| 825 | ||
| 826 | fn doTheTest() void { | |
| 827 | var ptr: fn () callconv(.Async) i32 = undefined; | |
| 828 | ptr = func; | |
| 829 | var buf: [100]u8 align(16) = undefined; | |
| 830 | var result: i32 = undefined; | |
| 831 | const f = @asyncCall(&buf, &result, ptr, .{}); | |
| 832 | _ = await f; | |
| 833 | expect(result == 1234); | |
| 834 | ok = true; | |
| 835 | } | |
| 836 | ||
| 837 | fn func() i32 { | |
| 838 | suspend { | |
| 839 | frame = @frame(); | |
| 840 | } | |
| 841 | return 1234; | |
| 842 | } | |
| 843 | }; | |
| 844 | _ = async S.doTheTest(); | |
| 845 | resume S.frame; | |
| 846 | expect(S.ok); | |
| 847 | } | |
| 848 | ||
| 849 | test "cast fn to async fn when it is inferred to be async, awaited directly" { | |
| 850 | const S = struct { | |
| 851 | var frame: anyframe = undefined; | |
| 852 | var ok = false; | |
| 853 | ||
| 854 | fn doTheTest() void { | |
| 855 | var ptr: fn () callconv(.Async) i32 = undefined; | |
| 856 | ptr = func; | |
| 857 | var buf: [100]u8 align(16) = undefined; | |
| 858 | var result: i32 = undefined; | |
| 859 | _ = await @asyncCall(&buf, &result, ptr, .{}); | |
| 860 | expect(result == 1234); | |
| 861 | ok = true; | |
| 862 | } | |
| 863 | ||
| 864 | fn func() i32 { | |
| 865 | suspend { | |
| 866 | frame = @frame(); | |
| 867 | } | |
| 868 | return 1234; | |
| 869 | } | |
| 870 | }; | |
| 871 | _ = async S.doTheTest(); | |
| 872 | resume S.frame; | |
| 873 | expect(S.ok); | |
| 874 | } | |
| 875 | ||
| 876 | test "await does not force async if callee is blocking" { | |
| 877 | const S = struct { | |
| 878 | fn simple() i32 { | |
| 879 | return 1234; | |
| 880 | } | |
| 881 | }; | |
| 882 | var x = async S.simple(); | |
| 883 | expect(await x == 1234); | |
| 884 | } | |
| 885 | ||
| 886 | test "recursive async function" { | |
| 887 | expect(recursiveAsyncFunctionTest(false).doTheTest() == 55); | |
| 888 | expect(recursiveAsyncFunctionTest(true).doTheTest() == 55); | |
| 889 | } | |
| 890 | ||
| 891 | fn recursiveAsyncFunctionTest(comptime suspending_implementation: bool) type { | |
| 892 | return struct { | |
| 893 | fn fib(allocator: *std.mem.Allocator, x: u32) error{OutOfMemory}!u32 { | |
| 894 | if (x <= 1) return x; | |
| 895 | ||
| 896 | if (suspending_implementation) { | |
| 897 | suspend { | |
| 898 | resume @frame(); | |
| 899 | } | |
| 900 | } | |
| 901 | ||
| 902 | const f1 = try allocator.create(@Frame(fib)); | |
| 903 | defer allocator.destroy(f1); | |
| 904 | ||
| 905 | const f2 = try allocator.create(@Frame(fib)); | |
| 906 | defer allocator.destroy(f2); | |
| 907 | ||
| 908 | f1.* = async fib(allocator, x - 1); | |
| 909 | var f1_awaited = false; | |
| 910 | errdefer if (!f1_awaited) { | |
| 911 | _ = await f1; | |
| 912 | }; | |
| 913 | ||
| 914 | f2.* = async fib(allocator, x - 2); | |
| 915 | var f2_awaited = false; | |
| 916 | errdefer if (!f2_awaited) { | |
| 917 | _ = await f2; | |
| 918 | }; | |
| 919 | ||
| 920 | var sum: u32 = 0; | |
| 921 | ||
| 922 | f1_awaited = true; | |
| 923 | sum += try await f1; | |
| 924 | ||
| 925 | f2_awaited = true; | |
| 926 | sum += try await f2; | |
| 927 | ||
| 928 | return sum; | |
| 929 | } | |
| 930 | ||
| 931 | fn doTheTest() u32 { | |
| 932 | if (suspending_implementation) { | |
| 933 | var result: u32 = undefined; | |
| 934 | _ = async amain(&result); | |
| 935 | return result; | |
| 936 | } else { | |
| 937 | return fib(std.testing.allocator, 10) catch unreachable; | |
| 938 | } | |
| 939 | } | |
| 940 | ||
| 941 | fn amain(result: *u32) void { | |
| 942 | var x = async fib(std.testing.allocator, 10); | |
| 943 | result.* = (await x) catch unreachable; | |
| 944 | } | |
| 945 | }; | |
| 946 | } | |
| 947 | ||
| 948 | test "@asyncCall with comptime-known function, but not awaited directly" { | |
| 949 | const S = struct { | |
| 950 | var global_frame: anyframe = undefined; | |
| 951 | ||
| 952 | fn doTheTest() void { | |
| 953 | var frame: [1]@Frame(middle) = undefined; | |
| 954 | var result: @typeInfo(@typeInfo(@TypeOf(middle)).Fn.return_type.?).ErrorUnion.error_set!void = undefined; | |
| 955 | _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle, .{}); | |
| 956 | resume global_frame; | |
| 957 | std.testing.expectError(error.Fail, result); | |
| 958 | } | |
| 959 | fn middle() callconv(.Async) !void { | |
| 960 | var f = async middle2(); | |
| 961 | return await f; | |
| 962 | } | |
| 963 | ||
| 964 | fn middle2() !void { | |
| 965 | return failing(); | |
| 966 | } | |
| 967 | ||
| 968 | fn failing() !void { | |
| 969 | global_frame = @frame(); | |
| 970 | suspend {} | |
| 971 | return error.Fail; | |
| 972 | } | |
| 973 | }; | |
| 974 | S.doTheTest(); | |
| 975 | } | |
| 976 | ||
| 977 | test "@asyncCall with actual frame instead of byte buffer" { | |
| 978 | const S = struct { | |
| 979 | fn func() i32 { | |
| 980 | suspend {} | |
| 981 | return 1234; | |
| 982 | } | |
| 983 | }; | |
| 984 | var frame: @Frame(S.func) = undefined; | |
| 985 | var result: i32 = undefined; | |
| 986 | const ptr = @asyncCall(&frame, &result, S.func, .{}); | |
| 987 | resume ptr; | |
| 988 | expect(result == 1234); | |
| 989 | } | |
| 990 | ||
| 991 | test "@asyncCall using the result location inside the frame" { | |
| 992 | const S = struct { | |
| 993 | fn simple2(y: *i32) callconv(.Async) i32 { | |
| 994 | defer y.* += 2; | |
| 995 | y.* += 1; | |
| 996 | suspend {} | |
| 997 | return 1234; | |
| 998 | } | |
| 999 | fn getAnswer(f: anyframe->i32, out: *i32) void { | |
| 1000 | out.* = await f; | |
| 1001 | } | |
| 1002 | }; | |
| 1003 | var data: i32 = 1; | |
| 1004 | const Foo = struct { | |
| 1005 | bar: fn (*i32) callconv(.Async) i32, | |
| 1006 | }; | |
| 1007 | var foo = Foo{ .bar = S.simple2 }; | |
| 1008 | var bytes: [64]u8 align(16) = undefined; | |
| 1009 | const f = @asyncCall(&bytes, {}, foo.bar, .{&data}); | |
| 1010 | comptime expect(@TypeOf(f) == anyframe->i32); | |
| 1011 | expect(data == 2); | |
| 1012 | resume f; | |
| 1013 | expect(data == 4); | |
| 1014 | _ = async S.getAnswer(f, &data); | |
| 1015 | expect(data == 1234); | |
| 1016 | } | |
| 1017 | ||
| 1018 | test "@TypeOf an async function call of generic fn with error union type" { | |
| 1019 | const S = struct { | |
| 1020 | fn func(comptime x: anytype) anyerror!i32 { | |
| 1021 | const T = @TypeOf(async func(x)); | |
| 1022 | comptime expect(T == @typeInfo(@TypeOf(@frame())).Pointer.child); | |
| 1023 | return undefined; | |
| 1024 | } | |
| 1025 | }; | |
| 1026 | _ = async S.func(i32); | |
| 1027 | } | |
| 1028 | ||
| 1029 | test "using @TypeOf on a generic function call" { | |
| 1030 | const S = struct { | |
| 1031 | var global_frame: anyframe = undefined; | |
| 1032 | var global_ok = false; | |
| 1033 | ||
| 1034 | var buf: [100]u8 align(16) = undefined; | |
| 1035 | ||
| 1036 | fn amain(x: anytype) void { | |
| 1037 | if (x == 0) { | |
| 1038 | global_ok = true; | |
| 1039 | return; | |
| 1040 | } | |
| 1041 | suspend { | |
| 1042 | global_frame = @frame(); | |
| 1043 | } | |
| 1044 | const F = @TypeOf(async amain(x - 1)); | |
| 1045 | const frame = @intToPtr(*F, @ptrToInt(&buf)); | |
| 1046 | return await @asyncCall(frame, {}, amain, .{x - 1}); | |
| 1047 | } | |
| 1048 | }; | |
| 1049 | _ = async S.amain(@as(u32, 1)); | |
| 1050 | resume S.global_frame; | |
| 1051 | expect(S.global_ok); | |
| 1052 | } | |
| 1053 | ||
| 1054 | test "recursive call of await @asyncCall with struct return type" { | |
| 1055 | const S = struct { | |
| 1056 | var global_frame: anyframe = undefined; | |
| 1057 | var global_ok = false; | |
| 1058 | ||
| 1059 | var buf: [100]u8 align(16) = undefined; | |
| 1060 | ||
| 1061 | fn amain(x: anytype) Foo { | |
| 1062 | if (x == 0) { | |
| 1063 | global_ok = true; | |
| 1064 | return Foo{ .x = 1, .y = 2, .z = 3 }; | |
| 1065 | } | |
| 1066 | suspend { | |
| 1067 | global_frame = @frame(); | |
| 1068 | } | |
| 1069 | const F = @TypeOf(async amain(x - 1)); | |
| 1070 | const frame = @intToPtr(*F, @ptrToInt(&buf)); | |
| 1071 | return await @asyncCall(frame, {}, amain, .{x - 1}); | |
| 1072 | } | |
| 1073 | ||
| 1074 | const Foo = struct { | |
| 1075 | x: u64, | |
| 1076 | y: u64, | |
| 1077 | z: u64, | |
| 1078 | }; | |
| 1079 | }; | |
| 1080 | var res: S.Foo = undefined; | |
| 1081 | var frame: @TypeOf(async S.amain(@as(u32, 1))) = undefined; | |
| 1082 | _ = @asyncCall(&frame, &res, S.amain, .{@as(u32, 1)}); | |
| 1083 | resume S.global_frame; | |
| 1084 | expect(S.global_ok); | |
| 1085 | expect(res.x == 1); | |
| 1086 | expect(res.y == 2); | |
| 1087 | expect(res.z == 3); | |
| 1088 | } | |
| 1089 | ||
| 1090 | test "nosuspend function call" { | |
| 1091 | const S = struct { | |
| 1092 | fn doTheTest() void { | |
| 1093 | const result = nosuspend add(50, 100); | |
| 1094 | expect(result == 150); | |
| 1095 | } | |
| 1096 | fn add(a: i32, b: i32) i32 { | |
| 1097 | if (a > 100) { | |
| 1098 | suspend {} | |
| 1099 | } | |
| 1100 | return a + b; | |
| 1101 | } | |
| 1102 | }; | |
| 1103 | S.doTheTest(); | |
| 1104 | } | |
| 1105 | ||
| 1106 | test "await used in expression and awaiting fn with no suspend but async calling convention" { | |
| 1107 | const S = struct { | |
| 1108 | fn atest() void { | |
| 1109 | var f1 = async add(1, 2); | |
| 1110 | var f2 = async add(3, 4); | |
| 1111 | ||
| 1112 | const sum = (await f1) + (await f2); | |
| 1113 | expect(sum == 10); | |
| 1114 | } | |
| 1115 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1116 | return a + b; | |
| 1117 | } | |
| 1118 | }; | |
| 1119 | _ = async S.atest(); | |
| 1120 | } | |
| 1121 | ||
| 1122 | test "await used in expression after a fn call" { | |
| 1123 | const S = struct { | |
| 1124 | fn atest() void { | |
| 1125 | var f1 = async add(3, 4); | |
| 1126 | var sum: i32 = 0; | |
| 1127 | sum = foo() + await f1; | |
| 1128 | expect(sum == 8); | |
| 1129 | } | |
| 1130 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1131 | return a + b; | |
| 1132 | } | |
| 1133 | fn foo() i32 { | |
| 1134 | return 1; | |
| 1135 | } | |
| 1136 | }; | |
| 1137 | _ = async S.atest(); | |
| 1138 | } | |
| 1139 | ||
| 1140 | test "async fn call used in expression after a fn call" { | |
| 1141 | const S = struct { | |
| 1142 | fn atest() void { | |
| 1143 | var sum: i32 = 0; | |
| 1144 | sum = foo() + add(3, 4); | |
| 1145 | expect(sum == 8); | |
| 1146 | } | |
| 1147 | fn add(a: i32, b: i32) callconv(.Async) i32 { | |
| 1148 | return a + b; | |
| 1149 | } | |
| 1150 | fn foo() i32 { | |
| 1151 | return 1; | |
| 1152 | } | |
| 1153 | }; | |
| 1154 | _ = async S.atest(); | |
| 1155 | } | |
| 1156 | ||
| 1157 | test "suspend in for loop" { | |
| 1158 | const S = struct { | |
| 1159 | var global_frame: ?anyframe = null; | |
| 1160 | ||
| 1161 | fn doTheTest() void { | |
| 1162 | _ = async atest(); | |
| 1163 | while (global_frame) |f| resume f; | |
| 1164 | } | |
| 1165 | ||
| 1166 | fn atest() void { | |
| 1167 | expect(func(&[_]u8{ 1, 2, 3 }) == 6); | |
| 1168 | } | |
| 1169 | fn func(stuff: []const u8) u32 { | |
| 1170 | global_frame = @frame(); | |
| 1171 | var sum: u32 = 0; | |
| 1172 | for (stuff) |x| { | |
| 1173 | suspend {} | |
| 1174 | sum += x; | |
| 1175 | } | |
| 1176 | global_frame = null; | |
| 1177 | return sum; | |
| 1178 | } | |
| 1179 | }; | |
| 1180 | S.doTheTest(); | |
| 1181 | } | |
| 1182 | ||
| 1183 | test "suspend in while loop" { | |
| 1184 | const S = struct { | |
| 1185 | var global_frame: ?anyframe = null; | |
| 1186 | ||
| 1187 | fn doTheTest() void { | |
| 1188 | _ = async atest(); | |
| 1189 | while (global_frame) |f| resume f; | |
| 1190 | } | |
| 1191 | ||
| 1192 | fn atest() void { | |
| 1193 | expect(optional(6) == 6); | |
| 1194 | expect(errunion(6) == 6); | |
| 1195 | } | |
| 1196 | fn optional(stuff: ?u32) u32 { | |
| 1197 | global_frame = @frame(); | |
| 1198 | defer global_frame = null; | |
| 1199 | while (stuff) |val| { | |
| 1200 | suspend {} | |
| 1201 | return val; | |
| 1202 | } | |
| 1203 | return 0; | |
| 1204 | } | |
| 1205 | fn errunion(stuff: anyerror!u32) u32 { | |
| 1206 | global_frame = @frame(); | |
| 1207 | defer global_frame = null; | |
| 1208 | while (stuff) |val| { | |
| 1209 | suspend {} | |
| 1210 | return val; | |
| 1211 | } else |err| { | |
| 1212 | return 0; | |
| 1213 | } | |
| 1214 | } | |
| 1215 | }; | |
| 1216 | S.doTheTest(); | |
| 1217 | } | |
| 1218 | ||
| 1219 | test "correctly spill when returning the error union result of another async fn" { | |
| 1220 | const S = struct { | |
| 1221 | var global_frame: anyframe = undefined; | |
| 1222 | ||
| 1223 | fn doTheTest() void { | |
| 1224 | expect((atest() catch unreachable) == 1234); | |
| 1225 | } | |
| 1226 | ||
| 1227 | fn atest() !i32 { | |
| 1228 | return fallible1(); | |
| 1229 | } | |
| 1230 | ||
| 1231 | fn fallible1() anyerror!i32 { | |
| 1232 | suspend { | |
| 1233 | global_frame = @frame(); | |
| 1234 | } | |
| 1235 | return 1234; | |
| 1236 | } | |
| 1237 | }; | |
| 1238 | _ = async S.doTheTest(); | |
| 1239 | resume S.global_frame; | |
| 1240 | } | |
| 1241 | ||
| 1242 | test "spill target expr in a for loop" { | |
| 1243 | const S = struct { | |
| 1244 | var global_frame: anyframe = undefined; | |
| 1245 | ||
| 1246 | fn doTheTest() void { | |
| 1247 | var foo = Foo{ | |
| 1248 | .slice = &[_]i32{ 1, 2 }, | |
| 1249 | }; | |
| 1250 | expect(atest(&foo) == 3); | |
| 1251 | } | |
| 1252 | ||
| 1253 | const Foo = struct { | |
| 1254 | slice: []const i32, | |
| 1255 | }; | |
| 1256 | ||
| 1257 | fn atest(foo: *Foo) i32 { | |
| 1258 | var sum: i32 = 0; | |
| 1259 | for (foo.slice) |x| { | |
| 1260 | suspend { | |
| 1261 | global_frame = @frame(); | |
| 1262 | } | |
| 1263 | sum += x; | |
| 1264 | } | |
| 1265 | return sum; | |
| 1266 | } | |
| 1267 | }; | |
| 1268 | _ = async S.doTheTest(); | |
| 1269 | resume S.global_frame; | |
| 1270 | resume S.global_frame; | |
| 1271 | } | |
| 1272 | ||
| 1273 | test "spill target expr in a for loop, with a var decl in the loop body" { | |
| 1274 | const S = struct { | |
| 1275 | var global_frame: anyframe = undefined; | |
| 1276 | ||
| 1277 | fn doTheTest() void { | |
| 1278 | var foo = Foo{ | |
| 1279 | .slice = &[_]i32{ 1, 2 }, | |
| 1280 | }; | |
| 1281 | expect(atest(&foo) == 3); | |
| 1282 | } | |
| 1283 | ||
| 1284 | const Foo = struct { | |
| 1285 | slice: []const i32, | |
| 1286 | }; | |
| 1287 | ||
| 1288 | fn atest(foo: *Foo) i32 { | |
| 1289 | var sum: i32 = 0; | |
| 1290 | for (foo.slice) |x| { | |
| 1291 | // Previously this var decl would prevent spills. This test makes sure | |
| 1292 | // the for loop spills still happen even though there is a VarDecl in scope | |
| 1293 | // before the suspend. | |
| 1294 | var anything = true; | |
| 1295 | _ = anything; | |
| 1296 | suspend { | |
| 1297 | global_frame = @frame(); | |
| 1298 | } | |
| 1299 | sum += x; | |
| 1300 | } | |
| 1301 | return sum; | |
| 1302 | } | |
| 1303 | }; | |
| 1304 | _ = async S.doTheTest(); | |
| 1305 | resume S.global_frame; | |
| 1306 | resume S.global_frame; | |
| 1307 | } | |
| 1308 | ||
| 1309 | test "async call with @call" { | |
| 1310 | const S = struct { | |
| 1311 | var global_frame: anyframe = undefined; | |
| 1312 | fn doTheTest() void { | |
| 1313 | _ = @call(.{ .modifier = .async_kw }, atest, .{}); | |
| 1314 | resume global_frame; | |
| 1315 | } | |
| 1316 | fn atest() void { | |
| 1317 | var frame = @call(.{ .modifier = .async_kw }, afoo, .{}); | |
| 1318 | const res = await frame; | |
| 1319 | expect(res == 42); | |
| 1320 | } | |
| 1321 | fn afoo() i32 { | |
| 1322 | suspend { | |
| 1323 | global_frame = @frame(); | |
| 1324 | } | |
| 1325 | return 42; | |
| 1326 | } | |
| 1327 | }; | |
| 1328 | S.doTheTest(); | |
| 1329 | } | |
| 1330 | ||
| 1331 | test "async function passed 0-bit arg after non-0-bit arg" { | |
| 1332 | const S = struct { | |
| 1333 | var global_frame: anyframe = undefined; | |
| 1334 | var global_int: i32 = 0; | |
| 1335 | ||
| 1336 | fn foo() void { | |
| 1337 | bar(1, .{}) catch unreachable; | |
| 1338 | } | |
| 1339 | ||
| 1340 | fn bar(x: i32, args: anytype) anyerror!void { | |
| 1341 | global_frame = @frame(); | |
| 1342 | suspend {} | |
| 1343 | global_int = x; | |
| 1344 | } | |
| 1345 | }; | |
| 1346 | _ = async S.foo(); | |
| 1347 | resume S.global_frame; | |
| 1348 | expect(S.global_int == 1); | |
| 1349 | } | |
| 1350 | ||
| 1351 | test "async function passed align(16) arg after align(8) arg" { | |
| 1352 | const S = struct { | |
| 1353 | var global_frame: anyframe = undefined; | |
| 1354 | var global_int: u128 = 0; | |
| 1355 | ||
| 1356 | fn foo() void { | |
| 1357 | var a: u128 = 99; | |
| 1358 | bar(10, .{a}) catch unreachable; | |
| 1359 | } | |
| 1360 | ||
| 1361 | fn bar(x: u64, args: anytype) anyerror!void { | |
| 1362 | expect(x == 10); | |
| 1363 | global_frame = @frame(); | |
| 1364 | suspend {} | |
| 1365 | global_int = args[0]; | |
| 1366 | } | |
| 1367 | }; | |
| 1368 | _ = async S.foo(); | |
| 1369 | resume S.global_frame; | |
| 1370 | expect(S.global_int == 99); | |
| 1371 | } | |
| 1372 | ||
| 1373 | test "async function call resolves target fn frame, comptime func" { | |
| 1374 | const S = struct { | |
| 1375 | var global_frame: anyframe = undefined; | |
| 1376 | var global_int: i32 = 9; | |
| 1377 | ||
| 1378 | fn foo() anyerror!void { | |
| 1379 | const stack_size = 1000; | |
| 1380 | var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined; | |
| 1381 | return await @asyncCall(&stack_frame, {}, bar, .{}); | |
| 1382 | } | |
| 1383 | ||
| 1384 | fn bar() anyerror!void { | |
| 1385 | global_frame = @frame(); | |
| 1386 | suspend {} | |
| 1387 | global_int += 1; | |
| 1388 | } | |
| 1389 | }; | |
| 1390 | _ = async S.foo(); | |
| 1391 | resume S.global_frame; | |
| 1392 | expect(S.global_int == 10); | |
| 1393 | } | |
| 1394 | ||
| 1395 | test "async function call resolves target fn frame, runtime func" { | |
| 1396 | const S = struct { | |
| 1397 | var global_frame: anyframe = undefined; | |
| 1398 | var global_int: i32 = 9; | |
| 1399 | ||
| 1400 | fn foo() anyerror!void { | |
| 1401 | const stack_size = 1000; | |
| 1402 | var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined; | |
| 1403 | var func: fn () callconv(.Async) anyerror!void = bar; | |
| 1404 | return await @asyncCall(&stack_frame, {}, func, .{}); | |
| 1405 | } | |
| 1406 | ||
| 1407 | fn bar() anyerror!void { | |
| 1408 | global_frame = @frame(); | |
| 1409 | suspend {} | |
| 1410 | global_int += 1; | |
| 1411 | } | |
| 1412 | }; | |
| 1413 | _ = async S.foo(); | |
| 1414 | resume S.global_frame; | |
| 1415 | expect(S.global_int == 10); | |
| 1416 | } | |
| 1417 | ||
| 1418 | test "properly spill optional payload capture value" { | |
| 1419 | const S = struct { | |
| 1420 | var global_frame: anyframe = undefined; | |
| 1421 | var global_int: usize = 2; | |
| 1422 | ||
| 1423 | fn foo() void { | |
| 1424 | var opt: ?usize = 1234; | |
| 1425 | if (opt) |x| { | |
| 1426 | bar(); | |
| 1427 | global_int += x; | |
| 1428 | } | |
| 1429 | } | |
| 1430 | ||
| 1431 | fn bar() void { | |
| 1432 | global_frame = @frame(); | |
| 1433 | suspend {} | |
| 1434 | global_int += 1; | |
| 1435 | } | |
| 1436 | }; | |
| 1437 | _ = async S.foo(); | |
| 1438 | resume S.global_frame; | |
| 1439 | expect(S.global_int == 1237); | |
| 1440 | } | |
| 1441 | ||
| 1442 | test "handle defer interfering with return value spill" { | |
| 1443 | const S = struct { | |
| 1444 | var global_frame1: anyframe = undefined; | |
| 1445 | var global_frame2: anyframe = undefined; | |
| 1446 | var finished = false; | |
| 1447 | var baz_happened = false; | |
| 1448 | ||
| 1449 | fn doTheTest() void { | |
| 1450 | _ = async testFoo(); | |
| 1451 | resume global_frame1; | |
| 1452 | resume global_frame2; | |
| 1453 | expect(baz_happened); | |
| 1454 | expect(finished); | |
| 1455 | } | |
| 1456 | ||
| 1457 | fn testFoo() void { | |
| 1458 | expectError(error.Bad, foo()); | |
| 1459 | finished = true; | |
| 1460 | } | |
| 1461 | ||
| 1462 | fn foo() anyerror!void { | |
| 1463 | defer baz(); | |
| 1464 | return bar() catch |err| return err; | |
| 1465 | } | |
| 1466 | ||
| 1467 | fn bar() anyerror!void { | |
| 1468 | global_frame1 = @frame(); | |
| 1469 | suspend {} | |
| 1470 | return error.Bad; | |
| 1471 | } | |
| 1472 | ||
| 1473 | fn baz() void { | |
| 1474 | global_frame2 = @frame(); | |
| 1475 | suspend {} | |
| 1476 | baz_happened = true; | |
| 1477 | } | |
| 1478 | }; | |
| 1479 | S.doTheTest(); | |
| 1480 | } | |
| 1481 | ||
| 1482 | test "take address of temporary async frame" { | |
| 1483 | const S = struct { | |
| 1484 | var global_frame: anyframe = undefined; | |
| 1485 | var finished = false; | |
| 1486 | ||
| 1487 | fn doTheTest() void { | |
| 1488 | _ = async asyncDoTheTest(); | |
| 1489 | resume global_frame; | |
| 1490 | expect(finished); | |
| 1491 | } | |
| 1492 | ||
| 1493 | fn asyncDoTheTest() void { | |
| 1494 | expect(finishIt(&async foo(10)) == 1245); | |
| 1495 | finished = true; | |
| 1496 | } | |
| 1497 | ||
| 1498 | fn foo(arg: i32) i32 { | |
| 1499 | global_frame = @frame(); | |
| 1500 | suspend {} | |
| 1501 | return arg + 1234; | |
| 1502 | } | |
| 1503 | ||
| 1504 | fn finishIt(frame: anyframe->i32) i32 { | |
| 1505 | return (await frame) + 1; | |
| 1506 | } | |
| 1507 | }; | |
| 1508 | S.doTheTest(); | |
| 1509 | } | |
| 1510 | ||
| 1511 | test "nosuspend await" { | |
| 1512 | const S = struct { | |
| 1513 | var finished = false; | |
| 1514 | ||
| 1515 | fn doTheTest() void { | |
| 1516 | var frame = async foo(false); | |
| 1517 | expect(nosuspend await frame == 42); | |
| 1518 | finished = true; | |
| 1519 | } | |
| 1520 | ||
| 1521 | fn foo(want_suspend: bool) i32 { | |
| 1522 | if (want_suspend) { | |
| 1523 | suspend {} | |
| 1524 | } | |
| 1525 | return 42; | |
| 1526 | } | |
| 1527 | }; | |
| 1528 | S.doTheTest(); | |
| 1529 | expect(S.finished); | |
| 1530 | } | |
| 1531 | ||
| 1532 | test "nosuspend on function calls" { | |
| 1533 | const S0 = struct { | |
| 1534 | b: i32 = 42, | |
| 1535 | }; | |
| 1536 | const S1 = struct { | |
| 1537 | fn c() S0 { | |
| 1538 | return S0{}; | |
| 1539 | } | |
| 1540 | fn d() !S0 { | |
| 1541 | return S0{}; | |
| 1542 | } | |
| 1543 | }; | |
| 1544 | expectEqual(@as(i32, 42), nosuspend S1.c().b); | |
| 1545 | expectEqual(@as(i32, 42), (try nosuspend S1.d()).b); | |
| 1546 | } | |
| 1547 | ||
| 1548 | test "nosuspend on async function calls" { | |
| 1549 | const S0 = struct { | |
| 1550 | b: i32 = 42, | |
| 1551 | }; | |
| 1552 | const S1 = struct { | |
| 1553 | fn c() S0 { | |
| 1554 | return S0{}; | |
| 1555 | } | |
| 1556 | fn d() !S0 { | |
| 1557 | return S0{}; | |
| 1558 | } | |
| 1559 | }; | |
| 1560 | var frame_c = nosuspend async S1.c(); | |
| 1561 | expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1562 | var frame_d = nosuspend async S1.d(); | |
| 1563 | expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1564 | } | |
| 1565 | ||
| 1566 | // test "resume nosuspend async function calls" { | |
| 1567 | // const S0 = struct { | |
| 1568 | // b: i32 = 42, | |
| 1569 | // }; | |
| 1570 | // const S1 = struct { | |
| 1571 | // fn c() S0 { | |
| 1572 | // suspend {} | |
| 1573 | // return S0{}; | |
| 1574 | // } | |
| 1575 | // fn d() !S0 { | |
| 1576 | // suspend {} | |
| 1577 | // return S0{}; | |
| 1578 | // } | |
| 1579 | // }; | |
| 1580 | // var frame_c = nosuspend async S1.c(); | |
| 1581 | // resume frame_c; | |
| 1582 | // expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1583 | // var frame_d = nosuspend async S1.d(); | |
| 1584 | // resume frame_d; | |
| 1585 | // expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1586 | // } | |
| 1587 | ||
| 1588 | test "nosuspend resume async function calls" { | |
| 1589 | const S0 = struct { | |
| 1590 | b: i32 = 42, | |
| 1591 | }; | |
| 1592 | const S1 = struct { | |
| 1593 | fn c() S0 { | |
| 1594 | suspend {} | |
| 1595 | return S0{}; | |
| 1596 | } | |
| 1597 | fn d() !S0 { | |
| 1598 | suspend {} | |
| 1599 | return S0{}; | |
| 1600 | } | |
| 1601 | }; | |
| 1602 | var frame_c = async S1.c(); | |
| 1603 | nosuspend resume frame_c; | |
| 1604 | expectEqual(@as(i32, 42), (await frame_c).b); | |
| 1605 | var frame_d = async S1.d(); | |
| 1606 | nosuspend resume frame_d; | |
| 1607 | expectEqual(@as(i32, 42), (try await frame_d).b); | |
| 1608 | } | |
| 1609 | ||
| 1610 | test "avoid forcing frame alignment resolution implicit cast to *c_void" { | |
| 1611 | const S = struct { | |
| 1612 | var x: ?*c_void = null; | |
| 1613 | ||
| 1614 | fn foo() bool { | |
| 1615 | suspend { | |
| 1616 | x = @frame(); | |
| 1617 | } | |
| 1618 | return true; | |
| 1619 | } | |
| 1620 | }; | |
| 1621 | var frame = async S.foo(); | |
| 1622 | resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x)); | |
| 1623 | expect(nosuspend await frame); | |
| 1624 | } | |
| 1625 | ||
| 1626 | test "@asyncCall with pass-by-value arguments" { | |
| 1627 | const F0: u64 = 0xbeefbeefbeefbeef; | |
| 1628 | const F1: u64 = 0xf00df00df00df00d; | |
| 1629 | const F2: u64 = 0xcafecafecafecafe; | |
| 1630 | ||
| 1631 | const S = struct { | |
| 1632 | pub const ST = struct { f0: usize, f1: usize }; | |
| 1633 | pub const AT = [5]u8; | |
| 1634 | ||
| 1635 | pub fn f(_fill0: u64, s: ST, _fill1: u64, a: AT, _fill2: u64) callconv(.Async) void { | |
| 1636 | // Check that the array and struct arguments passed by value don't | |
| 1637 | // end up overflowing the adjacent fields in the frame structure. | |
| 1638 | expectEqual(F0, _fill0); | |
| 1639 | expectEqual(F1, _fill1); | |
| 1640 | expectEqual(F2, _fill2); | |
| 1641 | } | |
| 1642 | }; | |
| 1643 | ||
| 1644 | var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined; | |
| 1645 | // The function pointer must not be comptime-known. | |
| 1646 | var t = S.f; | |
| 1647 | var frame_ptr = @asyncCall(&buffer, {}, t, .{ | |
| 1648 | F0, | |
| 1649 | .{ .f0 = 1, .f1 = 2 }, | |
| 1650 | F1, | |
| 1651 | [_]u8{ 1, 2, 3, 4, 5 }, | |
| 1652 | F2, | |
| 1653 | }); | |
| 1654 | } | |
| 1655 | ||
| 1656 | test "@asyncCall with arguments having non-standard alignment" { | |
| 1657 | const F0: u64 = 0xbeefbeef; | |
| 1658 | const F1: u64 = 0xf00df00df00df00d; | |
| 1659 | ||
| 1660 | const S = struct { | |
| 1661 | pub fn f(_fill0: u32, s: struct { x: u64 align(16) }, _fill1: u64) callconv(.Async) void { | |
| 1662 | // The compiler inserts extra alignment for s, check that the | |
| 1663 | // generated code picks the right slot for fill1. | |
| 1664 | expectEqual(F0, _fill0); | |
| 1665 | expectEqual(F1, _fill1); | |
| 1666 | } | |
| 1667 | }; | |
| 1668 | ||
| 1669 | var buffer: [1024]u8 align(@alignOf(@Frame(S.f))) = undefined; | |
| 1670 | // The function pointer must not be comptime-known. | |
| 1671 | var t = S.f; | |
| 1672 | var frame_ptr = @asyncCall(&buffer, {}, t, .{ F0, undefined, F1 }); | |
| 1673 | } |
test/stage1/behavior/atomics.zig deleted-221| ... | ... | @@ -1,221 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const builtin = @import("builtin"); | |
| 5 | ||
| 6 | test "cmpxchg" { | |
| 7 | testCmpxchg(); | |
| 8 | comptime testCmpxchg(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testCmpxchg() void { | |
| 12 | var x: i32 = 1234; | |
| 13 | if (@cmpxchgWeak(i32, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 14 | expect(x1 == 1234); | |
| 15 | } else { | |
| 16 | @panic("cmpxchg should have failed"); | |
| 17 | } | |
| 18 | ||
| 19 | while (@cmpxchgWeak(i32, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 20 | expect(x1 == 1234); | |
| 21 | } | |
| 22 | expect(x == 5678); | |
| 23 | ||
| 24 | expect(@cmpxchgStrong(i32, &x, 5678, 42, .SeqCst, .SeqCst) == null); | |
| 25 | expect(x == 42); | |
| 26 | } | |
| 27 | ||
| 28 | test "fence" { | |
| 29 | var x: i32 = 1234; | |
| 30 | @fence(.SeqCst); | |
| 31 | x = 5678; | |
| 32 | } | |
| 33 | ||
| 34 | test "atomicrmw and atomicload" { | |
| 35 | var data: u8 = 200; | |
| 36 | testAtomicRmw(&data); | |
| 37 | expect(data == 42); | |
| 38 | testAtomicLoad(&data); | |
| 39 | } | |
| 40 | ||
| 41 | fn testAtomicRmw(ptr: *u8) void { | |
| 42 | const prev_value = @atomicRmw(u8, ptr, .Xchg, 42, .SeqCst); | |
| 43 | expect(prev_value == 200); | |
| 44 | comptime { | |
| 45 | var x: i32 = 1234; | |
| 46 | const y: i32 = 12345; | |
| 47 | expect(@atomicLoad(i32, &x, .SeqCst) == 1234); | |
| 48 | expect(@atomicLoad(i32, &y, .SeqCst) == 12345); | |
| 49 | } | |
| 50 | } | |
| 51 | ||
| 52 | fn testAtomicLoad(ptr: *u8) void { | |
| 53 | const x = @atomicLoad(u8, ptr, .SeqCst); | |
| 54 | expect(x == 42); | |
| 55 | } | |
| 56 | ||
| 57 | test "cmpxchg with ptr" { | |
| 58 | var data1: i32 = 1234; | |
| 59 | var data2: i32 = 5678; | |
| 60 | var data3: i32 = 9101; | |
| 61 | var x: *i32 = &data1; | |
| 62 | if (@cmpxchgWeak(*i32, &x, &data2, &data3, .SeqCst, .SeqCst)) |x1| { | |
| 63 | expect(x1 == &data1); | |
| 64 | } else { | |
| 65 | @panic("cmpxchg should have failed"); | |
| 66 | } | |
| 67 | ||
| 68 | while (@cmpxchgWeak(*i32, &x, &data1, &data3, .SeqCst, .SeqCst)) |x1| { | |
| 69 | expect(x1 == &data1); | |
| 70 | } | |
| 71 | expect(x == &data3); | |
| 72 | ||
| 73 | expect(@cmpxchgStrong(*i32, &x, &data3, &data2, .SeqCst, .SeqCst) == null); | |
| 74 | expect(x == &data2); | |
| 75 | } | |
| 76 | ||
| 77 | // TODO this test is disabled until this issue is resolved: | |
| 78 | // https://github.com/ziglang/zig/issues/2883 | |
| 79 | // otherwise cross compiling will result in: | |
| 80 | // lld: error: undefined symbol: __sync_val_compare_and_swap_16 | |
| 81 | //test "128-bit cmpxchg" { | |
| 82 | // var x: u128 align(16) = 1234; // TODO: https://github.com/ziglang/zig/issues/2987 | |
| 83 | // if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 84 | // expect(x1 == 1234); | |
| 85 | // } else { | |
| 86 | // @panic("cmpxchg should have failed"); | |
| 87 | // } | |
| 88 | // | |
| 89 | // while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| { | |
| 90 | // expect(x1 == 1234); | |
| 91 | // } | |
| 92 | // expect(x == 5678); | |
| 93 | // | |
| 94 | // expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null); | |
| 95 | // expect(x == 42); | |
| 96 | //} | |
| 97 | ||
| 98 | test "cmpxchg with ignored result" { | |
| 99 | var x: i32 = 1234; | |
| 100 | var ptr = &x; | |
| 101 | ||
| 102 | _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic); | |
| 103 | ||
| 104 | expectEqual(@as(i32, 5678), x); | |
| 105 | } | |
| 106 | ||
| 107 | var a_global_variable = @as(u32, 1234); | |
| 108 | ||
| 109 | test "cmpxchg on a global variable" { | |
| 110 | _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic); | |
| 111 | expectEqual(@as(u32, 42), a_global_variable); | |
| 112 | } | |
| 113 | ||
| 114 | test "atomic load and rmw with enum" { | |
| 115 | const Value = enum(u8) { | |
| 116 | a, | |
| 117 | b, | |
| 118 | c, | |
| 119 | }; | |
| 120 | var x = Value.a; | |
| 121 | ||
| 122 | expect(@atomicLoad(Value, &x, .SeqCst) != .b); | |
| 123 | ||
| 124 | _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst); | |
| 125 | expect(@atomicLoad(Value, &x, .SeqCst) == .c); | |
| 126 | expect(@atomicLoad(Value, &x, .SeqCst) != .a); | |
| 127 | expect(@atomicLoad(Value, &x, .SeqCst) != .b); | |
| 128 | } | |
| 129 | ||
| 130 | test "atomic store" { | |
| 131 | var x: u32 = 0; | |
| 132 | @atomicStore(u32, &x, 1, .SeqCst); | |
| 133 | expect(@atomicLoad(u32, &x, .SeqCst) == 1); | |
| 134 | @atomicStore(u32, &x, 12345678, .SeqCst); | |
| 135 | expect(@atomicLoad(u32, &x, .SeqCst) == 12345678); | |
| 136 | } | |
| 137 | ||
| 138 | test "atomic store comptime" { | |
| 139 | comptime testAtomicStore(); | |
| 140 | testAtomicStore(); | |
| 141 | } | |
| 142 | ||
| 143 | fn testAtomicStore() void { | |
| 144 | var x: u32 = 0; | |
| 145 | @atomicStore(u32, &x, 1, .SeqCst); | |
| 146 | expect(@atomicLoad(u32, &x, .SeqCst) == 1); | |
| 147 | @atomicStore(u32, &x, 12345678, .SeqCst); | |
| 148 | expect(@atomicLoad(u32, &x, .SeqCst) == 12345678); | |
| 149 | } | |
| 150 | ||
| 151 | test "atomicrmw with floats" { | |
| 152 | if (builtin.target.cpu.arch == .aarch64 or | |
| 153 | builtin.target.cpu.arch == .arm or | |
| 154 | builtin.target.cpu.arch == .riscv64) | |
| 155 | { | |
| 156 | // https://github.com/ziglang/zig/issues/4457 | |
| 157 | return error.SkipZigTest; | |
| 158 | } | |
| 159 | testAtomicRmwFloat(); | |
| 160 | comptime testAtomicRmwFloat(); | |
| 161 | } | |
| 162 | ||
| 163 | fn testAtomicRmwFloat() void { | |
| 164 | var x: f32 = 0; | |
| 165 | expect(x == 0); | |
| 166 | _ = @atomicRmw(f32, &x, .Xchg, 1, .SeqCst); | |
| 167 | expect(x == 1); | |
| 168 | _ = @atomicRmw(f32, &x, .Add, 5, .SeqCst); | |
| 169 | expect(x == 6); | |
| 170 | _ = @atomicRmw(f32, &x, .Sub, 2, .SeqCst); | |
| 171 | expect(x == 4); | |
| 172 | } | |
| 173 | ||
| 174 | test "atomicrmw with ints" { | |
| 175 | testAtomicRmwInt(); | |
| 176 | comptime testAtomicRmwInt(); | |
| 177 | } | |
| 178 | ||
| 179 | fn testAtomicRmwInt() void { | |
| 180 | var x: u8 = 1; | |
| 181 | var res = @atomicRmw(u8, &x, .Xchg, 3, .SeqCst); | |
| 182 | expect(x == 3 and res == 1); | |
| 183 | _ = @atomicRmw(u8, &x, .Add, 3, .SeqCst); | |
| 184 | expect(x == 6); | |
| 185 | _ = @atomicRmw(u8, &x, .Sub, 1, .SeqCst); | |
| 186 | expect(x == 5); | |
| 187 | _ = @atomicRmw(u8, &x, .And, 4, .SeqCst); | |
| 188 | expect(x == 4); | |
| 189 | _ = @atomicRmw(u8, &x, .Nand, 4, .SeqCst); | |
| 190 | expect(x == 0xfb); | |
| 191 | _ = @atomicRmw(u8, &x, .Or, 6, .SeqCst); | |
| 192 | expect(x == 0xff); | |
| 193 | _ = @atomicRmw(u8, &x, .Xor, 2, .SeqCst); | |
| 194 | expect(x == 0xfd); | |
| 195 | ||
| 196 | _ = @atomicRmw(u8, &x, .Max, 1, .SeqCst); | |
| 197 | expect(x == 0xfd); | |
| 198 | _ = @atomicRmw(u8, &x, .Min, 1, .SeqCst); | |
| 199 | expect(x == 1); | |
| 200 | } | |
| 201 | ||
| 202 | test "atomics with different types" { | |
| 203 | testAtomicsWithType(bool, true, false); | |
| 204 | inline for (.{ u1, i5, u15 }) |T| { | |
| 205 | var x: T = 0; | |
| 206 | testAtomicsWithType(T, 0, 1); | |
| 207 | } | |
| 208 | testAtomicsWithType(u0, 0, 0); | |
| 209 | testAtomicsWithType(i0, 0, 0); | |
| 210 | } | |
| 211 | ||
| 212 | fn testAtomicsWithType(comptime T: type, a: T, b: T) void { | |
| 213 | var x: T = b; | |
| 214 | @atomicStore(T, &x, a, .SeqCst); | |
| 215 | expect(x == a); | |
| 216 | expect(@atomicLoad(T, &x, .SeqCst) == a); | |
| 217 | expect(@atomicRmw(T, &x, .Xchg, b, .SeqCst) == a); | |
| 218 | expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst) == null); | |
| 219 | if (@sizeOf(T) != 0) | |
| 220 | expect(@cmpxchgStrong(T, &x, b, a, .SeqCst, .SeqCst).? == a); | |
| 221 | } |
test/stage1/behavior/await_struct.zig deleted-44| ... | ... | @@ -1,44 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | const Foo = struct { | |
| 6 | x: i32, | |
| 7 | }; | |
| 8 | ||
| 9 | var await_a_promise: anyframe = undefined; | |
| 10 | var await_final_result = Foo{ .x = 0 }; | |
| 11 | ||
| 12 | test "coroutine await struct" { | |
| 13 | await_seq('a'); | |
| 14 | var p = async await_amain(); | |
| 15 | await_seq('f'); | |
| 16 | resume await_a_promise; | |
| 17 | await_seq('i'); | |
| 18 | expect(await_final_result.x == 1234); | |
| 19 | expect(std.mem.eql(u8, &await_points, "abcdefghi")); | |
| 20 | } | |
| 21 | fn await_amain() callconv(.Async) void { | |
| 22 | await_seq('b'); | |
| 23 | var p = async await_another(); | |
| 24 | await_seq('e'); | |
| 25 | await_final_result = await p; | |
| 26 | await_seq('h'); | |
| 27 | } | |
| 28 | fn await_another() callconv(.Async) Foo { | |
| 29 | await_seq('c'); | |
| 30 | suspend { | |
| 31 | await_seq('d'); | |
| 32 | await_a_promise = @frame(); | |
| 33 | } | |
| 34 | await_seq('g'); | |
| 35 | return Foo{ .x = 1234 }; | |
| 36 | } | |
| 37 | ||
| 38 | var await_points = [_]u8{0} ** "abcdefghi".len; | |
| 39 | var await_seq_index: usize = 0; | |
| 40 | ||
| 41 | fn await_seq(c: u8) void { | |
| 42 | await_points[await_seq_index] = c; | |
| 43 | await_seq_index += 1; | |
| 44 | } |
test/stage1/behavior/bit_shifting.zig deleted-104| ... | ... | @@ -1,104 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type { | |
| 5 | const key_bits = @typeInfo(Key).Int.bits; | |
| 6 | expect(Key == std.meta.Int(.unsigned, key_bits)); | |
| 7 | expect(key_bits >= mask_bit_count); | |
| 8 | const shard_key_bits = mask_bit_count; | |
| 9 | const ShardKey = std.meta.Int(.unsigned, mask_bit_count); | |
| 10 | const shift_amount = key_bits - shard_key_bits; | |
| 11 | return struct { | |
| 12 | const Self = @This(); | |
| 13 | shards: [1 << shard_key_bits]?*Node, | |
| 14 | ||
| 15 | pub fn create() Self { | |
| 16 | return Self{ .shards = [_]?*Node{null} ** (1 << shard_key_bits) }; | |
| 17 | } | |
| 18 | ||
| 19 | fn getShardKey(key: Key) ShardKey { | |
| 20 | // https://github.com/ziglang/zig/issues/1544 | |
| 21 | // this special case is needed because you can't u32 >> 32. | |
| 22 | if (ShardKey == u0) return 0; | |
| 23 | ||
| 24 | // this can be u1 >> u0 | |
| 25 | const shard_key = key >> shift_amount; | |
| 26 | ||
| 27 | // TODO: https://github.com/ziglang/zig/issues/1544 | |
| 28 | // This cast could be implicit if we teach the compiler that | |
| 29 | // u32 >> 30 -> u2 | |
| 30 | return @intCast(ShardKey, shard_key); | |
| 31 | } | |
| 32 | ||
| 33 | pub fn put(self: *Self, node: *Node) void { | |
| 34 | const shard_key = Self.getShardKey(node.key); | |
| 35 | node.next = self.shards[shard_key]; | |
| 36 | self.shards[shard_key] = node; | |
| 37 | } | |
| 38 | ||
| 39 | pub fn get(self: *Self, key: Key) ?*Node { | |
| 40 | const shard_key = Self.getShardKey(key); | |
| 41 | var maybe_node = self.shards[shard_key]; | |
| 42 | while (maybe_node) |node| : (maybe_node = node.next) { | |
| 43 | if (node.key == key) return node; | |
| 44 | } | |
| 45 | return null; | |
| 46 | } | |
| 47 | ||
| 48 | pub const Node = struct { | |
| 49 | key: Key, | |
| 50 | value: V, | |
| 51 | next: ?*Node, | |
| 52 | ||
| 53 | pub fn init(self: *Node, key: Key, value: V) void { | |
| 54 | self.key = key; | |
| 55 | self.value = value; | |
| 56 | self.next = null; | |
| 57 | } | |
| 58 | }; | |
| 59 | }; | |
| 60 | } | |
| 61 | ||
| 62 | test "sharded table" { | |
| 63 | // realistic 16-way sharding | |
| 64 | testShardedTable(u32, 4, 8); | |
| 65 | ||
| 66 | testShardedTable(u5, 0, 32); // ShardKey == u0 | |
| 67 | testShardedTable(u5, 2, 32); | |
| 68 | testShardedTable(u5, 5, 32); | |
| 69 | ||
| 70 | testShardedTable(u1, 0, 2); | |
| 71 | testShardedTable(u1, 1, 2); // this does u1 >> u0 | |
| 72 | ||
| 73 | testShardedTable(u0, 0, 1); | |
| 74 | } | |
| 75 | fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime node_count: comptime_int) void { | |
| 76 | const Table = ShardedTable(Key, mask_bit_count, void); | |
| 77 | ||
| 78 | var table = Table.create(); | |
| 79 | var node_buffer: [node_count]Table.Node = undefined; | |
| 80 | for (node_buffer) |*node, i| { | |
| 81 | const key = @intCast(Key, i); | |
| 82 | expect(table.get(key) == null); | |
| 83 | node.init(key, {}); | |
| 84 | table.put(node); | |
| 85 | } | |
| 86 | ||
| 87 | for (node_buffer) |*node, i| { | |
| 88 | expect(table.get(@intCast(Key, i)) == node); | |
| 89 | } | |
| 90 | } | |
| 91 | ||
| 92 | // #2225 | |
| 93 | test "comptime shr of BigInt" { | |
| 94 | comptime { | |
| 95 | var n0 = 0xdeadbeef0000000000000000; | |
| 96 | std.debug.assert(n0 >> 64 == 0xdeadbeef); | |
| 97 | var n1 = 17908056155735594659; | |
| 98 | std.debug.assert(n1 >> 64 == 0); | |
| 99 | } | |
| 100 | } | |
| 101 | ||
| 102 | test "comptime shift safety check" { | |
| 103 | const x = @as(usize, 42) << @sizeOf(usize); | |
| 104 | } |
test/stage1/behavior/bitcast.zig deleted-197| ... | ... | @@ -1,197 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 7 | ||
| 8 | test "@bitCast i32 -> u32" { | |
| 9 | testBitCast_i32_u32(); | |
| 10 | comptime testBitCast_i32_u32(); | |
| 11 | } | |
| 12 | ||
| 13 | fn testBitCast_i32_u32() void { | |
| 14 | expect(conv(-1) == maxInt(u32)); | |
| 15 | expect(conv2(maxInt(u32)) == -1); | |
| 16 | } | |
| 17 | ||
| 18 | fn conv(x: i32) u32 { | |
| 19 | return @bitCast(u32, x); | |
| 20 | } | |
| 21 | fn conv2(x: u32) i32 { | |
| 22 | return @bitCast(i32, x); | |
| 23 | } | |
| 24 | ||
| 25 | test "@bitCast extern enum to its integer type" { | |
| 26 | const SOCK = extern enum { | |
| 27 | A, | |
| 28 | B, | |
| 29 | ||
| 30 | fn testBitCastExternEnum() void { | |
| 31 | var SOCK_DGRAM = @This().B; | |
| 32 | var sock_dgram = @bitCast(c_int, SOCK_DGRAM); | |
| 33 | expect(sock_dgram == 1); | |
| 34 | } | |
| 35 | }; | |
| 36 | ||
| 37 | SOCK.testBitCastExternEnum(); | |
| 38 | comptime SOCK.testBitCastExternEnum(); | |
| 39 | } | |
| 40 | ||
| 41 | test "@bitCast packed structs at runtime and comptime" { | |
| 42 | const Full = packed struct { | |
| 43 | number: u16, | |
| 44 | }; | |
| 45 | const Divided = packed struct { | |
| 46 | half1: u8, | |
| 47 | quarter3: u4, | |
| 48 | quarter4: u4, | |
| 49 | }; | |
| 50 | const S = struct { | |
| 51 | fn doTheTest() void { | |
| 52 | var full = Full{ .number = 0x1234 }; | |
| 53 | var two_halves = @bitCast(Divided, full); | |
| 54 | switch (native_endian) { | |
| 55 | .Big => { | |
| 56 | expect(two_halves.half1 == 0x12); | |
| 57 | expect(two_halves.quarter3 == 0x3); | |
| 58 | expect(two_halves.quarter4 == 0x4); | |
| 59 | }, | |
| 60 | .Little => { | |
| 61 | expect(two_halves.half1 == 0x34); | |
| 62 | expect(two_halves.quarter3 == 0x2); | |
| 63 | expect(two_halves.quarter4 == 0x1); | |
| 64 | }, | |
| 65 | } | |
| 66 | } | |
| 67 | }; | |
| 68 | S.doTheTest(); | |
| 69 | comptime S.doTheTest(); | |
| 70 | } | |
| 71 | ||
| 72 | test "@bitCast extern structs at runtime and comptime" { | |
| 73 | const Full = extern struct { | |
| 74 | number: u16, | |
| 75 | }; | |
| 76 | const TwoHalves = extern struct { | |
| 77 | half1: u8, | |
| 78 | half2: u8, | |
| 79 | }; | |
| 80 | const S = struct { | |
| 81 | fn doTheTest() void { | |
| 82 | var full = Full{ .number = 0x1234 }; | |
| 83 | var two_halves = @bitCast(TwoHalves, full); | |
| 84 | switch (native_endian) { | |
| 85 | .Big => { | |
| 86 | expect(two_halves.half1 == 0x12); | |
| 87 | expect(two_halves.half2 == 0x34); | |
| 88 | }, | |
| 89 | .Little => { | |
| 90 | expect(two_halves.half1 == 0x34); | |
| 91 | expect(two_halves.half2 == 0x12); | |
| 92 | }, | |
| 93 | } | |
| 94 | } | |
| 95 | }; | |
| 96 | S.doTheTest(); | |
| 97 | comptime S.doTheTest(); | |
| 98 | } | |
| 99 | ||
| 100 | test "bitcast packed struct to integer and back" { | |
| 101 | const LevelUpMove = packed struct { | |
| 102 | move_id: u9, | |
| 103 | level: u7, | |
| 104 | }; | |
| 105 | const S = struct { | |
| 106 | fn doTheTest() void { | |
| 107 | var move = LevelUpMove{ .move_id = 1, .level = 2 }; | |
| 108 | var v = @bitCast(u16, move); | |
| 109 | var back_to_a_move = @bitCast(LevelUpMove, v); | |
| 110 | expect(back_to_a_move.move_id == 1); | |
| 111 | expect(back_to_a_move.level == 2); | |
| 112 | } | |
| 113 | }; | |
| 114 | S.doTheTest(); | |
| 115 | comptime S.doTheTest(); | |
| 116 | } | |
| 117 | ||
| 118 | test "implicit cast to error union by returning" { | |
| 119 | const S = struct { | |
| 120 | fn entry() void { | |
| 121 | expect((func(-1) catch unreachable) == maxInt(u64)); | |
| 122 | } | |
| 123 | pub fn func(sz: i64) anyerror!u64 { | |
| 124 | return @bitCast(u64, sz); | |
| 125 | } | |
| 126 | }; | |
| 127 | S.entry(); | |
| 128 | comptime S.entry(); | |
| 129 | } | |
| 130 | ||
| 131 | // issue #3010: compiler segfault | |
| 132 | test "bitcast literal [4]u8 param to u32" { | |
| 133 | const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 }); | |
| 134 | expect(ip == maxInt(u32)); | |
| 135 | } | |
| 136 | ||
| 137 | test "bitcast packed struct literal to byte" { | |
| 138 | const Foo = packed struct { | |
| 139 | value: u8, | |
| 140 | }; | |
| 141 | const casted = @bitCast(u8, Foo{ .value = 0xF }); | |
| 142 | expect(casted == 0xf); | |
| 143 | } | |
| 144 | ||
| 145 | test "comptime bitcast used in expression has the correct type" { | |
| 146 | const Foo = packed struct { | |
| 147 | value: u8, | |
| 148 | }; | |
| 149 | expect(@bitCast(u8, Foo{ .value = 0xF }) == 0xf); | |
| 150 | } | |
| 151 | ||
| 152 | test "bitcast result to _" { | |
| 153 | _ = @bitCast(u8, @as(i8, 1)); | |
| 154 | } | |
| 155 | ||
| 156 | test "nested bitcast" { | |
| 157 | const S = struct { | |
| 158 | fn moo(x: isize) void { | |
| 159 | @import("std").testing.expectEqual(@intCast(isize, 42), x); | |
| 160 | } | |
| 161 | ||
| 162 | fn foo(x: isize) void { | |
| 163 | @This().moo( | |
| 164 | @bitCast(isize, if (x != 0) @bitCast(usize, x) else @bitCast(usize, x)), | |
| 165 | ); | |
| 166 | } | |
| 167 | }; | |
| 168 | ||
| 169 | S.foo(42); | |
| 170 | comptime S.foo(42); | |
| 171 | } | |
| 172 | ||
| 173 | test "bitcast passed as tuple element" { | |
| 174 | const S = struct { | |
| 175 | fn foo(args: anytype) void { | |
| 176 | comptime expect(@TypeOf(args[0]) == f32); | |
| 177 | expect(args[0] == 12.34); | |
| 178 | } | |
| 179 | }; | |
| 180 | S.foo(.{@bitCast(f32, @as(u32, 0x414570A4))}); | |
| 181 | } | |
| 182 | ||
| 183 | test "triple level result location with bitcast sandwich passed as tuple element" { | |
| 184 | const S = struct { | |
| 185 | fn foo(args: anytype) void { | |
| 186 | comptime expect(@TypeOf(args[0]) == f64); | |
| 187 | expect(args[0] > 12.33 and args[0] < 12.35); | |
| 188 | } | |
| 189 | }; | |
| 190 | S.foo(.{@as(f64, @bitCast(f32, @as(u32, 0x414570A4)))}); | |
| 191 | } | |
| 192 | ||
| 193 | test "bitcast generates a temporary value" { | |
| 194 | var y = @as(u16, 0x55AA); | |
| 195 | const x = @bitCast(u16, @bitCast([2]u8, y)); | |
| 196 | expectEqual(y, x); | |
| 197 | } |
test/stage1/behavior/bitreverse.zig deleted-69| ... | ... | @@ -1,69 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const minInt = std.math.minInt; | |
| 4 | ||
| 5 | test "@bitReverse" { | |
| 6 | comptime testBitReverse(); | |
| 7 | testBitReverse(); | |
| 8 | } | |
| 9 | ||
| 10 | fn testBitReverse() void { | |
| 11 | // using comptime_ints, unsigned | |
| 12 | expect(@bitReverse(u0, 0) == 0); | |
| 13 | expect(@bitReverse(u5, 0x12) == 0x9); | |
| 14 | expect(@bitReverse(u8, 0x12) == 0x48); | |
| 15 | expect(@bitReverse(u16, 0x1234) == 0x2c48); | |
| 16 | expect(@bitReverse(u24, 0x123456) == 0x6a2c48); | |
| 17 | expect(@bitReverse(u32, 0x12345678) == 0x1e6a2c48); | |
| 18 | expect(@bitReverse(u40, 0x123456789a) == 0x591e6a2c48); | |
| 19 | expect(@bitReverse(u48, 0x123456789abc) == 0x3d591e6a2c48); | |
| 20 | expect(@bitReverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48); | |
| 21 | expect(@bitReverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48); | |
| 22 | expect(@bitReverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 23 | ||
| 24 | // using runtime uints, unsigned | |
| 25 | var num0: u0 = 0; | |
| 26 | expect(@bitReverse(u0, num0) == 0); | |
| 27 | var num5: u5 = 0x12; | |
| 28 | expect(@bitReverse(u5, num5) == 0x9); | |
| 29 | var num8: u8 = 0x12; | |
| 30 | expect(@bitReverse(u8, num8) == 0x48); | |
| 31 | var num16: u16 = 0x1234; | |
| 32 | expect(@bitReverse(u16, num16) == 0x2c48); | |
| 33 | var num24: u24 = 0x123456; | |
| 34 | expect(@bitReverse(u24, num24) == 0x6a2c48); | |
| 35 | var num32: u32 = 0x12345678; | |
| 36 | expect(@bitReverse(u32, num32) == 0x1e6a2c48); | |
| 37 | var num40: u40 = 0x123456789a; | |
| 38 | expect(@bitReverse(u40, num40) == 0x591e6a2c48); | |
| 39 | var num48: u48 = 0x123456789abc; | |
| 40 | expect(@bitReverse(u48, num48) == 0x3d591e6a2c48); | |
| 41 | var num56: u56 = 0x123456789abcde; | |
| 42 | expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48); | |
| 43 | var num64: u64 = 0x123456789abcdef1; | |
| 44 | expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48); | |
| 45 | var num128: u128 = 0x123456789abcdef11121314151617181; | |
| 46 | expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 47 | ||
| 48 | // using comptime_ints, signed, positive | |
| 49 | expect(@bitReverse(u8, @as(u8, 0)) == 0); | |
| 50 | expect(@bitReverse(i8, @bitCast(i8, @as(u8, 0x92))) == @bitCast(i8, @as(u8, 0x49))); | |
| 51 | expect(@bitReverse(i16, @bitCast(i16, @as(u16, 0x1234))) == @bitCast(i16, @as(u16, 0x2c48))); | |
| 52 | expect(@bitReverse(i24, @bitCast(i24, @as(u24, 0x123456))) == @bitCast(i24, @as(u24, 0x6a2c48))); | |
| 53 | expect(@bitReverse(i32, @bitCast(i32, @as(u32, 0x12345678))) == @bitCast(i32, @as(u32, 0x1e6a2c48))); | |
| 54 | expect(@bitReverse(i40, @bitCast(i40, @as(u40, 0x123456789a))) == @bitCast(i40, @as(u40, 0x591e6a2c48))); | |
| 55 | expect(@bitReverse(i48, @bitCast(i48, @as(u48, 0x123456789abc))) == @bitCast(i48, @as(u48, 0x3d591e6a2c48))); | |
| 56 | expect(@bitReverse(i56, @bitCast(i56, @as(u56, 0x123456789abcde))) == @bitCast(i56, @as(u56, 0x7b3d591e6a2c48))); | |
| 57 | expect(@bitReverse(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1))) == @bitCast(i64, @as(u64, 0x8f7b3d591e6a2c48))); | |
| 58 | expect(@bitReverse(i128, @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181))) == @bitCast(i128, @as(u128, 0x818e868a828c84888f7b3d591e6a2c48))); | |
| 59 | ||
| 60 | // using signed, negative. Compare to runtime ints returned from llvm. | |
| 61 | var neg8: i8 = -18; | |
| 62 | expect(@bitReverse(i8, @as(i8, -18)) == @bitReverse(i8, neg8)); | |
| 63 | var neg16: i16 = -32694; | |
| 64 | expect(@bitReverse(i16, @as(i16, -32694)) == @bitReverse(i16, neg16)); | |
| 65 | var neg24: i24 = -6773785; | |
| 66 | expect(@bitReverse(i24, @as(i24, -6773785)) == @bitReverse(i24, neg24)); | |
| 67 | var neg32: i32 = -16773785; | |
| 68 | expect(@bitReverse(i32, @as(i32, -16773785)) == @bitReverse(i32, neg32)); | |
| 69 | } |
test/stage1/behavior/bool.zig deleted-35| ... | ... | @@ -1,35 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "bool literals" { | |
| 4 | expect(true); | |
| 5 | expect(!false); | |
| 6 | } | |
| 7 | ||
| 8 | test "cast bool to int" { | |
| 9 | const t = true; | |
| 10 | const f = false; | |
| 11 | expect(@boolToInt(t) == @as(u32, 1)); | |
| 12 | expect(@boolToInt(f) == @as(u32, 0)); | |
| 13 | nonConstCastBoolToInt(t, f); | |
| 14 | } | |
| 15 | ||
| 16 | fn nonConstCastBoolToInt(t: bool, f: bool) void { | |
| 17 | expect(@boolToInt(t) == @as(u32, 1)); | |
| 18 | expect(@boolToInt(f) == @as(u32, 0)); | |
| 19 | } | |
| 20 | ||
| 21 | test "bool cmp" { | |
| 22 | expect(testBoolCmp(true, false) == false); | |
| 23 | } | |
| 24 | fn testBoolCmp(a: bool, b: bool) bool { | |
| 25 | return a == b; | |
| 26 | } | |
| 27 | ||
| 28 | const global_f = false; | |
| 29 | const global_t = true; | |
| 30 | const not_global_f = !global_f; | |
| 31 | const not_global_t = !global_t; | |
| 32 | test "compile time bool not" { | |
| 33 | expect(not_global_f); | |
| 34 | expect(!not_global_t); | |
| 35 | } |
test/stage1/behavior/bugs/1025.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const A = struct { | |
| 2 | B: type, | |
| 3 | }; | |
| 4 | ||
| 5 | fn getA() A { | |
| 6 | return A{ .B = u8 }; | |
| 7 | } | |
| 8 | ||
| 9 | test "bug 1025" { | |
| 10 | const a = getA(); | |
| 11 | @import("std").testing.expect(a.B == u8); | |
| 12 | } |
test/stage1/behavior/bugs/1076.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "comptime code should not modify constant data" { | |
| 6 | testCastPtrOfArrayToSliceAndPtr(); | |
| 7 | comptime testCastPtrOfArrayToSliceAndPtr(); | |
| 8 | } | |
| 9 | ||
| 10 | fn testCastPtrOfArrayToSliceAndPtr() void { | |
| 11 | { | |
| 12 | var array = "aoeu".*; | |
| 13 | const x: [*]u8 = &array; | |
| 14 | x[0] += 1; | |
| 15 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 16 | } | |
| 17 | { | |
| 18 | var array: [4]u8 = "aoeu".*; | |
| 19 | const x: [*]u8 = &array; | |
| 20 | x[0] += 1; | |
| 21 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 22 | } | |
| 23 | } |
test/stage1/behavior/bugs/1111.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const Foo = extern enum { | |
| 2 | Bar = -1, | |
| 3 | }; | |
| 4 | ||
| 5 | test "issue 1111 fixed" { | |
| 6 | const v = Foo.Bar; | |
| 7 | ||
| 8 | switch (v) { | |
| 9 | Foo.Bar => return, | |
| 10 | } | |
| 11 | } |
test/stage1/behavior/bugs/1120.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const A = packed struct { | |
| 5 | a: u2, | |
| 6 | b: u6, | |
| 7 | }; | |
| 8 | const B = packed struct { | |
| 9 | q: u8, | |
| 10 | a: u2, | |
| 11 | b: u6, | |
| 12 | }; | |
| 13 | test "bug 1120" { | |
| 14 | var a = A{ .a = 2, .b = 2 }; | |
| 15 | var b = B{ .q = 22, .a = 3, .b = 2 }; | |
| 16 | var t: usize = 0; | |
| 17 | const ptr = switch (t) { | |
| 18 | 0 => &a.a, | |
| 19 | 1 => &b.a, | |
| 20 | else => unreachable, | |
| 21 | }; | |
| 22 | expect(ptr.* == 2); | |
| 23 | } |
test/stage1/behavior/bugs/1277.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const S = struct { | |
| 4 | f: ?fn () i32, | |
| 5 | }; | |
| 6 | ||
| 7 | const s = S{ .f = f }; | |
| 8 | ||
| 9 | fn f() i32 { | |
| 10 | return 1234; | |
| 11 | } | |
| 12 | ||
| 13 | test "don't emit an LLVM global for a const function when it's in an optional in a struct" { | |
| 14 | std.testing.expect(s.f.?() == 1234); | |
| 15 | } |
test/stage1/behavior/bugs/1310.zig deleted-24| ... | ... | @@ -1,24 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | pub const VM = ?[*]const struct_InvocationTable_; | |
| 5 | pub const struct_InvocationTable_ = extern struct { | |
| 6 | GetVM: ?fn (?[*]VM) callconv(.C) c_int, | |
| 7 | }; | |
| 8 | ||
| 9 | pub const struct_VM_ = extern struct { | |
| 10 | functions: ?[*]const struct_InvocationTable_, | |
| 11 | }; | |
| 12 | ||
| 13 | //excised output from stdlib.h etc | |
| 14 | ||
| 15 | pub const InvocationTable_ = struct_InvocationTable_; | |
| 16 | pub const VM_ = struct_VM_; | |
| 17 | ||
| 18 | fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 { | |
| 19 | return 11; | |
| 20 | } | |
| 21 | ||
| 22 | test "fixed" { | |
| 23 | expect(agent_callback(undefined, undefined) == 11); | |
| 24 | } |
test/stage1/behavior/bugs/1322.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const B = union(enum) { | |
| 4 | c: C, | |
| 5 | None, | |
| 6 | }; | |
| 7 | ||
| 8 | const A = struct { | |
| 9 | b: B, | |
| 10 | }; | |
| 11 | ||
| 12 | const C = struct {}; | |
| 13 | ||
| 14 | test "tagged union with all void fields but a meaningful tag" { | |
| 15 | var a: A = A{ .b = B{ .c = C{} } }; | |
| 16 | std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).c); | |
| 17 | a = A{ .b = B.None }; | |
| 18 | std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).None); | |
| 19 | } |
test/stage1/behavior/bugs/1381.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const B = union(enum) { | |
| 4 | D: u8, | |
| 5 | E: u16, | |
| 6 | }; | |
| 7 | ||
| 8 | const A = union(enum) { | |
| 9 | B: B, | |
| 10 | C: u8, | |
| 11 | }; | |
| 12 | ||
| 13 | test "union that needs padding bytes inside an array" { | |
| 14 | var as = [_]A{ | |
| 15 | A{ .B = B{ .D = 1 } }, | |
| 16 | A{ .B = B{ .D = 1 } }, | |
| 17 | }; | |
| 18 | ||
| 19 | const a = as[0].B; | |
| 20 | std.testing.expect(a.D == 1); | |
| 21 | } |
test/stage1/behavior/bugs/1421.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const S = struct { | |
| 5 | fn method() std.builtin.TypeInfo { | |
| 6 | return @typeInfo(S); | |
| 7 | } | |
| 8 | }; | |
| 9 | ||
| 10 | test "functions with return type required to be comptime are generic" { | |
| 11 | const ti = S.method(); | |
| 12 | expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct); | |
| 13 | } |
test/stage1/behavior/bugs/1442.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const Union = union(enum) { | |
| 4 | Text: []const u8, | |
| 5 | Color: u32, | |
| 6 | }; | |
| 7 | ||
| 8 | test "const error union field alignment" { | |
| 9 | var union_or_err: anyerror!Union = Union{ .Color = 1234 }; | |
| 10 | std.testing.expect((union_or_err catch unreachable).Color == 1234); | |
| 11 | } |
test/stage1/behavior/bugs/1467.zig deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | pub const E = enum(u32) { A, B, C }; | |
| 2 | pub const S = extern struct { | |
| 3 | e: E, | |
| 4 | }; | |
| 5 | test "bug 1467" { | |
| 6 | const s: S = undefined; | |
| 7 | } |
test/stage1/behavior/bugs/1486.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const ptr = &global; | |
| 4 | var global: u64 = 123; | |
| 5 | ||
| 6 | test "constant pointer to global variable causes runtime load" { | |
| 7 | global = 1234; | |
| 8 | expect(&global == ptr); | |
| 9 | expect(ptr.* == 1234); | |
| 10 | } |
test/stage1/behavior/bugs/1500.zig deleted-10| ... | ... | @@ -1,10 +0,0 @@ |
| 1 | const A = struct { | |
| 2 | b: B, | |
| 3 | }; | |
| 4 | ||
| 5 | const B = fn (A) void; | |
| 6 | ||
| 7 | test "allow these dependencies" { | |
| 8 | var a: A = undefined; | |
| 9 | var b: B = undefined; | |
| 10 | } |
test/stage1/behavior/bugs/1607.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | ||
| 4 | const a = [_]u8{ 1, 2, 3 }; | |
| 5 | ||
| 6 | fn checkAddress(s: []const u8) void { | |
| 7 | for (s) |*i, j| { | |
| 8 | testing.expect(i == &a[j]); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | test "slices pointing at the same address as global array." { | |
| 13 | checkAddress(&a); | |
| 14 | comptime checkAddress(&a); | |
| 15 | } |
test/stage1/behavior/bugs/1735.zig deleted-46| ... | ... | @@ -1,46 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const mystruct = struct { | |
| 4 | pending: ?listofstructs, | |
| 5 | }; | |
| 6 | pub fn TailQueue(comptime T: type) type { | |
| 7 | return struct { | |
| 8 | const Self = @This(); | |
| 9 | ||
| 10 | pub const Node = struct { | |
| 11 | prev: ?*Node, | |
| 12 | next: ?*Node, | |
| 13 | data: T, | |
| 14 | }; | |
| 15 | ||
| 16 | first: ?*Node, | |
| 17 | last: ?*Node, | |
| 18 | len: usize, | |
| 19 | ||
| 20 | pub fn init() Self { | |
| 21 | return Self{ | |
| 22 | .first = null, | |
| 23 | .last = null, | |
| 24 | .len = 0, | |
| 25 | }; | |
| 26 | } | |
| 27 | }; | |
| 28 | } | |
| 29 | const listofstructs = TailQueue(mystruct); | |
| 30 | ||
| 31 | const a = struct { | |
| 32 | const Self = @This(); | |
| 33 | ||
| 34 | foo: listofstructs, | |
| 35 | ||
| 36 | pub fn init() Self { | |
| 37 | return Self{ | |
| 38 | .foo = listofstructs.init(), | |
| 39 | }; | |
| 40 | } | |
| 41 | }; | |
| 42 | ||
| 43 | test "intialization" { | |
| 44 | var t = a.init(); | |
| 45 | std.testing.expect(t.foo.len == 0); | |
| 46 | } |
test/stage1/behavior/bugs/1741.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "fixed" { | |
| 4 | const x: f32 align(128) = 12.34; | |
| 5 | std.testing.expect(@ptrToInt(&x) % 128 == 0); | |
| 6 | } |
test/stage1/behavior/bugs/1851.zig deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "allocation and looping over 3-byte integer" { | |
| 5 | expect(@sizeOf(u24) == 4); | |
| 6 | expect(@sizeOf([1]u24) == 4); | |
| 7 | expect(@alignOf(u24) == 4); | |
| 8 | expect(@alignOf([1]u24) == 4); | |
| 9 | ||
| 10 | var x = try std.testing.allocator.alloc(u24, 2); | |
| 11 | defer std.testing.allocator.free(x); | |
| 12 | expect(x.len == 2); | |
| 13 | x[0] = 0xFFFFFF; | |
| 14 | x[1] = 0xFFFFFF; | |
| 15 | ||
| 16 | const bytes = std.mem.sliceAsBytes(x); | |
| 17 | expect(@TypeOf(bytes) == []align(4) u8); | |
| 18 | expect(bytes.len == 8); | |
| 19 | ||
| 20 | for (bytes) |*b| { | |
| 21 | b.* = 0x00; | |
| 22 | } | |
| 23 | ||
| 24 | expect(x[0] == 0x00); | |
| 25 | expect(x[1] == 0x00); | |
| 26 | } |
test/stage1/behavior/bugs/1914.zig deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const A = struct { | |
| 4 | b_list_pointer: *const []B, | |
| 5 | }; | |
| 6 | const B = struct { | |
| 7 | a_pointer: *const A, | |
| 8 | }; | |
| 9 | ||
| 10 | const b_list: []B = &[_]B{}; | |
| 11 | const a = A{ .b_list_pointer = &b_list }; | |
| 12 | ||
| 13 | test "segfault bug" { | |
| 14 | const assert = std.debug.assert; | |
| 15 | const obj = B{ .a_pointer = &a }; | |
| 16 | assert(obj.a_pointer == &a); // this makes zig crash | |
| 17 | } | |
| 18 | ||
| 19 | const A2 = struct { | |
| 20 | pointer: *B, | |
| 21 | }; | |
| 22 | ||
| 23 | pub const B2 = struct { | |
| 24 | pointer_array: []*A2, | |
| 25 | }; | |
| 26 | ||
| 27 | var b_value = B2{ .pointer_array = &[_]*A2{} }; | |
| 28 | ||
| 29 | test "basic stuff" { | |
| 30 | std.debug.assert(&b_value == &b_value); | |
| 31 | } |
test/stage1/behavior/bugs/2006.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const S = struct { | |
| 5 | p: *S, | |
| 6 | }; | |
| 7 | test "bug 2006" { | |
| 8 | var a: S = undefined; | |
| 9 | a = S{ .p = undefined }; | |
| 10 | expect(@sizeOf(S) != 0); | |
| 11 | expect(@sizeOf(*void) == 0); | |
| 12 | } |
test/stage1/behavior/bugs/2114.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const math = std.math; | |
| 4 | ||
| 5 | fn ctz(x: anytype) usize { | |
| 6 | return @ctz(@TypeOf(x), x); | |
| 7 | } | |
| 8 | ||
| 9 | test "fixed" { | |
| 10 | testClz(); | |
| 11 | comptime testClz(); | |
| 12 | } | |
| 13 | ||
| 14 | fn testClz() void { | |
| 15 | expect(ctz(@as(u128, 0x40000000000000000000000000000000)) == 126); | |
| 16 | expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000)); | |
| 17 | expect(ctz(@as(u128, 0x80000000000000000000000000000000)) == 127); | |
| 18 | expect(ctz(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127); | |
| 19 | } |
test/stage1/behavior/bugs/2346.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | test "fixed" { | |
| 2 | const a: *void = undefined; | |
| 3 | const b: *[1]void = a; | |
| 4 | const c: *[0]u8 = undefined; | |
| 5 | const d: []u8 = c; | |
| 6 | } |
test/stage1/behavior/bugs/2578.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const Foo = struct { | |
| 2 | y: u8, | |
| 3 | }; | |
| 4 | ||
| 5 | var foo: Foo = undefined; | |
| 6 | const t = &foo; | |
| 7 | ||
| 8 | fn bar(pointer: ?*c_void) void {} | |
| 9 | ||
| 10 | test "fixed" { | |
| 11 | bar(t); | |
| 12 | } |
test/stage1/behavior/bugs/2692.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | fn foo(a: []u8) void {} | |
| 2 | ||
| 3 | test "address of 0 length array" { | |
| 4 | var pt: [0]u8 = undefined; | |
| 5 | foo(&pt); | |
| 6 | } |
test/stage1/behavior/bugs/2889.zig deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const source = "A-"; | |
| 4 | ||
| 5 | fn parseNote() ?i32 { | |
| 6 | const letter = source[0]; | |
| 7 | const modifier = source[1]; | |
| 8 | ||
| 9 | const semitone = blk: { | |
| 10 | if (letter == 'C' and modifier == '-') break :blk @as(i32, 0); | |
| 11 | if (letter == 'C' and modifier == '#') break :blk @as(i32, 1); | |
| 12 | if (letter == 'D' and modifier == '-') break :blk @as(i32, 2); | |
| 13 | if (letter == 'D' and modifier == '#') break :blk @as(i32, 3); | |
| 14 | if (letter == 'E' and modifier == '-') break :blk @as(i32, 4); | |
| 15 | if (letter == 'F' and modifier == '-') break :blk @as(i32, 5); | |
| 16 | if (letter == 'F' and modifier == '#') break :blk @as(i32, 6); | |
| 17 | if (letter == 'G' and modifier == '-') break :blk @as(i32, 7); | |
| 18 | if (letter == 'G' and modifier == '#') break :blk @as(i32, 8); | |
| 19 | if (letter == 'A' and modifier == '-') break :blk @as(i32, 9); | |
| 20 | if (letter == 'A' and modifier == '#') break :blk @as(i32, 10); | |
| 21 | if (letter == 'B' and modifier == '-') break :blk @as(i32, 11); | |
| 22 | return null; | |
| 23 | }; | |
| 24 | ||
| 25 | return semitone; | |
| 26 | } | |
| 27 | ||
| 28 | test "fixed" { | |
| 29 | const result = parseNote(); | |
| 30 | std.testing.expect(result.? == 9); | |
| 31 | } |
test/stage1/behavior/bugs/3007.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | free: bool, | |
| 5 | ||
| 6 | pub const FooError = error{NotFree}; | |
| 7 | }; | |
| 8 | ||
| 9 | var foo = Foo{ .free = true }; | |
| 10 | var default_foo: ?*Foo = null; | |
| 11 | ||
| 12 | fn get_foo() Foo.FooError!*Foo { | |
| 13 | if (foo.free) { | |
| 14 | foo.free = false; | |
| 15 | return &foo; | |
| 16 | } | |
| 17 | return error.NotFree; | |
| 18 | } | |
| 19 | ||
| 20 | test "fixed" { | |
| 21 | default_foo = get_foo() catch null; // This Line | |
| 22 | std.testing.expect(!default_foo.?.free); | |
| 23 | } |
test/stage1/behavior/bugs/3046.zig deleted-19| ... | ... | @@ -1,19 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const SomeStruct = struct { | |
| 5 | field: i32, | |
| 6 | }; | |
| 7 | ||
| 8 | fn couldFail() anyerror!i32 { | |
| 9 | return 1; | |
| 10 | } | |
| 11 | ||
| 12 | var some_struct: SomeStruct = undefined; | |
| 13 | ||
| 14 | test "fixed" { | |
| 15 | some_struct = SomeStruct{ | |
| 16 | .field = couldFail() catch |_| @as(i32, 0), | |
| 17 | }; | |
| 18 | expect(some_struct.field == 1); | |
| 19 | } |
test/stage1/behavior/bugs/3112.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const State = struct { | |
| 5 | const Self = @This(); | |
| 6 | enter: fn (previous: ?Self) void, | |
| 7 | }; | |
| 8 | ||
| 9 | fn prev(p: ?State) void { | |
| 10 | expect(p == null); | |
| 11 | } | |
| 12 | ||
| 13 | test "zig test crash" { | |
| 14 | var global: State = undefined; | |
| 15 | global.enter = prev; | |
| 16 | global.enter(null); | |
| 17 | } |
test/stage1/behavior/bugs/3367.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const Foo = struct { | |
| 2 | usingnamespace Mixin; | |
| 3 | }; | |
| 4 | ||
| 5 | const Mixin = struct { | |
| 6 | pub fn two(self: Foo) void {} | |
| 7 | }; | |
| 8 | ||
| 9 | test "container member access usingnamespace decls" { | |
| 10 | var foo = Foo{}; | |
| 11 | foo.two(); | |
| 12 | } |
test/stage1/behavior/bugs/3384.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "resolve array slice using builtin" { | |
| 5 | expect(@hasDecl(@This(), "std") == true); | |
| 6 | expect(@hasDecl(@This(), "std"[0..0]) == false); | |
| 7 | expect(@hasDecl(@This(), "std"[0..1]) == false); | |
| 8 | expect(@hasDecl(@This(), "std"[0..2]) == false); | |
| 9 | expect(@hasDecl(@This(), "std"[0..3]) == true); | |
| 10 | expect(@hasDecl(@This(), "std"[0..]) == true); | |
| 11 | } |
test/stage1/behavior/bugs/3468.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | // zig fmt: off | |
| 2 | test "pointer deref next to assignment" { | |
| 3 | var a:i32=2; | |
| 4 | var b=&a; | |
| 5 | b.*=3; | |
| 6 | } |
test/stage1/behavior/bugs/3586.zig deleted-11| ... | ... | @@ -1,11 +0,0 @@ |
| 1 | const NoteParams = struct {}; | |
| 2 | ||
| 3 | const Container = struct { | |
| 4 | params: ?NoteParams, | |
| 5 | }; | |
| 6 | ||
| 7 | test "fixed" { | |
| 8 | var ctr = Container{ | |
| 9 | .params = NoteParams{}, | |
| 10 | }; | |
| 11 | } |
test/stage1/behavior/bugs/3742.zig deleted-38| ... | ... | @@ -1,38 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | pub const GET = struct { | |
| 4 | key: []const u8, | |
| 5 | ||
| 6 | pub fn init(key: []const u8) GET { | |
| 7 | return .{ .key = key }; | |
| 8 | } | |
| 9 | ||
| 10 | pub const Redis = struct { | |
| 11 | pub const Command = struct { | |
| 12 | pub fn serialize(self: GET, comptime rootSerializer: type) void { | |
| 13 | return rootSerializer.serializeCommand(.{ "GET", self.key }); | |
| 14 | } | |
| 15 | }; | |
| 16 | }; | |
| 17 | }; | |
| 18 | ||
| 19 | pub fn isCommand(comptime T: type) bool { | |
| 20 | const tid = @typeInfo(T); | |
| 21 | return (tid == .Struct or tid == .Enum or tid == .Union) and | |
| 22 | @hasDecl(T, "Redis") and @hasDecl(T.Redis, "Command"); | |
| 23 | } | |
| 24 | ||
| 25 | pub const ArgSerializer = struct { | |
| 26 | pub fn serializeCommand(command: anytype) void { | |
| 27 | const CmdT = @TypeOf(command); | |
| 28 | ||
| 29 | if (comptime isCommand(CmdT)) { | |
| 30 | // COMMENTING THE NEXT LINE REMOVES THE ERROR | |
| 31 | return CmdT.Redis.Command.serialize(command, ArgSerializer); | |
| 32 | } | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | test "fixed" { | |
| 37 | ArgSerializer.serializeCommand(GET.init("banana")); | |
| 38 | } |
test/stage1/behavior/bugs/394.zig deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | const E = union(enum) { | |
| 2 | A: [9]u8, | |
| 3 | B: u64, | |
| 4 | }; | |
| 5 | const S = struct { | |
| 6 | x: u8, | |
| 7 | y: E, | |
| 8 | }; | |
| 9 | ||
| 10 | const expect = @import("std").testing.expect; | |
| 11 | ||
| 12 | test "bug 394 fixed" { | |
| 13 | const x = S{ | |
| 14 | .x = 3, | |
| 15 | .y = E{ .B = 1 }, | |
| 16 | }; | |
| 17 | expect(x.x == 3); | |
| 18 | } |
test/stage1/behavior/bugs/421.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "bitCast to array" { | |
| 4 | comptime testBitCastArray(); | |
| 5 | testBitCastArray(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testBitCastArray() void { | |
| 9 | expect(extractOne64(0x0123456789abcdef0123456789abcdef) == 0x0123456789abcdef); | |
| 10 | } | |
| 11 | ||
| 12 | fn extractOne64(a: u128) u64 { | |
| 13 | const x = @bitCast([2]u64, a); | |
| 14 | return x[1]; | |
| 15 | } |
test/stage1/behavior/bugs/4328.zig deleted-71| ... | ... | @@ -1,71 +0,0 @@ |
| 1 | const expectEqual = @import("std").testing.expectEqual; | |
| 2 | ||
| 3 | const FILE = extern struct { | |
| 4 | dummy_field: u8, | |
| 5 | }; | |
| 6 | ||
| 7 | extern fn printf([*c]const u8, ...) c_int; | |
| 8 | extern fn fputs([*c]const u8, noalias [*c]FILE) c_int; | |
| 9 | extern fn ftell([*c]FILE) c_long; | |
| 10 | extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE; | |
| 11 | ||
| 12 | const S = extern struct { | |
| 13 | state: c_short, | |
| 14 | ||
| 15 | extern fn s_do_thing([*c]S, b: c_int) c_short; | |
| 16 | }; | |
| 17 | ||
| 18 | test "Extern function calls in @TypeOf" { | |
| 19 | const Test = struct { | |
| 20 | fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) { | |
| 21 | return 0; | |
| 22 | } | |
| 23 | ||
| 24 | fn test_fn_2(a: anytype) @TypeOf((S{ .state = 0 }).s_do_thing(a)) { | |
| 25 | return 1; | |
| 26 | } | |
| 27 | ||
| 28 | fn doTheTest() void { | |
| 29 | expectEqual(c_int, @TypeOf(test_fn_1(0, 42))); | |
| 30 | expectEqual(c_short, @TypeOf(test_fn_2(0))); | |
| 31 | } | |
| 32 | }; | |
| 33 | ||
| 34 | Test.doTheTest(); | |
| 35 | comptime Test.doTheTest(); | |
| 36 | } | |
| 37 | ||
| 38 | test "Peer resolution of extern function calls in @TypeOf" { | |
| 39 | const Test = struct { | |
| 40 | fn test_fn() @TypeOf(ftell(null), fputs(null, null)) { | |
| 41 | return 0; | |
| 42 | } | |
| 43 | ||
| 44 | fn doTheTest() void { | |
| 45 | expectEqual(c_long, @TypeOf(test_fn())); | |
| 46 | } | |
| 47 | }; | |
| 48 | ||
| 49 | Test.doTheTest(); | |
| 50 | comptime Test.doTheTest(); | |
| 51 | } | |
| 52 | ||
| 53 | test "Extern function calls, dereferences and field access in @TypeOf" { | |
| 54 | const Test = struct { | |
| 55 | fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) { | |
| 56 | return .{ .dummy_field = 0 }; | |
| 57 | } | |
| 58 | ||
| 59 | fn test_fn_2(a: anytype) @TypeOf(fopen("test", "r").*.dummy_field) { | |
| 60 | return 255; | |
| 61 | } | |
| 62 | ||
| 63 | fn doTheTest() void { | |
| 64 | expectEqual(FILE, @TypeOf(test_fn_1(0))); | |
| 65 | expectEqual(u8, @TypeOf(test_fn_2(0))); | |
| 66 | } | |
| 67 | }; | |
| 68 | ||
| 69 | Test.doTheTest(); | |
| 70 | comptime Test.doTheTest(); | |
| 71 | } |
test/stage1/behavior/bugs/4560.zig deleted-32| ... | ... | @@ -1,32 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "fixed" { | |
| 4 | var s: S = .{ | |
| 5 | .a = 1, | |
| 6 | .b = .{ | |
| 7 | .size = 123, | |
| 8 | .max_distance_from_start_index = 456, | |
| 9 | }, | |
| 10 | }; | |
| 11 | std.testing.expect(s.a == 1); | |
| 12 | std.testing.expect(s.b.size == 123); | |
| 13 | std.testing.expect(s.b.max_distance_from_start_index == 456); | |
| 14 | } | |
| 15 | ||
| 16 | const S = struct { | |
| 17 | a: u32, | |
| 18 | b: Map, | |
| 19 | ||
| 20 | const Map = StringHashMap(*S); | |
| 21 | }; | |
| 22 | ||
| 23 | pub fn StringHashMap(comptime V: type) type { | |
| 24 | return HashMap([]const u8, V); | |
| 25 | } | |
| 26 | ||
| 27 | pub fn HashMap(comptime K: type, comptime V: type) type { | |
| 28 | return struct { | |
| 29 | size: usize, | |
| 30 | max_distance_from_start_index: usize, | |
| 31 | }; | |
| 32 | } |
test/stage1/behavior/bugs/4769_a.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | // | |
| \ No newline at end of file |
test/stage1/behavior/bugs/4769_b.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | //! | |
| \ No newline at end of file |
test/stage1/behavior/bugs/4769_c.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | /// | |
| \ No newline at end of file |
test/stage1/behavior/bugs/4954.zig deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | fn f(buf: []u8) void { | |
| 2 | var ptr = &buf[@sizeOf(u32)]; | |
| 3 | } | |
| 4 | ||
| 5 | test "crash" { | |
| 6 | var buf: [4096]u8 = undefined; | |
| 7 | f(&buf); | |
| 8 | } |
test/stage1/behavior/bugs/529.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | ||
| 5 | extern fn issue529(?*A) void; | |
| 6 | ||
| 7 | comptime { | |
| 8 | _ = @import("529_other_file_2.zig"); | |
| 9 | } | |
| 10 | ||
| 11 | test "issue 529 fixed" { | |
| 12 | @import("529_other_file.zig").issue529(null); | |
| 13 | issue529(null); | |
| 14 | } |
test/stage1/behavior/bugs/529_other_file.zig deleted-5| ... | ... | @@ -1,5 +0,0 @@ |
| 1 | pub const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | ||
| 5 | pub extern fn issue529(?*A) void; |
test/stage1/behavior/bugs/529_other_file_2.zig deleted-4| ... | ... | @@ -1,4 +0,0 @@ |
| 1 | pub const A = extern struct { | |
| 2 | field: c_int, | |
| 3 | }; | |
| 4 | export fn issue529(a: ?*A) void {} |
test/stage1/behavior/bugs/5398.zig deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | ||
| 4 | pub const Mesh = struct { | |
| 5 | id: u32, | |
| 6 | }; | |
| 7 | pub const Material = struct { | |
| 8 | transparent: bool = true, | |
| 9 | emits_shadows: bool = true, | |
| 10 | render_color: bool = true, | |
| 11 | }; | |
| 12 | pub const Renderable = struct { | |
| 13 | material: Material, | |
| 14 | // The compiler inserts some padding here to ensure Mesh is correctly aligned. | |
| 15 | mesh: Mesh, | |
| 16 | }; | |
| 17 | ||
| 18 | var renderable: Renderable = undefined; | |
| 19 | ||
| 20 | test "assignment of field with padding" { | |
| 21 | renderable = Renderable{ | |
| 22 | .mesh = Mesh{ .id = 0 }, | |
| 23 | .material = Material{ | |
| 24 | .transparent = false, | |
| 25 | .emits_shadows = false, | |
| 26 | }, | |
| 27 | }; | |
| 28 | testing.expectEqual(false, renderable.material.transparent); | |
| 29 | testing.expectEqual(false, renderable.material.emits_shadows); | |
| 30 | testing.expectEqual(true, renderable.material.render_color); | |
| 31 | } |
test/stage1/behavior/bugs/5413.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "Peer type resolution with string literals and unknown length u8 pointers" { | |
| 4 | expect(@TypeOf("", "a", @as([*:0]const u8, "")) == [*:0]const u8); | |
| 5 | expect(@TypeOf(@as([*:0]const u8, "baz"), "foo", "bar") == [*:0]const u8); | |
| 6 | } |
test/stage1/behavior/bugs/5474.zig deleted-57| ... | ... | @@ -1,57 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | // baseline (control) struct with array of scalar | |
| 4 | const Box0 = struct { | |
| 5 | items: [4]Item, | |
| 6 | ||
| 7 | const Item = struct { | |
| 8 | num: u32, | |
| 9 | }; | |
| 10 | }; | |
| 11 | ||
| 12 | // struct with array of empty struct | |
| 13 | const Box1 = struct { | |
| 14 | items: [4]Item, | |
| 15 | ||
| 16 | const Item = struct {}; | |
| 17 | }; | |
| 18 | ||
| 19 | // struct with array of zero-size struct | |
| 20 | const Box2 = struct { | |
| 21 | items: [4]Item, | |
| 22 | ||
| 23 | const Item = struct { | |
| 24 | nothing: void, | |
| 25 | }; | |
| 26 | }; | |
| 27 | ||
| 28 | fn doTest() void { | |
| 29 | // var | |
| 30 | { | |
| 31 | var box0: Box0 = .{ .items = undefined }; | |
| 32 | std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == false); | |
| 33 | ||
| 34 | var box1: Box1 = .{ .items = undefined }; | |
| 35 | std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == false); | |
| 36 | ||
| 37 | var box2: Box2 = .{ .items = undefined }; | |
| 38 | std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == false); | |
| 39 | } | |
| 40 | ||
| 41 | // const | |
| 42 | { | |
| 43 | const box0: Box0 = .{ .items = undefined }; | |
| 44 | std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).Pointer.is_const == true); | |
| 45 | ||
| 46 | const box1: Box1 = .{ .items = undefined }; | |
| 47 | std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).Pointer.is_const == true); | |
| 48 | ||
| 49 | const box2: Box2 = .{ .items = undefined }; | |
| 50 | std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).Pointer.is_const == true); | |
| 51 | } | |
| 52 | } | |
| 53 | ||
| 54 | test "pointer-to-array constness for zero-size elements" { | |
| 55 | doTest(); | |
| 56 | comptime doTest(); | |
| 57 | } |
test/stage1/behavior/bugs/5487.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const io = @import("std").io; | |
| 2 | ||
| 3 | pub fn write(_: void, bytes: []const u8) !usize { | |
| 4 | return 0; | |
| 5 | } | |
| 6 | pub fn writer() io.Writer(void, @typeInfo(@typeInfo(@TypeOf(write)).Fn.return_type.?).ErrorUnion.error_set, write) { | |
| 7 | return io.Writer(void, @typeInfo(@typeInfo(@TypeOf(write)).Fn.return_type.?).ErrorUnion.error_set, write){ .context = {} }; | |
| 8 | } | |
| 9 | ||
| 10 | test "crash" { | |
| 11 | _ = io.multiWriter(.{writer()}); | |
| 12 | } |
test/stage1/behavior/bugs/624.zig deleted-23| ... | ... | @@ -1,23 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const TestContext = struct { | |
| 5 | server_context: *ListenerContext, | |
| 6 | }; | |
| 7 | ||
| 8 | const ListenerContext = struct { | |
| 9 | context_alloc: *ContextAllocator, | |
| 10 | }; | |
| 11 | ||
| 12 | const ContextAllocator = MemoryPool(TestContext); | |
| 13 | ||
| 14 | fn MemoryPool(comptime T: type) type { | |
| 15 | return struct { | |
| 16 | n: usize, | |
| 17 | }; | |
| 18 | } | |
| 19 | ||
| 20 | test "foo" { | |
| 21 | var allocator = ContextAllocator{ .n = 10 }; | |
| 22 | expect(allocator.n == 10); | |
| 23 | } |
test/stage1/behavior/bugs/6456.zig deleted-42| ... | ... | @@ -1,42 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const StructField = std.builtin.TypeInfo.StructField; | |
| 4 | const Declaration = std.builtin.TypeInfo.Declaration; | |
| 5 | ||
| 6 | const text = | |
| 7 | \\f1 | |
| 8 | \\f2 | |
| 9 | \\f3 | |
| 10 | ; | |
| 11 | ||
| 12 | test "issue 6456" { | |
| 13 | comptime { | |
| 14 | var fields: []const StructField = &[0]StructField{}; | |
| 15 | ||
| 16 | var it = std.mem.tokenize(text, "\n"); | |
| 17 | while (it.next()) |name| { | |
| 18 | fields = fields ++ &[_]StructField{StructField{ | |
| 19 | .alignment = 0, | |
| 20 | .name = name, | |
| 21 | .field_type = usize, | |
| 22 | .default_value = @as(?usize, null), | |
| 23 | .is_comptime = false, | |
| 24 | }}; | |
| 25 | } | |
| 26 | ||
| 27 | const T = @Type(.{ | |
| 28 | .Struct = .{ | |
| 29 | .layout = .Auto, | |
| 30 | .is_tuple = false, | |
| 31 | .fields = fields, | |
| 32 | .decls = &[_]Declaration{}, | |
| 33 | }, | |
| 34 | }); | |
| 35 | ||
| 36 | const gen_fields = @typeInfo(T).Struct.fields; | |
| 37 | testing.expectEqual(3, gen_fields.len); | |
| 38 | testing.expectEqualStrings("f1", gen_fields[0].name); | |
| 39 | testing.expectEqualStrings("f2", gen_fields[1].name); | |
| 40 | testing.expectEqualStrings("f3", gen_fields[2].name); | |
| 41 | } | |
| 42 | } |
test/stage1/behavior/bugs/655.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const other_file = @import("655_other_file.zig"); | |
| 3 | ||
| 4 | test "function with *const parameter with type dereferenced by namespace" { | |
| 5 | const x: other_file.Integer = 1234; | |
| 6 | comptime std.testing.expect(@TypeOf(&x) == *const other_file.Integer); | |
| 7 | foo(&x); | |
| 8 | } | |
| 9 | ||
| 10 | fn foo(x: *const other_file.Integer) void { | |
| 11 | std.testing.expect(x.* == 1234); | |
| 12 | } |
test/stage1/behavior/bugs/655_other_file.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub const Integer = u32; |
test/stage1/behavior/bugs/656.zig deleted-31| ... | ... | @@ -1,31 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const PrefixOp = union(enum) { | |
| 4 | Return, | |
| 5 | AddrOf: Value, | |
| 6 | }; | |
| 7 | ||
| 8 | const Value = struct { | |
| 9 | align_expr: ?u32, | |
| 10 | }; | |
| 11 | ||
| 12 | test "optional if after an if in a switch prong of a switch with 2 prongs in an else" { | |
| 13 | foo(false, true); | |
| 14 | } | |
| 15 | ||
| 16 | fn foo(a: bool, b: bool) void { | |
| 17 | var prefix_op = PrefixOp{ | |
| 18 | .AddrOf = Value{ .align_expr = 1234 }, | |
| 19 | }; | |
| 20 | if (a) {} else { | |
| 21 | switch (prefix_op) { | |
| 22 | PrefixOp.AddrOf => |addr_of_info| { | |
| 23 | if (b) {} | |
| 24 | if (addr_of_info.align_expr) |align_expr| { | |
| 25 | expect(align_expr == 1234); | |
| 26 | } | |
| 27 | }, | |
| 28 | PrefixOp.Return => {}, | |
| 29 | } | |
| 30 | } | |
| 31 | } |
test/stage1/behavior/bugs/6781.zig deleted-74| ... | ... | @@ -1,74 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | ||
| 4 | const segfault = true; | |
| 5 | ||
| 6 | pub const JournalHeader = packed struct { | |
| 7 | hash_chain_root: u128 = undefined, | |
| 8 | prev_hash_chain_root: u128, | |
| 9 | checksum: u128 = undefined, | |
| 10 | magic: u64, | |
| 11 | command: u32, | |
| 12 | size: u32, | |
| 13 | ||
| 14 | pub fn calculate_checksum(self: *const JournalHeader, entry: []const u8) u128 { | |
| 15 | assert(entry.len >= @sizeOf(JournalHeader)); | |
| 16 | assert(entry.len == self.size); | |
| 17 | ||
| 18 | const checksum_offset = @byteOffsetOf(JournalHeader, "checksum"); | |
| 19 | const checksum_size = @sizeOf(@TypeOf(self.checksum)); | |
| 20 | assert(checksum_offset == 0 + 16 + 16); | |
| 21 | assert(checksum_size == 16); | |
| 22 | ||
| 23 | var target: [32]u8 = undefined; | |
| 24 | std.crypto.hash.Blake3.hash(entry[checksum_offset + checksum_size ..], target[0..], .{}); | |
| 25 | return @bitCast(u128, target[0..checksum_size].*); | |
| 26 | } | |
| 27 | ||
| 28 | pub fn calculate_hash_chain_root(self: *const JournalHeader) u128 { | |
| 29 | const hash_chain_root_size = @sizeOf(@TypeOf(self.hash_chain_root)); | |
| 30 | assert(hash_chain_root_size == 16); | |
| 31 | ||
| 32 | const prev_hash_chain_root_offset = @byteOffsetOf(JournalHeader, "prev_hash_chain_root"); | |
| 33 | const prev_hash_chain_root_size = @sizeOf(@TypeOf(self.prev_hash_chain_root)); | |
| 34 | assert(prev_hash_chain_root_offset == 0 + 16); | |
| 35 | assert(prev_hash_chain_root_size == 16); | |
| 36 | ||
| 37 | const checksum_offset = @byteOffsetOf(JournalHeader, "checksum"); | |
| 38 | const checksum_size = @sizeOf(@TypeOf(self.checksum)); | |
| 39 | assert(checksum_offset == 0 + 16 + 16); | |
| 40 | assert(checksum_size == 16); | |
| 41 | ||
| 42 | assert(prev_hash_chain_root_offset + prev_hash_chain_root_size == checksum_offset); | |
| 43 | ||
| 44 | const header = @bitCast([@sizeOf(JournalHeader)]u8, self.*); | |
| 45 | const source = header[prev_hash_chain_root_offset .. checksum_offset + checksum_size]; | |
| 46 | assert(source.len == prev_hash_chain_root_size + checksum_size); | |
| 47 | var target: [32]u8 = undefined; | |
| 48 | std.crypto.hash.Blake3.hash(source, target[0..], .{}); | |
| 49 | if (segfault) { | |
| 50 | return @bitCast(u128, target[0..hash_chain_root_size].*); | |
| 51 | } else { | |
| 52 | var array = target[0..hash_chain_root_size].*; | |
| 53 | return @bitCast(u128, array); | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | pub fn set_checksum_and_hash_chain_root(self: *JournalHeader, entry: []const u8) void { | |
| 58 | self.checksum = self.calculate_checksum(entry); | |
| 59 | self.hash_chain_root = self.calculate_hash_chain_root(); | |
| 60 | } | |
| 61 | }; | |
| 62 | ||
| 63 | test "fixed" { | |
| 64 | var buffer = [_]u8{0} ** 65536; | |
| 65 | var entry = std.mem.bytesAsValue(JournalHeader, buffer[0..@sizeOf(JournalHeader)]); | |
| 66 | entry.* = .{ | |
| 67 | .prev_hash_chain_root = 0, | |
| 68 | .magic = 0, | |
| 69 | .command = 0, | |
| 70 | .size = 64 + 128, | |
| 71 | }; | |
| 72 | entry.set_checksum_and_hash_chain_root(buffer[0..entry.size]); | |
| 73 | try std.io.null_writer.print("{}\n", .{entry}); | |
| 74 | } |
test/stage1/behavior/bugs/679.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | pub fn List(comptime T: type) type { | |
| 5 | return u32; | |
| 6 | } | |
| 7 | ||
| 8 | const ElementList = List(Element); | |
| 9 | const Element = struct { | |
| 10 | link: ElementList, | |
| 11 | }; | |
| 12 | ||
| 13 | test "false dependency loop in struct definition" { | |
| 14 | const listType = ElementList; | |
| 15 | var x: listType = 42; | |
| 16 | expect(x == 42); | |
| 17 | } |
test/stage1/behavior/bugs/6850.zig deleted-12| ... | ... | @@ -1,12 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | test "lazy sizeof comparison with zero" { | |
| 4 | const Empty = struct {}; | |
| 5 | const T = *Empty; | |
| 6 | ||
| 7 | std.testing.expect(hasNoBits(T)); | |
| 8 | } | |
| 9 | ||
| 10 | fn hasNoBits(comptime T: type) bool { | |
| 11 | return @sizeOf(T) == 0; | |
| 12 | } |
test/stage1/behavior/bugs/7003.zig deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | test "@Type should resolve its children types" { | |
| 2 | const sparse = enum(u2) { a, b, c }; | |
| 3 | const dense = enum(u2) { a, b, c, d }; | |
| 4 | ||
| 5 | comptime var sparse_info = @typeInfo(anyerror!sparse); | |
| 6 | sparse_info.ErrorUnion.payload = dense; | |
| 7 | const B = @Type(sparse_info); | |
| 8 | } |
test/stage1/behavior/bugs/7027.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const Foobar = struct { | |
| 2 | myTypes: [128]type, | |
| 3 | str: [1024]u8, | |
| 4 | ||
| 5 | fn foo() @This() { | |
| 6 | comptime var foobar: Foobar = undefined; | |
| 7 | foobar.str = [_]u8{'a'} ** 1024; | |
| 8 | return foobar; | |
| 9 | } | |
| 10 | }; | |
| 11 | ||
| 12 | fn foo(arg: anytype) void {} | |
| 13 | ||
| 14 | test "" { | |
| 15 | comptime var foobar = Foobar.foo(); | |
| 16 | foo(foobar.str[0..10]); | |
| 17 | } |
test/stage1/behavior/bugs/704.zig deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | const xxx = struct { | |
| 2 | pub fn bar(self: *xxx) void {} | |
| 3 | }; | |
| 4 | test "bug 704" { | |
| 5 | var x: xxx = undefined; | |
| 6 | x.bar(); | |
| 7 | } |
test/stage1/behavior/bugs/7047.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | const U = union(enum) { | |
| 4 | T: type, | |
| 5 | N: void, | |
| 6 | }; | |
| 7 | ||
| 8 | fn S(comptime query: U) type { | |
| 9 | return struct { | |
| 10 | fn tag() type { | |
| 11 | return query.T; | |
| 12 | } | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | test "compiler doesn't consider equal unions with different 'type' payload" { | |
| 17 | const s1 = S(U{ .T = u32 }).tag(); | |
| 18 | std.testing.expectEqual(u32, s1); | |
| 19 | ||
| 20 | const s2 = S(U{ .T = u64 }).tag(); | |
| 21 | std.testing.expectEqual(u64, s2); | |
| 22 | } |
test/stage1/behavior/bugs/718.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const mem = std.mem; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const Keys = struct { | |
| 5 | up: bool, | |
| 6 | down: bool, | |
| 7 | left: bool, | |
| 8 | right: bool, | |
| 9 | }; | |
| 10 | var keys: Keys = undefined; | |
| 11 | test "zero keys with @memset" { | |
| 12 | @memset(@ptrCast([*]u8, &keys), 0, @sizeOf(@TypeOf(keys))); | |
| 13 | expect(!keys.up); | |
| 14 | expect(!keys.down); | |
| 15 | expect(!keys.left); | |
| 16 | expect(!keys.right); | |
| 17 | } |
test/stage1/behavior/bugs/7250.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const nrfx_uart_t = extern struct { | |
| 2 | p_reg: [*c]u32, | |
| 3 | drv_inst_idx: u8, | |
| 4 | }; | |
| 5 | ||
| 6 | pub fn nrfx_uart_rx(p_instance: [*c]const nrfx_uart_t) void {} | |
| 7 | ||
| 8 | threadlocal var g_uart0 = nrfx_uart_t{ | |
| 9 | .p_reg = 0, | |
| 10 | .drv_inst_idx = 0, | |
| 11 | }; | |
| 12 | ||
| 13 | test "reference a global threadlocal variable" { | |
| 14 | _ = nrfx_uart_rx(&g_uart0); | |
| 15 | } |
test/stage1/behavior/bugs/726.zig deleted-15| ... | ... | @@ -1,15 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@ptrCast from const to nullable" { | |
| 4 | const c: u8 = 4; | |
| 5 | var x: ?*const u8 = @ptrCast(?*const u8, &c); | |
| 6 | expect(x.?.* == 4); | |
| 7 | } | |
| 8 | ||
| 9 | test "@ptrCast from var in empty struct to nullable" { | |
| 10 | const container = struct { | |
| 11 | var c: u8 = 4; | |
| 12 | }; | |
| 13 | var x: ?*const u8 = @ptrCast(?*const u8, &container.c); | |
| 14 | expect(x.?.* == 4); | |
| 15 | } |
test/stage1/behavior/bugs/828.zig deleted-33| ... | ... | @@ -1,33 +0,0 @@ |
| 1 | const CountBy = struct { | |
| 2 | a: usize, | |
| 3 | ||
| 4 | const One = CountBy{ .a = 1 }; | |
| 5 | ||
| 6 | pub fn counter(self: *const CountBy) Counter { | |
| 7 | return Counter{ .i = 0 }; | |
| 8 | } | |
| 9 | }; | |
| 10 | ||
| 11 | const Counter = struct { | |
| 12 | i: usize, | |
| 13 | ||
| 14 | pub fn count(self: *Counter) bool { | |
| 15 | self.i += 1; | |
| 16 | return self.i <= 10; | |
| 17 | } | |
| 18 | }; | |
| 19 | ||
| 20 | fn constCount(comptime cb: *const CountBy, comptime unused: u32) void { | |
| 21 | comptime { | |
| 22 | var cnt = cb.counter(); | |
| 23 | if (cnt.i != 0) @compileError("Counter instance reused!"); | |
| 24 | while (cnt.count()) {} | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | test "comptime struct return should not return the same instance" { | |
| 29 | //the first parameter must be passed by reference to trigger the bug | |
| 30 | //a second parameter is required to trigger the bug | |
| 31 | const ValA = constCount(&CountBy.One, 12); | |
| 32 | const ValB = constCount(&CountBy.One, 15); | |
| 33 | } |
test/stage1/behavior/bugs/920.zig deleted-65| ... | ... | @@ -1,65 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const math = std.math; | |
| 3 | const Random = std.rand.Random; | |
| 4 | ||
| 5 | const ZigTable = struct { | |
| 6 | r: f64, | |
| 7 | x: [257]f64, | |
| 8 | f: [257]f64, | |
| 9 | ||
| 10 | pdf: fn (f64) f64, | |
| 11 | is_symmetric: bool, | |
| 12 | zero_case: fn (*Random, f64) f64, | |
| 13 | }; | |
| 14 | ||
| 15 | fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn (f64) f64, comptime f_inv: fn (f64) f64, comptime zero_case: fn (*Random, f64) f64) ZigTable { | |
| 16 | var tables: ZigTable = undefined; | |
| 17 | ||
| 18 | tables.is_symmetric = is_symmetric; | |
| 19 | tables.r = r; | |
| 20 | tables.pdf = f; | |
| 21 | tables.zero_case = zero_case; | |
| 22 | ||
| 23 | tables.x[0] = v / f(r); | |
| 24 | tables.x[1] = r; | |
| 25 | ||
| 26 | for (tables.x[2..256]) |*entry, i| { | |
| 27 | const last = tables.x[2 + i - 1]; | |
| 28 | entry.* = f_inv(v / last + f(last)); | |
| 29 | } | |
| 30 | tables.x[256] = 0; | |
| 31 | ||
| 32 | for (tables.f[0..]) |*entry, i| { | |
| 33 | entry.* = f(tables.x[i]); | |
| 34 | } | |
| 35 | ||
| 36 | return tables; | |
| 37 | } | |
| 38 | ||
| 39 | const norm_r = 3.6541528853610088; | |
| 40 | const norm_v = 0.00492867323399; | |
| 41 | ||
| 42 | fn norm_f(x: f64) f64 { | |
| 43 | return math.exp(-x * x / 2.0); | |
| 44 | } | |
| 45 | fn norm_f_inv(y: f64) f64 { | |
| 46 | return math.sqrt(-2.0 * math.ln(y)); | |
| 47 | } | |
| 48 | fn norm_zero_case(random: *Random, u: f64) f64 { | |
| 49 | return 0.0; | |
| 50 | } | |
| 51 | ||
| 52 | const NormalDist = blk: { | |
| 53 | @setEvalBranchQuota(30000); | |
| 54 | break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case); | |
| 55 | }; | |
| 56 | ||
| 57 | test "bug 920 fixed" { | |
| 58 | const NormalDist1 = blk: { | |
| 59 | break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case); | |
| 60 | }; | |
| 61 | ||
| 62 | for (NormalDist1.f) |_, i| { | |
| 63 | std.testing.expectEqual(NormalDist1.f[i], NormalDist.f[i]); | |
| 64 | } | |
| 65 | } |
test/stage1/behavior/byteswap.zig deleted-68| ... | ... | @@ -1,68 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@byteSwap integers" { | |
| 5 | const ByteSwapIntTest = struct { | |
| 6 | fn run() void { | |
| 7 | t(u0, 0, 0); | |
| 8 | t(u8, 0x12, 0x12); | |
| 9 | t(u16, 0x1234, 0x3412); | |
| 10 | t(u24, 0x123456, 0x563412); | |
| 11 | t(u32, 0x12345678, 0x78563412); | |
| 12 | t(u40, 0x123456789a, 0x9a78563412); | |
| 13 | t(i48, 0x123456789abc, @bitCast(i48, @as(u48, 0xbc9a78563412))); | |
| 14 | t(u56, 0x123456789abcde, 0xdebc9a78563412); | |
| 15 | t(u64, 0x123456789abcdef1, 0xf1debc9a78563412); | |
| 16 | t(u128, 0x123456789abcdef11121314151617181, 0x8171615141312111f1debc9a78563412); | |
| 17 | ||
| 18 | t(u0, @as(u0, 0), 0); | |
| 19 | t(i8, @as(i8, -50), -50); | |
| 20 | t(i16, @bitCast(i16, @as(u16, 0x1234)), @bitCast(i16, @as(u16, 0x3412))); | |
| 21 | t(i24, @bitCast(i24, @as(u24, 0x123456)), @bitCast(i24, @as(u24, 0x563412))); | |
| 22 | t(i32, @bitCast(i32, @as(u32, 0x12345678)), @bitCast(i32, @as(u32, 0x78563412))); | |
| 23 | t(u40, @bitCast(i40, @as(u40, 0x123456789a)), @as(u40, 0x9a78563412)); | |
| 24 | t(i48, @bitCast(i48, @as(u48, 0x123456789abc)), @bitCast(i48, @as(u48, 0xbc9a78563412))); | |
| 25 | t(i56, @bitCast(i56, @as(u56, 0x123456789abcde)), @bitCast(i56, @as(u56, 0xdebc9a78563412))); | |
| 26 | t(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1)), @bitCast(i64, @as(u64, 0xf1debc9a78563412))); | |
| 27 | t( | |
| 28 | i128, | |
| 29 | @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181)), | |
| 30 | @bitCast(i128, @as(u128, 0x8171615141312111f1debc9a78563412)), | |
| 31 | ); | |
| 32 | } | |
| 33 | fn t(comptime I: type, input: I, expected_output: I) void { | |
| 34 | std.testing.expectEqual(expected_output, @byteSwap(I, input)); | |
| 35 | } | |
| 36 | }; | |
| 37 | comptime ByteSwapIntTest.run(); | |
| 38 | ByteSwapIntTest.run(); | |
| 39 | } | |
| 40 | ||
| 41 | test "@byteSwap vectors" { | |
| 42 | // https://github.com/ziglang/zig/issues/3563 | |
| 43 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; | |
| 44 | ||
| 45 | // https://github.com/ziglang/zig/issues/3317 | |
| 46 | if (std.Target.current.cpu.arch == .mipsel or std.Target.current.cpu.arch == .mips) return error.SkipZigTest; | |
| 47 | ||
| 48 | const ByteSwapVectorTest = struct { | |
| 49 | fn run() void { | |
| 50 | t(u8, 2, [_]u8{ 0x12, 0x13 }, [_]u8{ 0x12, 0x13 }); | |
| 51 | t(u16, 2, [_]u16{ 0x1234, 0x2345 }, [_]u16{ 0x3412, 0x4523 }); | |
| 52 | t(u24, 2, [_]u24{ 0x123456, 0x234567 }, [_]u24{ 0x563412, 0x674523 }); | |
| 53 | } | |
| 54 | ||
| 55 | fn t( | |
| 56 | comptime I: type, | |
| 57 | comptime n: comptime_int, | |
| 58 | input: std.meta.Vector(n, I), | |
| 59 | expected_vector: std.meta.Vector(n, I), | |
| 60 | ) void { | |
| 61 | const actual_output: [n]I = @byteSwap(I, input); | |
| 62 | const expected_output: [n]I = expected_vector; | |
| 63 | std.testing.expectEqual(expected_output, actual_output); | |
| 64 | } | |
| 65 | }; | |
| 66 | comptime ByteSwapVectorTest.run(); | |
| 67 | ByteSwapVectorTest.run(); | |
| 68 | } |
test/stage1/behavior/byval_arg_var.zig deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | var result: []const u8 = "wrong"; | |
| 4 | ||
| 5 | test "pass string literal byvalue to a generic var param" { | |
| 6 | start(); | |
| 7 | blowUpStack(10); | |
| 8 | ||
| 9 | std.testing.expect(std.mem.eql(u8, result, "string literal")); | |
| 10 | } | |
| 11 | ||
| 12 | fn start() void { | |
| 13 | foo("string literal"); | |
| 14 | } | |
| 15 | ||
| 16 | fn foo(x: anytype) void { | |
| 17 | bar(x); | |
| 18 | } | |
| 19 | ||
| 20 | fn bar(x: anytype) void { | |
| 21 | result = x; | |
| 22 | } | |
| 23 | ||
| 24 | fn blowUpStack(x: u32) void { | |
| 25 | if (x == 0) return; | |
| 26 | blowUpStack(x - 1); | |
| 27 | } |
test/stage1/behavior/call.zig deleted-74| ... | ... | @@ -1,74 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "basic invocations" { | |
| 6 | const foo = struct { | |
| 7 | fn foo() i32 { | |
| 8 | return 1234; | |
| 9 | } | |
| 10 | }.foo; | |
| 11 | expect(@call(.{}, foo, .{}) == 1234); | |
| 12 | comptime { | |
| 13 | // modifiers that allow comptime calls | |
| 14 | expect(@call(.{}, foo, .{}) == 1234); | |
| 15 | expect(@call(.{ .modifier = .no_async }, foo, .{}) == 1234); | |
| 16 | expect(@call(.{ .modifier = .always_tail }, foo, .{}) == 1234); | |
| 17 | expect(@call(.{ .modifier = .always_inline }, foo, .{}) == 1234); | |
| 18 | } | |
| 19 | { | |
| 20 | // comptime call without comptime keyword | |
| 21 | const result = @call(.{ .modifier = .compile_time }, foo, .{}) == 1234; | |
| 22 | comptime expect(result); | |
| 23 | } | |
| 24 | { | |
| 25 | // call of non comptime-known function | |
| 26 | var alias_foo = foo; | |
| 27 | expect(@call(.{ .modifier = .no_async }, alias_foo, .{}) == 1234); | |
| 28 | expect(@call(.{ .modifier = .never_tail }, alias_foo, .{}) == 1234); | |
| 29 | expect(@call(.{ .modifier = .never_inline }, alias_foo, .{}) == 1234); | |
| 30 | } | |
| 31 | } | |
| 32 | ||
| 33 | test "tuple parameters" { | |
| 34 | const add = struct { | |
| 35 | fn add(a: i32, b: i32) i32 { | |
| 36 | return a + b; | |
| 37 | } | |
| 38 | }.add; | |
| 39 | var a: i32 = 12; | |
| 40 | var b: i32 = 34; | |
| 41 | expect(@call(.{}, add, .{ a, 34 }) == 46); | |
| 42 | expect(@call(.{}, add, .{ 12, b }) == 46); | |
| 43 | expect(@call(.{}, add, .{ a, b }) == 46); | |
| 44 | expect(@call(.{}, add, .{ 12, 34 }) == 46); | |
| 45 | comptime expect(@call(.{}, add, .{ 12, 34 }) == 46); | |
| 46 | { | |
| 47 | const separate_args0 = .{ a, b }; | |
| 48 | const separate_args1 = .{ a, 34 }; | |
| 49 | const separate_args2 = .{ 12, 34 }; | |
| 50 | const separate_args3 = .{ 12, b }; | |
| 51 | expect(@call(.{ .modifier = .always_inline }, add, separate_args0) == 46); | |
| 52 | expect(@call(.{ .modifier = .always_inline }, add, separate_args1) == 46); | |
| 53 | expect(@call(.{ .modifier = .always_inline }, add, separate_args2) == 46); | |
| 54 | expect(@call(.{ .modifier = .always_inline }, add, separate_args3) == 46); | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | test "comptime call with bound function as parameter" { | |
| 59 | const S = struct { | |
| 60 | fn ReturnType(func: anytype) type { | |
| 61 | return switch (@typeInfo(@TypeOf(func))) { | |
| 62 | .BoundFn => |info| info, | |
| 63 | else => unreachable, | |
| 64 | }.return_type orelse void; | |
| 65 | } | |
| 66 | ||
| 67 | fn call_me_maybe() ?i32 { | |
| 68 | return 123; | |
| 69 | } | |
| 70 | }; | |
| 71 | ||
| 72 | var inst: S = undefined; | |
| 73 | expectEqual(?i32, S.ReturnType(inst.call_me_maybe)); | |
| 74 | } |
test/stage1/behavior/cast.zig deleted-927| ... | ... | @@ -1,927 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | const maxInt = std.math.maxInt; | |
| 5 | const Vector = std.meta.Vector; | |
| 6 | const native_endian = @import("builtin").target.cpu.arch.endian(); | |
| 7 | ||
| 8 | test "int to ptr cast" { | |
| 9 | const x = @as(usize, 13); | |
| 10 | const y = @intToPtr(*u8, x); | |
| 11 | const z = @ptrToInt(y); | |
| 12 | expect(z == 13); | |
| 13 | } | |
| 14 | ||
| 15 | test "integer literal to pointer cast" { | |
| 16 | const vga_mem = @intToPtr(*u16, 0xB8000); | |
| 17 | expect(@ptrToInt(vga_mem) == 0xB8000); | |
| 18 | } | |
| 19 | ||
| 20 | test "pointer reinterpret const float to int" { | |
| 21 | // The hex representation is 0x3fe3333333333303. | |
| 22 | const float: f64 = 5.99999999999994648725e-01; | |
| 23 | const float_ptr = &float; | |
| 24 | const int_ptr = @ptrCast(*const i32, float_ptr); | |
| 25 | const int_val = int_ptr.*; | |
| 26 | if (native_endian == .Little) | |
| 27 | expect(int_val == 0x33333303) | |
| 28 | else | |
| 29 | expect(int_val == 0x3fe33333); | |
| 30 | } | |
| 31 | ||
| 32 | test "implicitly cast indirect pointer to maybe-indirect pointer" { | |
| 33 | const S = struct { | |
| 34 | const Self = @This(); | |
| 35 | x: u8, | |
| 36 | fn constConst(p: *const *const Self) u8 { | |
| 37 | return p.*.x; | |
| 38 | } | |
| 39 | fn maybeConstConst(p: ?*const *const Self) u8 { | |
| 40 | return p.?.*.x; | |
| 41 | } | |
| 42 | fn constConstConst(p: *const *const *const Self) u8 { | |
| 43 | return p.*.*.x; | |
| 44 | } | |
| 45 | fn maybeConstConstConst(p: ?*const *const *const Self) u8 { | |
| 46 | return p.?.*.*.x; | |
| 47 | } | |
| 48 | }; | |
| 49 | const s = S{ .x = 42 }; | |
| 50 | const p = &s; | |
| 51 | const q = &p; | |
| 52 | const r = &q; | |
| 53 | expect(42 == S.constConst(q)); | |
| 54 | expect(42 == S.maybeConstConst(q)); | |
| 55 | expect(42 == S.constConstConst(r)); | |
| 56 | expect(42 == S.maybeConstConstConst(r)); | |
| 57 | } | |
| 58 | ||
| 59 | test "explicit cast from integer to error type" { | |
| 60 | testCastIntToErr(error.ItBroke); | |
| 61 | comptime testCastIntToErr(error.ItBroke); | |
| 62 | } | |
| 63 | fn testCastIntToErr(err: anyerror) void { | |
| 64 | const x = @errorToInt(err); | |
| 65 | const y = @intToError(x); | |
| 66 | expect(error.ItBroke == y); | |
| 67 | } | |
| 68 | ||
| 69 | test "peer resolve arrays of different size to const slice" { | |
| 70 | expect(mem.eql(u8, boolToStr(true), "true")); | |
| 71 | expect(mem.eql(u8, boolToStr(false), "false")); | |
| 72 | comptime expect(mem.eql(u8, boolToStr(true), "true")); | |
| 73 | comptime expect(mem.eql(u8, boolToStr(false), "false")); | |
| 74 | } | |
| 75 | fn boolToStr(b: bool) []const u8 { | |
| 76 | return if (b) "true" else "false"; | |
| 77 | } | |
| 78 | ||
| 79 | test "peer resolve array and const slice" { | |
| 80 | testPeerResolveArrayConstSlice(true); | |
| 81 | comptime testPeerResolveArrayConstSlice(true); | |
| 82 | } | |
| 83 | fn testPeerResolveArrayConstSlice(b: bool) void { | |
| 84 | const value1 = if (b) "aoeu" else @as([]const u8, "zz"); | |
| 85 | const value2 = if (b) @as([]const u8, "zz") else "aoeu"; | |
| 86 | expect(mem.eql(u8, value1, "aoeu")); | |
| 87 | expect(mem.eql(u8, value2, "zz")); | |
| 88 | } | |
| 89 | ||
| 90 | test "implicitly cast from T to anyerror!?T" { | |
| 91 | castToOptionalTypeError(1); | |
| 92 | comptime castToOptionalTypeError(1); | |
| 93 | } | |
| 94 | ||
| 95 | const A = struct { | |
| 96 | a: i32, | |
| 97 | }; | |
| 98 | fn castToOptionalTypeError(z: i32) void { | |
| 99 | const x = @as(i32, 1); | |
| 100 | const y: anyerror!?i32 = x; | |
| 101 | expect((try y).? == 1); | |
| 102 | ||
| 103 | const f = z; | |
| 104 | const g: anyerror!?i32 = f; | |
| 105 | ||
| 106 | const a = A{ .a = z }; | |
| 107 | const b: anyerror!?A = a; | |
| 108 | expect((b catch unreachable).?.a == 1); | |
| 109 | } | |
| 110 | ||
| 111 | test "implicitly cast from int to anyerror!?T" { | |
| 112 | implicitIntLitToOptional(); | |
| 113 | comptime implicitIntLitToOptional(); | |
| 114 | } | |
| 115 | fn implicitIntLitToOptional() void { | |
| 116 | const f: ?i32 = 1; | |
| 117 | const g: anyerror!?i32 = 1; | |
| 118 | } | |
| 119 | ||
| 120 | test "return null from fn() anyerror!?&T" { | |
| 121 | const a = returnNullFromOptionalTypeErrorRef(); | |
| 122 | const b = returnNullLitFromOptionalTypeErrorRef(); | |
| 123 | expect((try a) == null and (try b) == null); | |
| 124 | } | |
| 125 | fn returnNullFromOptionalTypeErrorRef() anyerror!?*A { | |
| 126 | const a: ?*A = null; | |
| 127 | return a; | |
| 128 | } | |
| 129 | fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { | |
| 130 | return null; | |
| 131 | } | |
| 132 | ||
| 133 | test "peer type resolution: ?T and T" { | |
| 134 | expect(peerTypeTAndOptionalT(true, false).? == 0); | |
| 135 | expect(peerTypeTAndOptionalT(false, false).? == 3); | |
| 136 | comptime { | |
| 137 | expect(peerTypeTAndOptionalT(true, false).? == 0); | |
| 138 | expect(peerTypeTAndOptionalT(false, false).? == 3); | |
| 139 | } | |
| 140 | } | |
| 141 | fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { | |
| 142 | if (c) { | |
| 143 | return if (b) null else @as(usize, 0); | |
| 144 | } | |
| 145 | ||
| 146 | return @as(usize, 3); | |
| 147 | } | |
| 148 | ||
| 149 | test "peer type resolution: [0]u8 and []const u8" { | |
| 150 | expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | |
| 151 | expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | |
| 152 | comptime { | |
| 153 | expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | |
| 154 | expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | |
| 155 | } | |
| 156 | } | |
| 157 | fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { | |
| 158 | if (a) { | |
| 159 | return &[_]u8{}; | |
| 160 | } | |
| 161 | ||
| 162 | return slice[0..1]; | |
| 163 | } | |
| 164 | ||
| 165 | test "implicitly cast from [N]T to ?[]const T" { | |
| 166 | expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | |
| 167 | comptime expect(mem.eql(u8, castToOptionalSlice().?, "hi")); | |
| 168 | } | |
| 169 | ||
| 170 | fn castToOptionalSlice() ?[]const u8 { | |
| 171 | return "hi"; | |
| 172 | } | |
| 173 | ||
| 174 | test "implicitly cast from [0]T to anyerror![]T" { | |
| 175 | testCastZeroArrayToErrSliceMut(); | |
| 176 | comptime testCastZeroArrayToErrSliceMut(); | |
| 177 | } | |
| 178 | ||
| 179 | fn testCastZeroArrayToErrSliceMut() void { | |
| 180 | expect((gimmeErrOrSlice() catch unreachable).len == 0); | |
| 181 | } | |
| 182 | ||
| 183 | fn gimmeErrOrSlice() anyerror![]u8 { | |
| 184 | return &[_]u8{}; | |
| 185 | } | |
| 186 | ||
| 187 | test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { | |
| 188 | const S = struct { | |
| 189 | fn doTheTest() anyerror!void { | |
| 190 | { | |
| 191 | var data = "hi".*; | |
| 192 | const slice = data[0..]; | |
| 193 | expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); | |
| 194 | expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); | |
| 195 | } | |
| 196 | { | |
| 197 | var data: [2]u8 = "hi".*; | |
| 198 | const slice = data[0..]; | |
| 199 | expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); | |
| 200 | expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); | |
| 201 | } | |
| 202 | } | |
| 203 | }; | |
| 204 | try S.doTheTest(); | |
| 205 | try comptime S.doTheTest(); | |
| 206 | } | |
| 207 | fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { | |
| 208 | if (a) { | |
| 209 | return &[_]u8{}; | |
| 210 | } | |
| 211 | ||
| 212 | return slice[0..1]; | |
| 213 | } | |
| 214 | ||
| 215 | test "resolve undefined with integer" { | |
| 216 | testResolveUndefWithInt(true, 1234); | |
| 217 | comptime testResolveUndefWithInt(true, 1234); | |
| 218 | } | |
| 219 | fn testResolveUndefWithInt(b: bool, x: i32) void { | |
| 220 | const value = if (b) x else undefined; | |
| 221 | if (b) { | |
| 222 | expect(value == x); | |
| 223 | } | |
| 224 | } | |
| 225 | ||
| 226 | test "implicit cast from &const [N]T to []const T" { | |
| 227 | testCastConstArrayRefToConstSlice(); | |
| 228 | comptime testCastConstArrayRefToConstSlice(); | |
| 229 | } | |
| 230 | ||
| 231 | fn testCastConstArrayRefToConstSlice() void { | |
| 232 | { | |
| 233 | const blah = "aoeu".*; | |
| 234 | const const_array_ref = &blah; | |
| 235 | expect(@TypeOf(const_array_ref) == *const [4:0]u8); | |
| 236 | const slice: []const u8 = const_array_ref; | |
| 237 | expect(mem.eql(u8, slice, "aoeu")); | |
| 238 | } | |
| 239 | { | |
| 240 | const blah: [4]u8 = "aoeu".*; | |
| 241 | const const_array_ref = &blah; | |
| 242 | expect(@TypeOf(const_array_ref) == *const [4]u8); | |
| 243 | const slice: []const u8 = const_array_ref; | |
| 244 | expect(mem.eql(u8, slice, "aoeu")); | |
| 245 | } | |
| 246 | } | |
| 247 | ||
| 248 | test "peer type resolution: error and [N]T" { | |
| 249 | expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); | |
| 250 | comptime expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); | |
| 251 | expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); | |
| 252 | comptime expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); | |
| 253 | } | |
| 254 | ||
| 255 | fn testPeerErrorAndArray(x: u8) anyerror![]const u8 { | |
| 256 | return switch (x) { | |
| 257 | 0x00 => "OK", | |
| 258 | else => error.BadValue, | |
| 259 | }; | |
| 260 | } | |
| 261 | fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { | |
| 262 | return switch (x) { | |
| 263 | 0x00 => "OK", | |
| 264 | 0x01 => "OKK", | |
| 265 | else => error.BadValue, | |
| 266 | }; | |
| 267 | } | |
| 268 | ||
| 269 | test "@floatToInt" { | |
| 270 | testFloatToInts(); | |
| 271 | comptime testFloatToInts(); | |
| 272 | } | |
| 273 | ||
| 274 | fn testFloatToInts() void { | |
| 275 | const x = @as(i32, 1e4); | |
| 276 | expect(x == 10000); | |
| 277 | const y = @floatToInt(i32, @as(f32, 1e4)); | |
| 278 | expect(y == 10000); | |
| 279 | expectFloatToInt(f16, 255.1, u8, 255); | |
| 280 | expectFloatToInt(f16, 127.2, i8, 127); | |
| 281 | expectFloatToInt(f16, -128.2, i8, -128); | |
| 282 | expectFloatToInt(f32, 255.1, u8, 255); | |
| 283 | expectFloatToInt(f32, 127.2, i8, 127); | |
| 284 | expectFloatToInt(f32, -128.2, i8, -128); | |
| 285 | expectFloatToInt(comptime_int, 1234, i16, 1234); | |
| 286 | } | |
| 287 | ||
| 288 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void { | |
| 289 | expect(@floatToInt(I, f) == i); | |
| 290 | } | |
| 291 | ||
| 292 | test "cast u128 to f128 and back" { | |
| 293 | comptime testCast128(); | |
| 294 | testCast128(); | |
| 295 | } | |
| 296 | ||
| 297 | fn testCast128() void { | |
| 298 | expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000); | |
| 299 | } | |
| 300 | ||
| 301 | fn cast128Int(x: f128) u128 { | |
| 302 | return @bitCast(u128, x); | |
| 303 | } | |
| 304 | ||
| 305 | fn cast128Float(x: u128) f128 { | |
| 306 | return @bitCast(f128, x); | |
| 307 | } | |
| 308 | ||
| 309 | test "single-item pointer of array to slice and to unknown length pointer" { | |
| 310 | testCastPtrOfArrayToSliceAndPtr(); | |
| 311 | comptime testCastPtrOfArrayToSliceAndPtr(); | |
| 312 | } | |
| 313 | ||
| 314 | fn testCastPtrOfArrayToSliceAndPtr() void { | |
| 315 | { | |
| 316 | var array = "aoeu".*; | |
| 317 | const x: [*]u8 = &array; | |
| 318 | x[0] += 1; | |
| 319 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 320 | const y: []u8 = &array; | |
| 321 | y[0] += 1; | |
| 322 | expect(mem.eql(u8, array[0..], "coeu")); | |
| 323 | } | |
| 324 | { | |
| 325 | var array: [4]u8 = "aoeu".*; | |
| 326 | const x: [*]u8 = &array; | |
| 327 | x[0] += 1; | |
| 328 | expect(mem.eql(u8, array[0..], "boeu")); | |
| 329 | const y: []u8 = &array; | |
| 330 | y[0] += 1; | |
| 331 | expect(mem.eql(u8, array[0..], "coeu")); | |
| 332 | } | |
| 333 | } | |
| 334 | ||
| 335 | test "cast *[1][*]const u8 to [*]const ?[*]const u8" { | |
| 336 | const window_name = [1][*]const u8{"window name"}; | |
| 337 | const x: [*]const ?[*]const u8 = &window_name; | |
| 338 | expect(mem.eql(u8, std.mem.spanZ(@ptrCast([*:0]const u8, x[0].?)), "window name")); | |
| 339 | } | |
| 340 | ||
| 341 | test "@intCast comptime_int" { | |
| 342 | const result = @intCast(i32, 1234); | |
| 343 | expect(@TypeOf(result) == i32); | |
| 344 | expect(result == 1234); | |
| 345 | } | |
| 346 | ||
| 347 | test "@floatCast comptime_int and comptime_float" { | |
| 348 | { | |
| 349 | const result = @floatCast(f16, 1234); | |
| 350 | expect(@TypeOf(result) == f16); | |
| 351 | expect(result == 1234.0); | |
| 352 | } | |
| 353 | { | |
| 354 | const result = @floatCast(f16, 1234.0); | |
| 355 | expect(@TypeOf(result) == f16); | |
| 356 | expect(result == 1234.0); | |
| 357 | } | |
| 358 | { | |
| 359 | const result = @floatCast(f32, 1234); | |
| 360 | expect(@TypeOf(result) == f32); | |
| 361 | expect(result == 1234.0); | |
| 362 | } | |
| 363 | { | |
| 364 | const result = @floatCast(f32, 1234.0); | |
| 365 | expect(@TypeOf(result) == f32); | |
| 366 | expect(result == 1234.0); | |
| 367 | } | |
| 368 | } | |
| 369 | ||
| 370 | test "vector casts" { | |
| 371 | const S = struct { | |
| 372 | fn doTheTest() void { | |
| 373 | // Upcast (implicit, equivalent to @intCast) | |
| 374 | var up0: Vector(2, u8) = [_]u8{ 0x55, 0xaa }; | |
| 375 | var up1 = @as(Vector(2, u16), up0); | |
| 376 | var up2 = @as(Vector(2, u32), up0); | |
| 377 | var up3 = @as(Vector(2, u64), up0); | |
| 378 | // Downcast (safety-checked) | |
| 379 | var down0 = up3; | |
| 380 | var down1 = @intCast(Vector(2, u32), down0); | |
| 381 | var down2 = @intCast(Vector(2, u16), down0); | |
| 382 | var down3 = @intCast(Vector(2, u8), down0); | |
| 383 | ||
| 384 | expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa })); | |
| 385 | expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa })); | |
| 386 | expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa })); | |
| 387 | ||
| 388 | expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa })); | |
| 389 | expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa })); | |
| 390 | expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa })); | |
| 391 | } | |
| 392 | ||
| 393 | fn doTheTestFloat() void { | |
| 394 | var vec = @splat(2, @as(f32, 1234.0)); | |
| 395 | var wider: Vector(2, f64) = vec; | |
| 396 | expect(wider[0] == 1234.0); | |
| 397 | expect(wider[1] == 1234.0); | |
| 398 | } | |
| 399 | }; | |
| 400 | ||
| 401 | S.doTheTest(); | |
| 402 | comptime S.doTheTest(); | |
| 403 | S.doTheTestFloat(); | |
| 404 | comptime S.doTheTestFloat(); | |
| 405 | } | |
| 406 | ||
| 407 | test "comptime_int @intToFloat" { | |
| 408 | { | |
| 409 | const result = @intToFloat(f16, 1234); | |
| 410 | expect(@TypeOf(result) == f16); | |
| 411 | expect(result == 1234.0); | |
| 412 | } | |
| 413 | { | |
| 414 | const result = @intToFloat(f32, 1234); | |
| 415 | expect(@TypeOf(result) == f32); | |
| 416 | expect(result == 1234.0); | |
| 417 | } | |
| 418 | { | |
| 419 | const result = @intToFloat(f64, 1234); | |
| 420 | expect(@TypeOf(result) == f64); | |
| 421 | expect(result == 1234.0); | |
| 422 | } | |
| 423 | { | |
| 424 | const result = @intToFloat(f128, 1234); | |
| 425 | expect(@TypeOf(result) == f128); | |
| 426 | expect(result == 1234.0); | |
| 427 | } | |
| 428 | // big comptime_int (> 64 bits) to f128 conversion | |
| 429 | { | |
| 430 | const result = @intToFloat(f128, 0x1_0000_0000_0000_0000); | |
| 431 | expect(@TypeOf(result) == f128); | |
| 432 | expect(result == 0x1_0000_0000_0000_0000.0); | |
| 433 | } | |
| 434 | } | |
| 435 | ||
| 436 | test "@intCast i32 to u7" { | |
| 437 | var x: u128 = maxInt(u128); | |
| 438 | var y: i32 = 120; | |
| 439 | var z = x >> @intCast(u7, y); | |
| 440 | expect(z == 0xff); | |
| 441 | } | |
| 442 | ||
| 443 | test "@floatCast cast down" { | |
| 444 | { | |
| 445 | var double: f64 = 0.001534; | |
| 446 | var single = @floatCast(f32, double); | |
| 447 | expect(single == 0.001534); | |
| 448 | } | |
| 449 | { | |
| 450 | const double: f64 = 0.001534; | |
| 451 | const single = @floatCast(f32, double); | |
| 452 | expect(single == 0.001534); | |
| 453 | } | |
| 454 | } | |
| 455 | ||
| 456 | test "implicit cast undefined to optional" { | |
| 457 | expect(MakeType(void).getNull() == null); | |
| 458 | expect(MakeType(void).getNonNull() != null); | |
| 459 | } | |
| 460 | ||
| 461 | fn MakeType(comptime T: type) type { | |
| 462 | return struct { | |
| 463 | fn getNull() ?T { | |
| 464 | return null; | |
| 465 | } | |
| 466 | ||
| 467 | fn getNonNull() ?T { | |
| 468 | return @as(T, undefined); | |
| 469 | } | |
| 470 | }; | |
| 471 | } | |
| 472 | ||
| 473 | test "implicit cast from *[N]T to ?[*]T" { | |
| 474 | var x: ?[*]u16 = null; | |
| 475 | var y: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | |
| 476 | ||
| 477 | x = &y; | |
| 478 | expect(std.mem.eql(u16, x.?[0..4], y[0..4])); | |
| 479 | x.?[0] = 8; | |
| 480 | y[3] = 6; | |
| 481 | expect(std.mem.eql(u16, x.?[0..4], y[0..4])); | |
| 482 | } | |
| 483 | ||
| 484 | test "implicit cast from *[N]T to [*c]T" { | |
| 485 | var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | |
| 486 | var y: [*c]u16 = &x; | |
| 487 | ||
| 488 | expect(std.mem.eql(u16, x[0..4], y[0..4])); | |
| 489 | x[0] = 8; | |
| 490 | y[3] = 6; | |
| 491 | expect(std.mem.eql(u16, x[0..4], y[0..4])); | |
| 492 | } | |
| 493 | ||
| 494 | test "implicit cast from *T to ?*c_void" { | |
| 495 | var a: u8 = 1; | |
| 496 | incrementVoidPtrValue(&a); | |
| 497 | std.testing.expect(a == 2); | |
| 498 | } | |
| 499 | ||
| 500 | fn incrementVoidPtrValue(value: ?*c_void) void { | |
| 501 | @ptrCast(*u8, value.?).* += 1; | |
| 502 | } | |
| 503 | ||
| 504 | test "implicit cast from [*]T to ?*c_void" { | |
| 505 | var a = [_]u8{ 3, 2, 1 }; | |
| 506 | var runtime_zero: usize = 0; | |
| 507 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); | |
| 508 | expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); | |
| 509 | } | |
| 510 | ||
| 511 | fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { | |
| 512 | var n: usize = 0; | |
| 513 | while (n < len) : (n += 1) { | |
| 514 | @ptrCast([*]u8, array.?)[n] += 1; | |
| 515 | } | |
| 516 | } | |
| 517 | ||
| 518 | test "*usize to *void" { | |
| 519 | var i = @as(usize, 0); | |
| 520 | var v = @ptrCast(*void, &i); | |
| 521 | v.* = {}; | |
| 522 | } | |
| 523 | ||
| 524 | test "compile time int to ptr of function" { | |
| 525 | foobar(FUNCTION_CONSTANT); | |
| 526 | } | |
| 527 | ||
| 528 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | |
| 529 | pub const PFN_void = fn (*c_void) callconv(.C) void; | |
| 530 | ||
| 531 | fn foobar(func: PFN_void) void { | |
| 532 | std.testing.expect(@ptrToInt(func) == maxInt(usize)); | |
| 533 | } | |
| 534 | ||
| 535 | test "implicit ptr to *c_void" { | |
| 536 | var a: u32 = 1; | |
| 537 | var ptr: *align(@alignOf(u32)) c_void = &a; | |
| 538 | var b: *u32 = @ptrCast(*u32, ptr); | |
| 539 | expect(b.* == 1); | |
| 540 | var ptr2: ?*align(@alignOf(u32)) c_void = &a; | |
| 541 | var c: *u32 = @ptrCast(*u32, ptr2.?); | |
| 542 | expect(c.* == 1); | |
| 543 | } | |
| 544 | ||
| 545 | test "@intCast to comptime_int" { | |
| 546 | expect(@intCast(comptime_int, 0) == 0); | |
| 547 | } | |
| 548 | ||
| 549 | test "implicit cast comptime numbers to any type when the value fits" { | |
| 550 | const a: u64 = 255; | |
| 551 | var b: u8 = a; | |
| 552 | expect(b == 255); | |
| 553 | } | |
| 554 | ||
| 555 | test "@intToEnum passed a comptime_int to an enum with one item" { | |
| 556 | const E = enum { | |
| 557 | A, | |
| 558 | }; | |
| 559 | const x = @intToEnum(E, 0); | |
| 560 | expect(x == E.A); | |
| 561 | } | |
| 562 | ||
| 563 | test "@intToEnum runtime to an extern enum with duplicate values" { | |
| 564 | const E = extern enum(u8) { | |
| 565 | A = 1, | |
| 566 | B = 1, | |
| 567 | }; | |
| 568 | var a: u8 = 1; | |
| 569 | var x = @intToEnum(E, a); | |
| 570 | expect(x == E.A); | |
| 571 | expect(x == E.B); | |
| 572 | } | |
| 573 | ||
| 574 | test "@intCast to u0 and use the result" { | |
| 575 | const S = struct { | |
| 576 | fn doTheTest(zero: u1, one: u1, bigzero: i32) void { | |
| 577 | expect((one << @intCast(u0, bigzero)) == 1); | |
| 578 | expect((zero << @intCast(u0, bigzero)) == 0); | |
| 579 | } | |
| 580 | }; | |
| 581 | S.doTheTest(0, 1, 0); | |
| 582 | comptime S.doTheTest(0, 1, 0); | |
| 583 | } | |
| 584 | ||
| 585 | test "peer type resolution: unreachable, null, slice" { | |
| 586 | const S = struct { | |
| 587 | fn doTheTest(num: usize, word: []const u8) void { | |
| 588 | const result = switch (num) { | |
| 589 | 0 => null, | |
| 590 | 1 => word, | |
| 591 | else => unreachable, | |
| 592 | }; | |
| 593 | expect(mem.eql(u8, result.?, "hi")); | |
| 594 | } | |
| 595 | }; | |
| 596 | S.doTheTest(1, "hi"); | |
| 597 | } | |
| 598 | ||
| 599 | test "peer type resolution: unreachable, error set, unreachable" { | |
| 600 | const Error = error{ | |
| 601 | FileDescriptorAlreadyPresentInSet, | |
| 602 | OperationCausesCircularLoop, | |
| 603 | FileDescriptorNotRegistered, | |
| 604 | SystemResources, | |
| 605 | UserResourceLimitReached, | |
| 606 | FileDescriptorIncompatibleWithEpoll, | |
| 607 | Unexpected, | |
| 608 | }; | |
| 609 | var err = Error.SystemResources; | |
| 610 | const transformed_err = switch (err) { | |
| 611 | error.FileDescriptorAlreadyPresentInSet => unreachable, | |
| 612 | error.OperationCausesCircularLoop => unreachable, | |
| 613 | error.FileDescriptorNotRegistered => unreachable, | |
| 614 | error.SystemResources => error.SystemResources, | |
| 615 | error.UserResourceLimitReached => error.UserResourceLimitReached, | |
| 616 | error.FileDescriptorIncompatibleWithEpoll => unreachable, | |
| 617 | error.Unexpected => unreachable, | |
| 618 | }; | |
| 619 | expect(transformed_err == error.SystemResources); | |
| 620 | } | |
| 621 | ||
| 622 | test "implicit cast comptime_int to comptime_float" { | |
| 623 | comptime expect(@as(comptime_float, 10) == @as(f32, 10)); | |
| 624 | expect(2 == 2.0); | |
| 625 | } | |
| 626 | ||
| 627 | test "implicit cast *[0]T to E![]const u8" { | |
| 628 | var x = @as(anyerror![]const u8, &[0]u8{}); | |
| 629 | expect((x catch unreachable).len == 0); | |
| 630 | } | |
| 631 | ||
| 632 | test "peer cast *[0]T to E![]const T" { | |
| 633 | var buffer: [5]u8 = "abcde".*; | |
| 634 | var buf: anyerror![]const u8 = buffer[0..]; | |
| 635 | var b = false; | |
| 636 | var y = if (b) &[0]u8{} else buf; | |
| 637 | expect(mem.eql(u8, "abcde", y catch unreachable)); | |
| 638 | } | |
| 639 | ||
| 640 | test "peer cast *[0]T to []const T" { | |
| 641 | var buffer: [5]u8 = "abcde".*; | |
| 642 | var buf: []const u8 = buffer[0..]; | |
| 643 | var b = false; | |
| 644 | var y = if (b) &[0]u8{} else buf; | |
| 645 | expect(mem.eql(u8, "abcde", y)); | |
| 646 | } | |
| 647 | ||
| 648 | var global_array: [4]u8 = undefined; | |
| 649 | test "cast from array reference to fn" { | |
| 650 | const f = @ptrCast(fn () callconv(.C) void, &global_array); | |
| 651 | expect(@ptrToInt(f) == @ptrToInt(&global_array)); | |
| 652 | } | |
| 653 | ||
| 654 | test "*const [N]null u8 to ?[]const u8" { | |
| 655 | const S = struct { | |
| 656 | fn doTheTest() void { | |
| 657 | var a = "Hello"; | |
| 658 | var b: ?[]const u8 = a; | |
| 659 | expect(mem.eql(u8, b.?, "Hello")); | |
| 660 | } | |
| 661 | }; | |
| 662 | S.doTheTest(); | |
| 663 | comptime S.doTheTest(); | |
| 664 | } | |
| 665 | ||
| 666 | test "peer resolution of string literals" { | |
| 667 | const S = struct { | |
| 668 | const E = extern enum { | |
| 669 | a, | |
| 670 | b, | |
| 671 | c, | |
| 672 | d, | |
| 673 | }; | |
| 674 | ||
| 675 | fn doTheTest(e: E) void { | |
| 676 | const cmd = switch (e) { | |
| 677 | .a => "one", | |
| 678 | .b => "two", | |
| 679 | .c => "three", | |
| 680 | .d => "four", | |
| 681 | }; | |
| 682 | expect(mem.eql(u8, cmd, "two")); | |
| 683 | } | |
| 684 | }; | |
| 685 | S.doTheTest(.b); | |
| 686 | comptime S.doTheTest(.b); | |
| 687 | } | |
| 688 | ||
| 689 | test "type coercion related to sentinel-termination" { | |
| 690 | const S = struct { | |
| 691 | fn doTheTest() void { | |
| 692 | // [:x]T to []T | |
| 693 | { | |
| 694 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 695 | var slice: [:0]i32 = &array; | |
| 696 | var dest: []i32 = slice; | |
| 697 | expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 698 | } | |
| 699 | ||
| 700 | // [*:x]T to [*]T | |
| 701 | { | |
| 702 | var array = [4:99]i32{ 1, 2, 3, 4 }; | |
| 703 | var dest: [*]i32 = &array; | |
| 704 | expect(dest[0] == 1); | |
| 705 | expect(dest[1] == 2); | |
| 706 | expect(dest[2] == 3); | |
| 707 | expect(dest[3] == 4); | |
| 708 | expect(dest[4] == 99); | |
| 709 | } | |
| 710 | ||
| 711 | // [N:x]T to [N]T | |
| 712 | { | |
| 713 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 714 | var dest: [4]i32 = array; | |
| 715 | expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 716 | } | |
| 717 | ||
| 718 | // *[N:x]T to *[N]T | |
| 719 | { | |
| 720 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 721 | var dest: *[4]i32 = &array; | |
| 722 | expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); | |
| 723 | } | |
| 724 | ||
| 725 | // [:x]T to [*:x]T | |
| 726 | { | |
| 727 | var array = [4:0]i32{ 1, 2, 3, 4 }; | |
| 728 | var slice: [:0]i32 = &array; | |
| 729 | var dest: [*:0]i32 = slice; | |
| 730 | expect(dest[0] == 1); | |
| 731 | expect(dest[1] == 2); | |
| 732 | expect(dest[2] == 3); | |
| 733 | expect(dest[3] == 4); | |
| 734 | expect(dest[4] == 0); | |
| 735 | } | |
| 736 | } | |
| 737 | }; | |
| 738 | S.doTheTest(); | |
| 739 | comptime S.doTheTest(); | |
| 740 | } | |
| 741 | ||
| 742 | test "cast i8 fn call peers to i32 result" { | |
| 743 | const S = struct { | |
| 744 | fn doTheTest() void { | |
| 745 | var cond = true; | |
| 746 | const value: i32 = if (cond) smallBoi() else bigBoi(); | |
| 747 | expect(value == 123); | |
| 748 | } | |
| 749 | fn smallBoi() i8 { | |
| 750 | return 123; | |
| 751 | } | |
| 752 | fn bigBoi() i16 { | |
| 753 | return 1234; | |
| 754 | } | |
| 755 | }; | |
| 756 | S.doTheTest(); | |
| 757 | comptime S.doTheTest(); | |
| 758 | } | |
| 759 | ||
| 760 | test "return u8 coercing into ?u32 return type" { | |
| 761 | const S = struct { | |
| 762 | fn doTheTest() void { | |
| 763 | expect(foo(123).? == 123); | |
| 764 | } | |
| 765 | fn foo(arg: u8) ?u32 { | |
| 766 | return arg; | |
| 767 | } | |
| 768 | }; | |
| 769 | S.doTheTest(); | |
| 770 | comptime S.doTheTest(); | |
| 771 | } | |
| 772 | ||
| 773 | test "peer result null and comptime_int" { | |
| 774 | const S = struct { | |
| 775 | fn blah(n: i32) ?i32 { | |
| 776 | if (n == 0) { | |
| 777 | return null; | |
| 778 | } else if (n < 0) { | |
| 779 | return -1; | |
| 780 | } else { | |
| 781 | return 1; | |
| 782 | } | |
| 783 | } | |
| 784 | }; | |
| 785 | ||
| 786 | expect(S.blah(0) == null); | |
| 787 | comptime expect(S.blah(0) == null); | |
| 788 | expect(S.blah(10).? == 1); | |
| 789 | comptime expect(S.blah(10).? == 1); | |
| 790 | expect(S.blah(-10).? == -1); | |
| 791 | comptime expect(S.blah(-10).? == -1); | |
| 792 | } | |
| 793 | ||
| 794 | test "peer type resolution implicit cast to return type" { | |
| 795 | const S = struct { | |
| 796 | fn doTheTest() void { | |
| 797 | for ("hello") |c| _ = f(c); | |
| 798 | } | |
| 799 | fn f(c: u8) []const u8 { | |
| 800 | return switch (c) { | |
| 801 | 'h', 'e' => &[_]u8{c}, // should cast to slice | |
| 802 | 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice | |
| 803 | else => ([_]u8{c})[0..], // is a slice | |
| 804 | }; | |
| 805 | } | |
| 806 | }; | |
| 807 | S.doTheTest(); | |
| 808 | comptime S.doTheTest(); | |
| 809 | } | |
| 810 | ||
| 811 | test "peer type resolution implicit cast to variable type" { | |
| 812 | const S = struct { | |
| 813 | fn doTheTest() void { | |
| 814 | var x: []const u8 = undefined; | |
| 815 | for ("hello") |c| x = switch (c) { | |
| 816 | 'h', 'e' => &[_]u8{c}, // should cast to slice | |
| 817 | 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice | |
| 818 | else => ([_]u8{c})[0..], // is a slice | |
| 819 | }; | |
| 820 | } | |
| 821 | }; | |
| 822 | S.doTheTest(); | |
| 823 | comptime S.doTheTest(); | |
| 824 | } | |
| 825 | ||
| 826 | test "variable initialization uses result locations properly with regards to the type" { | |
| 827 | var b = true; | |
| 828 | const x: i32 = if (b) 1 else 2; | |
| 829 | expect(x == 1); | |
| 830 | } | |
| 831 | ||
| 832 | test "cast between [*c]T and ?[*:0]T on fn parameter" { | |
| 833 | const S = struct { | |
| 834 | const Handler = ?fn ([*c]const u8) callconv(.C) void; | |
| 835 | fn addCallback(handler: Handler) void {} | |
| 836 | ||
| 837 | fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {} | |
| 838 | ||
| 839 | fn doTheTest() void { | |
| 840 | addCallback(myCallback); | |
| 841 | } | |
| 842 | }; | |
| 843 | S.doTheTest(); | |
| 844 | } | |
| 845 | ||
| 846 | test "cast between C pointer with different but compatible types" { | |
| 847 | const S = struct { | |
| 848 | fn foo(arg: [*]c_ushort) u16 { | |
| 849 | return arg[0]; | |
| 850 | } | |
| 851 | fn doTheTest() void { | |
| 852 | var x = [_]u16{ 4, 2, 1, 3 }; | |
| 853 | expect(foo(@ptrCast([*]u16, &x)) == 4); | |
| 854 | } | |
| 855 | }; | |
| 856 | S.doTheTest(); | |
| 857 | } | |
| 858 | ||
| 859 | var global_struct: struct { f0: usize } = undefined; | |
| 860 | ||
| 861 | test "assignment to optional pointer result loc" { | |
| 862 | var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct }; | |
| 863 | expect(foo.ptr.? == @ptrCast(*c_void, &global_struct)); | |
| 864 | } | |
| 865 | ||
| 866 | test "peer type resolve string lit with sentinel-terminated mutable slice" { | |
| 867 | var array: [4:0]u8 = undefined; | |
| 868 | array[4] = 0; // TODO remove this when #4372 is solved | |
| 869 | var slice: [:0]u8 = array[0..4 :0]; | |
| 870 | comptime expect(@TypeOf(slice, "hi") == [:0]const u8); | |
| 871 | comptime expect(@TypeOf("hi", slice) == [:0]const u8); | |
| 872 | } | |
| 873 | ||
| 874 | test "peer type unsigned int to signed" { | |
| 875 | var w: u31 = 5; | |
| 876 | var x: u8 = 7; | |
| 877 | var y: i32 = -5; | |
| 878 | var a = w + y + x; | |
| 879 | comptime expect(@TypeOf(a) == i32); | |
| 880 | expect(a == 7); | |
| 881 | } | |
| 882 | ||
| 883 | test "peer type resolve array pointers, one of them const" { | |
| 884 | var array1: [4]u8 = undefined; | |
| 885 | const array2: [5]u8 = undefined; | |
| 886 | comptime expect(@TypeOf(&array1, &array2) == []const u8); | |
| 887 | comptime expect(@TypeOf(&array2, &array1) == []const u8); | |
| 888 | } | |
| 889 | ||
| 890 | test "peer type resolve array pointer and unknown pointer" { | |
| 891 | const const_array: [4]u8 = undefined; | |
| 892 | var array: [4]u8 = undefined; | |
| 893 | var const_ptr: [*]const u8 = undefined; | |
| 894 | var ptr: [*]u8 = undefined; | |
| 895 | ||
| 896 | comptime expect(@TypeOf(&array, ptr) == [*]u8); | |
| 897 | comptime expect(@TypeOf(ptr, &array) == [*]u8); | |
| 898 | ||
| 899 | comptime expect(@TypeOf(&const_array, ptr) == [*]const u8); | |
| 900 | comptime expect(@TypeOf(ptr, &const_array) == [*]const u8); | |
| 901 | ||
| 902 | comptime expect(@TypeOf(&array, const_ptr) == [*]const u8); | |
| 903 | comptime expect(@TypeOf(const_ptr, &array) == [*]const u8); | |
| 904 | ||
| 905 | comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8); | |
| 906 | comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8); | |
| 907 | } | |
| 908 | ||
| 909 | test "comptime float casts" { | |
| 910 | const a = @intToFloat(comptime_float, 1); | |
| 911 | expect(a == 1); | |
| 912 | expect(@TypeOf(a) == comptime_float); | |
| 913 | const b = @floatToInt(comptime_int, 2); | |
| 914 | expect(b == 2); | |
| 915 | expect(@TypeOf(b) == comptime_int); | |
| 916 | } | |
| 917 | ||
| 918 | test "cast from ?[*]T to ??[*]T" { | |
| 919 | const a: ??[*]u8 = @as(?[*]u8, null); | |
| 920 | expect(a != null and a.? == null); | |
| 921 | } | |
| 922 | ||
| 923 | test "cast between *[N]void and []void" { | |
| 924 | var a: [4]void = undefined; | |
| 925 | var b: []void = &a; | |
| 926 | expect(b.len == 4); | |
| 927 | } |
test/stage1/behavior/const_slice_child.zig deleted-47| ... | ... | @@ -1,47 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const debug = std.debug; | |
| 3 | const testing = std.testing; | |
| 4 | const expect = testing.expect; | |
| 5 | ||
| 6 | var argv: [*]const [*]const u8 = undefined; | |
| 7 | ||
| 8 | test "const slice child" { | |
| 9 | const strs = [_][*]const u8{ | |
| 10 | "one", | |
| 11 | "two", | |
| 12 | "three", | |
| 13 | }; | |
| 14 | argv = &strs; | |
| 15 | bar(strs.len); | |
| 16 | } | |
| 17 | ||
| 18 | fn foo(args: [][]const u8) void { | |
| 19 | expect(args.len == 3); | |
| 20 | expect(streql(args[0], "one")); | |
| 21 | expect(streql(args[1], "two")); | |
| 22 | expect(streql(args[2], "three")); | |
| 23 | } | |
| 24 | ||
| 25 | fn bar(argc: usize) void { | |
| 26 | const args = testing.allocator.alloc([]const u8, argc) catch unreachable; | |
| 27 | defer testing.allocator.free(args); | |
| 28 | for (args) |_, i| { | |
| 29 | const ptr = argv[i]; | |
| 30 | args[i] = ptr[0..strlen(ptr)]; | |
| 31 | } | |
| 32 | foo(args); | |
| 33 | } | |
| 34 | ||
| 35 | fn strlen(ptr: [*]const u8) usize { | |
| 36 | var count: usize = 0; | |
| 37 | while (ptr[count] != 0) : (count += 1) {} | |
| 38 | return count; | |
| 39 | } | |
| 40 | ||
| 41 | fn streql(a: []const u8, b: []const u8) bool { | |
| 42 | if (a.len != b.len) return false; | |
| 43 | for (a) |item, index| { | |
| 44 | if (b[index] != item) return false; | |
| 45 | } | |
| 46 | return true; | |
| 47 | } |
test/stage1/behavior/defer.zig deleted-114| ... | ... | @@ -1,114 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const expectError = std.testing.expectError; | |
| 5 | ||
| 6 | var result: [3]u8 = undefined; | |
| 7 | var index: usize = undefined; | |
| 8 | ||
| 9 | fn runSomeErrorDefers(x: bool) !bool { | |
| 10 | index = 0; | |
| 11 | defer { | |
| 12 | result[index] = 'a'; | |
| 13 | index += 1; | |
| 14 | } | |
| 15 | errdefer { | |
| 16 | result[index] = 'b'; | |
| 17 | index += 1; | |
| 18 | } | |
| 19 | defer { | |
| 20 | result[index] = 'c'; | |
| 21 | index += 1; | |
| 22 | } | |
| 23 | return if (x) x else error.FalseNotAllowed; | |
| 24 | } | |
| 25 | ||
| 26 | test "mixing normal and error defers" { | |
| 27 | expect(runSomeErrorDefers(true) catch unreachable); | |
| 28 | expect(result[0] == 'c'); | |
| 29 | expect(result[1] == 'a'); | |
| 30 | ||
| 31 | const ok = runSomeErrorDefers(false) catch |err| x: { | |
| 32 | expect(err == error.FalseNotAllowed); | |
| 33 | break :x true; | |
| 34 | }; | |
| 35 | expect(ok); | |
| 36 | expect(result[0] == 'c'); | |
| 37 | expect(result[1] == 'b'); | |
| 38 | expect(result[2] == 'a'); | |
| 39 | } | |
| 40 | ||
| 41 | test "break and continue inside loop inside defer expression" { | |
| 42 | testBreakContInDefer(10); | |
| 43 | comptime testBreakContInDefer(10); | |
| 44 | } | |
| 45 | ||
| 46 | fn testBreakContInDefer(x: usize) void { | |
| 47 | defer { | |
| 48 | var i: usize = 0; | |
| 49 | while (i < x) : (i += 1) { | |
| 50 | if (i < 5) continue; | |
| 51 | if (i == 5) break; | |
| 52 | } | |
| 53 | expect(i == 5); | |
| 54 | } | |
| 55 | } | |
| 56 | ||
| 57 | test "defer and labeled break" { | |
| 58 | var i = @as(usize, 0); | |
| 59 | ||
| 60 | blk: { | |
| 61 | defer i += 1; | |
| 62 | break :blk; | |
| 63 | } | |
| 64 | ||
| 65 | expect(i == 1); | |
| 66 | } | |
| 67 | ||
| 68 | test "errdefer does not apply to fn inside fn" { | |
| 69 | if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| expect(e == error.Bad); | |
| 70 | } | |
| 71 | ||
| 72 | fn testNestedFnErrDefer() anyerror!void { | |
| 73 | var a: i32 = 0; | |
| 74 | errdefer a += 1; | |
| 75 | const S = struct { | |
| 76 | fn baz() anyerror { | |
| 77 | return error.Bad; | |
| 78 | } | |
| 79 | }; | |
| 80 | return S.baz(); | |
| 81 | } | |
| 82 | ||
| 83 | test "return variable while defer expression in scope to modify it" { | |
| 84 | const S = struct { | |
| 85 | fn doTheTest() void { | |
| 86 | expect(notNull().? == 1); | |
| 87 | } | |
| 88 | ||
| 89 | fn notNull() ?u8 { | |
| 90 | var res: ?u8 = 1; | |
| 91 | defer res = null; | |
| 92 | return res; | |
| 93 | } | |
| 94 | }; | |
| 95 | ||
| 96 | S.doTheTest(); | |
| 97 | comptime S.doTheTest(); | |
| 98 | } | |
| 99 | ||
| 100 | test "errdefer with payload" { | |
| 101 | const S = struct { | |
| 102 | fn foo() !i32 { | |
| 103 | errdefer |a| { | |
| 104 | expectEqual(error.One, a); | |
| 105 | } | |
| 106 | return error.One; | |
| 107 | } | |
| 108 | fn doTheTest() void { | |
| 109 | expectError(error.One, foo()); | |
| 110 | } | |
| 111 | }; | |
| 112 | S.doTheTest(); | |
| 113 | comptime S.doTheTest(); | |
| 114 | } |
test/stage1/behavior/enum.zig deleted-1204| ... | ... | @@ -1,1204 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const Tag = @import("std").meta.Tag; | |
| 4 | ||
| 5 | test "extern enum" { | |
| 6 | const S = struct { | |
| 7 | const i = extern enum { | |
| 8 | n = 0, | |
| 9 | o = 2, | |
| 10 | p = 4, | |
| 11 | q = 4, | |
| 12 | }; | |
| 13 | fn doTheTest(y: c_int) void { | |
| 14 | var x = i.o; | |
| 15 | switch (x) { | |
| 16 | .n, .p => unreachable, | |
| 17 | .o => {}, | |
| 18 | } | |
| 19 | } | |
| 20 | }; | |
| 21 | S.doTheTest(52); | |
| 22 | comptime S.doTheTest(52); | |
| 23 | } | |
| 24 | ||
| 25 | test "non-exhaustive enum" { | |
| 26 | const S = struct { | |
| 27 | const E = enum(u8) { | |
| 28 | a, | |
| 29 | b, | |
| 30 | _, | |
| 31 | }; | |
| 32 | fn doTheTest(y: u8) void { | |
| 33 | var e: E = .b; | |
| 34 | expect(switch (e) { | |
| 35 | .a => false, | |
| 36 | .b => true, | |
| 37 | _ => false, | |
| 38 | }); | |
| 39 | e = @intToEnum(E, 12); | |
| 40 | expect(switch (e) { | |
| 41 | .a => false, | |
| 42 | .b => false, | |
| 43 | _ => true, | |
| 44 | }); | |
| 45 | ||
| 46 | expect(switch (e) { | |
| 47 | .a => false, | |
| 48 | .b => false, | |
| 49 | else => true, | |
| 50 | }); | |
| 51 | e = .b; | |
| 52 | expect(switch (e) { | |
| 53 | .a => false, | |
| 54 | else => true, | |
| 55 | }); | |
| 56 | ||
| 57 | expect(@typeInfo(E).Enum.fields.len == 2); | |
| 58 | e = @intToEnum(E, 12); | |
| 59 | expect(@enumToInt(e) == 12); | |
| 60 | e = @intToEnum(E, y); | |
| 61 | expect(@enumToInt(e) == 52); | |
| 62 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 63 | } | |
| 64 | }; | |
| 65 | S.doTheTest(52); | |
| 66 | comptime S.doTheTest(52); | |
| 67 | } | |
| 68 | ||
| 69 | test "empty non-exhaustive enum" { | |
| 70 | const S = struct { | |
| 71 | const E = enum(u8) { | |
| 72 | _, | |
| 73 | }; | |
| 74 | fn doTheTest(y: u8) void { | |
| 75 | var e = @intToEnum(E, y); | |
| 76 | expect(switch (e) { | |
| 77 | _ => true, | |
| 78 | }); | |
| 79 | expect(@enumToInt(e) == y); | |
| 80 | ||
| 81 | expect(@typeInfo(E).Enum.fields.len == 0); | |
| 82 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 83 | } | |
| 84 | }; | |
| 85 | S.doTheTest(42); | |
| 86 | comptime S.doTheTest(42); | |
| 87 | } | |
| 88 | ||
| 89 | test "single field non-exhaustive enum" { | |
| 90 | const S = struct { | |
| 91 | const E = enum(u8) { | |
| 92 | a, | |
| 93 | _, | |
| 94 | }; | |
| 95 | fn doTheTest(y: u8) void { | |
| 96 | var e: E = .a; | |
| 97 | expect(switch (e) { | |
| 98 | .a => true, | |
| 99 | _ => false, | |
| 100 | }); | |
| 101 | e = @intToEnum(E, 12); | |
| 102 | expect(switch (e) { | |
| 103 | .a => false, | |
| 104 | _ => true, | |
| 105 | }); | |
| 106 | ||
| 107 | expect(switch (e) { | |
| 108 | .a => false, | |
| 109 | else => true, | |
| 110 | }); | |
| 111 | e = .a; | |
| 112 | expect(switch (e) { | |
| 113 | .a => true, | |
| 114 | else => false, | |
| 115 | }); | |
| 116 | ||
| 117 | expect(@enumToInt(@intToEnum(E, y)) == y); | |
| 118 | expect(@typeInfo(E).Enum.fields.len == 1); | |
| 119 | expect(@typeInfo(E).Enum.is_exhaustive == false); | |
| 120 | } | |
| 121 | }; | |
| 122 | S.doTheTest(23); | |
| 123 | comptime S.doTheTest(23); | |
| 124 | } | |
| 125 | ||
| 126 | test "enum type" { | |
| 127 | const foo1 = Foo{ .One = 13 }; | |
| 128 | const foo2 = Foo{ | |
| 129 | .Two = Point{ | |
| 130 | .x = 1234, | |
| 131 | .y = 5678, | |
| 132 | }, | |
| 133 | }; | |
| 134 | const bar = Bar.B; | |
| 135 | ||
| 136 | expect(bar == Bar.B); | |
| 137 | expect(@typeInfo(Foo).Union.fields.len == 3); | |
| 138 | expect(@typeInfo(Bar).Enum.fields.len == 4); | |
| 139 | expect(@sizeOf(Foo) == @sizeOf(FooNoVoid)); | |
| 140 | expect(@sizeOf(Bar) == 1); | |
| 141 | } | |
| 142 | ||
| 143 | test "enum as return value" { | |
| 144 | switch (returnAnInt(13)) { | |
| 145 | Foo.One => |value| expect(value == 13), | |
| 146 | else => unreachable, | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | const Point = struct { | |
| 151 | x: u64, | |
| 152 | y: u64, | |
| 153 | }; | |
| 154 | const Foo = union(enum) { | |
| 155 | One: i32, | |
| 156 | Two: Point, | |
| 157 | Three: void, | |
| 158 | }; | |
| 159 | const FooNoVoid = union(enum) { | |
| 160 | One: i32, | |
| 161 | Two: Point, | |
| 162 | }; | |
| 163 | const Bar = enum { | |
| 164 | A, | |
| 165 | B, | |
| 166 | C, | |
| 167 | D, | |
| 168 | }; | |
| 169 | ||
| 170 | fn returnAnInt(x: i32) Foo { | |
| 171 | return Foo{ .One = x }; | |
| 172 | } | |
| 173 | ||
| 174 | test "constant enum with payload" { | |
| 175 | var empty = AnEnumWithPayload{ .Empty = {} }; | |
| 176 | var full = AnEnumWithPayload{ .Full = 13 }; | |
| 177 | shouldBeEmpty(empty); | |
| 178 | shouldBeNotEmpty(full); | |
| 179 | } | |
| 180 | ||
| 181 | fn shouldBeEmpty(x: AnEnumWithPayload) void { | |
| 182 | switch (x) { | |
| 183 | AnEnumWithPayload.Empty => {}, | |
| 184 | else => unreachable, | |
| 185 | } | |
| 186 | } | |
| 187 | ||
| 188 | fn shouldBeNotEmpty(x: AnEnumWithPayload) void { | |
| 189 | switch (x) { | |
| 190 | AnEnumWithPayload.Empty => unreachable, | |
| 191 | else => {}, | |
| 192 | } | |
| 193 | } | |
| 194 | ||
| 195 | const AnEnumWithPayload = union(enum) { | |
| 196 | Empty: void, | |
| 197 | Full: i32, | |
| 198 | }; | |
| 199 | ||
| 200 | const Number = enum { | |
| 201 | Zero, | |
| 202 | One, | |
| 203 | Two, | |
| 204 | Three, | |
| 205 | Four, | |
| 206 | }; | |
| 207 | ||
| 208 | test "enum to int" { | |
| 209 | shouldEqual(Number.Zero, 0); | |
| 210 | shouldEqual(Number.One, 1); | |
| 211 | shouldEqual(Number.Two, 2); | |
| 212 | shouldEqual(Number.Three, 3); | |
| 213 | shouldEqual(Number.Four, 4); | |
| 214 | } | |
| 215 | ||
| 216 | fn shouldEqual(n: Number, expected: u3) void { | |
| 217 | expect(@enumToInt(n) == expected); | |
| 218 | } | |
| 219 | ||
| 220 | test "int to enum" { | |
| 221 | testIntToEnumEval(3); | |
| 222 | } | |
| 223 | fn testIntToEnumEval(x: i32) void { | |
| 224 | expect(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three); | |
| 225 | } | |
| 226 | const IntToEnumNumber = enum { | |
| 227 | Zero, | |
| 228 | One, | |
| 229 | Two, | |
| 230 | Three, | |
| 231 | Four, | |
| 232 | }; | |
| 233 | ||
| 234 | test "@tagName" { | |
| 235 | expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 236 | comptime expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three")); | |
| 237 | } | |
| 238 | ||
| 239 | test "@tagName extern enum with duplicates" { | |
| 240 | expect(mem.eql(u8, testEnumTagNameBare(ExternDuplicates.B), "A")); | |
| 241 | comptime expect(mem.eql(u8, testEnumTagNameBare(ExternDuplicates.B), "A")); | |
| 242 | } | |
| 243 | ||
| 244 | test "@tagName non-exhaustive enum" { | |
| 245 | expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); | |
| 246 | comptime expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B")); | |
| 247 | } | |
| 248 | ||
| 249 | fn testEnumTagNameBare(n: anytype) []const u8 { | |
| 250 | return @tagName(n); | |
| 251 | } | |
| 252 | ||
| 253 | const BareNumber = enum { | |
| 254 | One, | |
| 255 | Two, | |
| 256 | Three, | |
| 257 | }; | |
| 258 | ||
| 259 | const ExternDuplicates = extern enum(u8) { | |
| 260 | A = 1, | |
| 261 | B = 1, | |
| 262 | }; | |
| 263 | ||
| 264 | const NonExhaustive = enum(u8) { | |
| 265 | A, | |
| 266 | B, | |
| 267 | _, | |
| 268 | }; | |
| 269 | ||
| 270 | test "enum alignment" { | |
| 271 | comptime { | |
| 272 | expect(@alignOf(AlignTestEnum) >= @alignOf([9]u8)); | |
| 273 | expect(@alignOf(AlignTestEnum) >= @alignOf(u64)); | |
| 274 | } | |
| 275 | } | |
| 276 | ||
| 277 | const AlignTestEnum = union(enum) { | |
| 278 | A: [9]u8, | |
| 279 | B: u64, | |
| 280 | }; | |
| 281 | ||
| 282 | const ValueCount1 = enum { | |
| 283 | I0, | |
| 284 | }; | |
| 285 | const ValueCount2 = enum { | |
| 286 | I0, | |
| 287 | I1, | |
| 288 | }; | |
| 289 | const ValueCount256 = enum { | |
| 290 | I0, | |
| 291 | I1, | |
| 292 | I2, | |
| 293 | I3, | |
| 294 | I4, | |
| 295 | I5, | |
| 296 | I6, | |
| 297 | I7, | |
| 298 | I8, | |
| 299 | I9, | |
| 300 | I10, | |
| 301 | I11, | |
| 302 | I12, | |
| 303 | I13, | |
| 304 | I14, | |
| 305 | I15, | |
| 306 | I16, | |
| 307 | I17, | |
| 308 | I18, | |
| 309 | I19, | |
| 310 | I20, | |
| 311 | I21, | |
| 312 | I22, | |
| 313 | I23, | |
| 314 | I24, | |
| 315 | I25, | |
| 316 | I26, | |
| 317 | I27, | |
| 318 | I28, | |
| 319 | I29, | |
| 320 | I30, | |
| 321 | I31, | |
| 322 | I32, | |
| 323 | I33, | |
| 324 | I34, | |
| 325 | I35, | |
| 326 | I36, | |
| 327 | I37, | |
| 328 | I38, | |
| 329 | I39, | |
| 330 | I40, | |
| 331 | I41, | |
| 332 | I42, | |
| 333 | I43, | |
| 334 | I44, | |
| 335 | I45, | |
| 336 | I46, | |
| 337 | I47, | |
| 338 | I48, | |
| 339 | I49, | |
| 340 | I50, | |
| 341 | I51, | |
| 342 | I52, | |
| 343 | I53, | |
| 344 | I54, | |
| 345 | I55, | |
| 346 | I56, | |
| 347 | I57, | |
| 348 | I58, | |
| 349 | I59, | |
| 350 | I60, | |
| 351 | I61, | |
| 352 | I62, | |
| 353 | I63, | |
| 354 | I64, | |
| 355 | I65, | |
| 356 | I66, | |
| 357 | I67, | |
| 358 | I68, | |
| 359 | I69, | |
| 360 | I70, | |
| 361 | I71, | |
| 362 | I72, | |
| 363 | I73, | |
| 364 | I74, | |
| 365 | I75, | |
| 366 | I76, | |
| 367 | I77, | |
| 368 | I78, | |
| 369 | I79, | |
| 370 | I80, | |
| 371 | I81, | |
| 372 | I82, | |
| 373 | I83, | |
| 374 | I84, | |
| 375 | I85, | |
| 376 | I86, | |
| 377 | I87, | |
| 378 | I88, | |
| 379 | I89, | |
| 380 | I90, | |
| 381 | I91, | |
| 382 | I92, | |
| 383 | I93, | |
| 384 | I94, | |
| 385 | I95, | |
| 386 | I96, | |
| 387 | I97, | |
| 388 | I98, | |
| 389 | I99, | |
| 390 | I100, | |
| 391 | I101, | |
| 392 | I102, | |
| 393 | I103, | |
| 394 | I104, | |
| 395 | I105, | |
| 396 | I106, | |
| 397 | I107, | |
| 398 | I108, | |
| 399 | I109, | |
| 400 | I110, | |
| 401 | I111, | |
| 402 | I112, | |
| 403 | I113, | |
| 404 | I114, | |
| 405 | I115, | |
| 406 | I116, | |
| 407 | I117, | |
| 408 | I118, | |
| 409 | I119, | |
| 410 | I120, | |
| 411 | I121, | |
| 412 | I122, | |
| 413 | I123, | |
| 414 | I124, | |
| 415 | I125, | |
| 416 | I126, | |
| 417 | I127, | |
| 418 | I128, | |
| 419 | I129, | |
| 420 | I130, | |
| 421 | I131, | |
| 422 | I132, | |
| 423 | I133, | |
| 424 | I134, | |
| 425 | I135, | |
| 426 | I136, | |
| 427 | I137, | |
| 428 | I138, | |
| 429 | I139, | |
| 430 | I140, | |
| 431 | I141, | |
| 432 | I142, | |
| 433 | I143, | |
| 434 | I144, | |
| 435 | I145, | |
| 436 | I146, | |
| 437 | I147, | |
| 438 | I148, | |
| 439 | I149, | |
| 440 | I150, | |
| 441 | I151, | |
| 442 | I152, | |
| 443 | I153, | |
| 444 | I154, | |
| 445 | I155, | |
| 446 | I156, | |
| 447 | I157, | |
| 448 | I158, | |
| 449 | I159, | |
| 450 | I160, | |
| 451 | I161, | |
| 452 | I162, | |
| 453 | I163, | |
| 454 | I164, | |
| 455 | I165, | |
| 456 | I166, | |
| 457 | I167, | |
| 458 | I168, | |
| 459 | I169, | |
| 460 | I170, | |
| 461 | I171, | |
| 462 | I172, | |
| 463 | I173, | |
| 464 | I174, | |
| 465 | I175, | |
| 466 | I176, | |
| 467 | I177, | |
| 468 | I178, | |
| 469 | I179, | |
| 470 | I180, | |
| 471 | I181, | |
| 472 | I182, | |
| 473 | I183, | |
| 474 | I184, | |
| 475 | I185, | |
| 476 | I186, | |
| 477 | I187, | |
| 478 | I188, | |
| 479 | I189, | |
| 480 | I190, | |
| 481 | I191, | |
| 482 | I192, | |
| 483 | I193, | |
| 484 | I194, | |
| 485 | I195, | |
| 486 | I196, | |
| 487 | I197, | |
| 488 | I198, | |
| 489 | I199, | |
| 490 | I200, | |
| 491 | I201, | |
| 492 | I202, | |
| 493 | I203, | |
| 494 | I204, | |
| 495 | I205, | |
| 496 | I206, | |
| 497 | I207, | |
| 498 | I208, | |
| 499 | I209, | |
| 500 | I210, | |
| 501 | I211, | |
| 502 | I212, | |
| 503 | I213, | |
| 504 | I214, | |
| 505 | I215, | |
| 506 | I216, | |
| 507 | I217, | |
| 508 | I218, | |
| 509 | I219, | |
| 510 | I220, | |
| 511 | I221, | |
| 512 | I222, | |
| 513 | I223, | |
| 514 | I224, | |
| 515 | I225, | |
| 516 | I226, | |
| 517 | I227, | |
| 518 | I228, | |
| 519 | I229, | |
| 520 | I230, | |
| 521 | I231, | |
| 522 | I232, | |
| 523 | I233, | |
| 524 | I234, | |
| 525 | I235, | |
| 526 | I236, | |
| 527 | I237, | |
| 528 | I238, | |
| 529 | I239, | |
| 530 | I240, | |
| 531 | I241, | |
| 532 | I242, | |
| 533 | I243, | |
| 534 | I244, | |
| 535 | I245, | |
| 536 | I246, | |
| 537 | I247, | |
| 538 | I248, | |
| 539 | I249, | |
| 540 | I250, | |
| 541 | I251, | |
| 542 | I252, | |
| 543 | I253, | |
| 544 | I254, | |
| 545 | I255, | |
| 546 | }; | |
| 547 | const ValueCount257 = enum { | |
| 548 | I0, | |
| 549 | I1, | |
| 550 | I2, | |
| 551 | I3, | |
| 552 | I4, | |
| 553 | I5, | |
| 554 | I6, | |
| 555 | I7, | |
| 556 | I8, | |
| 557 | I9, | |
| 558 | I10, | |
| 559 | I11, | |
| 560 | I12, | |
| 561 | I13, | |
| 562 | I14, | |
| 563 | I15, | |
| 564 | I16, | |
| 565 | I17, | |
| 566 | I18, | |
| 567 | I19, | |
| 568 | I20, | |
| 569 | I21, | |
| 570 | I22, | |
| 571 | I23, | |
| 572 | I24, | |
| 573 | I25, | |
| 574 | I26, | |
| 575 | I27, | |
| 576 | I28, | |
| 577 | I29, | |
| 578 | I30, | |
| 579 | I31, | |
| 580 | I32, | |
| 581 | I33, | |
| 582 | I34, | |
| 583 | I35, | |
| 584 | I36, | |
| 585 | I37, | |
| 586 | I38, | |
| 587 | I39, | |
| 588 | I40, | |
| 589 | I41, | |
| 590 | I42, | |
| 591 | I43, | |
| 592 | I44, | |
| 593 | I45, | |
| 594 | I46, | |
| 595 | I47, | |
| 596 | I48, | |
| 597 | I49, | |
| 598 | I50, | |
| 599 | I51, | |
| 600 | I52, | |
| 601 | I53, | |
| 602 | I54, | |
| 603 | I55, | |
| 604 | I56, | |
| 605 | I57, | |
| 606 | I58, | |
| 607 | I59, | |
| 608 | I60, | |
| 609 | I61, | |
| 610 | I62, | |
| 611 | I63, | |
| 612 | I64, | |
| 613 | I65, | |
| 614 | I66, | |
| 615 | I67, | |
| 616 | I68, | |
| 617 | I69, | |
| 618 | I70, | |
| 619 | I71, | |
| 620 | I72, | |
| 621 | I73, | |
| 622 | I74, | |
| 623 | I75, | |
| 624 | I76, | |
| 625 | I77, | |
| 626 | I78, | |
| 627 | I79, | |
| 628 | I80, | |
| 629 | I81, | |
| 630 | I82, | |
| 631 | I83, | |
| 632 | I84, | |
| 633 | I85, | |
| 634 | I86, | |
| 635 | I87, | |
| 636 | I88, | |
| 637 | I89, | |
| 638 | I90, | |
| 639 | I91, | |
| 640 | I92, | |
| 641 | I93, | |
| 642 | I94, | |
| 643 | I95, | |
| 644 | I96, | |
| 645 | I97, | |
| 646 | I98, | |
| 647 | I99, | |
| 648 | I100, | |
| 649 | I101, | |
| 650 | I102, | |
| 651 | I103, | |
| 652 | I104, | |
| 653 | I105, | |
| 654 | I106, | |
| 655 | I107, | |
| 656 | I108, | |
| 657 | I109, | |
| 658 | I110, | |
| 659 | I111, | |
| 660 | I112, | |
| 661 | I113, | |
| 662 | I114, | |
| 663 | I115, | |
| 664 | I116, | |
| 665 | I117, | |
| 666 | I118, | |
| 667 | I119, | |
| 668 | I120, | |
| 669 | I121, | |
| 670 | I122, | |
| 671 | I123, | |
| 672 | I124, | |
| 673 | I125, | |
| 674 | I126, | |
| 675 | I127, | |
| 676 | I128, | |
| 677 | I129, | |
| 678 | I130, | |
| 679 | I131, | |
| 680 | I132, | |
| 681 | I133, | |
| 682 | I134, | |
| 683 | I135, | |
| 684 | I136, | |
| 685 | I137, | |
| 686 | I138, | |
| 687 | I139, | |
| 688 | I140, | |
| 689 | I141, | |
| 690 | I142, | |
| 691 | I143, | |
| 692 | I144, | |
| 693 | I145, | |
| 694 | I146, | |
| 695 | I147, | |
| 696 | I148, | |
| 697 | I149, | |
| 698 | I150, | |
| 699 | I151, | |
| 700 | I152, | |
| 701 | I153, | |
| 702 | I154, | |
| 703 | I155, | |
| 704 | I156, | |
| 705 | I157, | |
| 706 | I158, | |
| 707 | I159, | |
| 708 | I160, | |
| 709 | I161, | |
| 710 | I162, | |
| 711 | I163, | |
| 712 | I164, | |
| 713 | I165, | |
| 714 | I166, | |
| 715 | I167, | |
| 716 | I168, | |
| 717 | I169, | |
| 718 | I170, | |
| 719 | I171, | |
| 720 | I172, | |
| 721 | I173, | |
| 722 | I174, | |
| 723 | I175, | |
| 724 | I176, | |
| 725 | I177, | |
| 726 | I178, | |
| 727 | I179, | |
| 728 | I180, | |
| 729 | I181, | |
| 730 | I182, | |
| 731 | I183, | |
| 732 | I184, | |
| 733 | I185, | |
| 734 | I186, | |
| 735 | I187, | |
| 736 | I188, | |
| 737 | I189, | |
| 738 | I190, | |
| 739 | I191, | |
| 740 | I192, | |
| 741 | I193, | |
| 742 | I194, | |
| 743 | I195, | |
| 744 | I196, | |
| 745 | I197, | |
| 746 | I198, | |
| 747 | I199, | |
| 748 | I200, | |
| 749 | I201, | |
| 750 | I202, | |
| 751 | I203, | |
| 752 | I204, | |
| 753 | I205, | |
| 754 | I206, | |
| 755 | I207, | |
| 756 | I208, | |
| 757 | I209, | |
| 758 | I210, | |
| 759 | I211, | |
| 760 | I212, | |
| 761 | I213, | |
| 762 | I214, | |
| 763 | I215, | |
| 764 | I216, | |
| 765 | I217, | |
| 766 | I218, | |
| 767 | I219, | |
| 768 | I220, | |
| 769 | I221, | |
| 770 | I222, | |
| 771 | I223, | |
| 772 | I224, | |
| 773 | I225, | |
| 774 | I226, | |
| 775 | I227, | |
| 776 | I228, | |
| 777 | I229, | |
| 778 | I230, | |
| 779 | I231, | |
| 780 | I232, | |
| 781 | I233, | |
| 782 | I234, | |
| 783 | I235, | |
| 784 | I236, | |
| 785 | I237, | |
| 786 | I238, | |
| 787 | I239, | |
| 788 | I240, | |
| 789 | I241, | |
| 790 | I242, | |
| 791 | I243, | |
| 792 | I244, | |
| 793 | I245, | |
| 794 | I246, | |
| 795 | I247, | |
| 796 | I248, | |
| 797 | I249, | |
| 798 | I250, | |
| 799 | I251, | |
| 800 | I252, | |
| 801 | I253, | |
| 802 | I254, | |
| 803 | I255, | |
| 804 | I256, | |
| 805 | }; | |
| 806 | ||
| 807 | test "enum sizes" { | |
| 808 | comptime { | |
| 809 | expect(@sizeOf(ValueCount1) == 0); | |
| 810 | expect(@sizeOf(ValueCount2) == 1); | |
| 811 | expect(@sizeOf(ValueCount256) == 1); | |
| 812 | expect(@sizeOf(ValueCount257) == 2); | |
| 813 | } | |
| 814 | } | |
| 815 | ||
| 816 | const Small2 = enum(u2) { | |
| 817 | One, | |
| 818 | Two, | |
| 819 | }; | |
| 820 | const Small = enum(u2) { | |
| 821 | One, | |
| 822 | Two, | |
| 823 | Three, | |
| 824 | Four, | |
| 825 | }; | |
| 826 | ||
| 827 | test "set enum tag type" { | |
| 828 | { | |
| 829 | var x = Small.One; | |
| 830 | x = Small.Two; | |
| 831 | comptime expect(Tag(Small) == u2); | |
| 832 | } | |
| 833 | { | |
| 834 | var x = Small2.One; | |
| 835 | x = Small2.Two; | |
| 836 | comptime expect(Tag(Small2) == u2); | |
| 837 | } | |
| 838 | } | |
| 839 | ||
| 840 | const A = enum(u3) { | |
| 841 | One, | |
| 842 | Two, | |
| 843 | Three, | |
| 844 | Four, | |
| 845 | One2, | |
| 846 | Two2, | |
| 847 | Three2, | |
| 848 | Four2, | |
| 849 | }; | |
| 850 | ||
| 851 | const B = enum(u3) { | |
| 852 | One3, | |
| 853 | Two3, | |
| 854 | Three3, | |
| 855 | Four3, | |
| 856 | One23, | |
| 857 | Two23, | |
| 858 | Three23, | |
| 859 | Four23, | |
| 860 | }; | |
| 861 | ||
| 862 | const C = enum(u2) { | |
| 863 | One4, | |
| 864 | Two4, | |
| 865 | Three4, | |
| 866 | Four4, | |
| 867 | }; | |
| 868 | ||
| 869 | const BitFieldOfEnums = packed struct { | |
| 870 | a: A, | |
| 871 | b: B, | |
| 872 | c: C, | |
| 873 | }; | |
| 874 | ||
| 875 | const bit_field_1 = BitFieldOfEnums{ | |
| 876 | .a = A.Two, | |
| 877 | .b = B.Three3, | |
| 878 | .c = C.Four4, | |
| 879 | }; | |
| 880 | ||
| 881 | test "bit field access with enum fields" { | |
| 882 | var data = bit_field_1; | |
| 883 | expect(getA(&data) == A.Two); | |
| 884 | expect(getB(&data) == B.Three3); | |
| 885 | expect(getC(&data) == C.Four4); | |
| 886 | comptime expect(@sizeOf(BitFieldOfEnums) == 1); | |
| 887 | ||
| 888 | data.b = B.Four3; | |
| 889 | expect(data.b == B.Four3); | |
| 890 | ||
| 891 | data.a = A.Three; | |
| 892 | expect(data.a == A.Three); | |
| 893 | expect(data.b == B.Four3); | |
| 894 | } | |
| 895 | ||
| 896 | fn getA(data: *const BitFieldOfEnums) A { | |
| 897 | return data.a; | |
| 898 | } | |
| 899 | ||
| 900 | fn getB(data: *const BitFieldOfEnums) B { | |
| 901 | return data.b; | |
| 902 | } | |
| 903 | ||
| 904 | fn getC(data: *const BitFieldOfEnums) C { | |
| 905 | return data.c; | |
| 906 | } | |
| 907 | ||
| 908 | test "casting enum to its tag type" { | |
| 909 | testCastEnumTag(Small2.Two); | |
| 910 | comptime testCastEnumTag(Small2.Two); | |
| 911 | } | |
| 912 | ||
| 913 | fn testCastEnumTag(value: Small2) void { | |
| 914 | expect(@enumToInt(value) == 1); | |
| 915 | } | |
| 916 | ||
| 917 | const MultipleChoice = enum(u32) { | |
| 918 | A = 20, | |
| 919 | B = 40, | |
| 920 | C = 60, | |
| 921 | D = 1000, | |
| 922 | }; | |
| 923 | ||
| 924 | test "enum with specified tag values" { | |
| 925 | testEnumWithSpecifiedTagValues(MultipleChoice.C); | |
| 926 | comptime testEnumWithSpecifiedTagValues(MultipleChoice.C); | |
| 927 | } | |
| 928 | ||
| 929 | fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void { | |
| 930 | expect(@enumToInt(x) == 60); | |
| 931 | expect(1234 == switch (x) { | |
| 932 | MultipleChoice.A => 1, | |
| 933 | MultipleChoice.B => 2, | |
| 934 | MultipleChoice.C => @as(u32, 1234), | |
| 935 | MultipleChoice.D => 4, | |
| 936 | }); | |
| 937 | } | |
| 938 | ||
| 939 | const MultipleChoice2 = enum(u32) { | |
| 940 | Unspecified1, | |
| 941 | A = 20, | |
| 942 | Unspecified2, | |
| 943 | B = 40, | |
| 944 | Unspecified3, | |
| 945 | C = 60, | |
| 946 | Unspecified4, | |
| 947 | D = 1000, | |
| 948 | Unspecified5, | |
| 949 | }; | |
| 950 | ||
| 951 | test "enum with specified and unspecified tag values" { | |
| 952 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); | |
| 953 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D); | |
| 954 | } | |
| 955 | ||
| 956 | fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void { | |
| 957 | expect(@enumToInt(x) == 1000); | |
| 958 | expect(1234 == switch (x) { | |
| 959 | MultipleChoice2.A => 1, | |
| 960 | MultipleChoice2.B => 2, | |
| 961 | MultipleChoice2.C => 3, | |
| 962 | MultipleChoice2.D => @as(u32, 1234), | |
| 963 | MultipleChoice2.Unspecified1 => 5, | |
| 964 | MultipleChoice2.Unspecified2 => 6, | |
| 965 | MultipleChoice2.Unspecified3 => 7, | |
| 966 | MultipleChoice2.Unspecified4 => 8, | |
| 967 | MultipleChoice2.Unspecified5 => 9, | |
| 968 | }); | |
| 969 | } | |
| 970 | ||
| 971 | test "cast integer literal to enum" { | |
| 972 | expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1); | |
| 973 | expect(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B); | |
| 974 | } | |
| 975 | ||
| 976 | const EnumWithOneMember = enum { | |
| 977 | Eof, | |
| 978 | }; | |
| 979 | ||
| 980 | fn doALoopThing(id: EnumWithOneMember) void { | |
| 981 | while (true) { | |
| 982 | if (id == EnumWithOneMember.Eof) { | |
| 983 | break; | |
| 984 | } | |
| 985 | @compileError("above if condition should be comptime"); | |
| 986 | } | |
| 987 | } | |
| 988 | ||
| 989 | test "comparison operator on enum with one member is comptime known" { | |
| 990 | doALoopThing(EnumWithOneMember.Eof); | |
| 991 | } | |
| 992 | ||
| 993 | const State = enum { | |
| 994 | Start, | |
| 995 | }; | |
| 996 | test "switch on enum with one member is comptime known" { | |
| 997 | var state = State.Start; | |
| 998 | switch (state) { | |
| 999 | State.Start => return, | |
| 1000 | } | |
| 1001 | @compileError("analysis should not reach here"); | |
| 1002 | } | |
| 1003 | ||
| 1004 | const EnumWithTagValues = enum(u4) { | |
| 1005 | A = 1 << 0, | |
| 1006 | B = 1 << 1, | |
| 1007 | C = 1 << 2, | |
| 1008 | D = 1 << 3, | |
| 1009 | }; | |
| 1010 | test "enum with tag values don't require parens" { | |
| 1011 | expect(@enumToInt(EnumWithTagValues.C) == 0b0100); | |
| 1012 | } | |
| 1013 | ||
| 1014 | test "enum with 1 field but explicit tag type should still have the tag type" { | |
| 1015 | const Enum = enum(u8) { | |
| 1016 | B = 2, | |
| 1017 | }; | |
| 1018 | comptime @import("std").testing.expect(@sizeOf(Enum) == @sizeOf(u8)); | |
| 1019 | } | |
| 1020 | ||
| 1021 | test "empty extern enum with members" { | |
| 1022 | const E = extern enum { | |
| 1023 | A, | |
| 1024 | B, | |
| 1025 | C, | |
| 1026 | }; | |
| 1027 | expect(@sizeOf(E) == @sizeOf(c_int)); | |
| 1028 | } | |
| 1029 | ||
| 1030 | test "tag name with assigned enum values" { | |
| 1031 | const LocalFoo = enum { | |
| 1032 | A = 1, | |
| 1033 | B = 0, | |
| 1034 | }; | |
| 1035 | var b = LocalFoo.B; | |
| 1036 | expect(mem.eql(u8, @tagName(b), "B")); | |
| 1037 | } | |
| 1038 | ||
| 1039 | test "enum literal equality" { | |
| 1040 | const x = .hi; | |
| 1041 | const y = .ok; | |
| 1042 | const z = .hi; | |
| 1043 | ||
| 1044 | expect(x != y); | |
| 1045 | expect(x == z); | |
| 1046 | } | |
| 1047 | ||
| 1048 | test "enum literal cast to enum" { | |
| 1049 | const Color = enum { | |
| 1050 | Auto, | |
| 1051 | Off, | |
| 1052 | On, | |
| 1053 | }; | |
| 1054 | ||
| 1055 | var color1: Color = .Auto; | |
| 1056 | var color2 = Color.Auto; | |
| 1057 | expect(color1 == color2); | |
| 1058 | } | |
| 1059 | ||
| 1060 | test "peer type resolution with enum literal" { | |
| 1061 | const Items = enum { | |
| 1062 | one, | |
| 1063 | two, | |
| 1064 | }; | |
| 1065 | ||
| 1066 | expect(Items.two == .two); | |
| 1067 | expect(.two == Items.two); | |
| 1068 | } | |
| 1069 | ||
| 1070 | test "enum literal in array literal" { | |
| 1071 | const Items = enum { | |
| 1072 | one, | |
| 1073 | two, | |
| 1074 | }; | |
| 1075 | ||
| 1076 | const array = [_]Items{ | |
| 1077 | .one, | |
| 1078 | .two, | |
| 1079 | }; | |
| 1080 | ||
| 1081 | expect(array[0] == .one); | |
| 1082 | expect(array[1] == .two); | |
| 1083 | } | |
| 1084 | ||
| 1085 | test "signed integer as enum tag" { | |
| 1086 | const SignedEnum = enum(i2) { | |
| 1087 | A0 = -1, | |
| 1088 | A1 = 0, | |
| 1089 | A2 = 1, | |
| 1090 | }; | |
| 1091 | ||
| 1092 | expect(@enumToInt(SignedEnum.A0) == -1); | |
| 1093 | expect(@enumToInt(SignedEnum.A1) == 0); | |
| 1094 | expect(@enumToInt(SignedEnum.A2) == 1); | |
| 1095 | } | |
| 1096 | ||
| 1097 | test "enum value allocation" { | |
| 1098 | const LargeEnum = enum(u32) { | |
| 1099 | A0 = 0x80000000, | |
| 1100 | A1, | |
| 1101 | A2, | |
| 1102 | }; | |
| 1103 | ||
| 1104 | expect(@enumToInt(LargeEnum.A0) == 0x80000000); | |
| 1105 | expect(@enumToInt(LargeEnum.A1) == 0x80000001); | |
| 1106 | expect(@enumToInt(LargeEnum.A2) == 0x80000002); | |
| 1107 | } | |
| 1108 | ||
| 1109 | test "enum literal casting to tagged union" { | |
| 1110 | const Arch = union(enum) { | |
| 1111 | x86_64, | |
| 1112 | arm: Arm32, | |
| 1113 | ||
| 1114 | const Arm32 = enum { | |
| 1115 | v8_5a, | |
| 1116 | v8_4a, | |
| 1117 | }; | |
| 1118 | }; | |
| 1119 | ||
| 1120 | var t = true; | |
| 1121 | var x: Arch = .x86_64; | |
| 1122 | var y = if (t) x else .x86_64; | |
| 1123 | switch (y) { | |
| 1124 | .x86_64 => {}, | |
| 1125 | else => @panic("fail"), | |
| 1126 | } | |
| 1127 | } | |
| 1128 | ||
| 1129 | test "enum with one member and custom tag type" { | |
| 1130 | const E = enum(u2) { | |
| 1131 | One, | |
| 1132 | }; | |
| 1133 | expect(@enumToInt(E.One) == 0); | |
| 1134 | const E2 = enum(u2) { | |
| 1135 | One = 2, | |
| 1136 | }; | |
| 1137 | expect(@enumToInt(E2.One) == 2); | |
| 1138 | } | |
| 1139 | ||
| 1140 | test "enum literal casting to optional" { | |
| 1141 | var bar: ?Bar = undefined; | |
| 1142 | bar = .B; | |
| 1143 | ||
| 1144 | expect(bar.? == Bar.B); | |
| 1145 | } | |
| 1146 | ||
| 1147 | test "enum literal casting to error union with payload enum" { | |
| 1148 | var bar: error{B}!Bar = undefined; | |
| 1149 | bar = .B; // should never cast to the error set | |
| 1150 | ||
| 1151 | expect((try bar) == Bar.B); | |
| 1152 | } | |
| 1153 | ||
| 1154 | test "enum with one member and u1 tag type @enumToInt" { | |
| 1155 | const Enum = enum(u1) { | |
| 1156 | Test, | |
| 1157 | }; | |
| 1158 | expect(@enumToInt(Enum.Test) == 0); | |
| 1159 | } | |
| 1160 | ||
| 1161 | test "enum with comptime_int tag type" { | |
| 1162 | const Enum = enum(comptime_int) { | |
| 1163 | One = 3, | |
| 1164 | Two = 2, | |
| 1165 | Three = 1, | |
| 1166 | }; | |
| 1167 | comptime expect(Tag(Enum) == comptime_int); | |
| 1168 | } | |
| 1169 | ||
| 1170 | test "enum with one member default to u0 tag type" { | |
| 1171 | const E0 = enum { | |
| 1172 | X, | |
| 1173 | }; | |
| 1174 | comptime expect(Tag(E0) == u0); | |
| 1175 | } | |
| 1176 | ||
| 1177 | test "tagName on enum literals" { | |
| 1178 | expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); | |
| 1179 | comptime expect(mem.eql(u8, @tagName(.FooBar), "FooBar")); | |
| 1180 | } | |
| 1181 | ||
| 1182 | test "method call on an enum" { | |
| 1183 | const S = struct { | |
| 1184 | const E = enum { | |
| 1185 | one, | |
| 1186 | two, | |
| 1187 | ||
| 1188 | fn method(self: *E) bool { | |
| 1189 | return self.* == .two; | |
| 1190 | } | |
| 1191 | ||
| 1192 | fn generic_method(self: *E, foo: anytype) bool { | |
| 1193 | return self.* == .two and foo == bool; | |
| 1194 | } | |
| 1195 | }; | |
| 1196 | fn doTheTest() void { | |
| 1197 | var e = E.two; | |
| 1198 | expect(e.method()); | |
| 1199 | expect(e.generic_method(bool)); | |
| 1200 | } | |
| 1201 | }; | |
| 1202 | S.doTheTest(); | |
| 1203 | comptime S.doTheTest(); | |
| 1204 | } |
test/stage1/behavior/enum_with_members.zig deleted-27| ... | ... | @@ -1,27 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const fmt = @import("std").fmt; | |
| 4 | ||
| 5 | const ET = union(enum) { | |
| 6 | SINT: i32, | |
| 7 | UINT: u32, | |
| 8 | ||
| 9 | pub fn print(a: *const ET, buf: []u8) anyerror!usize { | |
| 10 | return switch (a.*) { | |
| 11 | ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}), | |
| 12 | ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, fmt.FormatOptions{}), | |
| 13 | }; | |
| 14 | } | |
| 15 | }; | |
| 16 | ||
| 17 | test "enum with members" { | |
| 18 | const a = ET{ .SINT = -42 }; | |
| 19 | const b = ET{ .UINT = 42 }; | |
| 20 | var buf: [20]u8 = undefined; | |
| 21 | ||
| 22 | expect((a.print(buf[0..]) catch unreachable) == 3); | |
| 23 | expect(mem.eql(u8, buf[0..3], "-42")); | |
| 24 | ||
| 25 | expect((b.print(buf[0..]) catch unreachable) == 2); | |
| 26 | expect(mem.eql(u8, buf[0..2], "42")); | |
| 27 | } |
test/stage1/behavior/error.zig deleted-452| ... | ... | @@ -1,452 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectError = std.testing.expectError; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const mem = std.mem; | |
| 6 | ||
| 7 | pub fn foo() anyerror!i32 { | |
| 8 | const x = try bar(); | |
| 9 | return x + 1; | |
| 10 | } | |
| 11 | ||
| 12 | pub fn bar() anyerror!i32 { | |
| 13 | return 13; | |
| 14 | } | |
| 15 | ||
| 16 | pub fn baz() anyerror!i32 { | |
| 17 | const y = foo() catch 1234; | |
| 18 | return y + 1; | |
| 19 | } | |
| 20 | ||
| 21 | test "error wrapping" { | |
| 22 | expect((baz() catch unreachable) == 15); | |
| 23 | } | |
| 24 | ||
| 25 | fn gimmeItBroke() []const u8 { | |
| 26 | return @errorName(error.ItBroke); | |
| 27 | } | |
| 28 | ||
| 29 | test "@errorName" { | |
| 30 | expect(mem.eql(u8, @errorName(error.AnError), "AnError")); | |
| 31 | expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName")); | |
| 32 | } | |
| 33 | ||
| 34 | test "error values" { | |
| 35 | const a = @errorToInt(error.err1); | |
| 36 | const b = @errorToInt(error.err2); | |
| 37 | expect(a != b); | |
| 38 | } | |
| 39 | ||
| 40 | test "redefinition of error values allowed" { | |
| 41 | shouldBeNotEqual(error.AnError, error.SecondError); | |
| 42 | } | |
| 43 | fn shouldBeNotEqual(a: anyerror, b: anyerror) void { | |
| 44 | if (a == b) unreachable; | |
| 45 | } | |
| 46 | ||
| 47 | test "error binary operator" { | |
| 48 | const a = errBinaryOperatorG(true) catch 3; | |
| 49 | const b = errBinaryOperatorG(false) catch 3; | |
| 50 | expect(a == 3); | |
| 51 | expect(b == 10); | |
| 52 | } | |
| 53 | fn errBinaryOperatorG(x: bool) anyerror!isize { | |
| 54 | return if (x) error.ItBroke else @as(isize, 10); | |
| 55 | } | |
| 56 | ||
| 57 | test "unwrap simple value from error" { | |
| 58 | const i = unwrapSimpleValueFromErrorDo() catch unreachable; | |
| 59 | expect(i == 13); | |
| 60 | } | |
| 61 | fn unwrapSimpleValueFromErrorDo() anyerror!isize { | |
| 62 | return 13; | |
| 63 | } | |
| 64 | ||
| 65 | test "error return in assignment" { | |
| 66 | doErrReturnInAssignment() catch unreachable; | |
| 67 | } | |
| 68 | ||
| 69 | fn doErrReturnInAssignment() anyerror!void { | |
| 70 | var x: i32 = undefined; | |
| 71 | x = try makeANonErr(); | |
| 72 | } | |
| 73 | ||
| 74 | fn makeANonErr() anyerror!i32 { | |
| 75 | return 1; | |
| 76 | } | |
| 77 | ||
| 78 | test "error union type " { | |
| 79 | testErrorUnionType(); | |
| 80 | comptime testErrorUnionType(); | |
| 81 | } | |
| 82 | ||
| 83 | fn testErrorUnionType() void { | |
| 84 | const x: anyerror!i32 = 1234; | |
| 85 | if (x) |value| expect(value == 1234) else |_| unreachable; | |
| 86 | expect(@typeInfo(@TypeOf(x)) == .ErrorUnion); | |
| 87 | expect(@typeInfo(@typeInfo(@TypeOf(x)).ErrorUnion.error_set) == .ErrorSet); | |
| 88 | expect(@typeInfo(@TypeOf(x)).ErrorUnion.error_set == anyerror); | |
| 89 | } | |
| 90 | ||
| 91 | test "error set type" { | |
| 92 | testErrorSetType(); | |
| 93 | comptime testErrorSetType(); | |
| 94 | } | |
| 95 | ||
| 96 | const MyErrSet = error{ | |
| 97 | OutOfMemory, | |
| 98 | FileNotFound, | |
| 99 | }; | |
| 100 | ||
| 101 | fn testErrorSetType() void { | |
| 102 | expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2); | |
| 103 | ||
| 104 | const a: MyErrSet!i32 = 5678; | |
| 105 | const b: MyErrSet!i32 = MyErrSet.OutOfMemory; | |
| 106 | ||
| 107 | if (a) |value| expect(value == 5678) else |err| switch (err) { | |
| 108 | error.OutOfMemory => unreachable, | |
| 109 | error.FileNotFound => unreachable, | |
| 110 | } | |
| 111 | } | |
| 112 | ||
| 113 | test "explicit error set cast" { | |
| 114 | testExplicitErrorSetCast(Set1.A); | |
| 115 | comptime testExplicitErrorSetCast(Set1.A); | |
| 116 | } | |
| 117 | ||
| 118 | const Set1 = error{ | |
| 119 | A, | |
| 120 | B, | |
| 121 | }; | |
| 122 | const Set2 = error{ | |
| 123 | A, | |
| 124 | C, | |
| 125 | }; | |
| 126 | ||
| 127 | fn testExplicitErrorSetCast(set1: Set1) void { | |
| 128 | var x = @errSetCast(Set2, set1); | |
| 129 | var y = @errSetCast(Set1, x); | |
| 130 | expect(y == error.A); | |
| 131 | } | |
| 132 | ||
| 133 | test "comptime test error for empty error set" { | |
| 134 | testComptimeTestErrorEmptySet(1234); | |
| 135 | comptime testComptimeTestErrorEmptySet(1234); | |
| 136 | } | |
| 137 | ||
| 138 | const EmptyErrorSet = error{}; | |
| 139 | ||
| 140 | fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void { | |
| 141 | if (x) |v| expect(v == 1234) else |err| @compileError("bad"); | |
| 142 | } | |
| 143 | ||
| 144 | test "syntax: optional operator in front of error union operator" { | |
| 145 | comptime { | |
| 146 | expect(?(anyerror!i32) == ?(anyerror!i32)); | |
| 147 | } | |
| 148 | } | |
| 149 | ||
| 150 | test "comptime err to int of error set with only 1 possible value" { | |
| 151 | testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A)); | |
| 152 | comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A)); | |
| 153 | } | |
| 154 | fn testErrToIntWithOnePossibleValue( | |
| 155 | x: error{A}, | |
| 156 | comptime value: u32, | |
| 157 | ) void { | |
| 158 | if (@errorToInt(x) != value) { | |
| 159 | @compileError("bad"); | |
| 160 | } | |
| 161 | } | |
| 162 | ||
| 163 | test "empty error union" { | |
| 164 | const x = error{} || error{}; | |
| 165 | } | |
| 166 | ||
| 167 | test "error union peer type resolution" { | |
| 168 | testErrorUnionPeerTypeResolution(1); | |
| 169 | } | |
| 170 | ||
| 171 | fn testErrorUnionPeerTypeResolution(x: i32) void { | |
| 172 | const y = switch (x) { | |
| 173 | 1 => bar_1(), | |
| 174 | 2 => baz_1(), | |
| 175 | else => quux_1(), | |
| 176 | }; | |
| 177 | if (y) |_| { | |
| 178 | @panic("expected error"); | |
| 179 | } else |e| { | |
| 180 | expect(e == error.A); | |
| 181 | } | |
| 182 | } | |
| 183 | ||
| 184 | fn bar_1() anyerror { | |
| 185 | return error.A; | |
| 186 | } | |
| 187 | ||
| 188 | fn baz_1() !i32 { | |
| 189 | return error.B; | |
| 190 | } | |
| 191 | ||
| 192 | fn quux_1() !i32 { | |
| 193 | return error.C; | |
| 194 | } | |
| 195 | ||
| 196 | test "error: fn returning empty error set can be passed as fn returning any error" { | |
| 197 | entry(); | |
| 198 | comptime entry(); | |
| 199 | } | |
| 200 | ||
| 201 | fn entry() void { | |
| 202 | foo2(bar2); | |
| 203 | } | |
| 204 | ||
| 205 | fn foo2(f: fn () anyerror!void) void { | |
| 206 | const x = f(); | |
| 207 | } | |
| 208 | ||
| 209 | fn bar2() (error{}!void) {} | |
| 210 | ||
| 211 | test "error: Zero sized error set returned with value payload crash" { | |
| 212 | _ = foo3(0) catch {}; | |
| 213 | _ = comptime foo3(0) catch {}; | |
| 214 | } | |
| 215 | ||
| 216 | const Error = error{}; | |
| 217 | fn foo3(b: usize) Error!usize { | |
| 218 | return b; | |
| 219 | } | |
| 220 | ||
| 221 | test "error: Infer error set from literals" { | |
| 222 | _ = nullLiteral("n") catch |err| handleErrors(err); | |
| 223 | _ = floatLiteral("n") catch |err| handleErrors(err); | |
| 224 | _ = intLiteral("n") catch |err| handleErrors(err); | |
| 225 | _ = comptime nullLiteral("n") catch |err| handleErrors(err); | |
| 226 | _ = comptime floatLiteral("n") catch |err| handleErrors(err); | |
| 227 | _ = comptime intLiteral("n") catch |err| handleErrors(err); | |
| 228 | } | |
| 229 | ||
| 230 | fn handleErrors(err: anytype) noreturn { | |
| 231 | switch (err) { | |
| 232 | error.T => {}, | |
| 233 | } | |
| 234 | ||
| 235 | unreachable; | |
| 236 | } | |
| 237 | ||
| 238 | fn nullLiteral(str: []const u8) !?i64 { | |
| 239 | if (str[0] == 'n') return null; | |
| 240 | ||
| 241 | return error.T; | |
| 242 | } | |
| 243 | ||
| 244 | fn floatLiteral(str: []const u8) !?f64 { | |
| 245 | if (str[0] == 'n') return 1.0; | |
| 246 | ||
| 247 | return error.T; | |
| 248 | } | |
| 249 | ||
| 250 | fn intLiteral(str: []const u8) !?i64 { | |
| 251 | if (str[0] == 'n') return 1; | |
| 252 | ||
| 253 | return error.T; | |
| 254 | } | |
| 255 | ||
| 256 | test "nested error union function call in optional unwrap" { | |
| 257 | const S = struct { | |
| 258 | const Foo = struct { | |
| 259 | a: i32, | |
| 260 | }; | |
| 261 | ||
| 262 | fn errorable() !i32 { | |
| 263 | var x: Foo = (try getFoo()) orelse return error.Other; | |
| 264 | return x.a; | |
| 265 | } | |
| 266 | ||
| 267 | fn errorable2() !i32 { | |
| 268 | var x: Foo = (try getFoo2()) orelse return error.Other; | |
| 269 | return x.a; | |
| 270 | } | |
| 271 | ||
| 272 | fn errorable3() !i32 { | |
| 273 | var x: Foo = (try getFoo3()) orelse return error.Other; | |
| 274 | return x.a; | |
| 275 | } | |
| 276 | ||
| 277 | fn getFoo() anyerror!?Foo { | |
| 278 | return Foo{ .a = 1234 }; | |
| 279 | } | |
| 280 | ||
| 281 | fn getFoo2() anyerror!?Foo { | |
| 282 | return error.Failure; | |
| 283 | } | |
| 284 | ||
| 285 | fn getFoo3() anyerror!?Foo { | |
| 286 | return null; | |
| 287 | } | |
| 288 | }; | |
| 289 | expect((try S.errorable()) == 1234); | |
| 290 | expectError(error.Failure, S.errorable2()); | |
| 291 | expectError(error.Other, S.errorable3()); | |
| 292 | comptime { | |
| 293 | expect((try S.errorable()) == 1234); | |
| 294 | expectError(error.Failure, S.errorable2()); | |
| 295 | expectError(error.Other, S.errorable3()); | |
| 296 | } | |
| 297 | } | |
| 298 | ||
| 299 | test "widen cast integer payload of error union function call" { | |
| 300 | const S = struct { | |
| 301 | fn errorable() !u64 { | |
| 302 | var x = @as(u64, try number()); | |
| 303 | return x; | |
| 304 | } | |
| 305 | ||
| 306 | fn number() anyerror!u32 { | |
| 307 | return 1234; | |
| 308 | } | |
| 309 | }; | |
| 310 | expect((try S.errorable()) == 1234); | |
| 311 | } | |
| 312 | ||
| 313 | test "return function call to error set from error union function" { | |
| 314 | const S = struct { | |
| 315 | fn errorable() anyerror!i32 { | |
| 316 | return fail(); | |
| 317 | } | |
| 318 | ||
| 319 | fn fail() anyerror { | |
| 320 | return error.Failure; | |
| 321 | } | |
| 322 | }; | |
| 323 | expectError(error.Failure, S.errorable()); | |
| 324 | comptime expectError(error.Failure, S.errorable()); | |
| 325 | } | |
| 326 | ||
| 327 | test "optional error set is the same size as error set" { | |
| 328 | comptime expect(@sizeOf(?anyerror) == @sizeOf(anyerror)); | |
| 329 | const S = struct { | |
| 330 | fn returnsOptErrSet() ?anyerror { | |
| 331 | return null; | |
| 332 | } | |
| 333 | }; | |
| 334 | expect(S.returnsOptErrSet() == null); | |
| 335 | comptime expect(S.returnsOptErrSet() == null); | |
| 336 | } | |
| 337 | ||
| 338 | test "debug info for optional error set" { | |
| 339 | const SomeError = error{Hello}; | |
| 340 | var a_local_variable: ?SomeError = null; | |
| 341 | } | |
| 342 | ||
| 343 | test "nested catch" { | |
| 344 | const S = struct { | |
| 345 | fn entry() void { | |
| 346 | expectError(error.Bad, func()); | |
| 347 | } | |
| 348 | fn fail() anyerror!Foo { | |
| 349 | return error.Wrong; | |
| 350 | } | |
| 351 | fn func() anyerror!Foo { | |
| 352 | const x = fail() catch | |
| 353 | fail() catch | |
| 354 | return error.Bad; | |
| 355 | unreachable; | |
| 356 | } | |
| 357 | const Foo = struct { | |
| 358 | field: i32, | |
| 359 | }; | |
| 360 | }; | |
| 361 | S.entry(); | |
| 362 | comptime S.entry(); | |
| 363 | } | |
| 364 | ||
| 365 | test "implicit cast to optional to error union to return result loc" { | |
| 366 | const S = struct { | |
| 367 | fn entry() void { | |
| 368 | var x: Foo = undefined; | |
| 369 | if (func(&x)) |opt| { | |
| 370 | expect(opt != null); | |
| 371 | } else |_| @panic("expected non error"); | |
| 372 | } | |
| 373 | fn func(f: *Foo) anyerror!?*Foo { | |
| 374 | return f; | |
| 375 | } | |
| 376 | const Foo = struct { | |
| 377 | field: i32, | |
| 378 | }; | |
| 379 | }; | |
| 380 | S.entry(); | |
| 381 | //comptime S.entry(); TODO | |
| 382 | } | |
| 383 | ||
| 384 | test "function pointer with return type that is error union with payload which is pointer of parent struct" { | |
| 385 | const S = struct { | |
| 386 | const Foo = struct { | |
| 387 | fun: fn (a: i32) (anyerror!*Foo), | |
| 388 | }; | |
| 389 | ||
| 390 | const Err = error{UnspecifiedErr}; | |
| 391 | ||
| 392 | fn bar(a: i32) anyerror!*Foo { | |
| 393 | return Err.UnspecifiedErr; | |
| 394 | } | |
| 395 | ||
| 396 | fn doTheTest() void { | |
| 397 | var x = Foo{ .fun = bar }; | |
| 398 | expectError(error.UnspecifiedErr, x.fun(1)); | |
| 399 | } | |
| 400 | }; | |
| 401 | S.doTheTest(); | |
| 402 | } | |
| 403 | ||
| 404 | test "return result loc as peer result loc in inferred error set function" { | |
| 405 | const S = struct { | |
| 406 | fn doTheTest() void { | |
| 407 | if (foo(2)) |x| { | |
| 408 | expect(x.Two); | |
| 409 | } else |e| switch (e) { | |
| 410 | error.Whatever => @panic("fail"), | |
| 411 | } | |
| 412 | expectError(error.Whatever, foo(99)); | |
| 413 | } | |
| 414 | const FormValue = union(enum) { | |
| 415 | One: void, | |
| 416 | Two: bool, | |
| 417 | }; | |
| 418 | ||
| 419 | fn foo(id: u64) !FormValue { | |
| 420 | return switch (id) { | |
| 421 | 2 => FormValue{ .Two = true }, | |
| 422 | 1 => FormValue{ .One = {} }, | |
| 423 | else => return error.Whatever, | |
| 424 | }; | |
| 425 | } | |
| 426 | }; | |
| 427 | S.doTheTest(); | |
| 428 | comptime S.doTheTest(); | |
| 429 | } | |
| 430 | ||
| 431 | test "error payload type is correctly resolved" { | |
| 432 | const MyIntWrapper = struct { | |
| 433 | const Self = @This(); | |
| 434 | ||
| 435 | x: i32, | |
| 436 | ||
| 437 | pub fn create() anyerror!Self { | |
| 438 | return Self{ .x = 42 }; | |
| 439 | } | |
| 440 | }; | |
| 441 | ||
| 442 | expectEqual(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create()); | |
| 443 | } | |
| 444 | ||
| 445 | test "error union comptime caching" { | |
| 446 | const S = struct { | |
| 447 | fn foo(comptime arg: anytype) void {} | |
| 448 | }; | |
| 449 | ||
| 450 | S.foo(@as(anyerror!void, {})); | |
| 451 | S.foo(@as(anyerror!void, {})); | |
| 452 | } | |
| \ No newline at end of file |
test/stage1/behavior/eval.zig deleted-832| ... | ... | @@ -1,832 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "compile time recursion" { | |
| 6 | expect(some_data.len == 21); | |
| 7 | } | |
| 8 | var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined; | |
| 9 | fn fibonacci(x: i32) i32 { | |
| 10 | if (x <= 1) return 1; | |
| 11 | return fibonacci(x - 1) + fibonacci(x - 2); | |
| 12 | } | |
| 13 | ||
| 14 | fn unwrapAndAddOne(blah: ?i32) i32 { | |
| 15 | return blah.? + 1; | |
| 16 | } | |
| 17 | const should_be_1235 = unwrapAndAddOne(1234); | |
| 18 | test "static add one" { | |
| 19 | expect(should_be_1235 == 1235); | |
| 20 | } | |
| 21 | ||
| 22 | test "inlined loop" { | |
| 23 | comptime var i = 0; | |
| 24 | comptime var sum = 0; | |
| 25 | inline while (i <= 5) : (i += 1) | |
| 26 | sum += i; | |
| 27 | expect(sum == 15); | |
| 28 | } | |
| 29 | ||
| 30 | fn gimme1or2(comptime a: bool) i32 { | |
| 31 | const x: i32 = 1; | |
| 32 | const y: i32 = 2; | |
| 33 | comptime var z: i32 = if (a) x else y; | |
| 34 | return z; | |
| 35 | } | |
| 36 | test "inline variable gets result of const if" { | |
| 37 | expect(gimme1or2(true) == 1); | |
| 38 | expect(gimme1or2(false) == 2); | |
| 39 | } | |
| 40 | ||
| 41 | test "static function evaluation" { | |
| 42 | expect(statically_added_number == 3); | |
| 43 | } | |
| 44 | const statically_added_number = staticAdd(1, 2); | |
| 45 | fn staticAdd(a: i32, b: i32) i32 { | |
| 46 | return a + b; | |
| 47 | } | |
| 48 | ||
| 49 | test "const expr eval on single expr blocks" { | |
| 50 | expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 51 | comptime expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3); | |
| 52 | } | |
| 53 | ||
| 54 | fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 { | |
| 55 | const literal = 3; | |
| 56 | ||
| 57 | const result = if (b) b: { | |
| 58 | break :b literal; | |
| 59 | } else b: { | |
| 60 | break :b x; | |
| 61 | }; | |
| 62 | ||
| 63 | return result; | |
| 64 | } | |
| 65 | ||
| 66 | test "statically initialized list" { | |
| 67 | expect(static_point_list[0].x == 1); | |
| 68 | expect(static_point_list[0].y == 2); | |
| 69 | expect(static_point_list[1].x == 3); | |
| 70 | expect(static_point_list[1].y == 4); | |
| 71 | } | |
| 72 | const Point = struct { | |
| 73 | x: i32, | |
| 74 | y: i32, | |
| 75 | }; | |
| 76 | const static_point_list = [_]Point{ | |
| 77 | makePoint(1, 2), | |
| 78 | makePoint(3, 4), | |
| 79 | }; | |
| 80 | fn makePoint(x: i32, y: i32) Point { | |
| 81 | return Point{ | |
| 82 | .x = x, | |
| 83 | .y = y, | |
| 84 | }; | |
| 85 | } | |
| 86 | ||
| 87 | test "static eval list init" { | |
| 88 | expect(static_vec3.data[2] == 1.0); | |
| 89 | expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0); | |
| 90 | } | |
| 91 | const static_vec3 = vec3(0.0, 0.0, 1.0); | |
| 92 | pub const Vec3 = struct { | |
| 93 | data: [3]f32, | |
| 94 | }; | |
| 95 | pub fn vec3(x: f32, y: f32, z: f32) Vec3 { | |
| 96 | return Vec3{ | |
| 97 | .data = [_]f32{ | |
| 98 | x, | |
| 99 | y, | |
| 100 | z, | |
| 101 | }, | |
| 102 | }; | |
| 103 | } | |
| 104 | ||
| 105 | test "constant expressions" { | |
| 106 | var array: [array_size]u8 = undefined; | |
| 107 | expect(@sizeOf(@TypeOf(array)) == 20); | |
| 108 | } | |
| 109 | const array_size: u8 = 20; | |
| 110 | ||
| 111 | test "constant struct with negation" { | |
| 112 | expect(vertices[0].x == -0.6); | |
| 113 | } | |
| 114 | const Vertex = struct { | |
| 115 | x: f32, | |
| 116 | y: f32, | |
| 117 | r: f32, | |
| 118 | g: f32, | |
| 119 | b: f32, | |
| 120 | }; | |
| 121 | const vertices = [_]Vertex{ | |
| 122 | Vertex{ | |
| 123 | .x = -0.6, | |
| 124 | .y = -0.4, | |
| 125 | .r = 1.0, | |
| 126 | .g = 0.0, | |
| 127 | .b = 0.0, | |
| 128 | }, | |
| 129 | Vertex{ | |
| 130 | .x = 0.6, | |
| 131 | .y = -0.4, | |
| 132 | .r = 0.0, | |
| 133 | .g = 1.0, | |
| 134 | .b = 0.0, | |
| 135 | }, | |
| 136 | Vertex{ | |
| 137 | .x = 0.0, | |
| 138 | .y = 0.6, | |
| 139 | .r = 0.0, | |
| 140 | .g = 0.0, | |
| 141 | .b = 1.0, | |
| 142 | }, | |
| 143 | }; | |
| 144 | ||
| 145 | test "statically initialized struct" { | |
| 146 | st_init_str_foo.x += 1; | |
| 147 | expect(st_init_str_foo.x == 14); | |
| 148 | } | |
| 149 | const StInitStrFoo = struct { | |
| 150 | x: i32, | |
| 151 | y: bool, | |
| 152 | }; | |
| 153 | var st_init_str_foo = StInitStrFoo{ | |
| 154 | .x = 13, | |
| 155 | .y = true, | |
| 156 | }; | |
| 157 | ||
| 158 | test "statically initalized array literal" { | |
| 159 | const y: [4]u8 = st_init_arr_lit_x; | |
| 160 | expect(y[3] == 4); | |
| 161 | } | |
| 162 | const st_init_arr_lit_x = [_]u8{ | |
| 163 | 1, | |
| 164 | 2, | |
| 165 | 3, | |
| 166 | 4, | |
| 167 | }; | |
| 168 | ||
| 169 | test "const slice" { | |
| 170 | comptime { | |
| 171 | const a = "1234567890"; | |
| 172 | expect(a.len == 10); | |
| 173 | const b = a[1..2]; | |
| 174 | expect(b.len == 1); | |
| 175 | expect(b[0] == '2'); | |
| 176 | } | |
| 177 | } | |
| 178 | ||
| 179 | test "try to trick eval with runtime if" { | |
| 180 | expect(testTryToTrickEvalWithRuntimeIf(true) == 10); | |
| 181 | } | |
| 182 | ||
| 183 | fn testTryToTrickEvalWithRuntimeIf(b: bool) usize { | |
| 184 | comptime var i: usize = 0; | |
| 185 | inline while (i < 10) : (i += 1) { | |
| 186 | const result = if (b) false else true; | |
| 187 | } | |
| 188 | comptime { | |
| 189 | return i; | |
| 190 | } | |
| 191 | } | |
| 192 | ||
| 193 | test "inlined loop has array literal with elided runtime scope on first iteration but not second iteration" { | |
| 194 | var runtime = [1]i32{3}; | |
| 195 | comptime var i: usize = 0; | |
| 196 | inline while (i < 2) : (i += 1) { | |
| 197 | const result = if (i == 0) [1]i32{2} else runtime; | |
| 198 | } | |
| 199 | comptime { | |
| 200 | expect(i == 2); | |
| 201 | } | |
| 202 | } | |
| 203 | ||
| 204 | fn max(comptime T: type, a: T, b: T) T { | |
| 205 | if (T == bool) { | |
| 206 | return a or b; | |
| 207 | } else if (a > b) { | |
| 208 | return a; | |
| 209 | } else { | |
| 210 | return b; | |
| 211 | } | |
| 212 | } | |
| 213 | fn letsTryToCompareBools(a: bool, b: bool) bool { | |
| 214 | return max(bool, a, b); | |
| 215 | } | |
| 216 | test "inlined block and runtime block phi" { | |
| 217 | expect(letsTryToCompareBools(true, true)); | |
| 218 | expect(letsTryToCompareBools(true, false)); | |
| 219 | expect(letsTryToCompareBools(false, true)); | |
| 220 | expect(!letsTryToCompareBools(false, false)); | |
| 221 | ||
| 222 | comptime { | |
| 223 | expect(letsTryToCompareBools(true, true)); | |
| 224 | expect(letsTryToCompareBools(true, false)); | |
| 225 | expect(letsTryToCompareBools(false, true)); | |
| 226 | expect(!letsTryToCompareBools(false, false)); | |
| 227 | } | |
| 228 | } | |
| 229 | ||
| 230 | const CmdFn = struct { | |
| 231 | name: []const u8, | |
| 232 | func: fn (i32) i32, | |
| 233 | }; | |
| 234 | ||
| 235 | const cmd_fns = [_]CmdFn{ | |
| 236 | CmdFn{ | |
| 237 | .name = "one", | |
| 238 | .func = one, | |
| 239 | }, | |
| 240 | CmdFn{ | |
| 241 | .name = "two", | |
| 242 | .func = two, | |
| 243 | }, | |
| 244 | CmdFn{ | |
| 245 | .name = "three", | |
| 246 | .func = three, | |
| 247 | }, | |
| 248 | }; | |
| 249 | fn one(value: i32) i32 { | |
| 250 | return value + 1; | |
| 251 | } | |
| 252 | fn two(value: i32) i32 { | |
| 253 | return value + 2; | |
| 254 | } | |
| 255 | fn three(value: i32) i32 { | |
| 256 | return value + 3; | |
| 257 | } | |
| 258 | ||
| 259 | fn performFn(comptime prefix_char: u8, start_value: i32) i32 { | |
| 260 | var result: i32 = start_value; | |
| 261 | comptime var i = 0; | |
| 262 | inline while (i < cmd_fns.len) : (i += 1) { | |
| 263 | if (cmd_fns[i].name[0] == prefix_char) { | |
| 264 | result = cmd_fns[i].func(result); | |
| 265 | } | |
| 266 | } | |
| 267 | return result; | |
| 268 | } | |
| 269 | ||
| 270 | test "comptime iterate over fn ptr list" { | |
| 271 | expect(performFn('t', 1) == 6); | |
| 272 | expect(performFn('o', 0) == 1); | |
| 273 | expect(performFn('w', 99) == 99); | |
| 274 | } | |
| 275 | ||
| 276 | test "eval @setRuntimeSafety at compile-time" { | |
| 277 | const result = comptime fnWithSetRuntimeSafety(); | |
| 278 | expect(result == 1234); | |
| 279 | } | |
| 280 | ||
| 281 | fn fnWithSetRuntimeSafety() i32 { | |
| 282 | @setRuntimeSafety(true); | |
| 283 | return 1234; | |
| 284 | } | |
| 285 | ||
| 286 | test "eval @setFloatMode at compile-time" { | |
| 287 | const result = comptime fnWithFloatMode(); | |
| 288 | expect(result == 1234.0); | |
| 289 | } | |
| 290 | ||
| 291 | fn fnWithFloatMode() f32 { | |
| 292 | @setFloatMode(std.builtin.FloatMode.Strict); | |
| 293 | return 1234.0; | |
| 294 | } | |
| 295 | ||
| 296 | const SimpleStruct = struct { | |
| 297 | field: i32, | |
| 298 | ||
| 299 | fn method(self: *const SimpleStruct) i32 { | |
| 300 | return self.field + 3; | |
| 301 | } | |
| 302 | }; | |
| 303 | ||
| 304 | var simple_struct = SimpleStruct{ .field = 1234 }; | |
| 305 | ||
| 306 | const bound_fn = simple_struct.method; | |
| 307 | ||
| 308 | test "call method on bound fn referring to var instance" { | |
| 309 | expect(bound_fn() == 1237); | |
| 310 | } | |
| 311 | ||
| 312 | test "ptr to local array argument at comptime" { | |
| 313 | comptime { | |
| 314 | var bytes: [10]u8 = undefined; | |
| 315 | modifySomeBytes(bytes[0..]); | |
| 316 | expect(bytes[0] == 'a'); | |
| 317 | expect(bytes[9] == 'b'); | |
| 318 | } | |
| 319 | } | |
| 320 | ||
| 321 | fn modifySomeBytes(bytes: []u8) void { | |
| 322 | bytes[0] = 'a'; | |
| 323 | bytes[9] = 'b'; | |
| 324 | } | |
| 325 | ||
| 326 | test "comparisons 0 <= uint and 0 > uint should be comptime" { | |
| 327 | testCompTimeUIntComparisons(1234); | |
| 328 | } | |
| 329 | fn testCompTimeUIntComparisons(x: u32) void { | |
| 330 | if (!(0 <= x)) { | |
| 331 | @compileError("this condition should be comptime known"); | |
| 332 | } | |
| 333 | if (0 > x) { | |
| 334 | @compileError("this condition should be comptime known"); | |
| 335 | } | |
| 336 | if (!(x >= 0)) { | |
| 337 | @compileError("this condition should be comptime known"); | |
| 338 | } | |
| 339 | if (x < 0) { | |
| 340 | @compileError("this condition should be comptime known"); | |
| 341 | } | |
| 342 | } | |
| 343 | ||
| 344 | test "const ptr to variable data changes at runtime" { | |
| 345 | expect(foo_ref.name[0] == 'a'); | |
| 346 | foo_ref.name = "b"; | |
| 347 | expect(foo_ref.name[0] == 'b'); | |
| 348 | } | |
| 349 | ||
| 350 | const Foo = struct { | |
| 351 | name: []const u8, | |
| 352 | }; | |
| 353 | ||
| 354 | var foo_contents = Foo{ .name = "a" }; | |
| 355 | const foo_ref = &foo_contents; | |
| 356 | ||
| 357 | test "create global array with for loop" { | |
| 358 | expect(global_array[5] == 5 * 5); | |
| 359 | expect(global_array[9] == 9 * 9); | |
| 360 | } | |
| 361 | ||
| 362 | const global_array = x: { | |
| 363 | var result: [10]usize = undefined; | |
| 364 | for (result) |*item, index| { | |
| 365 | item.* = index * index; | |
| 366 | } | |
| 367 | break :x result; | |
| 368 | }; | |
| 369 | ||
| 370 | test "compile-time downcast when the bits fit" { | |
| 371 | comptime { | |
| 372 | const spartan_count: u16 = 255; | |
| 373 | const byte = @intCast(u8, spartan_count); | |
| 374 | expect(byte == 255); | |
| 375 | } | |
| 376 | } | |
| 377 | ||
| 378 | const hi1 = "hi"; | |
| 379 | const hi2 = hi1; | |
| 380 | test "const global shares pointer with other same one" { | |
| 381 | assertEqualPtrs(&hi1[0], &hi2[0]); | |
| 382 | comptime expect(&hi1[0] == &hi2[0]); | |
| 383 | } | |
| 384 | fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) void { | |
| 385 | expect(ptr1 == ptr2); | |
| 386 | } | |
| 387 | ||
| 388 | test "@setEvalBranchQuota" { | |
| 389 | comptime { | |
| 390 | // 1001 for the loop and then 1 more for the expect fn call | |
| 391 | @setEvalBranchQuota(1002); | |
| 392 | var i = 0; | |
| 393 | var sum = 0; | |
| 394 | while (i < 1001) : (i += 1) { | |
| 395 | sum += i; | |
| 396 | } | |
| 397 | expect(sum == 500500); | |
| 398 | } | |
| 399 | } | |
| 400 | ||
| 401 | test "float literal at compile time not lossy" { | |
| 402 | expect(16777216.0 + 1.0 == 16777217.0); | |
| 403 | expect(9007199254740992.0 + 1.0 == 9007199254740993.0); | |
| 404 | } | |
| 405 | ||
| 406 | test "f32 at compile time is lossy" { | |
| 407 | expect(@as(f32, 1 << 24) + 1 == 1 << 24); | |
| 408 | } | |
| 409 | ||
| 410 | test "f64 at compile time is lossy" { | |
| 411 | expect(@as(f64, 1 << 53) + 1 == 1 << 53); | |
| 412 | } | |
| 413 | ||
| 414 | test "f128 at compile time is lossy" { | |
| 415 | expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0); | |
| 416 | } | |
| 417 | ||
| 418 | comptime { | |
| 419 | expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192); | |
| 420 | } | |
| 421 | ||
| 422 | pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type { | |
| 423 | return struct { | |
| 424 | pub const Node = struct {}; | |
| 425 | }; | |
| 426 | } | |
| 427 | ||
| 428 | test "string literal used as comptime slice is memoized" { | |
| 429 | const a = "link"; | |
| 430 | const b = "link"; | |
| 431 | comptime expect(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node); | |
| 432 | comptime expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node); | |
| 433 | } | |
| 434 | ||
| 435 | test "comptime slice of undefined pointer of length 0" { | |
| 436 | const slice1 = @as([*]i32, undefined)[0..0]; | |
| 437 | expect(slice1.len == 0); | |
| 438 | const slice2 = @as([*]i32, undefined)[100..100]; | |
| 439 | expect(slice2.len == 0); | |
| 440 | } | |
| 441 | ||
| 442 | fn copyWithPartialInline(s: []u32, b: []u8) void { | |
| 443 | comptime var i: usize = 0; | |
| 444 | inline while (i < 4) : (i += 1) { | |
| 445 | s[i] = 0; | |
| 446 | s[i] |= @as(u32, b[i * 4 + 0]) << 24; | |
| 447 | s[i] |= @as(u32, b[i * 4 + 1]) << 16; | |
| 448 | s[i] |= @as(u32, b[i * 4 + 2]) << 8; | |
| 449 | s[i] |= @as(u32, b[i * 4 + 3]) << 0; | |
| 450 | } | |
| 451 | } | |
| 452 | ||
| 453 | test "binary math operator in partially inlined function" { | |
| 454 | var s: [4]u32 = undefined; | |
| 455 | var b: [16]u8 = undefined; | |
| 456 | ||
| 457 | for (b) |*r, i| | |
| 458 | r.* = @intCast(u8, i + 1); | |
| 459 | ||
| 460 | copyWithPartialInline(s[0..], b[0..]); | |
| 461 | expect(s[0] == 0x1020304); | |
| 462 | expect(s[1] == 0x5060708); | |
| 463 | expect(s[2] == 0x90a0b0c); | |
| 464 | expect(s[3] == 0xd0e0f10); | |
| 465 | } | |
| 466 | ||
| 467 | test "comptime function with the same args is memoized" { | |
| 468 | comptime { | |
| 469 | expect(MakeType(i32) == MakeType(i32)); | |
| 470 | expect(MakeType(i32) != MakeType(f64)); | |
| 471 | } | |
| 472 | } | |
| 473 | ||
| 474 | fn MakeType(comptime T: type) type { | |
| 475 | return struct { | |
| 476 | field: T, | |
| 477 | }; | |
| 478 | } | |
| 479 | ||
| 480 | test "comptime function with mutable pointer is not memoized" { | |
| 481 | comptime { | |
| 482 | var x: i32 = 1; | |
| 483 | const ptr = &x; | |
| 484 | increment(ptr); | |
| 485 | increment(ptr); | |
| 486 | expect(x == 3); | |
| 487 | } | |
| 488 | } | |
| 489 | ||
| 490 | fn increment(value: *i32) void { | |
| 491 | value.* += 1; | |
| 492 | } | |
| 493 | ||
| 494 | fn generateTable(comptime T: type) [1010]T { | |
| 495 | var res: [1010]T = undefined; | |
| 496 | var i: usize = 0; | |
| 497 | while (i < 1010) : (i += 1) { | |
| 498 | res[i] = @intCast(T, i); | |
| 499 | } | |
| 500 | return res; | |
| 501 | } | |
| 502 | ||
| 503 | fn doesAlotT(comptime T: type, value: usize) T { | |
| 504 | @setEvalBranchQuota(5000); | |
| 505 | const table = comptime blk: { | |
| 506 | break :blk generateTable(T); | |
| 507 | }; | |
| 508 | return table[value]; | |
| 509 | } | |
| 510 | ||
| 511 | test "@setEvalBranchQuota at same scope as generic function call" { | |
| 512 | expect(doesAlotT(u32, 2) == 2); | |
| 513 | } | |
| 514 | ||
| 515 | test "comptime slice of slice preserves comptime var" { | |
| 516 | comptime { | |
| 517 | var buff: [10]u8 = undefined; | |
| 518 | buff[0..][0..][0] = 1; | |
| 519 | expect(buff[0..][0..][0] == 1); | |
| 520 | } | |
| 521 | } | |
| 522 | ||
| 523 | test "comptime slice of pointer preserves comptime var" { | |
| 524 | comptime { | |
| 525 | var buff: [10]u8 = undefined; | |
| 526 | var a = @ptrCast([*]u8, &buff); | |
| 527 | a[0..1][0] = 1; | |
| 528 | expect(buff[0..][0..][0] == 1); | |
| 529 | } | |
| 530 | } | |
| 531 | ||
| 532 | const SingleFieldStruct = struct { | |
| 533 | x: i32, | |
| 534 | ||
| 535 | fn read_x(self: *const SingleFieldStruct) i32 { | |
| 536 | return self.x; | |
| 537 | } | |
| 538 | }; | |
| 539 | test "const ptr to comptime mutable data is not memoized" { | |
| 540 | comptime { | |
| 541 | var foo = SingleFieldStruct{ .x = 1 }; | |
| 542 | expect(foo.read_x() == 1); | |
| 543 | foo.x = 2; | |
| 544 | expect(foo.read_x() == 2); | |
| 545 | } | |
| 546 | } | |
| 547 | ||
| 548 | test "array concat of slices gives slice" { | |
| 549 | comptime { | |
| 550 | var a: []const u8 = "aoeu"; | |
| 551 | var b: []const u8 = "asdf"; | |
| 552 | const c = a ++ b; | |
| 553 | expect(std.mem.eql(u8, c, "aoeuasdf")); | |
| 554 | } | |
| 555 | } | |
| 556 | ||
| 557 | test "comptime shlWithOverflow" { | |
| 558 | const ct_shifted: u64 = comptime amt: { | |
| 559 | var amt = @as(u64, 0); | |
| 560 | _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt); | |
| 561 | break :amt amt; | |
| 562 | }; | |
| 563 | ||
| 564 | const rt_shifted: u64 = amt: { | |
| 565 | var amt = @as(u64, 0); | |
| 566 | _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt); | |
| 567 | break :amt amt; | |
| 568 | }; | |
| 569 | ||
| 570 | expect(ct_shifted == rt_shifted); | |
| 571 | } | |
| 572 | ||
| 573 | test "runtime 128 bit integer division" { | |
| 574 | var a: u128 = 152313999999999991610955792383; | |
| 575 | var b: u128 = 10000000000000000000; | |
| 576 | var c = a / b; | |
| 577 | expect(c == 15231399999); | |
| 578 | } | |
| 579 | ||
| 580 | pub const Info = struct { | |
| 581 | version: u8, | |
| 582 | }; | |
| 583 | ||
| 584 | pub const diamond_info = Info{ .version = 0 }; | |
| 585 | ||
| 586 | test "comptime modification of const struct field" { | |
| 587 | comptime { | |
| 588 | var res = diamond_info; | |
| 589 | res.version = 1; | |
| 590 | expect(diamond_info.version == 0); | |
| 591 | expect(res.version == 1); | |
| 592 | } | |
| 593 | } | |
| 594 | ||
| 595 | test "pointer to type" { | |
| 596 | comptime { | |
| 597 | var T: type = i32; | |
| 598 | expect(T == i32); | |
| 599 | var ptr = &T; | |
| 600 | expect(@TypeOf(ptr) == *type); | |
| 601 | ptr.* = f32; | |
| 602 | expect(T == f32); | |
| 603 | expect(*T == *f32); | |
| 604 | } | |
| 605 | } | |
| 606 | ||
| 607 | test "slice of type" { | |
| 608 | comptime { | |
| 609 | var types_array = [_]type{ i32, f64, type }; | |
| 610 | for (types_array) |T, i| { | |
| 611 | switch (i) { | |
| 612 | 0 => expect(T == i32), | |
| 613 | 1 => expect(T == f64), | |
| 614 | 2 => expect(T == type), | |
| 615 | else => unreachable, | |
| 616 | } | |
| 617 | } | |
| 618 | for (types_array[0..]) |T, i| { | |
| 619 | switch (i) { | |
| 620 | 0 => expect(T == i32), | |
| 621 | 1 => expect(T == f64), | |
| 622 | 2 => expect(T == type), | |
| 623 | else => unreachable, | |
| 624 | } | |
| 625 | } | |
| 626 | } | |
| 627 | } | |
| 628 | ||
| 629 | const Wrapper = struct { | |
| 630 | T: type, | |
| 631 | }; | |
| 632 | ||
| 633 | fn wrap(comptime T: type) Wrapper { | |
| 634 | return Wrapper{ .T = T }; | |
| 635 | } | |
| 636 | ||
| 637 | test "function which returns struct with type field causes implicit comptime" { | |
| 638 | const ty = wrap(i32).T; | |
| 639 | expect(ty == i32); | |
| 640 | } | |
| 641 | ||
| 642 | test "call method with comptime pass-by-non-copying-value self parameter" { | |
| 643 | const S = struct { | |
| 644 | a: u8, | |
| 645 | ||
| 646 | fn b(comptime s: @This()) u8 { | |
| 647 | return s.a; | |
| 648 | } | |
| 649 | }; | |
| 650 | ||
| 651 | const s = S{ .a = 2 }; | |
| 652 | var b = s.b(); | |
| 653 | expect(b == 2); | |
| 654 | } | |
| 655 | ||
| 656 | test "@tagName of @typeInfo" { | |
| 657 | const str = @tagName(@typeInfo(u8)); | |
| 658 | expect(std.mem.eql(u8, str, "Int")); | |
| 659 | } | |
| 660 | ||
| 661 | test "setting backward branch quota just before a generic fn call" { | |
| 662 | @setEvalBranchQuota(1001); | |
| 663 | loopNTimes(1001); | |
| 664 | } | |
| 665 | ||
| 666 | fn loopNTimes(comptime n: usize) void { | |
| 667 | comptime var i = 0; | |
| 668 | inline while (i < n) : (i += 1) {} | |
| 669 | } | |
| 670 | ||
| 671 | test "variable inside inline loop that has different types on different iterations" { | |
| 672 | testVarInsideInlineLoop(.{ true, @as(u32, 42) }); | |
| 673 | } | |
| 674 | ||
| 675 | fn testVarInsideInlineLoop(args: anytype) void { | |
| 676 | comptime var i = 0; | |
| 677 | inline while (i < args.len) : (i += 1) { | |
| 678 | const x = args[i]; | |
| 679 | if (i == 0) expect(x); | |
| 680 | if (i == 1) expect(x == 42); | |
| 681 | } | |
| 682 | } | |
| 683 | ||
| 684 | test "inline for with same type but different values" { | |
| 685 | var res: usize = 0; | |
| 686 | inline for ([_]type{ [2]u8, [1]u8, [2]u8 }) |T| { | |
| 687 | var a: T = undefined; | |
| 688 | res += a.len; | |
| 689 | } | |
| 690 | expect(res == 5); | |
| 691 | } | |
| 692 | ||
| 693 | test "refer to the type of a generic function" { | |
| 694 | const Func = fn (type) void; | |
| 695 | const f: Func = doNothingWithType; | |
| 696 | f(i32); | |
| 697 | } | |
| 698 | ||
| 699 | fn doNothingWithType(comptime T: type) void {} | |
| 700 | ||
| 701 | test "zero extend from u0 to u1" { | |
| 702 | var zero_u0: u0 = 0; | |
| 703 | var zero_u1: u1 = zero_u0; | |
| 704 | expect(zero_u1 == 0); | |
| 705 | } | |
| 706 | ||
| 707 | test "bit shift a u1" { | |
| 708 | var x: u1 = 1; | |
| 709 | var y = x << 0; | |
| 710 | expect(y == 1); | |
| 711 | } | |
| 712 | ||
| 713 | test "comptime pointer cast array and then slice" { | |
| 714 | const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 }; | |
| 715 | ||
| 716 | const ptrA: [*]const u8 = @ptrCast([*]const u8, &array); | |
| 717 | const sliceA: []const u8 = ptrA[0..2]; | |
| 718 | ||
| 719 | const ptrB: [*]const u8 = &array; | |
| 720 | const sliceB: []const u8 = ptrB[0..2]; | |
| 721 | ||
| 722 | expect(sliceA[1] == 2); | |
| 723 | expect(sliceB[1] == 2); | |
| 724 | } | |
| 725 | ||
| 726 | test "slice bounds in comptime concatenation" { | |
| 727 | const bs = comptime blk: { | |
| 728 | const b = "........1........"; | |
| 729 | break :blk b[8..9]; | |
| 730 | }; | |
| 731 | const str = "" ++ bs; | |
| 732 | expect(str.len == 1); | |
| 733 | expect(std.mem.eql(u8, str, "1")); | |
| 734 | ||
| 735 | const str2 = bs ++ ""; | |
| 736 | expect(str2.len == 1); | |
| 737 | expect(std.mem.eql(u8, str2, "1")); | |
| 738 | } | |
| 739 | ||
| 740 | test "comptime bitwise operators" { | |
| 741 | comptime { | |
| 742 | expect(3 & 1 == 1); | |
| 743 | expect(3 & -1 == 3); | |
| 744 | expect(-3 & -1 == -3); | |
| 745 | expect(3 | -1 == -1); | |
| 746 | expect(-3 | -1 == -1); | |
| 747 | expect(3 ^ -1 == -4); | |
| 748 | expect(-3 ^ -1 == 2); | |
| 749 | expect(~@as(i8, -1) == 0); | |
| 750 | expect(~@as(i128, -1) == 0); | |
| 751 | expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611); | |
| 752 | expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615); | |
| 753 | expect(~@as(u128, 0) == 0xffffffffffffffffffffffffffffffff); | |
| 754 | } | |
| 755 | } | |
| 756 | ||
| 757 | test "*align(1) u16 is the same as *align(1:0:2) u16" { | |
| 758 | comptime { | |
| 759 | expect(*align(1:0:2) u16 == *align(1) u16); | |
| 760 | expect(*align(2:0:2) u16 == *u16); | |
| 761 | } | |
| 762 | } | |
| 763 | ||
| 764 | test "array concatenation forces comptime" { | |
| 765 | var a = oneItem(3) ++ oneItem(4); | |
| 766 | expect(std.mem.eql(i32, &a, &[_]i32{ 3, 4 })); | |
| 767 | } | |
| 768 | ||
| 769 | test "array multiplication forces comptime" { | |
| 770 | var a = oneItem(3) ** scalar(2); | |
| 771 | expect(std.mem.eql(i32, &a, &[_]i32{ 3, 3 })); | |
| 772 | } | |
| 773 | ||
| 774 | fn oneItem(x: i32) [1]i32 { | |
| 775 | return [_]i32{x}; | |
| 776 | } | |
| 777 | ||
| 778 | fn scalar(x: u32) u32 { | |
| 779 | return x; | |
| 780 | } | |
| 781 | ||
| 782 | test "no undeclared identifier error in unanalyzed branches" { | |
| 783 | if (false) { | |
| 784 | lol_this_doesnt_exist = nonsense; | |
| 785 | } | |
| 786 | } | |
| 787 | ||
| 788 | test "comptime assign int to optional int" { | |
| 789 | comptime { | |
| 790 | var x: ?i32 = null; | |
| 791 | x = 2; | |
| 792 | x.? *= 10; | |
| 793 | expectEqual(20, x.?); | |
| 794 | } | |
| 795 | } | |
| 796 | ||
| 797 | test "return 0 from function that has u0 return type" { | |
| 798 | const S = struct { | |
| 799 | fn foo_zero() u0 { | |
| 800 | return 0; | |
| 801 | } | |
| 802 | }; | |
| 803 | comptime { | |
| 804 | if (S.foo_zero() != 0) { | |
| 805 | @compileError("test failed"); | |
| 806 | } | |
| 807 | } | |
| 808 | } | |
| 809 | ||
| 810 | test "two comptime calls with array default initialized to undefined" { | |
| 811 | const S = struct { | |
| 812 | const CrossTarget = struct { | |
| 813 | dynamic_linker: DynamicLinker = DynamicLinker{}, | |
| 814 | ||
| 815 | pub fn parse() void { | |
| 816 | var result: CrossTarget = .{}; | |
| 817 | result.getCpuArch(); | |
| 818 | } | |
| 819 | ||
| 820 | pub fn getCpuArch(self: CrossTarget) void {} | |
| 821 | }; | |
| 822 | ||
| 823 | const DynamicLinker = struct { | |
| 824 | buffer: [255]u8 = undefined, | |
| 825 | }; | |
| 826 | }; | |
| 827 | ||
| 828 | comptime { | |
| 829 | S.CrossTarget.parse(); | |
| 830 | S.CrossTarget.parse(); | |
| 831 | } | |
| 832 | } |
test/stage1/behavior/field_parent_ptr.zig deleted-41| ... | ... | @@ -1,41 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@fieldParentPtr non-first field" { | |
| 4 | testParentFieldPtr(&foo.c); | |
| 5 | comptime testParentFieldPtr(&foo.c); | |
| 6 | } | |
| 7 | ||
| 8 | test "@fieldParentPtr first field" { | |
| 9 | testParentFieldPtrFirst(&foo.a); | |
| 10 | comptime testParentFieldPtrFirst(&foo.a); | |
| 11 | } | |
| 12 | ||
| 13 | const Foo = struct { | |
| 14 | a: bool, | |
| 15 | b: f32, | |
| 16 | c: i32, | |
| 17 | d: i32, | |
| 18 | }; | |
| 19 | ||
| 20 | const foo = Foo{ | |
| 21 | .a = true, | |
| 22 | .b = 0.123, | |
| 23 | .c = 1234, | |
| 24 | .d = -10, | |
| 25 | }; | |
| 26 | ||
| 27 | fn testParentFieldPtr(c: *const i32) void { | |
| 28 | expect(c == &foo.c); | |
| 29 | ||
| 30 | const base = @fieldParentPtr(Foo, "c", c); | |
| 31 | expect(base == &foo); | |
| 32 | expect(&base.c == c); | |
| 33 | } | |
| 34 | ||
| 35 | fn testParentFieldPtrFirst(a: *const bool) void { | |
| 36 | expect(a == &foo.a); | |
| 37 | ||
| 38 | const base = @fieldParentPtr(Foo, "a", a); | |
| 39 | expect(base == &foo); | |
| 40 | expect(&base.a == a); | |
| 41 | } |
test/stage1/behavior/floatop.zig deleted-465| ... | ... | @@ -1,465 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const math = std.math; | |
| 4 | const pi = std.math.pi; | |
| 5 | const e = std.math.e; | |
| 6 | const Vector = std.meta.Vector; | |
| 7 | ||
| 8 | const epsilon = 0.000001; | |
| 9 | ||
| 10 | test "@sqrt" { | |
| 11 | comptime testSqrt(); | |
| 12 | testSqrt(); | |
| 13 | } | |
| 14 | ||
| 15 | fn testSqrt() void { | |
| 16 | { | |
| 17 | var a: f16 = 4; | |
| 18 | expect(@sqrt(a) == 2); | |
| 19 | } | |
| 20 | { | |
| 21 | var a: f32 = 9; | |
| 22 | expect(@sqrt(a) == 3); | |
| 23 | var b: f32 = 1.1; | |
| 24 | expect(math.approxEqAbs(f32, @sqrt(b), 1.0488088481701516, epsilon)); | |
| 25 | } | |
| 26 | { | |
| 27 | var a: f64 = 25; | |
| 28 | expect(@sqrt(a) == 5); | |
| 29 | } | |
| 30 | { | |
| 31 | const a: comptime_float = 25.0; | |
| 32 | expect(@sqrt(a) == 5.0); | |
| 33 | } | |
| 34 | // TODO https://github.com/ziglang/zig/issues/4026 | |
| 35 | //{ | |
| 36 | // var a: f128 = 49; | |
| 37 | // expect(@sqrt(a) == 7); | |
| 38 | //} | |
| 39 | { | |
| 40 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 41 | var result = @sqrt(v); | |
| 42 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 1.1)), result[0], epsilon)); | |
| 43 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 2.2)), result[1], epsilon)); | |
| 44 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 3.3)), result[2], epsilon)); | |
| 45 | expect(math.approxEqAbs(f32, @sqrt(@as(f32, 4.4)), result[3], epsilon)); | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | test "more @sqrt f16 tests" { | |
| 50 | // TODO these are not all passing at comptime | |
| 51 | expect(@sqrt(@as(f16, 0.0)) == 0.0); | |
| 52 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon)); | |
| 53 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 3.6)), 1.897367, epsilon)); | |
| 54 | expect(@sqrt(@as(f16, 4.0)) == 2.0); | |
| 55 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 7.539840)), 2.745877, epsilon)); | |
| 56 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 19.230934)), 4.385309, epsilon)); | |
| 57 | expect(@sqrt(@as(f16, 64.0)) == 8.0); | |
| 58 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 64.1)), 8.006248, epsilon)); | |
| 59 | expect(math.approxEqAbs(f16, @sqrt(@as(f16, 8942.230469)), 94.563370, epsilon)); | |
| 60 | ||
| 61 | // special cases | |
| 62 | expect(math.isPositiveInf(@sqrt(@as(f16, math.inf(f16))))); | |
| 63 | expect(@sqrt(@as(f16, 0.0)) == 0.0); | |
| 64 | expect(@sqrt(@as(f16, -0.0)) == -0.0); | |
| 65 | expect(math.isNan(@sqrt(@as(f16, -1.0)))); | |
| 66 | expect(math.isNan(@sqrt(@as(f16, math.nan(f16))))); | |
| 67 | } | |
| 68 | ||
| 69 | test "@sin" { | |
| 70 | comptime testSin(); | |
| 71 | testSin(); | |
| 72 | } | |
| 73 | ||
| 74 | fn testSin() void { | |
| 75 | // TODO test f128, and c_longdouble | |
| 76 | // https://github.com/ziglang/zig/issues/4026 | |
| 77 | { | |
| 78 | var a: f16 = 0; | |
| 79 | expect(@sin(a) == 0); | |
| 80 | } | |
| 81 | { | |
| 82 | var a: f32 = 0; | |
| 83 | expect(@sin(a) == 0); | |
| 84 | } | |
| 85 | { | |
| 86 | var a: f64 = 0; | |
| 87 | expect(@sin(a) == 0); | |
| 88 | } | |
| 89 | { | |
| 90 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 91 | var result = @sin(v); | |
| 92 | expect(math.approxEqAbs(f32, @sin(@as(f32, 1.1)), result[0], epsilon)); | |
| 93 | expect(math.approxEqAbs(f32, @sin(@as(f32, 2.2)), result[1], epsilon)); | |
| 94 | expect(math.approxEqAbs(f32, @sin(@as(f32, 3.3)), result[2], epsilon)); | |
| 95 | expect(math.approxEqAbs(f32, @sin(@as(f32, 4.4)), result[3], epsilon)); | |
| 96 | } | |
| 97 | } | |
| 98 | ||
| 99 | test "@cos" { | |
| 100 | comptime testCos(); | |
| 101 | testCos(); | |
| 102 | } | |
| 103 | ||
| 104 | fn testCos() void { | |
| 105 | // TODO test f128, and c_longdouble | |
| 106 | // https://github.com/ziglang/zig/issues/4026 | |
| 107 | { | |
| 108 | var a: f16 = 0; | |
| 109 | expect(@cos(a) == 1); | |
| 110 | } | |
| 111 | { | |
| 112 | var a: f32 = 0; | |
| 113 | expect(@cos(a) == 1); | |
| 114 | } | |
| 115 | { | |
| 116 | var a: f64 = 0; | |
| 117 | expect(@cos(a) == 1); | |
| 118 | } | |
| 119 | { | |
| 120 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 121 | var result = @cos(v); | |
| 122 | expect(math.approxEqAbs(f32, @cos(@as(f32, 1.1)), result[0], epsilon)); | |
| 123 | expect(math.approxEqAbs(f32, @cos(@as(f32, 2.2)), result[1], epsilon)); | |
| 124 | expect(math.approxEqAbs(f32, @cos(@as(f32, 3.3)), result[2], epsilon)); | |
| 125 | expect(math.approxEqAbs(f32, @cos(@as(f32, 4.4)), result[3], epsilon)); | |
| 126 | } | |
| 127 | } | |
| 128 | ||
| 129 | test "@exp" { | |
| 130 | comptime testExp(); | |
| 131 | testExp(); | |
| 132 | } | |
| 133 | ||
| 134 | fn testExp() void { | |
| 135 | // TODO test f128, and c_longdouble | |
| 136 | // https://github.com/ziglang/zig/issues/4026 | |
| 137 | { | |
| 138 | var a: f16 = 0; | |
| 139 | expect(@exp(a) == 1); | |
| 140 | } | |
| 141 | { | |
| 142 | var a: f32 = 0; | |
| 143 | expect(@exp(a) == 1); | |
| 144 | } | |
| 145 | { | |
| 146 | var a: f64 = 0; | |
| 147 | expect(@exp(a) == 1); | |
| 148 | } | |
| 149 | { | |
| 150 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 151 | var result = @exp(v); | |
| 152 | expect(math.approxEqAbs(f32, @exp(@as(f32, 1.1)), result[0], epsilon)); | |
| 153 | expect(math.approxEqAbs(f32, @exp(@as(f32, 2.2)), result[1], epsilon)); | |
| 154 | expect(math.approxEqAbs(f32, @exp(@as(f32, 0.3)), result[2], epsilon)); | |
| 155 | expect(math.approxEqAbs(f32, @exp(@as(f32, 0.4)), result[3], epsilon)); | |
| 156 | } | |
| 157 | } | |
| 158 | ||
| 159 | test "@exp2" { | |
| 160 | comptime testExp2(); | |
| 161 | testExp2(); | |
| 162 | } | |
| 163 | ||
| 164 | fn testExp2() void { | |
| 165 | // TODO test f128, and c_longdouble | |
| 166 | // https://github.com/ziglang/zig/issues/4026 | |
| 167 | { | |
| 168 | var a: f16 = 2; | |
| 169 | expect(@exp2(a) == 4); | |
| 170 | } | |
| 171 | { | |
| 172 | var a: f32 = 2; | |
| 173 | expect(@exp2(a) == 4); | |
| 174 | } | |
| 175 | { | |
| 176 | var a: f64 = 2; | |
| 177 | expect(@exp2(a) == 4); | |
| 178 | } | |
| 179 | { | |
| 180 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 181 | var result = @exp2(v); | |
| 182 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 1.1)), result[0], epsilon)); | |
| 183 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 2.2)), result[1], epsilon)); | |
| 184 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.3)), result[2], epsilon)); | |
| 185 | expect(math.approxEqAbs(f32, @exp2(@as(f32, 0.4)), result[3], epsilon)); | |
| 186 | } | |
| 187 | } | |
| 188 | ||
| 189 | test "@log" { | |
| 190 | // Old musl (and glibc?), and our current math.ln implementation do not return 1 | |
| 191 | // so also accept those values. | |
| 192 | comptime testLog(); | |
| 193 | testLog(); | |
| 194 | } | |
| 195 | ||
| 196 | fn testLog() void { | |
| 197 | // TODO test f128, and c_longdouble | |
| 198 | // https://github.com/ziglang/zig/issues/4026 | |
| 199 | { | |
| 200 | var a: f16 = e; | |
| 201 | expect(math.approxEqAbs(f16, @log(a), 1, epsilon)); | |
| 202 | } | |
| 203 | { | |
| 204 | var a: f32 = e; | |
| 205 | expect(@log(a) == 1 or @log(a) == @bitCast(f32, @as(u32, 0x3f7fffff))); | |
| 206 | } | |
| 207 | { | |
| 208 | var a: f64 = e; | |
| 209 | expect(@log(a) == 1 or @log(a) == @bitCast(f64, @as(u64, 0x3ff0000000000000))); | |
| 210 | } | |
| 211 | { | |
| 212 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 213 | var result = @log(v); | |
| 214 | expect(math.approxEqAbs(f32, @log(@as(f32, 1.1)), result[0], epsilon)); | |
| 215 | expect(math.approxEqAbs(f32, @log(@as(f32, 2.2)), result[1], epsilon)); | |
| 216 | expect(math.approxEqAbs(f32, @log(@as(f32, 0.3)), result[2], epsilon)); | |
| 217 | expect(math.approxEqAbs(f32, @log(@as(f32, 0.4)), result[3], epsilon)); | |
| 218 | } | |
| 219 | } | |
| 220 | ||
| 221 | test "@log2" { | |
| 222 | comptime testLog2(); | |
| 223 | testLog2(); | |
| 224 | } | |
| 225 | ||
| 226 | fn testLog2() void { | |
| 227 | // TODO test f128, and c_longdouble | |
| 228 | // https://github.com/ziglang/zig/issues/4026 | |
| 229 | { | |
| 230 | var a: f16 = 4; | |
| 231 | expect(@log2(a) == 2); | |
| 232 | } | |
| 233 | { | |
| 234 | var a: f32 = 4; | |
| 235 | expect(@log2(a) == 2); | |
| 236 | } | |
| 237 | { | |
| 238 | var a: f64 = 4; | |
| 239 | expect(@log2(a) == 2); | |
| 240 | } | |
| 241 | { | |
| 242 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 243 | var result = @log2(v); | |
| 244 | expect(math.approxEqAbs(f32, @log2(@as(f32, 1.1)), result[0], epsilon)); | |
| 245 | expect(math.approxEqAbs(f32, @log2(@as(f32, 2.2)), result[1], epsilon)); | |
| 246 | expect(math.approxEqAbs(f32, @log2(@as(f32, 0.3)), result[2], epsilon)); | |
| 247 | expect(math.approxEqAbs(f32, @log2(@as(f32, 0.4)), result[3], epsilon)); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 | test "@log10" { | |
| 252 | comptime testLog10(); | |
| 253 | testLog10(); | |
| 254 | } | |
| 255 | ||
| 256 | fn testLog10() void { | |
| 257 | // TODO test f128, and c_longdouble | |
| 258 | // https://github.com/ziglang/zig/issues/4026 | |
| 259 | { | |
| 260 | var a: f16 = 100; | |
| 261 | expect(@log10(a) == 2); | |
| 262 | } | |
| 263 | { | |
| 264 | var a: f32 = 100; | |
| 265 | expect(@log10(a) == 2); | |
| 266 | } | |
| 267 | { | |
| 268 | var a: f64 = 1000; | |
| 269 | expect(@log10(a) == 3); | |
| 270 | } | |
| 271 | { | |
| 272 | var v: Vector(4, f32) = [_]f32{ 1.1, 2.2, 0.3, 0.4 }; | |
| 273 | var result = @log10(v); | |
| 274 | expect(math.approxEqAbs(f32, @log10(@as(f32, 1.1)), result[0], epsilon)); | |
| 275 | expect(math.approxEqAbs(f32, @log10(@as(f32, 2.2)), result[1], epsilon)); | |
| 276 | expect(math.approxEqAbs(f32, @log10(@as(f32, 0.3)), result[2], epsilon)); | |
| 277 | expect(math.approxEqAbs(f32, @log10(@as(f32, 0.4)), result[3], epsilon)); | |
| 278 | } | |
| 279 | } | |
| 280 | ||
| 281 | test "@fabs" { | |
| 282 | comptime testFabs(); | |
| 283 | testFabs(); | |
| 284 | } | |
| 285 | ||
| 286 | fn testFabs() void { | |
| 287 | // TODO test f128, and c_longdouble | |
| 288 | // https://github.com/ziglang/zig/issues/4026 | |
| 289 | { | |
| 290 | var a: f16 = -2.5; | |
| 291 | var b: f16 = 2.5; | |
| 292 | expect(@fabs(a) == 2.5); | |
| 293 | expect(@fabs(b) == 2.5); | |
| 294 | } | |
| 295 | { | |
| 296 | var a: f32 = -2.5; | |
| 297 | var b: f32 = 2.5; | |
| 298 | expect(@fabs(a) == 2.5); | |
| 299 | expect(@fabs(b) == 2.5); | |
| 300 | } | |
| 301 | { | |
| 302 | var a: f64 = -2.5; | |
| 303 | var b: f64 = 2.5; | |
| 304 | expect(@fabs(a) == 2.5); | |
| 305 | expect(@fabs(b) == 2.5); | |
| 306 | } | |
| 307 | { | |
| 308 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 309 | var result = @fabs(v); | |
| 310 | expect(math.approxEqAbs(f32, @fabs(@as(f32, 1.1)), result[0], epsilon)); | |
| 311 | expect(math.approxEqAbs(f32, @fabs(@as(f32, -2.2)), result[1], epsilon)); | |
| 312 | expect(math.approxEqAbs(f32, @fabs(@as(f32, 0.3)), result[2], epsilon)); | |
| 313 | expect(math.approxEqAbs(f32, @fabs(@as(f32, -0.4)), result[3], epsilon)); | |
| 314 | } | |
| 315 | } | |
| 316 | ||
| 317 | test "@floor" { | |
| 318 | comptime testFloor(); | |
| 319 | testFloor(); | |
| 320 | } | |
| 321 | ||
| 322 | fn testFloor() void { | |
| 323 | // TODO test f128, and c_longdouble | |
| 324 | // https://github.com/ziglang/zig/issues/4026 | |
| 325 | { | |
| 326 | var a: f16 = 2.1; | |
| 327 | expect(@floor(a) == 2); | |
| 328 | } | |
| 329 | { | |
| 330 | var a: f32 = 2.1; | |
| 331 | expect(@floor(a) == 2); | |
| 332 | } | |
| 333 | { | |
| 334 | var a: f64 = 3.5; | |
| 335 | expect(@floor(a) == 3); | |
| 336 | } | |
| 337 | { | |
| 338 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 339 | var result = @floor(v); | |
| 340 | expect(math.approxEqAbs(f32, @floor(@as(f32, 1.1)), result[0], epsilon)); | |
| 341 | expect(math.approxEqAbs(f32, @floor(@as(f32, -2.2)), result[1], epsilon)); | |
| 342 | expect(math.approxEqAbs(f32, @floor(@as(f32, 0.3)), result[2], epsilon)); | |
| 343 | expect(math.approxEqAbs(f32, @floor(@as(f32, -0.4)), result[3], epsilon)); | |
| 344 | } | |
| 345 | } | |
| 346 | ||
| 347 | test "@ceil" { | |
| 348 | comptime testCeil(); | |
| 349 | testCeil(); | |
| 350 | } | |
| 351 | ||
| 352 | fn testCeil() void { | |
| 353 | // TODO test f128, and c_longdouble | |
| 354 | // https://github.com/ziglang/zig/issues/4026 | |
| 355 | { | |
| 356 | var a: f16 = 2.1; | |
| 357 | expect(@ceil(a) == 3); | |
| 358 | } | |
| 359 | { | |
| 360 | var a: f32 = 2.1; | |
| 361 | expect(@ceil(a) == 3); | |
| 362 | } | |
| 363 | { | |
| 364 | var a: f64 = 3.5; | |
| 365 | expect(@ceil(a) == 4); | |
| 366 | } | |
| 367 | { | |
| 368 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 369 | var result = @ceil(v); | |
| 370 | expect(math.approxEqAbs(f32, @ceil(@as(f32, 1.1)), result[0], epsilon)); | |
| 371 | expect(math.approxEqAbs(f32, @ceil(@as(f32, -2.2)), result[1], epsilon)); | |
| 372 | expect(math.approxEqAbs(f32, @ceil(@as(f32, 0.3)), result[2], epsilon)); | |
| 373 | expect(math.approxEqAbs(f32, @ceil(@as(f32, -0.4)), result[3], epsilon)); | |
| 374 | } | |
| 375 | } | |
| 376 | ||
| 377 | test "@trunc" { | |
| 378 | comptime testTrunc(); | |
| 379 | testTrunc(); | |
| 380 | } | |
| 381 | ||
| 382 | fn testTrunc() void { | |
| 383 | // TODO test f128, and c_longdouble | |
| 384 | // https://github.com/ziglang/zig/issues/4026 | |
| 385 | { | |
| 386 | var a: f16 = 2.1; | |
| 387 | expect(@trunc(a) == 2); | |
| 388 | } | |
| 389 | { | |
| 390 | var a: f32 = 2.1; | |
| 391 | expect(@trunc(a) == 2); | |
| 392 | } | |
| 393 | { | |
| 394 | var a: f64 = -3.5; | |
| 395 | expect(@trunc(a) == -3); | |
| 396 | } | |
| 397 | { | |
| 398 | var v: Vector(4, f32) = [_]f32{ 1.1, -2.2, 0.3, -0.4 }; | |
| 399 | var result = @trunc(v); | |
| 400 | expect(math.approxEqAbs(f32, @trunc(@as(f32, 1.1)), result[0], epsilon)); | |
| 401 | expect(math.approxEqAbs(f32, @trunc(@as(f32, -2.2)), result[1], epsilon)); | |
| 402 | expect(math.approxEqAbs(f32, @trunc(@as(f32, 0.3)), result[2], epsilon)); | |
| 403 | expect(math.approxEqAbs(f32, @trunc(@as(f32, -0.4)), result[3], epsilon)); | |
| 404 | } | |
| 405 | } | |
| 406 | ||
| 407 | test "floating point comparisons" { | |
| 408 | testFloatComparisons(); | |
| 409 | comptime testFloatComparisons(); | |
| 410 | } | |
| 411 | ||
| 412 | fn testFloatComparisons() void { | |
| 413 | inline for ([_]type{ f16, f32, f64, f128 }) |ty| { | |
| 414 | // No decimal part | |
| 415 | { | |
| 416 | const x: ty = 1.0; | |
| 417 | expect(x == 1); | |
| 418 | expect(x != 0); | |
| 419 | expect(x > 0); | |
| 420 | expect(x < 2); | |
| 421 | expect(x >= 1); | |
| 422 | expect(x <= 1); | |
| 423 | } | |
| 424 | // Non-zero decimal part | |
| 425 | { | |
| 426 | const x: ty = 1.5; | |
| 427 | expect(x != 1); | |
| 428 | expect(x != 2); | |
| 429 | expect(x > 1); | |
| 430 | expect(x < 2); | |
| 431 | expect(x >= 1); | |
| 432 | expect(x <= 2); | |
| 433 | } | |
| 434 | } | |
| 435 | } | |
| 436 | ||
| 437 | test "different sized float comparisons" { | |
| 438 | testDifferentSizedFloatComparisons(); | |
| 439 | comptime testDifferentSizedFloatComparisons(); | |
| 440 | } | |
| 441 | ||
| 442 | fn testDifferentSizedFloatComparisons() void { | |
| 443 | var a: f16 = 1; | |
| 444 | var b: f64 = 2; | |
| 445 | expect(a < b); | |
| 446 | } | |
| 447 | ||
| 448 | // TODO This is waiting on library support for the Windows build (not sure why the other's don't need it) | |
| 449 | //test "@nearbyint" { | |
| 450 | // comptime testNearbyInt(); | |
| 451 | // testNearbyInt(); | |
| 452 | //} | |
| 453 | ||
| 454 | //fn testNearbyInt() void { | |
| 455 | // // TODO test f16, f128, and c_longdouble | |
| 456 | // // https://github.com/ziglang/zig/issues/4026 | |
| 457 | // { | |
| 458 | // var a: f32 = 2.1; | |
| 459 | // expect(@nearbyint(a) == 2); | |
| 460 | // } | |
| 461 | // { | |
| 462 | // var a: f64 = -3.75; | |
| 463 | // expect(@nearbyint(a) == -4); | |
| 464 | // } | |
| 465 | //} |
test/stage1/behavior/fn.zig deleted-287| ... | ... | @@ -1,287 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const testing = std.testing; | |
| 4 | const expect = testing.expect; | |
| 5 | const expectEqual = testing.expectEqual; | |
| 6 | ||
| 7 | test "params" { | |
| 8 | expect(testParamsAdd(22, 11) == 33); | |
| 9 | } | |
| 10 | fn testParamsAdd(a: i32, b: i32) i32 { | |
| 11 | return a + b; | |
| 12 | } | |
| 13 | ||
| 14 | test "local variables" { | |
| 15 | testLocVars(2); | |
| 16 | } | |
| 17 | fn testLocVars(b: i32) void { | |
| 18 | const a: i32 = 1; | |
| 19 | if (a + b != 3) unreachable; | |
| 20 | } | |
| 21 | ||
| 22 | test "void parameters" { | |
| 23 | voidFun(1, void{}, 2, {}); | |
| 24 | } | |
| 25 | fn voidFun(a: i32, b: void, c: i32, d: void) void { | |
| 26 | const v = b; | |
| 27 | const vv: void = if (a == 1) v else {}; | |
| 28 | expect(a + c == 3); | |
| 29 | return vv; | |
| 30 | } | |
| 31 | ||
| 32 | test "mutable local variables" { | |
| 33 | var zero: i32 = 0; | |
| 34 | expect(zero == 0); | |
| 35 | ||
| 36 | var i = @as(i32, 0); | |
| 37 | while (i != 3) { | |
| 38 | i += 1; | |
| 39 | } | |
| 40 | expect(i == 3); | |
| 41 | } | |
| 42 | ||
| 43 | test "separate block scopes" { | |
| 44 | { | |
| 45 | const no_conflict: i32 = 5; | |
| 46 | expect(no_conflict == 5); | |
| 47 | } | |
| 48 | ||
| 49 | const c = x: { | |
| 50 | const no_conflict = @as(i32, 10); | |
| 51 | break :x no_conflict; | |
| 52 | }; | |
| 53 | expect(c == 10); | |
| 54 | } | |
| 55 | ||
| 56 | test "call function with empty string" { | |
| 57 | acceptsString(""); | |
| 58 | } | |
| 59 | ||
| 60 | fn acceptsString(foo: []u8) void {} | |
| 61 | ||
| 62 | fn @"weird function name"() i32 { | |
| 63 | return 1234; | |
| 64 | } | |
| 65 | test "weird function name" { | |
| 66 | expect(@"weird function name"() == 1234); | |
| 67 | } | |
| 68 | ||
| 69 | test "implicit cast function unreachable return" { | |
| 70 | wantsFnWithVoid(fnWithUnreachable); | |
| 71 | } | |
| 72 | ||
| 73 | fn wantsFnWithVoid(f: fn () void) void {} | |
| 74 | ||
| 75 | fn fnWithUnreachable() noreturn { | |
| 76 | unreachable; | |
| 77 | } | |
| 78 | ||
| 79 | test "function pointers" { | |
| 80 | const fns = [_]@TypeOf(fn1){ | |
| 81 | fn1, | |
| 82 | fn2, | |
| 83 | fn3, | |
| 84 | fn4, | |
| 85 | }; | |
| 86 | for (fns) |f, i| { | |
| 87 | expect(f() == @intCast(u32, i) + 5); | |
| 88 | } | |
| 89 | } | |
| 90 | fn fn1() u32 { | |
| 91 | return 5; | |
| 92 | } | |
| 93 | fn fn2() u32 { | |
| 94 | return 6; | |
| 95 | } | |
| 96 | fn fn3() u32 { | |
| 97 | return 7; | |
| 98 | } | |
| 99 | fn fn4() u32 { | |
| 100 | return 8; | |
| 101 | } | |
| 102 | ||
| 103 | test "number literal as an argument" { | |
| 104 | numberLiteralArg(3); | |
| 105 | comptime numberLiteralArg(3); | |
| 106 | } | |
| 107 | ||
| 108 | fn numberLiteralArg(a: anytype) void { | |
| 109 | expect(a == 3); | |
| 110 | } | |
| 111 | ||
| 112 | test "assign inline fn to const variable" { | |
| 113 | const a = inlineFn; | |
| 114 | a(); | |
| 115 | } | |
| 116 | ||
| 117 | fn inlineFn() callconv(.Inline) void {} | |
| 118 | ||
| 119 | test "pass by non-copying value" { | |
| 120 | expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3); | |
| 121 | } | |
| 122 | ||
| 123 | const Point = struct { | |
| 124 | x: i32, | |
| 125 | y: i32, | |
| 126 | }; | |
| 127 | ||
| 128 | fn addPointCoords(pt: Point) i32 { | |
| 129 | return pt.x + pt.y; | |
| 130 | } | |
| 131 | ||
| 132 | test "pass by non-copying value through var arg" { | |
| 133 | expect(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3); | |
| 134 | } | |
| 135 | ||
| 136 | fn addPointCoordsVar(pt: anytype) i32 { | |
| 137 | comptime expect(@TypeOf(pt) == Point); | |
| 138 | return pt.x + pt.y; | |
| 139 | } | |
| 140 | ||
| 141 | test "pass by non-copying value as method" { | |
| 142 | var pt = Point2{ .x = 1, .y = 2 }; | |
| 143 | expect(pt.addPointCoords() == 3); | |
| 144 | } | |
| 145 | ||
| 146 | const Point2 = struct { | |
| 147 | x: i32, | |
| 148 | y: i32, | |
| 149 | ||
| 150 | fn addPointCoords(self: Point2) i32 { | |
| 151 | return self.x + self.y; | |
| 152 | } | |
| 153 | }; | |
| 154 | ||
| 155 | test "pass by non-copying value as method, which is generic" { | |
| 156 | var pt = Point3{ .x = 1, .y = 2 }; | |
| 157 | expect(pt.addPointCoords(i32) == 3); | |
| 158 | } | |
| 159 | ||
| 160 | const Point3 = struct { | |
| 161 | x: i32, | |
| 162 | y: i32, | |
| 163 | ||
| 164 | fn addPointCoords(self: Point3, comptime T: type) i32 { | |
| 165 | return self.x + self.y; | |
| 166 | } | |
| 167 | }; | |
| 168 | ||
| 169 | test "pass by non-copying value as method, at comptime" { | |
| 170 | comptime { | |
| 171 | var pt = Point2{ .x = 1, .y = 2 }; | |
| 172 | expect(pt.addPointCoords() == 3); | |
| 173 | } | |
| 174 | } | |
| 175 | ||
| 176 | fn outer(y: u32) fn (u32) u32 { | |
| 177 | const Y = @TypeOf(y); | |
| 178 | const st = struct { | |
| 179 | fn get(z: u32) u32 { | |
| 180 | return z + @sizeOf(Y); | |
| 181 | } | |
| 182 | }; | |
| 183 | return st.get; | |
| 184 | } | |
| 185 | ||
| 186 | test "return inner function which references comptime variable of outer function" { | |
| 187 | var func = outer(10); | |
| 188 | expect(func(3) == 7); | |
| 189 | } | |
| 190 | ||
| 191 | test "extern struct with stdcallcc fn pointer" { | |
| 192 | const S = extern struct { | |
| 193 | ptr: fn () callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32, | |
| 194 | ||
| 195 | fn foo() callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32 { | |
| 196 | return 1234; | |
| 197 | } | |
| 198 | }; | |
| 199 | ||
| 200 | var s: S = undefined; | |
| 201 | s.ptr = S.foo; | |
| 202 | expect(s.ptr() == 1234); | |
| 203 | } | |
| 204 | ||
| 205 | test "implicit cast fn call result to optional in field result" { | |
| 206 | const S = struct { | |
| 207 | fn entry() void { | |
| 208 | var x = Foo{ | |
| 209 | .field = optionalPtr(), | |
| 210 | }; | |
| 211 | expect(x.field.?.* == 999); | |
| 212 | } | |
| 213 | ||
| 214 | const glob: i32 = 999; | |
| 215 | ||
| 216 | fn optionalPtr() *const i32 { | |
| 217 | return &glob; | |
| 218 | } | |
| 219 | ||
| 220 | const Foo = struct { | |
| 221 | field: ?*const i32, | |
| 222 | }; | |
| 223 | }; | |
| 224 | S.entry(); | |
| 225 | comptime S.entry(); | |
| 226 | } | |
| 227 | ||
| 228 | test "discard the result of a function that returns a struct" { | |
| 229 | const S = struct { | |
| 230 | fn entry() void { | |
| 231 | _ = func(); | |
| 232 | } | |
| 233 | ||
| 234 | fn func() Foo { | |
| 235 | return undefined; | |
| 236 | } | |
| 237 | ||
| 238 | const Foo = struct { | |
| 239 | a: u64, | |
| 240 | b: u64, | |
| 241 | }; | |
| 242 | }; | |
| 243 | S.entry(); | |
| 244 | comptime S.entry(); | |
| 245 | } | |
| 246 | ||
| 247 | test "function call with anon list literal" { | |
| 248 | const S = struct { | |
| 249 | fn doTheTest() void { | |
| 250 | consumeVec(.{ 9, 8, 7 }); | |
| 251 | } | |
| 252 | ||
| 253 | fn consumeVec(vec: [3]f32) void { | |
| 254 | expect(vec[0] == 9); | |
| 255 | expect(vec[1] == 8); | |
| 256 | expect(vec[2] == 7); | |
| 257 | } | |
| 258 | }; | |
| 259 | S.doTheTest(); | |
| 260 | comptime S.doTheTest(); | |
| 261 | } | |
| 262 | ||
| 263 | test "ability to give comptime types and non comptime types to same parameter" { | |
| 264 | const S = struct { | |
| 265 | fn doTheTest() void { | |
| 266 | var x: i32 = 1; | |
| 267 | expect(foo(x) == 10); | |
| 268 | expect(foo(i32) == 20); | |
| 269 | } | |
| 270 | ||
| 271 | fn foo(arg: anytype) i32 { | |
| 272 | if (@typeInfo(@TypeOf(arg)) == .Type and arg == i32) return 20; | |
| 273 | return 9 + arg; | |
| 274 | } | |
| 275 | }; | |
| 276 | S.doTheTest(); | |
| 277 | comptime S.doTheTest(); | |
| 278 | } | |
| 279 | ||
| 280 | test "function with inferred error set but returning no error" { | |
| 281 | const S = struct { | |
| 282 | fn foo() !void {} | |
| 283 | }; | |
| 284 | ||
| 285 | const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?; | |
| 286 | expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len); | |
| 287 | } |
test/stage1/behavior/fn_delegation.zig deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | a: u64 = 10, | |
| 5 | ||
| 6 | fn one(self: Foo) u64 { | |
| 7 | return self.a + 1; | |
| 8 | } | |
| 9 | ||
| 10 | const two = __two; | |
| 11 | ||
| 12 | fn __two(self: Foo) u64 { | |
| 13 | return self.a + 2; | |
| 14 | } | |
| 15 | ||
| 16 | const three = __three; | |
| 17 | ||
| 18 | const four = custom(Foo, 4); | |
| 19 | }; | |
| 20 | ||
| 21 | fn __three(self: Foo) u64 { | |
| 22 | return self.a + 3; | |
| 23 | } | |
| 24 | ||
| 25 | fn custom(comptime T: type, comptime num: u64) fn (T) u64 { | |
| 26 | return struct { | |
| 27 | fn function(self: T) u64 { | |
| 28 | return self.a + num; | |
| 29 | } | |
| 30 | }.function; | |
| 31 | } | |
| 32 | ||
| 33 | test "fn delegation" { | |
| 34 | const foo = Foo{}; | |
| 35 | expect(foo.one() == 11); | |
| 36 | expect(foo.two() == 12); | |
| 37 | expect(foo.three() == 13); | |
| 38 | expect(foo.four() == 14); | |
| 39 | } |
test/stage1/behavior/fn_in_struct_in_comptime.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn get_foo() fn (*u8) usize { | |
| 4 | comptime { | |
| 5 | return struct { | |
| 6 | fn func(ptr: *u8) usize { | |
| 7 | var u = @ptrToInt(ptr); | |
| 8 | return u; | |
| 9 | } | |
| 10 | }.func; | |
| 11 | } | |
| 12 | } | |
| 13 | ||
| 14 | test "define a function in an anonymous struct in comptime" { | |
| 15 | const foo = get_foo(); | |
| 16 | expect(foo(@intToPtr(*u8, 12345)) == 12345); | |
| 17 | } |
test/stage1/behavior/for.zig deleted-172| ... | ... | @@ -1,172 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const mem = std.mem; | |
| 5 | ||
| 6 | test "continue in for loop" { | |
| 7 | const array = [_]i32{ | |
| 8 | 1, | |
| 9 | 2, | |
| 10 | 3, | |
| 11 | 4, | |
| 12 | 5, | |
| 13 | }; | |
| 14 | var sum: i32 = 0; | |
| 15 | for (array) |x| { | |
| 16 | sum += x; | |
| 17 | if (x < 3) { | |
| 18 | continue; | |
| 19 | } | |
| 20 | break; | |
| 21 | } | |
| 22 | if (sum != 6) unreachable; | |
| 23 | } | |
| 24 | ||
| 25 | test "for loop with pointer elem var" { | |
| 26 | const source = "abcdefg"; | |
| 27 | var target: [source.len]u8 = undefined; | |
| 28 | mem.copy(u8, target[0..], source); | |
| 29 | mangleString(target[0..]); | |
| 30 | expect(mem.eql(u8, &target, "bcdefgh")); | |
| 31 | ||
| 32 | for (source) |*c, i| | |
| 33 | expect(@TypeOf(c) == *const u8); | |
| 34 | for (target) |*c, i| | |
| 35 | expect(@TypeOf(c) == *u8); | |
| 36 | } | |
| 37 | ||
| 38 | fn mangleString(s: []u8) void { | |
| 39 | for (s) |*c| { | |
| 40 | c.* += 1; | |
| 41 | } | |
| 42 | } | |
| 43 | ||
| 44 | test "basic for loop" { | |
| 45 | const expected_result = [_]u8{ 9, 8, 7, 6, 0, 1, 2, 3 } ** 3; | |
| 46 | ||
| 47 | var buffer: [expected_result.len]u8 = undefined; | |
| 48 | var buf_index: usize = 0; | |
| 49 | ||
| 50 | const array = [_]u8{ 9, 8, 7, 6 }; | |
| 51 | for (array) |item| { | |
| 52 | buffer[buf_index] = item; | |
| 53 | buf_index += 1; | |
| 54 | } | |
| 55 | for (array) |item, index| { | |
| 56 | buffer[buf_index] = @intCast(u8, index); | |
| 57 | buf_index += 1; | |
| 58 | } | |
| 59 | const array_ptr = &array; | |
| 60 | for (array_ptr) |item| { | |
| 61 | buffer[buf_index] = item; | |
| 62 | buf_index += 1; | |
| 63 | } | |
| 64 | for (array_ptr) |item, index| { | |
| 65 | buffer[buf_index] = @intCast(u8, index); | |
| 66 | buf_index += 1; | |
| 67 | } | |
| 68 | const unknown_size: []const u8 = &array; | |
| 69 | for (unknown_size) |item| { | |
| 70 | buffer[buf_index] = item; | |
| 71 | buf_index += 1; | |
| 72 | } | |
| 73 | for (unknown_size) |item, index| { | |
| 74 | buffer[buf_index] = @intCast(u8, index); | |
| 75 | buf_index += 1; | |
| 76 | } | |
| 77 | ||
| 78 | expect(mem.eql(u8, buffer[0..buf_index], &expected_result)); | |
| 79 | } | |
| 80 | ||
| 81 | test "break from outer for loop" { | |
| 82 | testBreakOuter(); | |
| 83 | comptime testBreakOuter(); | |
| 84 | } | |
| 85 | ||
| 86 | fn testBreakOuter() void { | |
| 87 | var array = "aoeu"; | |
| 88 | var count: usize = 0; | |
| 89 | outer: for (array) |_| { | |
| 90 | for (array) |_| { | |
| 91 | count += 1; | |
| 92 | break :outer; | |
| 93 | } | |
| 94 | } | |
| 95 | expect(count == 1); | |
| 96 | } | |
| 97 | ||
| 98 | test "continue outer for loop" { | |
| 99 | testContinueOuter(); | |
| 100 | comptime testContinueOuter(); | |
| 101 | } | |
| 102 | ||
| 103 | fn testContinueOuter() void { | |
| 104 | var array = "aoeu"; | |
| 105 | var counter: usize = 0; | |
| 106 | outer: for (array) |_| { | |
| 107 | for (array) |_| { | |
| 108 | counter += 1; | |
| 109 | continue :outer; | |
| 110 | } | |
| 111 | } | |
| 112 | expect(counter == array.len); | |
| 113 | } | |
| 114 | ||
| 115 | test "2 break statements and an else" { | |
| 116 | const S = struct { | |
| 117 | fn entry(t: bool, f: bool) void { | |
| 118 | var buf: [10]u8 = undefined; | |
| 119 | var ok = false; | |
| 120 | ok = for (buf) |item| { | |
| 121 | if (f) break false; | |
| 122 | if (t) break true; | |
| 123 | } else false; | |
| 124 | expect(ok); | |
| 125 | } | |
| 126 | }; | |
| 127 | S.entry(true, false); | |
| 128 | comptime S.entry(true, false); | |
| 129 | } | |
| 130 | ||
| 131 | test "for with null and T peer types and inferred result location type" { | |
| 132 | const S = struct { | |
| 133 | fn doTheTest(slice: []const u8) void { | |
| 134 | if (for (slice) |item| { | |
| 135 | if (item == 10) { | |
| 136 | break item; | |
| 137 | } | |
| 138 | } else null) |v| { | |
| 139 | @panic("fail"); | |
| 140 | } | |
| 141 | } | |
| 142 | }; | |
| 143 | S.doTheTest(&[_]u8{ 1, 2 }); | |
| 144 | comptime S.doTheTest(&[_]u8{ 1, 2 }); | |
| 145 | } | |
| 146 | ||
| 147 | test "for copies its payload" { | |
| 148 | const S = struct { | |
| 149 | fn doTheTest() void { | |
| 150 | var x = [_]usize{ 1, 2, 3 }; | |
| 151 | for (x) |value, i| { | |
| 152 | // Modify the original array | |
| 153 | x[i] += 99; | |
| 154 | expectEqual(value, i + 1); | |
| 155 | } | |
| 156 | } | |
| 157 | }; | |
| 158 | S.doTheTest(); | |
| 159 | comptime S.doTheTest(); | |
| 160 | } | |
| 161 | ||
| 162 | test "for on slice with allowzero ptr" { | |
| 163 | const S = struct { | |
| 164 | fn doTheTest(slice: []const u8) void { | |
| 165 | var ptr = @ptrCast([*]allowzero const u8, slice.ptr)[0..slice.len]; | |
| 166 | for (ptr) |x, i| expect(x == i + 1); | |
| 167 | for (ptr) |*x, i| expect(x.* == i + 1); | |
| 168 | } | |
| 169 | }; | |
| 170 | S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); | |
| 171 | comptime S.doTheTest(&[_]u8{ 1, 2, 3, 4 }); | |
| 172 | } |
test/stage1/behavior/generics.zig deleted-169| ... | ... | @@ -1,169 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | test "simple generic fn" { | |
| 7 | expect(max(i32, 3, -1) == 3); | |
| 8 | expect(max(f32, 0.123, 0.456) == 0.456); | |
| 9 | expect(add(2, 3) == 5); | |
| 10 | } | |
| 11 | ||
| 12 | fn max(comptime T: type, a: T, b: T) T { | |
| 13 | return if (a > b) a else b; | |
| 14 | } | |
| 15 | ||
| 16 | fn add(comptime a: i32, b: i32) i32 { | |
| 17 | return (comptime a) + b; | |
| 18 | } | |
| 19 | ||
| 20 | const the_max = max(u32, 1234, 5678); | |
| 21 | test "compile time generic eval" { | |
| 22 | expect(the_max == 5678); | |
| 23 | } | |
| 24 | ||
| 25 | fn gimmeTheBigOne(a: u32, b: u32) u32 { | |
| 26 | return max(u32, a, b); | |
| 27 | } | |
| 28 | ||
| 29 | fn shouldCallSameInstance(a: u32, b: u32) u32 { | |
| 30 | return max(u32, a, b); | |
| 31 | } | |
| 32 | ||
| 33 | fn sameButWithFloats(a: f64, b: f64) f64 { | |
| 34 | return max(f64, a, b); | |
| 35 | } | |
| 36 | ||
| 37 | test "fn with comptime args" { | |
| 38 | expect(gimmeTheBigOne(1234, 5678) == 5678); | |
| 39 | expect(shouldCallSameInstance(34, 12) == 34); | |
| 40 | expect(sameButWithFloats(0.43, 0.49) == 0.49); | |
| 41 | } | |
| 42 | ||
| 43 | test "var params" { | |
| 44 | expect(max_i32(12, 34) == 34); | |
| 45 | expect(max_f64(1.2, 3.4) == 3.4); | |
| 46 | } | |
| 47 | ||
| 48 | comptime { | |
| 49 | expect(max_i32(12, 34) == 34); | |
| 50 | expect(max_f64(1.2, 3.4) == 3.4); | |
| 51 | } | |
| 52 | ||
| 53 | fn max_var(a: anytype, b: anytype) @TypeOf(a + b) { | |
| 54 | return if (a > b) a else b; | |
| 55 | } | |
| 56 | ||
| 57 | fn max_i32(a: i32, b: i32) i32 { | |
| 58 | return max_var(a, b); | |
| 59 | } | |
| 60 | ||
| 61 | fn max_f64(a: f64, b: f64) f64 { | |
| 62 | return max_var(a, b); | |
| 63 | } | |
| 64 | ||
| 65 | pub fn List(comptime T: type) type { | |
| 66 | return SmallList(T, 8); | |
| 67 | } | |
| 68 | ||
| 69 | pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type { | |
| 70 | return struct { | |
| 71 | items: []T, | |
| 72 | length: usize, | |
| 73 | prealloc_items: [STATIC_SIZE]T, | |
| 74 | }; | |
| 75 | } | |
| 76 | ||
| 77 | test "function with return type type" { | |
| 78 | var list: List(i32) = undefined; | |
| 79 | var list2: List(i32) = undefined; | |
| 80 | list.length = 10; | |
| 81 | list2.length = 10; | |
| 82 | expect(list.prealloc_items.len == 8); | |
| 83 | expect(list2.prealloc_items.len == 8); | |
| 84 | } | |
| 85 | ||
| 86 | test "generic struct" { | |
| 87 | var a1 = GenNode(i32){ | |
| 88 | .value = 13, | |
| 89 | .next = null, | |
| 90 | }; | |
| 91 | var b1 = GenNode(bool){ | |
| 92 | .value = true, | |
| 93 | .next = null, | |
| 94 | }; | |
| 95 | expect(a1.value == 13); | |
| 96 | expect(a1.value == a1.getVal()); | |
| 97 | expect(b1.getVal()); | |
| 98 | } | |
| 99 | fn GenNode(comptime T: type) type { | |
| 100 | return struct { | |
| 101 | value: T, | |
| 102 | next: ?*GenNode(T), | |
| 103 | fn getVal(n: *const GenNode(T)) T { | |
| 104 | return n.value; | |
| 105 | } | |
| 106 | }; | |
| 107 | } | |
| 108 | ||
| 109 | test "const decls in struct" { | |
| 110 | expect(GenericDataThing(3).count_plus_one == 4); | |
| 111 | } | |
| 112 | fn GenericDataThing(comptime count: isize) type { | |
| 113 | return struct { | |
| 114 | const count_plus_one = count + 1; | |
| 115 | }; | |
| 116 | } | |
| 117 | ||
| 118 | test "use generic param in generic param" { | |
| 119 | expect(aGenericFn(i32, 3, 4) == 7); | |
| 120 | } | |
| 121 | fn aGenericFn(comptime T: type, comptime a: T, b: T) T { | |
| 122 | return a + b; | |
| 123 | } | |
| 124 | ||
| 125 | test "generic fn with implicit cast" { | |
| 126 | expect(getFirstByte(u8, &[_]u8{13}) == 13); | |
| 127 | expect(getFirstByte(u16, &[_]u16{ | |
| 128 | 0, | |
| 129 | 13, | |
| 130 | }) == 0); | |
| 131 | } | |
| 132 | fn getByte(ptr: ?*const u8) u8 { | |
| 133 | return ptr.?.*; | |
| 134 | } | |
| 135 | fn getFirstByte(comptime T: type, mem: []const T) u8 { | |
| 136 | return getByte(@ptrCast(*const u8, &mem[0])); | |
| 137 | } | |
| 138 | ||
| 139 | const foos = [_]fn (anytype) bool{ | |
| 140 | foo1, | |
| 141 | foo2, | |
| 142 | }; | |
| 143 | ||
| 144 | fn foo1(arg: anytype) bool { | |
| 145 | return arg; | |
| 146 | } | |
| 147 | fn foo2(arg: anytype) bool { | |
| 148 | return !arg; | |
| 149 | } | |
| 150 | ||
| 151 | test "array of generic fns" { | |
| 152 | expect(foos[0](true)); | |
| 153 | expect(!foos[1](true)); | |
| 154 | } | |
| 155 | ||
| 156 | test "generic fn keeps non-generic parameter types" { | |
| 157 | const A = 128; | |
| 158 | ||
| 159 | const S = struct { | |
| 160 | fn f(comptime T: type, s: []T) void { | |
| 161 | expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment); | |
| 162 | } | |
| 163 | }; | |
| 164 | ||
| 165 | // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that | |
| 166 | // `x` type not affect `s` parameter type. | |
| 167 | var x: [16]u8 align(A) = undefined; | |
| 168 | S.f(u8, &x); | |
| 169 | } |
test/stage1/behavior/hasdecl.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | const Foo = @import("hasdecl/foo.zig"); | |
| 5 | ||
| 6 | const Bar = struct { | |
| 7 | nope: i32, | |
| 8 | ||
| 9 | const hi = 1; | |
| 10 | pub var blah = "xxx"; | |
| 11 | }; | |
| 12 | ||
| 13 | test "@hasDecl" { | |
| 14 | expect(@hasDecl(Foo, "public_thing")); | |
| 15 | expect(!@hasDecl(Foo, "private_thing")); | |
| 16 | expect(!@hasDecl(Foo, "no_thing")); | |
| 17 | ||
| 18 | expect(@hasDecl(Bar, "hi")); | |
| 19 | expect(@hasDecl(Bar, "blah")); | |
| 20 | expect(!@hasDecl(Bar, "nope")); | |
| 21 | } |
test/stage1/behavior/hasdecl/foo.zig deleted-2| ... | ... | @@ -1,2 +0,0 @@ |
| 1 | pub const public_thing = 42; | |
| 2 | const private_thing = 666; |
test/stage1/behavior/hasfield.zig deleted-37| ... | ... | @@ -1,37 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const builtin = @import("builtin"); | |
| 3 | ||
| 4 | test "@hasField" { | |
| 5 | const struc = struct { | |
| 6 | a: i32, | |
| 7 | b: []u8, | |
| 8 | ||
| 9 | pub const nope = 1; | |
| 10 | }; | |
| 11 | expect(@hasField(struc, "a") == true); | |
| 12 | expect(@hasField(struc, "b") == true); | |
| 13 | expect(@hasField(struc, "non-existant") == false); | |
| 14 | expect(@hasField(struc, "nope") == false); | |
| 15 | ||
| 16 | const unin = union { | |
| 17 | a: u64, | |
| 18 | b: []u16, | |
| 19 | ||
| 20 | pub const nope = 1; | |
| 21 | }; | |
| 22 | expect(@hasField(unin, "a") == true); | |
| 23 | expect(@hasField(unin, "b") == true); | |
| 24 | expect(@hasField(unin, "non-existant") == false); | |
| 25 | expect(@hasField(unin, "nope") == false); | |
| 26 | ||
| 27 | const enm = enum { | |
| 28 | a, | |
| 29 | b, | |
| 30 | ||
| 31 | pub const nope = 1; | |
| 32 | }; | |
| 33 | expect(@hasField(enm, "a") == true); | |
| 34 | expect(@hasField(enm, "b") == true); | |
| 35 | expect(@hasField(enm, "non-existant") == false); | |
| 36 | expect(@hasField(enm, "nope") == false); | |
| 37 | } |
test/stage1/behavior/if.zig deleted-109| ... | ... | @@ -1,109 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | ||
| 5 | test "if statements" { | |
| 6 | shouldBeEqual(1, 1); | |
| 7 | firstEqlThird(2, 1, 2); | |
| 8 | } | |
| 9 | fn shouldBeEqual(a: i32, b: i32) void { | |
| 10 | if (a != b) { | |
| 11 | unreachable; | |
| 12 | } else { | |
| 13 | return; | |
| 14 | } | |
| 15 | } | |
| 16 | fn firstEqlThird(a: i32, b: i32, c: i32) void { | |
| 17 | if (a == b) { | |
| 18 | unreachable; | |
| 19 | } else if (b == c) { | |
| 20 | unreachable; | |
| 21 | } else if (a == c) { | |
| 22 | return; | |
| 23 | } else { | |
| 24 | unreachable; | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | test "else if expression" { | |
| 29 | expect(elseIfExpressionF(1) == 1); | |
| 30 | } | |
| 31 | fn elseIfExpressionF(c: u8) u8 { | |
| 32 | if (c == 0) { | |
| 33 | return 0; | |
| 34 | } else if (c == 1) { | |
| 35 | return 1; | |
| 36 | } else { | |
| 37 | return @as(u8, 2); | |
| 38 | } | |
| 39 | } | |
| 40 | ||
| 41 | // #2297 | |
| 42 | var global_with_val: anyerror!u32 = 0; | |
| 43 | var global_with_err: anyerror!u32 = error.SomeError; | |
| 44 | ||
| 45 | test "unwrap mutable global var" { | |
| 46 | if (global_with_val) |v| { | |
| 47 | expect(v == 0); | |
| 48 | } else |e| { | |
| 49 | unreachable; | |
| 50 | } | |
| 51 | if (global_with_err) |_| { | |
| 52 | unreachable; | |
| 53 | } else |e| { | |
| 54 | expect(e == error.SomeError); | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | test "labeled break inside comptime if inside runtime if" { | |
| 59 | var answer: i32 = 0; | |
| 60 | var c = true; | |
| 61 | if (c) { | |
| 62 | answer = if (true) blk: { | |
| 63 | break :blk @as(i32, 42); | |
| 64 | }; | |
| 65 | } | |
| 66 | expect(answer == 42); | |
| 67 | } | |
| 68 | ||
| 69 | test "const result loc, runtime if cond, else unreachable" { | |
| 70 | const Num = enum { | |
| 71 | One, | |
| 72 | Two, | |
| 73 | }; | |
| 74 | ||
| 75 | var t = true; | |
| 76 | const x = if (t) Num.Two else unreachable; | |
| 77 | expect(x == .Two); | |
| 78 | } | |
| 79 | ||
| 80 | test "if prongs cast to expected type instead of peer type resolution" { | |
| 81 | const S = struct { | |
| 82 | fn doTheTest(f: bool) void { | |
| 83 | var x: i32 = 0; | |
| 84 | x = if (f) 1 else 2; | |
| 85 | expect(x == 2); | |
| 86 | ||
| 87 | var b = true; | |
| 88 | const y: i32 = if (b) 1 else 2; | |
| 89 | expect(y == 1); | |
| 90 | } | |
| 91 | }; | |
| 92 | S.doTheTest(false); | |
| 93 | comptime S.doTheTest(false); | |
| 94 | } | |
| 95 | ||
| 96 | test "while copies its payload" { | |
| 97 | const S = struct { | |
| 98 | fn doTheTest() void { | |
| 99 | var tmp: ?i32 = 10; | |
| 100 | if (tmp) |value| { | |
| 101 | // Modify the original variable | |
| 102 | tmp = null; | |
| 103 | expectEqual(@as(i32, 10), value); | |
| 104 | } else unreachable; | |
| 105 | } | |
| 106 | }; | |
| 107 | S.doTheTest(); | |
| 108 | comptime S.doTheTest(); | |
| 109 | } |
test/stage1/behavior/import.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const expectEqual = @import("std").testing.expectEqual; | |
| 3 | const a_namespace = @import("import/a_namespace.zig"); | |
| 4 | ||
| 5 | test "call fn via namespace lookup" { | |
| 6 | expectEqual(@as(i32, 1234), a_namespace.foo()); | |
| 7 | } | |
| 8 | ||
| 9 | test "importing the same thing gives the same import" { | |
| 10 | expect(@import("std") == @import("std")); | |
| 11 | } | |
| 12 | ||
| 13 | test "import in non-toplevel scope" { | |
| 14 | const S = struct { | |
| 15 | usingnamespace @import("import/a_namespace.zig"); | |
| 16 | }; | |
| 17 | expectEqual(@as(i32, 1234), S.foo()); | |
| 18 | } | |
| 19 | ||
| 20 | test "import empty file" { | |
| 21 | const empty = @import("import/empty.zig"); | |
| 22 | } |
test/stage1/behavior/import/a_namespace.zig deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | pub fn foo() i32 { | |
| 2 | return 1234; | |
| 3 | } |
test/stage1/behavior/import/empty.zig deletedtest/stage1/behavior/incomplete_struct_param_tld.zig deleted-30| ... | ... | @@ -1,30 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const A = struct { | |
| 4 | b: B, | |
| 5 | }; | |
| 6 | ||
| 7 | const B = struct { | |
| 8 | c: C, | |
| 9 | }; | |
| 10 | ||
| 11 | const C = struct { | |
| 12 | x: i32, | |
| 13 | ||
| 14 | fn d(c: *const C) i32 { | |
| 15 | return c.x; | |
| 16 | } | |
| 17 | }; | |
| 18 | ||
| 19 | fn foo(a: A) i32 { | |
| 20 | return a.b.c.d(); | |
| 21 | } | |
| 22 | ||
| 23 | test "incomplete struct param top level declaration" { | |
| 24 | const a = A{ | |
| 25 | .b = B{ | |
| 26 | .c = C{ .x = 13 }, | |
| 27 | }, | |
| 28 | }; | |
| 29 | expect(foo(a) == 13); | |
| 30 | } |
test/stage1/behavior/inttoptr.zig deleted-26| ... | ... | @@ -1,26 +0,0 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const std = @import("std"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | ||
| 5 | test "casting random address to function pointer" { | |
| 6 | randomAddressToFunction(); | |
| 7 | comptime randomAddressToFunction(); | |
| 8 | } | |
| 9 | ||
| 10 | fn randomAddressToFunction() void { | |
| 11 | var addr: usize = 0xdeadbeef; | |
| 12 | var ptr = @intToPtr(fn () void, addr); | |
| 13 | } | |
| 14 | ||
| 15 | test "mutate through ptr initialized with constant intToPtr value" { | |
| 16 | forceCompilerAnalyzeBranchHardCodedPtrDereference(false); | |
| 17 | } | |
| 18 | ||
| 19 | fn forceCompilerAnalyzeBranchHardCodedPtrDereference(x: bool) void { | |
| 20 | const hardCodedP = @intToPtr(*volatile u8, 0xdeadbeef); | |
| 21 | if (x) { | |
| 22 | hardCodedP.* = hardCodedP.* | 10; | |
| 23 | } else { | |
| 24 | return; | |
| 25 | } | |
| 26 | } |
test/stage1/behavior/ir_block_deps.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn foo(id: u64) !i32 { | |
| 4 | return switch (id) { | |
| 5 | 1 => getErrInt(), | |
| 6 | 2 => { | |
| 7 | const size = try getErrInt(); | |
| 8 | return try getErrInt(); | |
| 9 | }, | |
| 10 | else => error.ItBroke, | |
| 11 | }; | |
| 12 | } | |
| 13 | ||
| 14 | fn getErrInt() anyerror!i32 { | |
| 15 | return 0; | |
| 16 | } | |
| 17 | ||
| 18 | test "ir block deps" { | |
| 19 | expect((foo(1) catch unreachable) == 0); | |
| 20 | expect((foo(2) catch unreachable) == 0); | |
| 21 | } |
test/stage1/behavior/math.zig deleted-872| ... | ... | @@ -1,872 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 5 | const maxInt = std.math.maxInt; | |
| 6 | const minInt = std.math.minInt; | |
| 7 | const mem = std.mem; | |
| 8 | ||
| 9 | test "division" { | |
| 10 | testDivision(); | |
| 11 | comptime testDivision(); | |
| 12 | } | |
| 13 | fn testDivision() void { | |
| 14 | expect(div(u32, 13, 3) == 4); | |
| 15 | expect(div(f16, 1.0, 2.0) == 0.5); | |
| 16 | expect(div(f32, 1.0, 2.0) == 0.5); | |
| 17 | ||
| 18 | expect(divExact(u32, 55, 11) == 5); | |
| 19 | expect(divExact(i32, -55, 11) == -5); | |
| 20 | expect(divExact(f16, 55.0, 11.0) == 5.0); | |
| 21 | expect(divExact(f16, -55.0, 11.0) == -5.0); | |
| 22 | expect(divExact(f32, 55.0, 11.0) == 5.0); | |
| 23 | expect(divExact(f32, -55.0, 11.0) == -5.0); | |
| 24 | ||
| 25 | expect(divFloor(i32, 5, 3) == 1); | |
| 26 | expect(divFloor(i32, -5, 3) == -2); | |
| 27 | expect(divFloor(f16, 5.0, 3.0) == 1.0); | |
| 28 | expect(divFloor(f16, -5.0, 3.0) == -2.0); | |
| 29 | expect(divFloor(f32, 5.0, 3.0) == 1.0); | |
| 30 | expect(divFloor(f32, -5.0, 3.0) == -2.0); | |
| 31 | expect(divFloor(i32, -0x80000000, -2) == 0x40000000); | |
| 32 | expect(divFloor(i32, 0, -0x80000000) == 0); | |
| 33 | expect(divFloor(i32, -0x40000001, 0x40000000) == -2); | |
| 34 | expect(divFloor(i32, -0x80000000, 1) == -0x80000000); | |
| 35 | expect(divFloor(i32, 10, 12) == 0); | |
| 36 | expect(divFloor(i32, -14, 12) == -2); | |
| 37 | expect(divFloor(i32, -2, 12) == -1); | |
| 38 | ||
| 39 | expect(divTrunc(i32, 5, 3) == 1); | |
| 40 | expect(divTrunc(i32, -5, 3) == -1); | |
| 41 | expect(divTrunc(f16, 5.0, 3.0) == 1.0); | |
| 42 | expect(divTrunc(f16, -5.0, 3.0) == -1.0); | |
| 43 | expect(divTrunc(f32, 5.0, 3.0) == 1.0); | |
| 44 | expect(divTrunc(f32, -5.0, 3.0) == -1.0); | |
| 45 | expect(divTrunc(f64, 5.0, 3.0) == 1.0); | |
| 46 | expect(divTrunc(f64, -5.0, 3.0) == -1.0); | |
| 47 | expect(divTrunc(i32, 10, 12) == 0); | |
| 48 | expect(divTrunc(i32, -14, 12) == -1); | |
| 49 | expect(divTrunc(i32, -2, 12) == 0); | |
| 50 | ||
| 51 | expect(mod(i32, 10, 12) == 10); | |
| 52 | expect(mod(i32, -14, 12) == 10); | |
| 53 | expect(mod(i32, -2, 12) == 10); | |
| 54 | ||
| 55 | comptime { | |
| 56 | expect( | |
| 57 | 1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600, | |
| 58 | ); | |
| 59 | expect( | |
| 60 | @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600, | |
| 61 | ); | |
| 62 | expect( | |
| 63 | 1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2, | |
| 64 | ); | |
| 65 | expect( | |
| 66 | @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2, | |
| 67 | ); | |
| 68 | expect( | |
| 69 | @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2, | |
| 70 | ); | |
| 71 | expect( | |
| 72 | @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2, | |
| 73 | ); | |
| 74 | expect( | |
| 75 | 4126227191251978491697987544882340798050766755606969681711 % 10 == 1, | |
| 76 | ); | |
| 77 | } | |
| 78 | } | |
| 79 | fn div(comptime T: type, a: T, b: T) T { | |
| 80 | return a / b; | |
| 81 | } | |
| 82 | fn divExact(comptime T: type, a: T, b: T) T { | |
| 83 | return @divExact(a, b); | |
| 84 | } | |
| 85 | fn divFloor(comptime T: type, a: T, b: T) T { | |
| 86 | return @divFloor(a, b); | |
| 87 | } | |
| 88 | fn divTrunc(comptime T: type, a: T, b: T) T { | |
| 89 | return @divTrunc(a, b); | |
| 90 | } | |
| 91 | fn mod(comptime T: type, a: T, b: T) T { | |
| 92 | return @mod(a, b); | |
| 93 | } | |
| 94 | ||
| 95 | test "@addWithOverflow" { | |
| 96 | var result: u8 = undefined; | |
| 97 | expect(@addWithOverflow(u8, 250, 100, &result)); | |
| 98 | expect(!@addWithOverflow(u8, 100, 150, &result)); | |
| 99 | expect(result == 250); | |
| 100 | } | |
| 101 | ||
| 102 | // TODO test mulWithOverflow | |
| 103 | // TODO test subWithOverflow | |
| 104 | ||
| 105 | test "@shlWithOverflow" { | |
| 106 | var result: u16 = undefined; | |
| 107 | expect(@shlWithOverflow(u16, 0b0010111111111111, 3, &result)); | |
| 108 | expect(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result)); | |
| 109 | expect(result == 0b1011111111111100); | |
| 110 | } | |
| 111 | ||
| 112 | test "@*WithOverflow with u0 values" { | |
| 113 | var result: u0 = undefined; | |
| 114 | expect(!@addWithOverflow(u0, 0, 0, &result)); | |
| 115 | expect(!@subWithOverflow(u0, 0, 0, &result)); | |
| 116 | expect(!@mulWithOverflow(u0, 0, 0, &result)); | |
| 117 | expect(!@shlWithOverflow(u0, 0, 0, &result)); | |
| 118 | } | |
| 119 | ||
| 120 | test "@clz" { | |
| 121 | testClz(); | |
| 122 | comptime testClz(); | |
| 123 | } | |
| 124 | ||
| 125 | fn testClz() void { | |
| 126 | expect(clz(u8, 0b10001010) == 0); | |
| 127 | expect(clz(u8, 0b00001010) == 4); | |
| 128 | expect(clz(u8, 0b00011010) == 3); | |
| 129 | expect(clz(u8, 0b00000000) == 8); | |
| 130 | expect(clz(u128, 0xffffffffffffffff) == 64); | |
| 131 | expect(clz(u128, 0x10000000000000000) == 63); | |
| 132 | } | |
| 133 | ||
| 134 | fn clz(comptime T: type, x: T) usize { | |
| 135 | return @clz(T, x); | |
| 136 | } | |
| 137 | ||
| 138 | test "@ctz" { | |
| 139 | testCtz(); | |
| 140 | comptime testCtz(); | |
| 141 | } | |
| 142 | ||
| 143 | fn testCtz() void { | |
| 144 | expect(ctz(u8, 0b10100000) == 5); | |
| 145 | expect(ctz(u8, 0b10001010) == 1); | |
| 146 | expect(ctz(u8, 0b00000000) == 8); | |
| 147 | expect(ctz(u16, 0b00000000) == 16); | |
| 148 | } | |
| 149 | ||
| 150 | fn ctz(comptime T: type, x: T) usize { | |
| 151 | return @ctz(T, x); | |
| 152 | } | |
| 153 | ||
| 154 | test "assignment operators" { | |
| 155 | var i: u32 = 0; | |
| 156 | i += 5; | |
| 157 | expect(i == 5); | |
| 158 | i -= 2; | |
| 159 | expect(i == 3); | |
| 160 | i *= 20; | |
| 161 | expect(i == 60); | |
| 162 | i /= 3; | |
| 163 | expect(i == 20); | |
| 164 | i %= 11; | |
| 165 | expect(i == 9); | |
| 166 | i <<= 1; | |
| 167 | expect(i == 18); | |
| 168 | i >>= 2; | |
| 169 | expect(i == 4); | |
| 170 | i = 6; | |
| 171 | i &= 5; | |
| 172 | expect(i == 4); | |
| 173 | i ^= 6; | |
| 174 | expect(i == 2); | |
| 175 | i = 6; | |
| 176 | i |= 3; | |
| 177 | expect(i == 7); | |
| 178 | } | |
| 179 | ||
| 180 | test "three expr in a row" { | |
| 181 | testThreeExprInARow(false, true); | |
| 182 | comptime testThreeExprInARow(false, true); | |
| 183 | } | |
| 184 | fn testThreeExprInARow(f: bool, t: bool) void { | |
| 185 | assertFalse(f or f or f); | |
| 186 | assertFalse(t and t and f); | |
| 187 | assertFalse(1 | 2 | 4 != 7); | |
| 188 | assertFalse(3 ^ 6 ^ 8 != 13); | |
| 189 | assertFalse(7 & 14 & 28 != 4); | |
| 190 | assertFalse(9 << 1 << 2 != 9 << 3); | |
| 191 | assertFalse(90 >> 1 >> 2 != 90 >> 3); | |
| 192 | assertFalse(100 - 1 + 1000 != 1099); | |
| 193 | assertFalse(5 * 4 / 2 % 3 != 1); | |
| 194 | assertFalse(@as(i32, @as(i32, 5)) != 5); | |
| 195 | assertFalse(!!false); | |
| 196 | assertFalse(@as(i32, 7) != --(@as(i32, 7))); | |
| 197 | } | |
| 198 | fn assertFalse(b: bool) void { | |
| 199 | expect(!b); | |
| 200 | } | |
| 201 | ||
| 202 | test "const number literal" { | |
| 203 | const one = 1; | |
| 204 | const eleven = ten + one; | |
| 205 | ||
| 206 | expect(eleven == 11); | |
| 207 | } | |
| 208 | const ten = 10; | |
| 209 | ||
| 210 | test "unsigned wrapping" { | |
| 211 | testUnsignedWrappingEval(maxInt(u32)); | |
| 212 | comptime testUnsignedWrappingEval(maxInt(u32)); | |
| 213 | } | |
| 214 | fn testUnsignedWrappingEval(x: u32) void { | |
| 215 | const zero = x +% 1; | |
| 216 | expect(zero == 0); | |
| 217 | const orig = zero -% 1; | |
| 218 | expect(orig == maxInt(u32)); | |
| 219 | } | |
| 220 | ||
| 221 | test "signed wrapping" { | |
| 222 | testSignedWrappingEval(maxInt(i32)); | |
| 223 | comptime testSignedWrappingEval(maxInt(i32)); | |
| 224 | } | |
| 225 | fn testSignedWrappingEval(x: i32) void { | |
| 226 | const min_val = x +% 1; | |
| 227 | expect(min_val == minInt(i32)); | |
| 228 | const max_val = min_val -% 1; | |
| 229 | expect(max_val == maxInt(i32)); | |
| 230 | } | |
| 231 | ||
| 232 | test "signed negation wrapping" { | |
| 233 | testSignedNegationWrappingEval(minInt(i16)); | |
| 234 | comptime testSignedNegationWrappingEval(minInt(i16)); | |
| 235 | } | |
| 236 | fn testSignedNegationWrappingEval(x: i16) void { | |
| 237 | expect(x == -32768); | |
| 238 | const neg = -%x; | |
| 239 | expect(neg == -32768); | |
| 240 | } | |
| 241 | ||
| 242 | test "unsigned negation wrapping" { | |
| 243 | testUnsignedNegationWrappingEval(1); | |
| 244 | comptime testUnsignedNegationWrappingEval(1); | |
| 245 | } | |
| 246 | fn testUnsignedNegationWrappingEval(x: u16) void { | |
| 247 | expect(x == 1); | |
| 248 | const neg = -%x; | |
| 249 | expect(neg == maxInt(u16)); | |
| 250 | } | |
| 251 | ||
| 252 | test "unsigned 64-bit division" { | |
| 253 | test_u64_div(); | |
| 254 | comptime test_u64_div(); | |
| 255 | } | |
| 256 | fn test_u64_div() void { | |
| 257 | const result = divWithResult(1152921504606846976, 34359738365); | |
| 258 | expect(result.quotient == 33554432); | |
| 259 | expect(result.remainder == 100663296); | |
| 260 | } | |
| 261 | fn divWithResult(a: u64, b: u64) DivResult { | |
| 262 | return DivResult{ | |
| 263 | .quotient = a / b, | |
| 264 | .remainder = a % b, | |
| 265 | }; | |
| 266 | } | |
| 267 | const DivResult = struct { | |
| 268 | quotient: u64, | |
| 269 | remainder: u64, | |
| 270 | }; | |
| 271 | ||
| 272 | test "binary not" { | |
| 273 | expect(comptime x: { | |
| 274 | break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101; | |
| 275 | }); | |
| 276 | expect(comptime x: { | |
| 277 | break :x ~@as(u64, 2147483647) == 18446744071562067968; | |
| 278 | }); | |
| 279 | testBinaryNot(0b1010101010101010); | |
| 280 | } | |
| 281 | ||
| 282 | fn testBinaryNot(x: u16) void { | |
| 283 | expect(~x == 0b0101010101010101); | |
| 284 | } | |
| 285 | ||
| 286 | test "small int addition" { | |
| 287 | var x: u2 = 0; | |
| 288 | expect(x == 0); | |
| 289 | ||
| 290 | x += 1; | |
| 291 | expect(x == 1); | |
| 292 | ||
| 293 | x += 1; | |
| 294 | expect(x == 2); | |
| 295 | ||
| 296 | x += 1; | |
| 297 | expect(x == 3); | |
| 298 | ||
| 299 | var result: @TypeOf(x) = 3; | |
| 300 | expect(@addWithOverflow(@TypeOf(x), x, 1, &result)); | |
| 301 | ||
| 302 | expect(result == 0); | |
| 303 | } | |
| 304 | ||
| 305 | test "float equality" { | |
| 306 | const x: f64 = 0.012; | |
| 307 | const y: f64 = x + 1.0; | |
| 308 | ||
| 309 | testFloatEqualityImpl(x, y); | |
| 310 | comptime testFloatEqualityImpl(x, y); | |
| 311 | } | |
| 312 | ||
| 313 | fn testFloatEqualityImpl(x: f64, y: f64) void { | |
| 314 | const y2 = x + 1.0; | |
| 315 | expect(y == y2); | |
| 316 | } | |
| 317 | ||
| 318 | test "allow signed integer division/remainder when values are comptime known and positive or exact" { | |
| 319 | expect(5 / 3 == 1); | |
| 320 | expect(-5 / -3 == 1); | |
| 321 | expect(-6 / 3 == -2); | |
| 322 | ||
| 323 | expect(5 % 3 == 2); | |
| 324 | expect(-6 % 3 == 0); | |
| 325 | } | |
| 326 | ||
| 327 | test "hex float literal parsing" { | |
| 328 | comptime expect(0x1.0 == 1.0); | |
| 329 | } | |
| 330 | ||
| 331 | test "quad hex float literal parsing in range" { | |
| 332 | const a = 0x1.af23456789bbaaab347645365cdep+5; | |
| 333 | const b = 0x1.dedafcff354b6ae9758763545432p-9; | |
| 334 | const c = 0x1.2f34dd5f437e849b4baab754cdefp+4534; | |
| 335 | const d = 0x1.edcbff8ad76ab5bf46463233214fp-435; | |
| 336 | } | |
| 337 | ||
| 338 | test "quad hex float literal parsing accurate" { | |
| 339 | const a: f128 = 0x1.1111222233334444555566667777p+0; | |
| 340 | ||
| 341 | // implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing. | |
| 342 | const expected: u128 = 0x3fff1111222233334444555566667777; | |
| 343 | expect(@bitCast(u128, a) == expected); | |
| 344 | ||
| 345 | // non-normalized | |
| 346 | const b: f128 = 0x11.111222233334444555566667777p-4; | |
| 347 | expect(@bitCast(u128, b) == expected); | |
| 348 | ||
| 349 | const S = struct { | |
| 350 | fn doTheTest() void { | |
| 351 | { | |
| 352 | var f: f128 = 0x1.2eab345678439abcdefea56782346p+5; | |
| 353 | expect(@bitCast(u128, f) == 0x40042eab345678439abcdefea5678234); | |
| 354 | } | |
| 355 | { | |
| 356 | var f: f128 = 0x1.edcb34a235253948765432134674fp-1; | |
| 357 | expect(@bitCast(u128, f) == 0x3ffeedcb34a235253948765432134674); | |
| 358 | } | |
| 359 | { | |
| 360 | var f: f128 = 0x1.353e45674d89abacc3a2ebf3ff4ffp-50; | |
| 361 | expect(@bitCast(u128, f) == 0x3fcd353e45674d89abacc3a2ebf3ff50); | |
| 362 | } | |
| 363 | { | |
| 364 | var f: f128 = 0x1.ed8764648369535adf4be3214567fp-9; | |
| 365 | expect(@bitCast(u128, f) == 0x3ff6ed8764648369535adf4be3214568); | |
| 366 | } | |
| 367 | const exp2ft = [_]f64{ | |
| 368 | 0x1.6a09e667f3bcdp-1, | |
| 369 | 0x1.7a11473eb0187p-1, | |
| 370 | 0x1.8ace5422aa0dbp-1, | |
| 371 | 0x1.9c49182a3f090p-1, | |
| 372 | 0x1.ae89f995ad3adp-1, | |
| 373 | 0x1.c199bdd85529cp-1, | |
| 374 | 0x1.d5818dcfba487p-1, | |
| 375 | 0x1.ea4afa2a490dap-1, | |
| 376 | 0x1.0000000000000p+0, | |
| 377 | 0x1.0b5586cf9890fp+0, | |
| 378 | 0x1.172b83c7d517bp+0, | |
| 379 | 0x1.2387a6e756238p+0, | |
| 380 | 0x1.306fe0a31b715p+0, | |
| 381 | 0x1.3dea64c123422p+0, | |
| 382 | 0x1.4bfdad5362a27p+0, | |
| 383 | 0x1.5ab07dd485429p+0, | |
| 384 | 0x1.8p23, | |
| 385 | 0x1.62e430p-1, | |
| 386 | 0x1.ebfbe0p-3, | |
| 387 | 0x1.c6b348p-5, | |
| 388 | 0x1.3b2c9cp-7, | |
| 389 | 0x1.0p127, | |
| 390 | -0x1.0p-149, | |
| 391 | }; | |
| 392 | ||
| 393 | const answers = [_]u64{ | |
| 394 | 0x3fe6a09e667f3bcd, | |
| 395 | 0x3fe7a11473eb0187, | |
| 396 | 0x3fe8ace5422aa0db, | |
| 397 | 0x3fe9c49182a3f090, | |
| 398 | 0x3feae89f995ad3ad, | |
| 399 | 0x3fec199bdd85529c, | |
| 400 | 0x3fed5818dcfba487, | |
| 401 | 0x3feea4afa2a490da, | |
| 402 | 0x3ff0000000000000, | |
| 403 | 0x3ff0b5586cf9890f, | |
| 404 | 0x3ff172b83c7d517b, | |
| 405 | 0x3ff2387a6e756238, | |
| 406 | 0x3ff306fe0a31b715, | |
| 407 | 0x3ff3dea64c123422, | |
| 408 | 0x3ff4bfdad5362a27, | |
| 409 | 0x3ff5ab07dd485429, | |
| 410 | 0x4168000000000000, | |
| 411 | 0x3fe62e4300000000, | |
| 412 | 0x3fcebfbe00000000, | |
| 413 | 0x3fac6b3480000000, | |
| 414 | 0x3f83b2c9c0000000, | |
| 415 | 0x47e0000000000000, | |
| 416 | 0xb6a0000000000000, | |
| 417 | }; | |
| 418 | ||
| 419 | for (exp2ft) |x, i| { | |
| 420 | expect(@bitCast(u64, x) == answers[i]); | |
| 421 | } | |
| 422 | } | |
| 423 | }; | |
| 424 | S.doTheTest(); | |
| 425 | comptime S.doTheTest(); | |
| 426 | } | |
| 427 | ||
| 428 | test "underscore separator parsing" { | |
| 429 | expect(0_0_0_0 == 0); | |
| 430 | expect(1_234_567 == 1234567); | |
| 431 | expect(001_234_567 == 1234567); | |
| 432 | expect(0_0_1_2_3_4_5_6_7 == 1234567); | |
| 433 | ||
| 434 | expect(0b0_0_0_0 == 0); | |
| 435 | expect(0b1010_1010 == 0b10101010); | |
| 436 | expect(0b0000_1010_1010 == 0b10101010); | |
| 437 | expect(0b1_0_1_0_1_0_1_0 == 0b10101010); | |
| 438 | ||
| 439 | expect(0o0_0_0_0 == 0); | |
| 440 | expect(0o1010_1010 == 0o10101010); | |
| 441 | expect(0o0000_1010_1010 == 0o10101010); | |
| 442 | expect(0o1_0_1_0_1_0_1_0 == 0o10101010); | |
| 443 | ||
| 444 | expect(0x0_0_0_0 == 0); | |
| 445 | expect(0x1010_1010 == 0x10101010); | |
| 446 | expect(0x0000_1010_1010 == 0x10101010); | |
| 447 | expect(0x1_0_1_0_1_0_1_0 == 0x10101010); | |
| 448 | ||
| 449 | expect(123_456.789_000e1_0 == 123456.789000e10); | |
| 450 | expect(0_1_2_3_4_5_6.7_8_9_0_0_0e0_0_1_0 == 123456.789000e10); | |
| 451 | ||
| 452 | expect(0x1234_5678.9ABC_DEF0p-1_0 == 0x12345678.9ABCDEF0p-10); | |
| 453 | expect(0x1_2_3_4_5_6_7_8.9_A_B_C_D_E_F_0p-0_0_0_1_0 == 0x12345678.9ABCDEF0p-10); | |
| 454 | } | |
| 455 | ||
| 456 | test "hex float literal within range" { | |
| 457 | const a = 0x1.0p16383; | |
| 458 | const b = 0x0.1p16387; | |
| 459 | const c = 0x1.0p-16382; | |
| 460 | } | |
| 461 | ||
| 462 | test "truncating shift left" { | |
| 463 | testShlTrunc(maxInt(u16)); | |
| 464 | comptime testShlTrunc(maxInt(u16)); | |
| 465 | } | |
| 466 | fn testShlTrunc(x: u16) void { | |
| 467 | const shifted = x << 1; | |
| 468 | expect(shifted == 65534); | |
| 469 | } | |
| 470 | ||
| 471 | test "truncating shift right" { | |
| 472 | testShrTrunc(maxInt(u16)); | |
| 473 | comptime testShrTrunc(maxInt(u16)); | |
| 474 | } | |
| 475 | fn testShrTrunc(x: u16) void { | |
| 476 | const shifted = x >> 1; | |
| 477 | expect(shifted == 32767); | |
| 478 | } | |
| 479 | ||
| 480 | test "exact shift left" { | |
| 481 | testShlExact(0b00110101); | |
| 482 | comptime testShlExact(0b00110101); | |
| 483 | } | |
| 484 | fn testShlExact(x: u8) void { | |
| 485 | const shifted = @shlExact(x, 2); | |
| 486 | expect(shifted == 0b11010100); | |
| 487 | } | |
| 488 | ||
| 489 | test "exact shift right" { | |
| 490 | testShrExact(0b10110100); | |
| 491 | comptime testShrExact(0b10110100); | |
| 492 | } | |
| 493 | fn testShrExact(x: u8) void { | |
| 494 | const shifted = @shrExact(x, 2); | |
| 495 | expect(shifted == 0b00101101); | |
| 496 | } | |
| 497 | ||
| 498 | test "shift left/right on u0 operand" { | |
| 499 | const S = struct { | |
| 500 | fn doTheTest() void { | |
| 501 | var x: u0 = 0; | |
| 502 | var y: u0 = 0; | |
| 503 | expectEqual(@as(u0, 0), x << 0); | |
| 504 | expectEqual(@as(u0, 0), x >> 0); | |
| 505 | expectEqual(@as(u0, 0), x << y); | |
| 506 | expectEqual(@as(u0, 0), x >> y); | |
| 507 | expectEqual(@as(u0, 0), @shlExact(x, 0)); | |
| 508 | expectEqual(@as(u0, 0), @shrExact(x, 0)); | |
| 509 | expectEqual(@as(u0, 0), @shlExact(x, y)); | |
| 510 | expectEqual(@as(u0, 0), @shrExact(x, y)); | |
| 511 | } | |
| 512 | }; | |
| 513 | S.doTheTest(); | |
| 514 | comptime S.doTheTest(); | |
| 515 | } | |
| 516 | ||
| 517 | test "comptime_int addition" { | |
| 518 | comptime { | |
| 519 | expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950); | |
| 520 | expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380); | |
| 521 | } | |
| 522 | } | |
| 523 | ||
| 524 | test "comptime_int multiplication" { | |
| 525 | comptime { | |
| 526 | expect( | |
| 527 | 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567, | |
| 528 | ); | |
| 529 | expect( | |
| 530 | 594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016, | |
| 531 | ); | |
| 532 | } | |
| 533 | } | |
| 534 | ||
| 535 | test "comptime_int shifting" { | |
| 536 | comptime { | |
| 537 | expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000); | |
| 538 | } | |
| 539 | } | |
| 540 | ||
| 541 | test "comptime_int multi-limb shift and mask" { | |
| 542 | comptime { | |
| 543 | var a = 0xefffffffa0000001eeeeeeefaaaaaaab; | |
| 544 | ||
| 545 | expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab); | |
| 546 | a >>= 32; | |
| 547 | expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef); | |
| 548 | a >>= 32; | |
| 549 | expect(@as(u32, a & 0xffffffff) == 0xa0000001); | |
| 550 | a >>= 32; | |
| 551 | expect(@as(u32, a & 0xffffffff) == 0xefffffff); | |
| 552 | a >>= 32; | |
| 553 | ||
| 554 | expect(a == 0); | |
| 555 | } | |
| 556 | } | |
| 557 | ||
| 558 | test "comptime_int multi-limb partial shift right" { | |
| 559 | comptime { | |
| 560 | var a = 0x1ffffffffeeeeeeee; | |
| 561 | a >>= 16; | |
| 562 | expect(a == 0x1ffffffffeeee); | |
| 563 | } | |
| 564 | } | |
| 565 | ||
| 566 | test "xor" { | |
| 567 | test_xor(); | |
| 568 | comptime test_xor(); | |
| 569 | } | |
| 570 | ||
| 571 | fn test_xor() void { | |
| 572 | expect(0xFF ^ 0x00 == 0xFF); | |
| 573 | expect(0xF0 ^ 0x0F == 0xFF); | |
| 574 | expect(0xFF ^ 0xF0 == 0x0F); | |
| 575 | expect(0xFF ^ 0x0F == 0xF0); | |
| 576 | expect(0xFF ^ 0xFF == 0x00); | |
| 577 | } | |
| 578 | ||
| 579 | test "comptime_int xor" { | |
| 580 | comptime { | |
| 581 | expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 582 | expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 583 | expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF); | |
| 584 | expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000); | |
| 585 | expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000); | |
| 586 | expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | |
| 587 | expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF); | |
| 588 | expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000); | |
| 589 | } | |
| 590 | } | |
| 591 | ||
| 592 | test "f128" { | |
| 593 | test_f128(); | |
| 594 | comptime test_f128(); | |
| 595 | } | |
| 596 | ||
| 597 | fn make_f128(x: f128) f128 { | |
| 598 | return x; | |
| 599 | } | |
| 600 | ||
| 601 | fn test_f128() void { | |
| 602 | expect(@sizeOf(f128) == 16); | |
| 603 | expect(make_f128(1.0) == 1.0); | |
| 604 | expect(make_f128(1.0) != 1.1); | |
| 605 | expect(make_f128(1.0) > 0.9); | |
| 606 | expect(make_f128(1.0) >= 0.9); | |
| 607 | expect(make_f128(1.0) >= 1.0); | |
| 608 | should_not_be_zero(1.0); | |
| 609 | } | |
| 610 | ||
| 611 | fn should_not_be_zero(x: f128) void { | |
| 612 | expect(x != 0.0); | |
| 613 | } | |
| 614 | ||
| 615 | test "comptime float rem int" { | |
| 616 | comptime { | |
| 617 | var x = @as(f32, 1) % 2; | |
| 618 | expect(x == 1.0); | |
| 619 | } | |
| 620 | } | |
| 621 | ||
| 622 | test "remainder division" { | |
| 623 | comptime remdiv(f16); | |
| 624 | comptime remdiv(f32); | |
| 625 | comptime remdiv(f64); | |
| 626 | comptime remdiv(f128); | |
| 627 | remdiv(f16); | |
| 628 | remdiv(f64); | |
| 629 | remdiv(f128); | |
| 630 | } | |
| 631 | ||
| 632 | fn remdiv(comptime T: type) void { | |
| 633 | expect(@as(T, 1) == @as(T, 1) % @as(T, 2)); | |
| 634 | expect(@as(T, 1) == @as(T, 7) % @as(T, 3)); | |
| 635 | } | |
| 636 | ||
| 637 | test "@sqrt" { | |
| 638 | testSqrt(f64, 12.0); | |
| 639 | comptime testSqrt(f64, 12.0); | |
| 640 | testSqrt(f32, 13.0); | |
| 641 | comptime testSqrt(f32, 13.0); | |
| 642 | testSqrt(f16, 13.0); | |
| 643 | comptime testSqrt(f16, 13.0); | |
| 644 | ||
| 645 | const x = 14.0; | |
| 646 | const y = x * x; | |
| 647 | const z = @sqrt(y); | |
| 648 | comptime expect(z == x); | |
| 649 | } | |
| 650 | ||
| 651 | fn testSqrt(comptime T: type, x: T) void { | |
| 652 | expect(@sqrt(x * x) == x); | |
| 653 | } | |
| 654 | ||
| 655 | test "@fabs" { | |
| 656 | testFabs(f128, 12.0); | |
| 657 | comptime testFabs(f128, 12.0); | |
| 658 | testFabs(f64, 12.0); | |
| 659 | comptime testFabs(f64, 12.0); | |
| 660 | testFabs(f32, 12.0); | |
| 661 | comptime testFabs(f32, 12.0); | |
| 662 | testFabs(f16, 12.0); | |
| 663 | comptime testFabs(f16, 12.0); | |
| 664 | ||
| 665 | const x = 14.0; | |
| 666 | const y = -x; | |
| 667 | const z = @fabs(y); | |
| 668 | comptime expectEqual(x, z); | |
| 669 | } | |
| 670 | ||
| 671 | fn testFabs(comptime T: type, x: T) void { | |
| 672 | const y = -x; | |
| 673 | const z = @fabs(y); | |
| 674 | expectEqual(x, z); | |
| 675 | } | |
| 676 | ||
| 677 | test "@floor" { | |
| 678 | // FIXME: Generates a floorl function call | |
| 679 | // testFloor(f128, 12.0); | |
| 680 | comptime testFloor(f128, 12.0); | |
| 681 | testFloor(f64, 12.0); | |
| 682 | comptime testFloor(f64, 12.0); | |
| 683 | testFloor(f32, 12.0); | |
| 684 | comptime testFloor(f32, 12.0); | |
| 685 | testFloor(f16, 12.0); | |
| 686 | comptime testFloor(f16, 12.0); | |
| 687 | ||
| 688 | const x = 14.0; | |
| 689 | const y = x + 0.7; | |
| 690 | const z = @floor(y); | |
| 691 | comptime expectEqual(x, z); | |
| 692 | } | |
| 693 | ||
| 694 | fn testFloor(comptime T: type, x: T) void { | |
| 695 | const y = x + 0.6; | |
| 696 | const z = @floor(y); | |
| 697 | expectEqual(x, z); | |
| 698 | } | |
| 699 | ||
| 700 | test "@ceil" { | |
| 701 | // FIXME: Generates a ceill function call | |
| 702 | //testCeil(f128, 12.0); | |
| 703 | comptime testCeil(f128, 12.0); | |
| 704 | testCeil(f64, 12.0); | |
| 705 | comptime testCeil(f64, 12.0); | |
| 706 | testCeil(f32, 12.0); | |
| 707 | comptime testCeil(f32, 12.0); | |
| 708 | testCeil(f16, 12.0); | |
| 709 | comptime testCeil(f16, 12.0); | |
| 710 | ||
| 711 | const x = 14.0; | |
| 712 | const y = x - 0.7; | |
| 713 | const z = @ceil(y); | |
| 714 | comptime expectEqual(x, z); | |
| 715 | } | |
| 716 | ||
| 717 | fn testCeil(comptime T: type, x: T) void { | |
| 718 | const y = x - 0.8; | |
| 719 | const z = @ceil(y); | |
| 720 | expectEqual(x, z); | |
| 721 | } | |
| 722 | ||
| 723 | test "@trunc" { | |
| 724 | // FIXME: Generates a truncl function call | |
| 725 | //testTrunc(f128, 12.0); | |
| 726 | comptime testTrunc(f128, 12.0); | |
| 727 | testTrunc(f64, 12.0); | |
| 728 | comptime testTrunc(f64, 12.0); | |
| 729 | testTrunc(f32, 12.0); | |
| 730 | comptime testTrunc(f32, 12.0); | |
| 731 | testTrunc(f16, 12.0); | |
| 732 | comptime testTrunc(f16, 12.0); | |
| 733 | ||
| 734 | const x = 14.0; | |
| 735 | const y = x + 0.7; | |
| 736 | const z = @trunc(y); | |
| 737 | comptime expectEqual(x, z); | |
| 738 | } | |
| 739 | ||
| 740 | fn testTrunc(comptime T: type, x: T) void { | |
| 741 | { | |
| 742 | const y = x + 0.8; | |
| 743 | const z = @trunc(y); | |
| 744 | expectEqual(x, z); | |
| 745 | } | |
| 746 | ||
| 747 | { | |
| 748 | const y = -x - 0.8; | |
| 749 | const z = @trunc(y); | |
| 750 | expectEqual(-x, z); | |
| 751 | } | |
| 752 | } | |
| 753 | ||
| 754 | test "@round" { | |
| 755 | // FIXME: Generates a roundl function call | |
| 756 | //testRound(f128, 12.0); | |
| 757 | comptime testRound(f128, 12.0); | |
| 758 | testRound(f64, 12.0); | |
| 759 | comptime testRound(f64, 12.0); | |
| 760 | testRound(f32, 12.0); | |
| 761 | comptime testRound(f32, 12.0); | |
| 762 | testRound(f16, 12.0); | |
| 763 | comptime testRound(f16, 12.0); | |
| 764 | ||
| 765 | const x = 14.0; | |
| 766 | const y = x + 0.4; | |
| 767 | const z = @round(y); | |
| 768 | comptime expectEqual(x, z); | |
| 769 | } | |
| 770 | ||
| 771 | fn testRound(comptime T: type, x: T) void { | |
| 772 | const y = x - 0.5; | |
| 773 | const z = @round(y); | |
| 774 | expectEqual(x, z); | |
| 775 | } | |
| 776 | ||
| 777 | test "comptime_int param and return" { | |
| 778 | const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702); | |
| 779 | expect(a == 137114567242441932203689521744947848950); | |
| 780 | ||
| 781 | const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768); | |
| 782 | expect(b == 985095453608931032642182098849559179469148836107390954364380); | |
| 783 | } | |
| 784 | ||
| 785 | fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int { | |
| 786 | return a + b; | |
| 787 | } | |
| 788 | ||
| 789 | test "vector integer addition" { | |
| 790 | const S = struct { | |
| 791 | fn doTheTest() void { | |
| 792 | var a: std.meta.Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; | |
| 793 | var b: std.meta.Vector(4, i32) = [_]i32{ 5, 6, 7, 8 }; | |
| 794 | var result = a + b; | |
| 795 | var result_array: [4]i32 = result; | |
| 796 | const expected = [_]i32{ 6, 8, 10, 12 }; | |
| 797 | expectEqualSlices(i32, &expected, &result_array); | |
| 798 | } | |
| 799 | }; | |
| 800 | S.doTheTest(); | |
| 801 | comptime S.doTheTest(); | |
| 802 | } | |
| 803 | ||
| 804 | test "NaN comparison" { | |
| 805 | testNanEqNan(f16); | |
| 806 | testNanEqNan(f32); | |
| 807 | testNanEqNan(f64); | |
| 808 | testNanEqNan(f128); | |
| 809 | comptime testNanEqNan(f16); | |
| 810 | comptime testNanEqNan(f32); | |
| 811 | comptime testNanEqNan(f64); | |
| 812 | comptime testNanEqNan(f128); | |
| 813 | } | |
| 814 | ||
| 815 | fn testNanEqNan(comptime F: type) void { | |
| 816 | var nan1 = std.math.nan(F); | |
| 817 | var nan2 = std.math.nan(F); | |
| 818 | expect(nan1 != nan2); | |
| 819 | expect(!(nan1 == nan2)); | |
| 820 | expect(!(nan1 > nan2)); | |
| 821 | expect(!(nan1 >= nan2)); | |
| 822 | expect(!(nan1 < nan2)); | |
| 823 | expect(!(nan1 <= nan2)); | |
| 824 | } | |
| 825 | ||
| 826 | test "128-bit multiplication" { | |
| 827 | var a: i128 = 3; | |
| 828 | var b: i128 = 2; | |
| 829 | var c = a * b; | |
| 830 | expect(c == 6); | |
| 831 | } | |
| 832 | ||
| 833 | test "vector comparison" { | |
| 834 | const S = struct { | |
| 835 | fn doTheTest() void { | |
| 836 | var a: std.meta.Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 }; | |
| 837 | var b: std.meta.Vector(6, i32) = [_]i32{ -1, 3, 0, 6, 10, -10 }; | |
| 838 | expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{ false, false, true, true, true, false })); | |
| 839 | expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{ false, true, true, true, true, false })); | |
| 840 | expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{ false, true, false, false, false, false })); | |
| 841 | expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{ true, false, true, true, true, true })); | |
| 842 | expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{ true, false, false, false, false, true })); | |
| 843 | expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{ true, true, false, false, false, true })); | |
| 844 | } | |
| 845 | }; | |
| 846 | S.doTheTest(); | |
| 847 | comptime S.doTheTest(); | |
| 848 | } | |
| 849 | ||
| 850 | test "compare undefined literal with comptime_int" { | |
| 851 | var x = undefined == 1; | |
| 852 | // x is now undefined with type bool | |
| 853 | x = true; | |
| 854 | expect(x); | |
| 855 | } | |
| 856 | ||
| 857 | test "signed zeros are represented properly" { | |
| 858 | const S = struct { | |
| 859 | fn doTheTest() void { | |
| 860 | inline for ([_]type{ f16, f32, f64, f128 }) |T| { | |
| 861 | const ST = std.meta.Int(.unsigned, @typeInfo(T).Float.bits); | |
| 862 | var as_fp_val = -@as(T, 0.0); | |
| 863 | var as_uint_val = @bitCast(ST, as_fp_val); | |
| 864 | // Ensure the sign bit is set. | |
| 865 | expect(as_uint_val >> (@typeInfo(T).Float.bits - 1) == 1); | |
| 866 | } | |
| 867 | } | |
| 868 | }; | |
| 869 | ||
| 870 | S.doTheTest(); | |
| 871 | comptime S.doTheTest(); | |
| 872 | } |
test/stage1/behavior/merge_error_sets.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | const A = error{ | |
| 2 | FileNotFound, | |
| 3 | NotDir, | |
| 4 | }; | |
| 5 | const B = error{OutOfMemory}; | |
| 6 | ||
| 7 | const C = A || B; | |
| 8 | ||
| 9 | fn foo() C!void { | |
| 10 | return error.NotDir; | |
| 11 | } | |
| 12 | ||
| 13 | test "merge error sets" { | |
| 14 | if (foo()) { | |
| 15 | @panic("unexpected"); | |
| 16 | } else |err| switch (err) { | |
| 17 | error.OutOfMemory => @panic("unexpected"), | |
| 18 | error.FileNotFound => @panic("unexpected"), | |
| 19 | error.NotDir => {}, | |
| 20 | } | |
| 21 | } |
test/stage1/behavior/misc.zig deleted-761| ... | ... | @@ -1,761 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | const mem = std.mem; | |
| 5 | const builtin = @import("builtin"); | |
| 6 | ||
| 7 | // normal comment | |
| 8 | ||
| 9 | /// this is a documentation comment | |
| 10 | /// doc comment line 2 | |
| 11 | fn emptyFunctionWithComments() void {} | |
| 12 | ||
| 13 | test "empty function with comments" { | |
| 14 | emptyFunctionWithComments(); | |
| 15 | } | |
| 16 | ||
| 17 | comptime { | |
| 18 | @export(disabledExternFn, .{ .name = "disabledExternFn", .linkage = .Internal }); | |
| 19 | } | |
| 20 | ||
| 21 | fn disabledExternFn() callconv(.C) void {} | |
| 22 | ||
| 23 | test "call disabled extern fn" { | |
| 24 | disabledExternFn(); | |
| 25 | } | |
| 26 | ||
| 27 | test "short circuit" { | |
| 28 | testShortCircuit(false, true); | |
| 29 | comptime testShortCircuit(false, true); | |
| 30 | } | |
| 31 | ||
| 32 | fn testShortCircuit(f: bool, t: bool) void { | |
| 33 | var hit_1 = f; | |
| 34 | var hit_2 = f; | |
| 35 | var hit_3 = f; | |
| 36 | var hit_4 = f; | |
| 37 | ||
| 38 | if (t or x: { | |
| 39 | expect(f); | |
| 40 | break :x f; | |
| 41 | }) { | |
| 42 | hit_1 = t; | |
| 43 | } | |
| 44 | if (f or x: { | |
| 45 | hit_2 = t; | |
| 46 | break :x f; | |
| 47 | }) { | |
| 48 | expect(f); | |
| 49 | } | |
| 50 | ||
| 51 | if (t and x: { | |
| 52 | hit_3 = t; | |
| 53 | break :x f; | |
| 54 | }) { | |
| 55 | expect(f); | |
| 56 | } | |
| 57 | if (f and x: { | |
| 58 | expect(f); | |
| 59 | break :x f; | |
| 60 | }) { | |
| 61 | expect(f); | |
| 62 | } else { | |
| 63 | hit_4 = t; | |
| 64 | } | |
| 65 | expect(hit_1); | |
| 66 | expect(hit_2); | |
| 67 | expect(hit_3); | |
| 68 | expect(hit_4); | |
| 69 | } | |
| 70 | ||
| 71 | test "truncate" { | |
| 72 | expect(testTruncate(0x10fd) == 0xfd); | |
| 73 | } | |
| 74 | fn testTruncate(x: u32) u8 { | |
| 75 | return @truncate(u8, x); | |
| 76 | } | |
| 77 | ||
| 78 | fn first4KeysOfHomeRow() []const u8 { | |
| 79 | return "aoeu"; | |
| 80 | } | |
| 81 | ||
| 82 | test "return string from function" { | |
| 83 | expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); | |
| 84 | } | |
| 85 | ||
| 86 | const g1: i32 = 1233 + 1; | |
| 87 | var g2: i32 = 0; | |
| 88 | ||
| 89 | test "global variables" { | |
| 90 | expect(g2 == 0); | |
| 91 | g2 = g1; | |
| 92 | expect(g2 == 1234); | |
| 93 | } | |
| 94 | ||
| 95 | test "memcpy and memset intrinsics" { | |
| 96 | var foo: [20]u8 = undefined; | |
| 97 | var bar: [20]u8 = undefined; | |
| 98 | ||
| 99 | @memset(&foo, 'A', foo.len); | |
| 100 | @memcpy(&bar, &foo, bar.len); | |
| 101 | ||
| 102 | if (bar[11] != 'A') unreachable; | |
| 103 | } | |
| 104 | ||
| 105 | test "builtin static eval" { | |
| 106 | const x: i32 = comptime x: { | |
| 107 | break :x 1 + 2 + 3; | |
| 108 | }; | |
| 109 | expect(x == comptime 6); | |
| 110 | } | |
| 111 | ||
| 112 | test "slicing" { | |
| 113 | var array: [20]i32 = undefined; | |
| 114 | ||
| 115 | array[5] = 1234; | |
| 116 | ||
| 117 | var slice = array[5..10]; | |
| 118 | ||
| 119 | if (slice.len != 5) unreachable; | |
| 120 | ||
| 121 | const ptr = &slice[0]; | |
| 122 | if (ptr.* != 1234) unreachable; | |
| 123 | ||
| 124 | var slice_rest = array[10..]; | |
| 125 | if (slice_rest.len != 10) unreachable; | |
| 126 | } | |
| 127 | ||
| 128 | test "constant equal function pointers" { | |
| 129 | const alias = emptyFn; | |
| 130 | expect(comptime x: { | |
| 131 | break :x emptyFn == alias; | |
| 132 | }); | |
| 133 | } | |
| 134 | ||
| 135 | fn emptyFn() void {} | |
| 136 | ||
| 137 | test "hex escape" { | |
| 138 | expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); | |
| 139 | } | |
| 140 | ||
| 141 | test "string concatenation" { | |
| 142 | expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); | |
| 143 | } | |
| 144 | ||
| 145 | test "array mult operator" { | |
| 146 | expect(mem.eql(u8, "ab" ** 5, "ababababab")); | |
| 147 | } | |
| 148 | ||
| 149 | test "string escapes" { | |
| 150 | expect(mem.eql(u8, "\"", "\x22")); | |
| 151 | expect(mem.eql(u8, "\'", "\x27")); | |
| 152 | expect(mem.eql(u8, "\n", "\x0a")); | |
| 153 | expect(mem.eql(u8, "\r", "\x0d")); | |
| 154 | expect(mem.eql(u8, "\t", "\x09")); | |
| 155 | expect(mem.eql(u8, "\\", "\x5c")); | |
| 156 | expect(mem.eql(u8, "\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01")); | |
| 157 | } | |
| 158 | ||
| 159 | test "multiline string" { | |
| 160 | const s1 = | |
| 161 | \\one | |
| 162 | \\two) | |
| 163 | \\three | |
| 164 | ; | |
| 165 | const s2 = "one\ntwo)\nthree"; | |
| 166 | expect(mem.eql(u8, s1, s2)); | |
| 167 | } | |
| 168 | ||
| 169 | test "multiline string comments at start" { | |
| 170 | const s1 = | |
| 171 | //\\one | |
| 172 | \\two) | |
| 173 | \\three | |
| 174 | ; | |
| 175 | const s2 = "two)\nthree"; | |
| 176 | expect(mem.eql(u8, s1, s2)); | |
| 177 | } | |
| 178 | ||
| 179 | test "multiline string comments at end" { | |
| 180 | const s1 = | |
| 181 | \\one | |
| 182 | \\two) | |
| 183 | //\\three | |
| 184 | ; | |
| 185 | const s2 = "one\ntwo)"; | |
| 186 | expect(mem.eql(u8, s1, s2)); | |
| 187 | } | |
| 188 | ||
| 189 | test "multiline string comments in middle" { | |
| 190 | const s1 = | |
| 191 | \\one | |
| 192 | //\\two) | |
| 193 | \\three | |
| 194 | ; | |
| 195 | const s2 = "one\nthree"; | |
| 196 | expect(mem.eql(u8, s1, s2)); | |
| 197 | } | |
| 198 | ||
| 199 | test "multiline string comments at multiple places" { | |
| 200 | const s1 = | |
| 201 | \\one | |
| 202 | //\\two | |
| 203 | \\three | |
| 204 | //\\four | |
| 205 | \\five | |
| 206 | ; | |
| 207 | const s2 = "one\nthree\nfive"; | |
| 208 | expect(mem.eql(u8, s1, s2)); | |
| 209 | } | |
| 210 | ||
| 211 | test "multiline C string" { | |
| 212 | const s1 = | |
| 213 | \\one | |
| 214 | \\two) | |
| 215 | \\three | |
| 216 | ; | |
| 217 | const s2 = "one\ntwo)\nthree"; | |
| 218 | expect(std.cstr.cmp(s1, s2) == 0); | |
| 219 | } | |
| 220 | ||
| 221 | test "type equality" { | |
| 222 | expect(*const u8 != *u8); | |
| 223 | } | |
| 224 | ||
| 225 | const global_a: i32 = 1234; | |
| 226 | const global_b: *const i32 = &global_a; | |
| 227 | const global_c: *const f32 = @ptrCast(*const f32, global_b); | |
| 228 | test "compile time global reinterpret" { | |
| 229 | const d = @ptrCast(*const i32, global_c); | |
| 230 | expect(d.* == 1234); | |
| 231 | } | |
| 232 | ||
| 233 | test "explicit cast maybe pointers" { | |
| 234 | const a: ?*i32 = undefined; | |
| 235 | const b: ?*f32 = @ptrCast(?*f32, a); | |
| 236 | } | |
| 237 | ||
| 238 | test "generic malloc free" { | |
| 239 | const a = memAlloc(u8, 10) catch unreachable; | |
| 240 | memFree(u8, a); | |
| 241 | } | |
| 242 | var some_mem: [100]u8 = undefined; | |
| 243 | fn memAlloc(comptime T: type, n: usize) anyerror![]T { | |
| 244 | return @ptrCast([*]T, &some_mem[0])[0..n]; | |
| 245 | } | |
| 246 | fn memFree(comptime T: type, memory: []T) void {} | |
| 247 | ||
| 248 | test "cast undefined" { | |
| 249 | const array: [100]u8 = undefined; | |
| 250 | const slice = @as([]const u8, &array); | |
| 251 | testCastUndefined(slice); | |
| 252 | } | |
| 253 | fn testCastUndefined(x: []const u8) void {} | |
| 254 | ||
| 255 | test "cast small unsigned to larger signed" { | |
| 256 | expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200)); | |
| 257 | expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999)); | |
| 258 | } | |
| 259 | fn castSmallUnsignedToLargerSigned1(x: u8) i16 { | |
| 260 | return x; | |
| 261 | } | |
| 262 | fn castSmallUnsignedToLargerSigned2(x: u16) i64 { | |
| 263 | return x; | |
| 264 | } | |
| 265 | ||
| 266 | test "implicit cast after unreachable" { | |
| 267 | expect(outer() == 1234); | |
| 268 | } | |
| 269 | fn inner() i32 { | |
| 270 | return 1234; | |
| 271 | } | |
| 272 | fn outer() i64 { | |
| 273 | return inner(); | |
| 274 | } | |
| 275 | ||
| 276 | test "pointer dereferencing" { | |
| 277 | var x = @as(i32, 3); | |
| 278 | const y = &x; | |
| 279 | ||
| 280 | y.* += 1; | |
| 281 | ||
| 282 | expect(x == 4); | |
| 283 | expect(y.* == 4); | |
| 284 | } | |
| 285 | ||
| 286 | test "call result of if else expression" { | |
| 287 | expect(mem.eql(u8, f2(true), "a")); | |
| 288 | expect(mem.eql(u8, f2(false), "b")); | |
| 289 | } | |
| 290 | fn f2(x: bool) []const u8 { | |
| 291 | return (if (x) fA else fB)(); | |
| 292 | } | |
| 293 | fn fA() []const u8 { | |
| 294 | return "a"; | |
| 295 | } | |
| 296 | fn fB() []const u8 { | |
| 297 | return "b"; | |
| 298 | } | |
| 299 | ||
| 300 | test "const expression eval handling of variables" { | |
| 301 | var x = true; | |
| 302 | while (x) { | |
| 303 | x = false; | |
| 304 | } | |
| 305 | } | |
| 306 | ||
| 307 | test "constant enum initialization with differing sizes" { | |
| 308 | test3_1(test3_foo); | |
| 309 | test3_2(test3_bar); | |
| 310 | } | |
| 311 | const Test3Foo = union(enum) { | |
| 312 | One: void, | |
| 313 | Two: f32, | |
| 314 | Three: Test3Point, | |
| 315 | }; | |
| 316 | const Test3Point = struct { | |
| 317 | x: i32, | |
| 318 | y: i32, | |
| 319 | }; | |
| 320 | const test3_foo = Test3Foo{ | |
| 321 | .Three = Test3Point{ | |
| 322 | .x = 3, | |
| 323 | .y = 4, | |
| 324 | }, | |
| 325 | }; | |
| 326 | const test3_bar = Test3Foo{ .Two = 13 }; | |
| 327 | fn test3_1(f: Test3Foo) void { | |
| 328 | switch (f) { | |
| 329 | Test3Foo.Three => |pt| { | |
| 330 | expect(pt.x == 3); | |
| 331 | expect(pt.y == 4); | |
| 332 | }, | |
| 333 | else => unreachable, | |
| 334 | } | |
| 335 | } | |
| 336 | fn test3_2(f: Test3Foo) void { | |
| 337 | switch (f) { | |
| 338 | Test3Foo.Two => |x| { | |
| 339 | expect(x == 13); | |
| 340 | }, | |
| 341 | else => unreachable, | |
| 342 | } | |
| 343 | } | |
| 344 | ||
| 345 | test "character literals" { | |
| 346 | expect('\'' == single_quote); | |
| 347 | } | |
| 348 | const single_quote = '\''; | |
| 349 | ||
| 350 | test "take address of parameter" { | |
| 351 | testTakeAddressOfParameter(12.34); | |
| 352 | } | |
| 353 | fn testTakeAddressOfParameter(f: f32) void { | |
| 354 | const f_ptr = &f; | |
| 355 | expect(f_ptr.* == 12.34); | |
| 356 | } | |
| 357 | ||
| 358 | test "pointer comparison" { | |
| 359 | const a = @as([]const u8, "a"); | |
| 360 | const b = &a; | |
| 361 | expect(ptrEql(b, b)); | |
| 362 | } | |
| 363 | fn ptrEql(a: *const []const u8, b: *const []const u8) bool { | |
| 364 | return a == b; | |
| 365 | } | |
| 366 | ||
| 367 | test "string concatenation" { | |
| 368 | const a = "OK" ++ " IT " ++ "WORKED"; | |
| 369 | const b = "OK IT WORKED"; | |
| 370 | ||
| 371 | comptime expect(@TypeOf(a) == *const [12:0]u8); | |
| 372 | comptime expect(@TypeOf(b) == *const [12:0]u8); | |
| 373 | ||
| 374 | const len = mem.len(b); | |
| 375 | const len_with_null = len + 1; | |
| 376 | { | |
| 377 | var i: u32 = 0; | |
| 378 | while (i < len_with_null) : (i += 1) { | |
| 379 | expect(a[i] == b[i]); | |
| 380 | } | |
| 381 | } | |
| 382 | expect(a[len] == 0); | |
| 383 | expect(b[len] == 0); | |
| 384 | } | |
| 385 | ||
| 386 | test "pointer to void return type" { | |
| 387 | testPointerToVoidReturnType() catch unreachable; | |
| 388 | } | |
| 389 | fn testPointerToVoidReturnType() anyerror!void { | |
| 390 | const a = testPointerToVoidReturnType2(); | |
| 391 | return a.*; | |
| 392 | } | |
| 393 | const test_pointer_to_void_return_type_x = void{}; | |
| 394 | fn testPointerToVoidReturnType2() *const void { | |
| 395 | return &test_pointer_to_void_return_type_x; | |
| 396 | } | |
| 397 | ||
| 398 | test "non const ptr to aliased type" { | |
| 399 | const int = i32; | |
| 400 | expect(?*int == ?*i32); | |
| 401 | } | |
| 402 | ||
| 403 | test "array 2D const double ptr" { | |
| 404 | const rect_2d_vertexes = [_][1]f32{ | |
| 405 | [_]f32{1.0}, | |
| 406 | [_]f32{2.0}, | |
| 407 | }; | |
| 408 | testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]); | |
| 409 | } | |
| 410 | ||
| 411 | fn testArray2DConstDoublePtr(ptr: *const f32) void { | |
| 412 | const ptr2 = @ptrCast([*]const f32, ptr); | |
| 413 | expect(ptr2[0] == 1.0); | |
| 414 | expect(ptr2[1] == 2.0); | |
| 415 | } | |
| 416 | ||
| 417 | const AStruct = struct { | |
| 418 | x: i32, | |
| 419 | }; | |
| 420 | const AnEnum = enum { | |
| 421 | One, | |
| 422 | Two, | |
| 423 | }; | |
| 424 | const AUnionEnum = union(enum) { | |
| 425 | One: i32, | |
| 426 | Two: void, | |
| 427 | }; | |
| 428 | const AUnion = union { | |
| 429 | One: void, | |
| 430 | Two: void, | |
| 431 | }; | |
| 432 | ||
| 433 | test "@typeName" { | |
| 434 | const Struct = struct {}; | |
| 435 | const Union = union { | |
| 436 | unused: u8, | |
| 437 | }; | |
| 438 | const Enum = enum { | |
| 439 | Unused, | |
| 440 | }; | |
| 441 | comptime { | |
| 442 | expect(mem.eql(u8, @typeName(i64), "i64")); | |
| 443 | expect(mem.eql(u8, @typeName(*usize), "*usize")); | |
| 444 | // https://github.com/ziglang/zig/issues/675 | |
| 445 | expect(mem.eql(u8, "behavior.misc.TypeFromFn(u8)", @typeName(TypeFromFn(u8)))); | |
| 446 | expect(mem.eql(u8, @typeName(Struct), "Struct")); | |
| 447 | expect(mem.eql(u8, @typeName(Union), "Union")); | |
| 448 | expect(mem.eql(u8, @typeName(Enum), "Enum")); | |
| 449 | } | |
| 450 | } | |
| 451 | ||
| 452 | fn TypeFromFn(comptime T: type) type { | |
| 453 | return struct {}; | |
| 454 | } | |
| 455 | ||
| 456 | test "double implicit cast in same expression" { | |
| 457 | var x = @as(i32, @as(u16, nine())); | |
| 458 | expect(x == 9); | |
| 459 | } | |
| 460 | fn nine() u8 { | |
| 461 | return 9; | |
| 462 | } | |
| 463 | ||
| 464 | test "global variable initialized to global variable array element" { | |
| 465 | expect(global_ptr == &gdt[0]); | |
| 466 | } | |
| 467 | const GDTEntry = struct { | |
| 468 | field: i32, | |
| 469 | }; | |
| 470 | var gdt = [_]GDTEntry{ | |
| 471 | GDTEntry{ .field = 1 }, | |
| 472 | GDTEntry{ .field = 2 }, | |
| 473 | }; | |
| 474 | var global_ptr = &gdt[0]; | |
| 475 | ||
| 476 | // can't really run this test but we can make sure it has no compile error | |
| 477 | // and generates code | |
| 478 | const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000]; | |
| 479 | export fn writeToVRam() void { | |
| 480 | vram[0] = 'X'; | |
| 481 | } | |
| 482 | ||
| 483 | const OpaqueA = opaque {}; | |
| 484 | const OpaqueB = opaque {}; | |
| 485 | test "opaque types" { | |
| 486 | expect(*OpaqueA != *OpaqueB); | |
| 487 | expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA")); | |
| 488 | expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB")); | |
| 489 | } | |
| 490 | ||
| 491 | test "variable is allowed to be a pointer to an opaque type" { | |
| 492 | var x: i32 = 1234; | |
| 493 | _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x)); | |
| 494 | } | |
| 495 | fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA { | |
| 496 | var a = ptr; | |
| 497 | return a; | |
| 498 | } | |
| 499 | ||
| 500 | test "comptime if inside runtime while which unconditionally breaks" { | |
| 501 | testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); | |
| 502 | comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); | |
| 503 | } | |
| 504 | fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void { | |
| 505 | while (cond) { | |
| 506 | if (false) {} | |
| 507 | break; | |
| 508 | } | |
| 509 | } | |
| 510 | ||
| 511 | test "implicit comptime while" { | |
| 512 | while (false) { | |
| 513 | @compileError("bad"); | |
| 514 | } | |
| 515 | } | |
| 516 | ||
| 517 | fn fnThatClosesOverLocalConst() type { | |
| 518 | const c = 1; | |
| 519 | return struct { | |
| 520 | fn g() i32 { | |
| 521 | return c; | |
| 522 | } | |
| 523 | }; | |
| 524 | } | |
| 525 | ||
| 526 | test "function closes over local const" { | |
| 527 | const x = fnThatClosesOverLocalConst().g(); | |
| 528 | expect(x == 1); | |
| 529 | } | |
| 530 | ||
| 531 | test "cold function" { | |
| 532 | thisIsAColdFn(); | |
| 533 | comptime thisIsAColdFn(); | |
| 534 | } | |
| 535 | ||
| 536 | fn thisIsAColdFn() void { | |
| 537 | @setCold(true); | |
| 538 | } | |
| 539 | ||
| 540 | const PackedStruct = packed struct { | |
| 541 | a: u8, | |
| 542 | b: u8, | |
| 543 | }; | |
| 544 | const PackedUnion = packed union { | |
| 545 | a: u8, | |
| 546 | b: u32, | |
| 547 | }; | |
| 548 | const PackedEnum = packed enum { | |
| 549 | A, | |
| 550 | B, | |
| 551 | }; | |
| 552 | ||
| 553 | test "packed struct, enum, union parameters in extern function" { | |
| 554 | testPackedStuff(&(PackedStruct{ | |
| 555 | .a = 1, | |
| 556 | .b = 2, | |
| 557 | }), &(PackedUnion{ .a = 1 }), PackedEnum.A); | |
| 558 | } | |
| 559 | ||
| 560 | export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion, c: PackedEnum) void {} | |
| 561 | ||
| 562 | test "slicing zero length array" { | |
| 563 | const s1 = ""[0..]; | |
| 564 | const s2 = ([_]u32{})[0..]; | |
| 565 | expect(s1.len == 0); | |
| 566 | expect(s2.len == 0); | |
| 567 | expect(mem.eql(u8, s1, "")); | |
| 568 | expect(mem.eql(u32, s2, &[_]u32{})); | |
| 569 | } | |
| 570 | ||
| 571 | const addr1 = @ptrCast(*const u8, emptyFn); | |
| 572 | test "comptime cast fn to ptr" { | |
| 573 | const addr2 = @ptrCast(*const u8, emptyFn); | |
| 574 | comptime expect(addr1 == addr2); | |
| 575 | } | |
| 576 | ||
| 577 | test "equality compare fn ptrs" { | |
| 578 | var a = emptyFn; | |
| 579 | expect(a == a); | |
| 580 | } | |
| 581 | ||
| 582 | test "self reference through fn ptr field" { | |
| 583 | const S = struct { | |
| 584 | const A = struct { | |
| 585 | f: fn (A) u8, | |
| 586 | }; | |
| 587 | ||
| 588 | fn foo(a: A) u8 { | |
| 589 | return 12; | |
| 590 | } | |
| 591 | }; | |
| 592 | var a: S.A = undefined; | |
| 593 | a.f = S.foo; | |
| 594 | expect(a.f(a) == 12); | |
| 595 | } | |
| 596 | ||
| 597 | test "volatile load and store" { | |
| 598 | var number: i32 = 1234; | |
| 599 | const ptr = @as(*volatile i32, &number); | |
| 600 | ptr.* += 1; | |
| 601 | expect(ptr.* == 1235); | |
| 602 | } | |
| 603 | ||
| 604 | test "slice string literal has correct type" { | |
| 605 | comptime { | |
| 606 | expect(@TypeOf("aoeu"[0..]) == *const [4:0]u8); | |
| 607 | const array = [_]i32{ 1, 2, 3, 4 }; | |
| 608 | expect(@TypeOf(array[0..]) == *const [4]i32); | |
| 609 | } | |
| 610 | var runtime_zero: usize = 0; | |
| 611 | comptime expect(@TypeOf("aoeu"[runtime_zero..]) == [:0]const u8); | |
| 612 | const array = [_]i32{ 1, 2, 3, 4 }; | |
| 613 | comptime expect(@TypeOf(array[runtime_zero..]) == []const i32); | |
| 614 | } | |
| 615 | ||
| 616 | test "struct inside function" { | |
| 617 | testStructInFn(); | |
| 618 | comptime testStructInFn(); | |
| 619 | } | |
| 620 | ||
| 621 | fn testStructInFn() void { | |
| 622 | const BlockKind = u32; | |
| 623 | ||
| 624 | const Block = struct { | |
| 625 | kind: BlockKind, | |
| 626 | }; | |
| 627 | ||
| 628 | var block = Block{ .kind = 1234 }; | |
| 629 | ||
| 630 | block.kind += 1; | |
| 631 | ||
| 632 | expect(block.kind == 1235); | |
| 633 | } | |
| 634 | ||
| 635 | test "fn call returning scalar optional in equality expression" { | |
| 636 | expect(getNull() == null); | |
| 637 | } | |
| 638 | ||
| 639 | fn getNull() ?*i32 { | |
| 640 | return null; | |
| 641 | } | |
| 642 | ||
| 643 | test "thread local variable" { | |
| 644 | const S = struct { | |
| 645 | threadlocal var t: i32 = 1234; | |
| 646 | }; | |
| 647 | S.t += 1; | |
| 648 | expect(S.t == 1235); | |
| 649 | } | |
| 650 | ||
| 651 | test "unicode escape in character literal" { | |
| 652 | var a: u24 = '\u{01f4a9}'; | |
| 653 | expect(a == 128169); | |
| 654 | } | |
| 655 | ||
| 656 | test "unicode character in character literal" { | |
| 657 | expect('💩' == 128169); | |
| 658 | } | |
| 659 | ||
| 660 | test "result location zero sized array inside struct field implicit cast to slice" { | |
| 661 | const E = struct { | |
| 662 | entries: []u32, | |
| 663 | }; | |
| 664 | var foo = E{ .entries = &[_]u32{} }; | |
| 665 | expect(foo.entries.len == 0); | |
| 666 | } | |
| 667 | ||
| 668 | var global_foo: *i32 = undefined; | |
| 669 | ||
| 670 | test "global variable assignment with optional unwrapping with var initialized to undefined" { | |
| 671 | const S = struct { | |
| 672 | var data: i32 = 1234; | |
| 673 | fn foo() ?*i32 { | |
| 674 | return &data; | |
| 675 | } | |
| 676 | }; | |
| 677 | global_foo = S.foo() orelse { | |
| 678 | @panic("bad"); | |
| 679 | }; | |
| 680 | expect(global_foo.* == 1234); | |
| 681 | } | |
| 682 | ||
| 683 | test "peer result location with typed parent, runtime condition, comptime prongs" { | |
| 684 | const S = struct { | |
| 685 | fn doTheTest(arg: i32) i32 { | |
| 686 | const st = Structy{ | |
| 687 | .bleh = if (arg == 1) 1 else 1, | |
| 688 | }; | |
| 689 | ||
| 690 | if (st.bleh == 1) | |
| 691 | return 1234; | |
| 692 | return 0; | |
| 693 | } | |
| 694 | ||
| 695 | const Structy = struct { | |
| 696 | bleh: i32, | |
| 697 | }; | |
| 698 | }; | |
| 699 | expect(S.doTheTest(0) == 1234); | |
| 700 | expect(S.doTheTest(1) == 1234); | |
| 701 | } | |
| 702 | ||
| 703 | test "nested optional field in struct" { | |
| 704 | const S2 = struct { | |
| 705 | y: u8, | |
| 706 | }; | |
| 707 | const S1 = struct { | |
| 708 | x: ?S2, | |
| 709 | }; | |
| 710 | var s = S1{ | |
| 711 | .x = S2{ .y = 127 }, | |
| 712 | }; | |
| 713 | expect(s.x.?.y == 127); | |
| 714 | } | |
| 715 | ||
| 716 | fn maybe(x: bool) anyerror!?u32 { | |
| 717 | return switch (x) { | |
| 718 | true => @as(u32, 42), | |
| 719 | else => null, | |
| 720 | }; | |
| 721 | } | |
| 722 | ||
| 723 | test "result location is optional inside error union" { | |
| 724 | const x = maybe(true) catch unreachable; | |
| 725 | expect(x.? == 42); | |
| 726 | } | |
| 727 | ||
| 728 | threadlocal var buffer: [11]u8 = undefined; | |
| 729 | ||
| 730 | test "pointer to thread local array" { | |
| 731 | const s = "Hello world"; | |
| 732 | std.mem.copy(u8, buffer[0..], s); | |
| 733 | std.testing.expectEqualSlices(u8, buffer[0..], s); | |
| 734 | } | |
| 735 | ||
| 736 | test "auto created variables have correct alignment" { | |
| 737 | const S = struct { | |
| 738 | fn foo(str: [*]const u8) u32 { | |
| 739 | for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| { | |
| 740 | return v; | |
| 741 | } | |
| 742 | return 0; | |
| 743 | } | |
| 744 | }; | |
| 745 | expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); | |
| 746 | comptime expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); | |
| 747 | } | |
| 748 | ||
| 749 | extern var opaque_extern_var: opaque {}; | |
| 750 | var var_to_export: u32 = 42; | |
| 751 | test "extern variable with non-pointer opaque type" { | |
| 752 | @export(var_to_export, .{ .name = "opaque_extern_var" }); | |
| 753 | expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42); | |
| 754 | } | |
| 755 | ||
| 756 | test "lazy typeInfo value as generic parameter" { | |
| 757 | const S = struct { | |
| 758 | fn foo(args: anytype) void {} | |
| 759 | }; | |
| 760 | S.foo(@typeInfo(@TypeOf(.{}))); | |
| 761 | } |
test/stage1/behavior/muladd.zig deleted-34| ... | ... | @@ -1,34 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@mulAdd" { | |
| 4 | comptime testMulAdd(); | |
| 5 | testMulAdd(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testMulAdd() void { | |
| 9 | { | |
| 10 | var a: f16 = 5.5; | |
| 11 | var b: f16 = 2.5; | |
| 12 | var c: f16 = 6.25; | |
| 13 | expect(@mulAdd(f16, a, b, c) == 20); | |
| 14 | } | |
| 15 | { | |
| 16 | var a: f32 = 5.5; | |
| 17 | var b: f32 = 2.5; | |
| 18 | var c: f32 = 6.25; | |
| 19 | expect(@mulAdd(f32, a, b, c) == 20); | |
| 20 | } | |
| 21 | { | |
| 22 | var a: f64 = 5.5; | |
| 23 | var b: f64 = 2.5; | |
| 24 | var c: f64 = 6.25; | |
| 25 | expect(@mulAdd(f64, a, b, c) == 20); | |
| 26 | } | |
| 27 | // Awaits implementation in libm.zig | |
| 28 | //{ | |
| 29 | // var a: f16 = 5.5; | |
| 30 | // var b: f128 = 2.5; | |
| 31 | // var c: f128 = 6.25; | |
| 32 | // expect(@mulAdd(f128, a, b, c) == 20); | |
| 33 | //} | |
| 34 | } |
test/stage1/behavior/namespace_depends_on_compile_var.zig deleted-14| ... | ... | @@ -1,14 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "namespace depends on compile var" { | |
| 5 | if (some_namespace.a_bool) { | |
| 6 | expect(some_namespace.a_bool); | |
| 7 | } else { | |
| 8 | expect(!some_namespace.a_bool); | |
| 9 | } | |
| 10 | } | |
| 11 | const some_namespace = switch (std.builtin.os.tag) { | |
| 12 | .linux => @import("namespace_depends_on_compile_var/a.zig"), | |
| 13 | else => @import("namespace_depends_on_compile_var/b.zig"), | |
| 14 | }; |
test/stage1/behavior/namespace_depends_on_compile_var/a.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub const a_bool = true; |
test/stage1/behavior/namespace_depends_on_compile_var/b.zig deleted-1| ... | ... | @@ -1 +0,0 @@ |
| 1 | pub const a_bool = false; |
test/stage1/behavior/null.zig deleted-162| ... | ... | @@ -1,162 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "optional type" { | |
| 4 | const x: ?bool = true; | |
| 5 | ||
| 6 | if (x) |y| { | |
| 7 | if (y) { | |
| 8 | // OK | |
| 9 | } else { | |
| 10 | unreachable; | |
| 11 | } | |
| 12 | } else { | |
| 13 | unreachable; | |
| 14 | } | |
| 15 | ||
| 16 | const next_x: ?i32 = null; | |
| 17 | ||
| 18 | const z = next_x orelse 1234; | |
| 19 | ||
| 20 | expect(z == 1234); | |
| 21 | ||
| 22 | const final_x: ?i32 = 13; | |
| 23 | ||
| 24 | const num = final_x orelse unreachable; | |
| 25 | ||
| 26 | expect(num == 13); | |
| 27 | } | |
| 28 | ||
| 29 | test "test maybe object and get a pointer to the inner value" { | |
| 30 | var maybe_bool: ?bool = true; | |
| 31 | ||
| 32 | if (maybe_bool) |*b| { | |
| 33 | b.* = false; | |
| 34 | } | |
| 35 | ||
| 36 | expect(maybe_bool.? == false); | |
| 37 | } | |
| 38 | ||
| 39 | test "rhs maybe unwrap return" { | |
| 40 | const x: ?bool = true; | |
| 41 | const y = x orelse return; | |
| 42 | } | |
| 43 | ||
| 44 | test "maybe return" { | |
| 45 | maybeReturnImpl(); | |
| 46 | comptime maybeReturnImpl(); | |
| 47 | } | |
| 48 | ||
| 49 | fn maybeReturnImpl() void { | |
| 50 | expect(foo(1235).?); | |
| 51 | if (foo(null) != null) unreachable; | |
| 52 | expect(!foo(1234).?); | |
| 53 | } | |
| 54 | ||
| 55 | fn foo(x: ?i32) ?bool { | |
| 56 | const value = x orelse return null; | |
| 57 | return value > 1234; | |
| 58 | } | |
| 59 | ||
| 60 | test "if var maybe pointer" { | |
| 61 | expect(shouldBeAPlus1(Particle{ | |
| 62 | .a = 14, | |
| 63 | .b = 1, | |
| 64 | .c = 1, | |
| 65 | .d = 1, | |
| 66 | }) == 15); | |
| 67 | } | |
| 68 | fn shouldBeAPlus1(p: Particle) u64 { | |
| 69 | var maybe_particle: ?Particle = p; | |
| 70 | if (maybe_particle) |*particle| { | |
| 71 | particle.a += 1; | |
| 72 | } | |
| 73 | if (maybe_particle) |particle| { | |
| 74 | return particle.a; | |
| 75 | } | |
| 76 | return 0; | |
| 77 | } | |
| 78 | const Particle = struct { | |
| 79 | a: u64, | |
| 80 | b: u64, | |
| 81 | c: u64, | |
| 82 | d: u64, | |
| 83 | }; | |
| 84 | ||
| 85 | test "null literal outside function" { | |
| 86 | const is_null = here_is_a_null_literal.context == null; | |
| 87 | expect(is_null); | |
| 88 | ||
| 89 | const is_non_null = here_is_a_null_literal.context != null; | |
| 90 | expect(!is_non_null); | |
| 91 | } | |
| 92 | const SillyStruct = struct { | |
| 93 | context: ?i32, | |
| 94 | }; | |
| 95 | const here_is_a_null_literal = SillyStruct{ .context = null }; | |
| 96 | ||
| 97 | test "test null runtime" { | |
| 98 | testTestNullRuntime(null); | |
| 99 | } | |
| 100 | fn testTestNullRuntime(x: ?i32) void { | |
| 101 | expect(x == null); | |
| 102 | expect(!(x != null)); | |
| 103 | } | |
| 104 | ||
| 105 | test "optional void" { | |
| 106 | optionalVoidImpl(); | |
| 107 | comptime optionalVoidImpl(); | |
| 108 | } | |
| 109 | ||
| 110 | fn optionalVoidImpl() void { | |
| 111 | expect(bar(null) == null); | |
| 112 | expect(bar({}) != null); | |
| 113 | } | |
| 114 | ||
| 115 | fn bar(x: ?void) ?void { | |
| 116 | if (x) |_| { | |
| 117 | return {}; | |
| 118 | } else { | |
| 119 | return null; | |
| 120 | } | |
| 121 | } | |
| 122 | ||
| 123 | const StructWithOptional = struct { | |
| 124 | field: ?i32, | |
| 125 | }; | |
| 126 | ||
| 127 | var struct_with_optional: StructWithOptional = undefined; | |
| 128 | ||
| 129 | test "unwrap optional which is field of global var" { | |
| 130 | struct_with_optional.field = null; | |
| 131 | if (struct_with_optional.field) |payload| { | |
| 132 | unreachable; | |
| 133 | } | |
| 134 | struct_with_optional.field = 1234; | |
| 135 | if (struct_with_optional.field) |payload| { | |
| 136 | expect(payload == 1234); | |
| 137 | } else { | |
| 138 | unreachable; | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | test "null with default unwrap" { | |
| 143 | const x: i32 = null orelse 1; | |
| 144 | expect(x == 1); | |
| 145 | } | |
| 146 | ||
| 147 | test "optional types" { | |
| 148 | comptime { | |
| 149 | const opt_type_struct = StructWithOptionalType{ .t = u8 }; | |
| 150 | expect(opt_type_struct.t != null and opt_type_struct.t.? == u8); | |
| 151 | } | |
| 152 | } | |
| 153 | ||
| 154 | const StructWithOptionalType = struct { | |
| 155 | t: ?type, | |
| 156 | }; | |
| 157 | ||
| 158 | test "optional pointer to 0 bit type null value at runtime" { | |
| 159 | const EmptyStruct = struct {}; | |
| 160 | var x: ?*EmptyStruct = null; | |
| 161 | expect(x == null); | |
| 162 | } |
test/stage1/behavior/optional.zig deleted-269| ... | ... | @@ -1,269 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | pub const EmptyStruct = struct {}; | |
| 7 | ||
| 8 | test "optional pointer to size zero struct" { | |
| 9 | var e = EmptyStruct{}; | |
| 10 | var o: ?*EmptyStruct = &e; | |
| 11 | expect(o != null); | |
| 12 | } | |
| 13 | ||
| 14 | test "equality compare nullable pointers" { | |
| 15 | testNullPtrsEql(); | |
| 16 | comptime testNullPtrsEql(); | |
| 17 | } | |
| 18 | ||
| 19 | fn testNullPtrsEql() void { | |
| 20 | var number: i32 = 1234; | |
| 21 | ||
| 22 | var x: ?*i32 = null; | |
| 23 | var y: ?*i32 = null; | |
| 24 | expect(x == y); | |
| 25 | y = &number; | |
| 26 | expect(x != y); | |
| 27 | expect(x != &number); | |
| 28 | expect(&number != x); | |
| 29 | x = &number; | |
| 30 | expect(x == y); | |
| 31 | expect(x == &number); | |
| 32 | expect(&number == x); | |
| 33 | } | |
| 34 | ||
| 35 | test "address of unwrap optional" { | |
| 36 | const S = struct { | |
| 37 | const Foo = struct { | |
| 38 | a: i32, | |
| 39 | }; | |
| 40 | ||
| 41 | var global: ?Foo = null; | |
| 42 | ||
| 43 | pub fn getFoo() anyerror!*Foo { | |
| 44 | return &global.?; | |
| 45 | } | |
| 46 | }; | |
| 47 | S.global = S.Foo{ .a = 1234 }; | |
| 48 | const foo = S.getFoo() catch unreachable; | |
| 49 | expect(foo.a == 1234); | |
| 50 | } | |
| 51 | ||
| 52 | test "equality compare optional with non-optional" { | |
| 53 | test_cmp_optional_non_optional(); | |
| 54 | comptime test_cmp_optional_non_optional(); | |
| 55 | } | |
| 56 | ||
| 57 | fn test_cmp_optional_non_optional() void { | |
| 58 | var ten: i32 = 10; | |
| 59 | var opt_ten: ?i32 = 10; | |
| 60 | var five: i32 = 5; | |
| 61 | var int_n: ?i32 = null; | |
| 62 | ||
| 63 | expect(int_n != ten); | |
| 64 | expect(opt_ten == ten); | |
| 65 | expect(opt_ten != five); | |
| 66 | ||
| 67 | // test evaluation is always lexical | |
| 68 | // ensure that the optional isn't always computed before the non-optional | |
| 69 | var mutable_state: i32 = 0; | |
| 70 | _ = blk1: { | |
| 71 | mutable_state += 1; | |
| 72 | break :blk1 @as(?f64, 10.0); | |
| 73 | } != blk2: { | |
| 74 | expect(mutable_state == 1); | |
| 75 | break :blk2 @as(f64, 5.0); | |
| 76 | }; | |
| 77 | _ = blk1: { | |
| 78 | mutable_state += 1; | |
| 79 | break :blk1 @as(f64, 10.0); | |
| 80 | } != blk2: { | |
| 81 | expect(mutable_state == 2); | |
| 82 | break :blk2 @as(?f64, 5.0); | |
| 83 | }; | |
| 84 | } | |
| 85 | ||
| 86 | test "passing an optional integer as a parameter" { | |
| 87 | const S = struct { | |
| 88 | fn entry() bool { | |
| 89 | var x: i32 = 1234; | |
| 90 | return foo(x); | |
| 91 | } | |
| 92 | ||
| 93 | fn foo(x: ?i32) bool { | |
| 94 | return x.? == 1234; | |
| 95 | } | |
| 96 | }; | |
| 97 | expect(S.entry()); | |
| 98 | comptime expect(S.entry()); | |
| 99 | } | |
| 100 | ||
| 101 | test "unwrap function call with optional pointer return value" { | |
| 102 | const S = struct { | |
| 103 | fn entry() void { | |
| 104 | expect(foo().?.* == 1234); | |
| 105 | expect(bar() == null); | |
| 106 | } | |
| 107 | const global: i32 = 1234; | |
| 108 | fn foo() ?*const i32 { | |
| 109 | return &global; | |
| 110 | } | |
| 111 | fn bar() ?*i32 { | |
| 112 | return null; | |
| 113 | } | |
| 114 | }; | |
| 115 | S.entry(); | |
| 116 | comptime S.entry(); | |
| 117 | } | |
| 118 | ||
| 119 | test "nested orelse" { | |
| 120 | const S = struct { | |
| 121 | fn entry() void { | |
| 122 | expect(func() == null); | |
| 123 | } | |
| 124 | fn maybe() ?Foo { | |
| 125 | return null; | |
| 126 | } | |
| 127 | fn func() ?Foo { | |
| 128 | const x = maybe() orelse | |
| 129 | maybe() orelse | |
| 130 | return null; | |
| 131 | unreachable; | |
| 132 | } | |
| 133 | const Foo = struct { | |
| 134 | field: i32, | |
| 135 | }; | |
| 136 | }; | |
| 137 | S.entry(); | |
| 138 | comptime S.entry(); | |
| 139 | } | |
| 140 | ||
| 141 | test "self-referential struct through a slice of optional" { | |
| 142 | const S = struct { | |
| 143 | const Node = struct { | |
| 144 | children: []?Node, | |
| 145 | data: ?u8, | |
| 146 | ||
| 147 | fn new() Node { | |
| 148 | return Node{ | |
| 149 | .children = undefined, | |
| 150 | .data = null, | |
| 151 | }; | |
| 152 | } | |
| 153 | }; | |
| 154 | }; | |
| 155 | ||
| 156 | var n = S.Node.new(); | |
| 157 | expect(n.data == null); | |
| 158 | } | |
| 159 | ||
| 160 | test "assigning to an unwrapped optional field in an inline loop" { | |
| 161 | comptime var maybe_pos_arg: ?comptime_int = null; | |
| 162 | inline for ("ab") |x| { | |
| 163 | maybe_pos_arg = 0; | |
| 164 | if (maybe_pos_arg.? != 0) { | |
| 165 | @compileError("bad"); | |
| 166 | } | |
| 167 | maybe_pos_arg.? = 10; | |
| 168 | } | |
| 169 | } | |
| 170 | ||
| 171 | test "coerce an anon struct literal to optional struct" { | |
| 172 | const S = struct { | |
| 173 | const Struct = struct { | |
| 174 | field: u32, | |
| 175 | }; | |
| 176 | export fn doTheTest() void { | |
| 177 | var maybe_dims: ?Struct = null; | |
| 178 | maybe_dims = .{ .field = 1 }; | |
| 179 | expect(maybe_dims.?.field == 1); | |
| 180 | } | |
| 181 | }; | |
| 182 | S.doTheTest(); | |
| 183 | comptime S.doTheTest(); | |
| 184 | } | |
| 185 | ||
| 186 | test "optional with void type" { | |
| 187 | const Foo = struct { | |
| 188 | x: ?void, | |
| 189 | }; | |
| 190 | var x = Foo{ .x = null }; | |
| 191 | expect(x.x == null); | |
| 192 | } | |
| 193 | ||
| 194 | test "0-bit child type coerced to optional return ptr result location" { | |
| 195 | const S = struct { | |
| 196 | fn doTheTest() void { | |
| 197 | var y = Foo{}; | |
| 198 | var z = y.thing(); | |
| 199 | expect(z != null); | |
| 200 | } | |
| 201 | ||
| 202 | const Foo = struct { | |
| 203 | pub const Bar = struct { | |
| 204 | field: *Foo, | |
| 205 | }; | |
| 206 | ||
| 207 | pub fn thing(self: *Foo) ?Bar { | |
| 208 | return Bar{ .field = self }; | |
| 209 | } | |
| 210 | }; | |
| 211 | }; | |
| 212 | S.doTheTest(); | |
| 213 | comptime S.doTheTest(); | |
| 214 | } | |
| 215 | ||
| 216 | test "0-bit child type coerced to optional" { | |
| 217 | const S = struct { | |
| 218 | fn doTheTest() void { | |
| 219 | var it: Foo = .{ | |
| 220 | .list = undefined, | |
| 221 | }; | |
| 222 | expect(it.foo() != null); | |
| 223 | } | |
| 224 | ||
| 225 | const Empty = struct {}; | |
| 226 | const Foo = struct { | |
| 227 | list: [10]Empty, | |
| 228 | ||
| 229 | fn foo(self: *Foo) ?*Empty { | |
| 230 | const data = &self.list[0]; | |
| 231 | return data; | |
| 232 | } | |
| 233 | }; | |
| 234 | }; | |
| 235 | S.doTheTest(); | |
| 236 | comptime S.doTheTest(); | |
| 237 | } | |
| 238 | ||
| 239 | test "array of optional unaligned types" { | |
| 240 | const Enum = enum { one, two, three }; | |
| 241 | ||
| 242 | const SomeUnion = union(enum) { | |
| 243 | Num: Enum, | |
| 244 | Other: u32, | |
| 245 | }; | |
| 246 | ||
| 247 | const values = [_]?SomeUnion{ | |
| 248 | SomeUnion{ .Num = .one }, | |
| 249 | SomeUnion{ .Num = .two }, | |
| 250 | SomeUnion{ .Num = .three }, | |
| 251 | SomeUnion{ .Num = .one }, | |
| 252 | SomeUnion{ .Num = .two }, | |
| 253 | SomeUnion{ .Num = .three }, | |
| 254 | }; | |
| 255 | ||
| 256 | // The index must be a runtime value | |
| 257 | var i: usize = 0; | |
| 258 | expectEqual(Enum.one, values[i].?.Num); | |
| 259 | i += 1; | |
| 260 | expectEqual(Enum.two, values[i].?.Num); | |
| 261 | i += 1; | |
| 262 | expectEqual(Enum.three, values[i].?.Num); | |
| 263 | i += 1; | |
| 264 | expectEqual(Enum.one, values[i].?.Num); | |
| 265 | i += 1; | |
| 266 | expectEqual(Enum.two, values[i].?.Num); | |
| 267 | i += 1; | |
| 268 | expectEqual(Enum.three, values[i].?.Num); | |
| 269 | } |
test/stage1/behavior/pointers.zig deleted-339| ... | ... | @@ -1,339 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectError = testing.expectError; | |
| 5 | ||
| 6 | test "dereference pointer" { | |
| 7 | comptime testDerefPtr(); | |
| 8 | testDerefPtr(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testDerefPtr() void { | |
| 12 | var x: i32 = 1234; | |
| 13 | var y = &x; | |
| 14 | y.* += 1; | |
| 15 | expect(x == 1235); | |
| 16 | } | |
| 17 | ||
| 18 | const Foo1 = struct { | |
| 19 | x: void, | |
| 20 | }; | |
| 21 | ||
| 22 | test "dereference pointer again" { | |
| 23 | testDerefPtrOneVal(); | |
| 24 | comptime testDerefPtrOneVal(); | |
| 25 | } | |
| 26 | ||
| 27 | fn testDerefPtrOneVal() void { | |
| 28 | // Foo1 satisfies the OnePossibleValueYes criteria | |
| 29 | const x = &Foo1{ .x = {} }; | |
| 30 | const y = x.*; | |
| 31 | expect(@TypeOf(y.x) == void); | |
| 32 | } | |
| 33 | ||
| 34 | test "pointer arithmetic" { | |
| 35 | var ptr: [*]const u8 = "abcd"; | |
| 36 | ||
| 37 | expect(ptr[0] == 'a'); | |
| 38 | ptr += 1; | |
| 39 | expect(ptr[0] == 'b'); | |
| 40 | ptr += 1; | |
| 41 | expect(ptr[0] == 'c'); | |
| 42 | ptr += 1; | |
| 43 | expect(ptr[0] == 'd'); | |
| 44 | ptr += 1; | |
| 45 | expect(ptr[0] == 0); | |
| 46 | ptr -= 1; | |
| 47 | expect(ptr[0] == 'd'); | |
| 48 | ptr -= 1; | |
| 49 | expect(ptr[0] == 'c'); | |
| 50 | ptr -= 1; | |
| 51 | expect(ptr[0] == 'b'); | |
| 52 | ptr -= 1; | |
| 53 | expect(ptr[0] == 'a'); | |
| 54 | } | |
| 55 | ||
| 56 | test "double pointer parsing" { | |
| 57 | comptime expect(PtrOf(PtrOf(i32)) == **i32); | |
| 58 | } | |
| 59 | ||
| 60 | fn PtrOf(comptime T: type) type { | |
| 61 | return *T; | |
| 62 | } | |
| 63 | ||
| 64 | test "assigning integer to C pointer" { | |
| 65 | var x: i32 = 0; | |
| 66 | var ptr: [*c]u8 = 0; | |
| 67 | var ptr2: [*c]u8 = x; | |
| 68 | } | |
| 69 | ||
| 70 | test "implicit cast single item pointer to C pointer and back" { | |
| 71 | var y: u8 = 11; | |
| 72 | var x: [*c]u8 = &y; | |
| 73 | var z: *u8 = x; | |
| 74 | z.* += 1; | |
| 75 | expect(y == 12); | |
| 76 | } | |
| 77 | ||
| 78 | test "C pointer comparison and arithmetic" { | |
| 79 | const S = struct { | |
| 80 | fn doTheTest() void { | |
| 81 | var one: usize = 1; | |
| 82 | var ptr1: [*c]u32 = 0; | |
| 83 | var ptr2 = ptr1 + 10; | |
| 84 | expect(ptr1 == 0); | |
| 85 | expect(ptr1 >= 0); | |
| 86 | expect(ptr1 <= 0); | |
| 87 | // expect(ptr1 < 1); | |
| 88 | // expect(ptr1 < one); | |
| 89 | // expect(1 > ptr1); | |
| 90 | // expect(one > ptr1); | |
| 91 | expect(ptr1 < ptr2); | |
| 92 | expect(ptr2 > ptr1); | |
| 93 | expect(ptr2 >= 40); | |
| 94 | expect(ptr2 == 40); | |
| 95 | expect(ptr2 <= 40); | |
| 96 | ptr2 -= 10; | |
| 97 | expect(ptr1 == ptr2); | |
| 98 | } | |
| 99 | }; | |
| 100 | S.doTheTest(); | |
| 101 | comptime S.doTheTest(); | |
| 102 | } | |
| 103 | ||
| 104 | test "peer type resolution with C pointers" { | |
| 105 | var ptr_one: *u8 = undefined; | |
| 106 | var ptr_many: [*]u8 = undefined; | |
| 107 | var ptr_c: [*c]u8 = undefined; | |
| 108 | var t = true; | |
| 109 | var x1 = if (t) ptr_one else ptr_c; | |
| 110 | var x2 = if (t) ptr_many else ptr_c; | |
| 111 | var x3 = if (t) ptr_c else ptr_one; | |
| 112 | var x4 = if (t) ptr_c else ptr_many; | |
| 113 | expect(@TypeOf(x1) == [*c]u8); | |
| 114 | expect(@TypeOf(x2) == [*c]u8); | |
| 115 | expect(@TypeOf(x3) == [*c]u8); | |
| 116 | expect(@TypeOf(x4) == [*c]u8); | |
| 117 | } | |
| 118 | ||
| 119 | test "implicit casting between C pointer and optional non-C pointer" { | |
| 120 | var slice: []const u8 = "aoeu"; | |
| 121 | const opt_many_ptr: ?[*]const u8 = slice.ptr; | |
| 122 | var ptr_opt_many_ptr = &opt_many_ptr; | |
| 123 | var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr; | |
| 124 | expect(c_ptr.*.* == 'a'); | |
| 125 | ptr_opt_many_ptr = c_ptr; | |
| 126 | expect(ptr_opt_many_ptr.*.?[1] == 'o'); | |
| 127 | } | |
| 128 | ||
| 129 | test "implicit cast error unions with non-optional to optional pointer" { | |
| 130 | const S = struct { | |
| 131 | fn doTheTest() void { | |
| 132 | expectError(error.Fail, foo()); | |
| 133 | } | |
| 134 | fn foo() anyerror!?*u8 { | |
| 135 | return bar() orelse error.Fail; | |
| 136 | } | |
| 137 | fn bar() ?*u8 { | |
| 138 | return null; | |
| 139 | } | |
| 140 | }; | |
| 141 | S.doTheTest(); | |
| 142 | comptime S.doTheTest(); | |
| 143 | } | |
| 144 | ||
| 145 | test "initialize const optional C pointer to null" { | |
| 146 | const a: ?[*c]i32 = null; | |
| 147 | expect(a == null); | |
| 148 | comptime expect(a == null); | |
| 149 | } | |
| 150 | ||
| 151 | test "compare equality of optional and non-optional pointer" { | |
| 152 | const a = @intToPtr(*const usize, 0x12345678); | |
| 153 | const b = @intToPtr(?*usize, 0x12345678); | |
| 154 | expect(a == b); | |
| 155 | expect(b == a); | |
| 156 | } | |
| 157 | ||
| 158 | test "allowzero pointer and slice" { | |
| 159 | var ptr = @intToPtr([*]allowzero i32, 0); | |
| 160 | var opt_ptr: ?[*]allowzero i32 = ptr; | |
| 161 | expect(opt_ptr != null); | |
| 162 | expect(@ptrToInt(ptr) == 0); | |
| 163 | var runtime_zero: usize = 0; | |
| 164 | var slice = ptr[runtime_zero..10]; | |
| 165 | comptime expect(@TypeOf(slice) == []allowzero i32); | |
| 166 | expect(@ptrToInt(&slice[5]) == 20); | |
| 167 | ||
| 168 | comptime expect(@typeInfo(@TypeOf(ptr)).Pointer.is_allowzero); | |
| 169 | comptime expect(@typeInfo(@TypeOf(slice)).Pointer.is_allowzero); | |
| 170 | } | |
| 171 | ||
| 172 | test "assign null directly to C pointer and test null equality" { | |
| 173 | var x: [*c]i32 = null; | |
| 174 | expect(x == null); | |
| 175 | expect(null == x); | |
| 176 | expect(!(x != null)); | |
| 177 | expect(!(null != x)); | |
| 178 | if (x) |same_x| { | |
| 179 | @panic("fail"); | |
| 180 | } | |
| 181 | var otherx: i32 = undefined; | |
| 182 | expect((x orelse &otherx) == &otherx); | |
| 183 | ||
| 184 | const y: [*c]i32 = null; | |
| 185 | comptime expect(y == null); | |
| 186 | comptime expect(null == y); | |
| 187 | comptime expect(!(y != null)); | |
| 188 | comptime expect(!(null != y)); | |
| 189 | if (y) |same_y| @panic("fail"); | |
| 190 | const othery: i32 = undefined; | |
| 191 | comptime expect((y orelse &othery) == &othery); | |
| 192 | ||
| 193 | var n: i32 = 1234; | |
| 194 | var x1: [*c]i32 = &n; | |
| 195 | expect(!(x1 == null)); | |
| 196 | expect(!(null == x1)); | |
| 197 | expect(x1 != null); | |
| 198 | expect(null != x1); | |
| 199 | expect(x1.?.* == 1234); | |
| 200 | if (x1) |same_x1| { | |
| 201 | expect(same_x1.* == 1234); | |
| 202 | } else { | |
| 203 | @panic("fail"); | |
| 204 | } | |
| 205 | expect((x1 orelse &otherx) == x1); | |
| 206 | ||
| 207 | const nc: i32 = 1234; | |
| 208 | const y1: [*c]const i32 = &nc; | |
| 209 | comptime expect(!(y1 == null)); | |
| 210 | comptime expect(!(null == y1)); | |
| 211 | comptime expect(y1 != null); | |
| 212 | comptime expect(null != y1); | |
| 213 | comptime expect(y1.?.* == 1234); | |
| 214 | if (y1) |same_y1| { | |
| 215 | expect(same_y1.* == 1234); | |
| 216 | } else { | |
| 217 | @compileError("fail"); | |
| 218 | } | |
| 219 | comptime expect((y1 orelse &othery) == y1); | |
| 220 | } | |
| 221 | ||
| 222 | test "null terminated pointer" { | |
| 223 | const S = struct { | |
| 224 | fn doTheTest() void { | |
| 225 | var array_with_zero = [_:0]u8{ 'h', 'e', 'l', 'l', 'o' }; | |
| 226 | var zero_ptr: [*:0]const u8 = @ptrCast([*:0]const u8, &array_with_zero); | |
| 227 | var no_zero_ptr: [*]const u8 = zero_ptr; | |
| 228 | var zero_ptr_again = @ptrCast([*:0]const u8, no_zero_ptr); | |
| 229 | expect(std.mem.eql(u8, std.mem.spanZ(zero_ptr_again), "hello")); | |
| 230 | } | |
| 231 | }; | |
| 232 | S.doTheTest(); | |
| 233 | comptime S.doTheTest(); | |
| 234 | } | |
| 235 | ||
| 236 | test "allow any sentinel" { | |
| 237 | const S = struct { | |
| 238 | fn doTheTest() void { | |
| 239 | var array = [_:std.math.minInt(i32)]i32{ 1, 2, 3, 4 }; | |
| 240 | var ptr: [*:std.math.minInt(i32)]i32 = &array; | |
| 241 | expect(ptr[4] == std.math.minInt(i32)); | |
| 242 | } | |
| 243 | }; | |
| 244 | S.doTheTest(); | |
| 245 | comptime S.doTheTest(); | |
| 246 | } | |
| 247 | ||
| 248 | test "pointer sentinel with enums" { | |
| 249 | const S = struct { | |
| 250 | const Number = enum { | |
| 251 | one, | |
| 252 | two, | |
| 253 | sentinel, | |
| 254 | }; | |
| 255 | ||
| 256 | fn doTheTest() void { | |
| 257 | var ptr: [*:.sentinel]const Number = &[_:.sentinel]Number{ .one, .two, .two, .one }; | |
| 258 | expect(ptr[4] == .sentinel); // TODO this should be comptime expect, see #3731 | |
| 259 | } | |
| 260 | }; | |
| 261 | S.doTheTest(); | |
| 262 | comptime S.doTheTest(); | |
| 263 | } | |
| 264 | ||
| 265 | test "pointer sentinel with optional element" { | |
| 266 | const S = struct { | |
| 267 | fn doTheTest() void { | |
| 268 | var ptr: [*:null]const ?i32 = &[_:null]?i32{ 1, 2, 3, 4 }; | |
| 269 | expect(ptr[4] == null); // TODO this should be comptime expect, see #3731 | |
| 270 | } | |
| 271 | }; | |
| 272 | S.doTheTest(); | |
| 273 | comptime S.doTheTest(); | |
| 274 | } | |
| 275 | ||
| 276 | test "pointer sentinel with +inf" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | const inf = std.math.inf_f32; | |
| 280 | var ptr: [*:inf]const f32 = &[_:inf]f32{ 1.1, 2.2, 3.3, 4.4 }; | |
| 281 | expect(ptr[4] == inf); // TODO this should be comptime expect, see #3731 | |
| 282 | } | |
| 283 | }; | |
| 284 | S.doTheTest(); | |
| 285 | comptime S.doTheTest(); | |
| 286 | } | |
| 287 | ||
| 288 | test "pointer to array at fixed address" { | |
| 289 | const array = @intToPtr(*volatile [1]u32, 0x10); | |
| 290 | // Silly check just to reference `array` | |
| 291 | expect(@ptrToInt(&array[0]) == 0x10); | |
| 292 | } | |
| 293 | ||
| 294 | test "pointer arithmetic affects the alignment" { | |
| 295 | { | |
| 296 | var ptr: [*]align(8) u32 = undefined; | |
| 297 | var x: usize = 1; | |
| 298 | ||
| 299 | expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 8); | |
| 300 | const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4 | |
| 301 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 4); | |
| 302 | const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8 | |
| 303 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 8); | |
| 304 | const ptr3 = ptr + 0; // no-op | |
| 305 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8); | |
| 306 | const ptr4 = ptr + x; // runtime-known addend | |
| 307 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4); | |
| 308 | } | |
| 309 | { | |
| 310 | var ptr: [*]align(8) [3]u8 = undefined; | |
| 311 | var x: usize = 1; | |
| 312 | ||
| 313 | const ptr1 = ptr + 17; // 3 * 17 = 51 | |
| 314 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1); | |
| 315 | const ptr2 = ptr + x; // runtime-known addend | |
| 316 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 1); | |
| 317 | const ptr3 = ptr + 8; // 3 * 8 = 24 -> lcd(8,24) = 8 | |
| 318 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8); | |
| 319 | const ptr4 = ptr + 4; // 3 * 4 = 12 -> lcd(8,12) = 4 | |
| 320 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 4); | |
| 321 | } | |
| 322 | } | |
| 323 | ||
| 324 | test "@ptrToInt on null optional at comptime" { | |
| 325 | { | |
| 326 | const pointer = @intToPtr(?*u8, 0x000); | |
| 327 | const x = @ptrToInt(pointer); | |
| 328 | comptime expect(0 == @ptrToInt(pointer)); | |
| 329 | } | |
| 330 | { | |
| 331 | const pointer = @intToPtr(?*u8, 0xf00); | |
| 332 | comptime expect(0xf00 == @ptrToInt(pointer)); | |
| 333 | } | |
| 334 | } | |
| 335 | ||
| 336 | test "indexing array with sentinel returns correct type" { | |
| 337 | var s: [:0]const u8 = "abc"; | |
| 338 | testing.expectEqualSlices(u8, "*const u8", @typeName(@TypeOf(&s[0]))); | |
| 339 | } |
test/stage1/behavior/popcount.zig deleted-43| ... | ... | @@ -1,43 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "@popCount" { | |
| 4 | comptime testPopCount(); | |
| 5 | testPopCount(); | |
| 6 | } | |
| 7 | ||
| 8 | fn testPopCount() void { | |
| 9 | { | |
| 10 | var x: u32 = 0xffffffff; | |
| 11 | expect(@popCount(u32, x) == 32); | |
| 12 | } | |
| 13 | { | |
| 14 | var x: u5 = 0x1f; | |
| 15 | expect(@popCount(u5, x) == 5); | |
| 16 | } | |
| 17 | { | |
| 18 | var x: u32 = 0xaa; | |
| 19 | expect(@popCount(u32, x) == 4); | |
| 20 | } | |
| 21 | { | |
| 22 | var x: u32 = 0xaaaaaaaa; | |
| 23 | expect(@popCount(u32, x) == 16); | |
| 24 | } | |
| 25 | { | |
| 26 | var x: u32 = 0xaaaaaaaa; | |
| 27 | expect(@popCount(u32, x) == 16); | |
| 28 | } | |
| 29 | { | |
| 30 | var x: i16 = -1; | |
| 31 | expect(@popCount(i16, x) == 16); | |
| 32 | } | |
| 33 | { | |
| 34 | var x: i8 = -120; | |
| 35 | expect(@popCount(i8, x) == 2); | |
| 36 | } | |
| 37 | comptime { | |
| 38 | expect(@popCount(u8, @bitCast(u8, @as(i8, -120))) == 2); | |
| 39 | } | |
| 40 | comptime { | |
| 41 | expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24); | |
| 42 | } | |
| 43 | } |
test/stage1/behavior/ptrcast.zig deleted-73| ... | ... | @@ -1,73 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const expect = std.testing.expect; | |
| 4 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 5 | ||
| 6 | test "reinterpret bytes as integer with nonzero offset" { | |
| 7 | testReinterpretBytesAsInteger(); | |
| 8 | comptime testReinterpretBytesAsInteger(); | |
| 9 | } | |
| 10 | ||
| 11 | fn testReinterpretBytesAsInteger() void { | |
| 12 | const bytes = "\x12\x34\x56\x78\xab"; | |
| 13 | const expected = switch (native_endian) { | |
| 14 | .Little => 0xab785634, | |
| 15 | .Big => 0x345678ab, | |
| 16 | }; | |
| 17 | expect(@ptrCast(*align(1) const u32, bytes[1..5]).* == expected); | |
| 18 | } | |
| 19 | ||
| 20 | test "reinterpret bytes of an array into an extern struct" { | |
| 21 | testReinterpretBytesAsExternStruct(); | |
| 22 | comptime testReinterpretBytesAsExternStruct(); | |
| 23 | } | |
| 24 | ||
| 25 | fn testReinterpretBytesAsExternStruct() void { | |
| 26 | var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 }; | |
| 27 | ||
| 28 | const S = extern struct { | |
| 29 | a: u8, | |
| 30 | b: u16, | |
| 31 | c: u8, | |
| 32 | }; | |
| 33 | ||
| 34 | var ptr = @ptrCast(*const S, &bytes); | |
| 35 | var val = ptr.c; | |
| 36 | expect(val == 5); | |
| 37 | } | |
| 38 | ||
| 39 | test "reinterpret struct field at comptime" { | |
| 40 | const numNative = comptime Bytes.init(0x12345678); | |
| 41 | if (native_endian != .Little) { | |
| 42 | expect(std.mem.eql(u8, &[_]u8{ 0x12, 0x34, 0x56, 0x78 }, &numNative.bytes)); | |
| 43 | } else { | |
| 44 | expect(std.mem.eql(u8, &[_]u8{ 0x78, 0x56, 0x34, 0x12 }, &numNative.bytes)); | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | const Bytes = struct { | |
| 49 | bytes: [4]u8, | |
| 50 | ||
| 51 | pub fn init(v: u32) Bytes { | |
| 52 | var res: Bytes = undefined; | |
| 53 | @ptrCast(*align(1) u32, &res.bytes).* = v; | |
| 54 | ||
| 55 | return res; | |
| 56 | } | |
| 57 | }; | |
| 58 | ||
| 59 | test "comptime ptrcast keeps larger alignment" { | |
| 60 | comptime { | |
| 61 | const a: u32 = 1234; | |
| 62 | const p = @ptrCast([*]const u8, &a); | |
| 63 | std.debug.assert(@TypeOf(p) == [*]align(@alignOf(u32)) const u8); | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | test "implicit optional pointer to optional c_void pointer" { | |
| 68 | var buf: [4]u8 = "aoeu".*; | |
| 69 | var x: ?[*]u8 = &buf; | |
| 70 | var y: ?*c_void = x; | |
| 71 | var z = @ptrCast(*[4]u8, y); | |
| 72 | expect(std.mem.eql(u8, z, "aoeu")); | |
| 73 | } |
test/stage1/behavior/pub_enum.zig deleted-13| ... | ... | @@ -1,13 +0,0 @@ |
| 1 | const other = @import("pub_enum/other.zig"); | |
| 2 | const expect = @import("std").testing.expect; | |
| 3 | ||
| 4 | test "pub enum" { | |
| 5 | pubEnumTest(other.APubEnum.Two); | |
| 6 | } | |
| 7 | fn pubEnumTest(foo: other.APubEnum) void { | |
| 8 | expect(foo == other.APubEnum.Two); | |
| 9 | } | |
| 10 | ||
| 11 | test "cast with imported symbol" { | |
| 12 | expect(@as(other.size_t, 42) == 42); | |
| 13 | } |
test/stage1/behavior/pub_enum/other.zig deleted-6| ... | ... | @@ -1,6 +0,0 @@ |
| 1 | pub const APubEnum = enum { | |
| 2 | One, | |
| 3 | Two, | |
| 4 | Three, | |
| 5 | }; | |
| 6 | pub const size_t = u64; |
test/stage1/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig deleted-37| ... | ... | @@ -1,37 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | ||
| 4 | var ok: bool = false; | |
| 5 | test "reference a variable in an if after an if in the 2nd switch prong" { | |
| 6 | foo(true, Num.Two, false, "aoeu"); | |
| 7 | expect(!ok); | |
| 8 | foo(false, Num.One, false, "aoeu"); | |
| 9 | expect(!ok); | |
| 10 | foo(true, Num.One, false, "aoeu"); | |
| 11 | expect(ok); | |
| 12 | } | |
| 13 | ||
| 14 | const Num = enum { | |
| 15 | One, | |
| 16 | Two, | |
| 17 | }; | |
| 18 | ||
| 19 | fn foo(c: bool, k: Num, c2: bool, b: []const u8) void { | |
| 20 | switch (k) { | |
| 21 | Num.Two => {}, | |
| 22 | Num.One => { | |
| 23 | if (c) { | |
| 24 | const output_path = b; | |
| 25 | ||
| 26 | if (c2) {} | |
| 27 | ||
| 28 | a(output_path); | |
| 29 | } | |
| 30 | }, | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | fn a(x: []const u8) void { | |
| 35 | expect(mem.eql(u8, x, "aoeu")); | |
| 36 | ok = true; | |
| 37 | } |
test/stage1/behavior/reflection.zig deleted-55| ... | ... | @@ -1,55 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const mem = @import("std").mem; | |
| 3 | const reflection = @This(); | |
| 4 | ||
| 5 | test "reflection: function return type, var args, and param types" { | |
| 6 | comptime { | |
| 7 | const info = @typeInfo(@TypeOf(dummy)).Fn; | |
| 8 | expect(info.return_type.? == i32); | |
| 9 | expect(!info.is_var_args); | |
| 10 | expect(info.args.len == 3); | |
| 11 | expect(info.args[0].arg_type.? == bool); | |
| 12 | expect(info.args[1].arg_type.? == i32); | |
| 13 | expect(info.args[2].arg_type.? == f32); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | fn dummy(a: bool, b: i32, c: f32) i32 { | |
| 18 | return 1234; | |
| 19 | } | |
| 20 | ||
| 21 | test "reflection: @field" { | |
| 22 | var f = Foo{ | |
| 23 | .one = 42, | |
| 24 | .two = true, | |
| 25 | .three = void{}, | |
| 26 | }; | |
| 27 | ||
| 28 | expect(f.one == f.one); | |
| 29 | expect(@field(f, "o" ++ "ne") == f.one); | |
| 30 | expect(@field(f, "t" ++ "wo") == f.two); | |
| 31 | expect(@field(f, "th" ++ "ree") == f.three); | |
| 32 | expect(@field(Foo, "const" ++ "ant") == Foo.constant); | |
| 33 | expect(@field(Bar, "O" ++ "ne") == Bar.One); | |
| 34 | expect(@field(Bar, "T" ++ "wo") == Bar.Two); | |
| 35 | expect(@field(Bar, "Th" ++ "ree") == Bar.Three); | |
| 36 | expect(@field(Bar, "F" ++ "our") == Bar.Four); | |
| 37 | expect(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2)); | |
| 38 | @field(f, "o" ++ "ne") = 4; | |
| 39 | expect(f.one == 4); | |
| 40 | } | |
| 41 | ||
| 42 | const Foo = struct { | |
| 43 | const constant = 52; | |
| 44 | ||
| 45 | one: i32, | |
| 46 | two: bool, | |
| 47 | three: void, | |
| 48 | }; | |
| 49 | ||
| 50 | const Bar = union(enum) { | |
| 51 | One: void, | |
| 52 | Two: i32, | |
| 53 | Three: bool, | |
| 54 | Four: f64, | |
| 55 | }; |
test/stage1/behavior/shuffle.zig deleted-63| ... | ... | @@ -1,63 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const expect = std.testing.expect; | |
| 5 | const Vector = std.meta.Vector; | |
| 6 | ||
| 7 | test "@shuffle" { | |
| 8 | // TODO investigate why this fails when cross-compiling to wasm. | |
| 9 | if (builtin.os.tag == .wasi) return error.SkipZigTest; | |
| 10 | ||
| 11 | const S = struct { | |
| 12 | fn doTheTest() void { | |
| 13 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 14 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; | |
| 15 | const mask: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }; | |
| 16 | var res = @shuffle(i32, v, x, mask); | |
| 17 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); | |
| 18 | ||
| 19 | // Implicit cast from array (of mask) | |
| 20 | res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) }); | |
| 21 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 40, 4 })); | |
| 22 | ||
| 23 | // Undefined | |
| 24 | const mask2: Vector(4, i32) = [4]i32{ 3, 1, 2, 0 }; | |
| 25 | res = @shuffle(i32, v, undefined, mask2); | |
| 26 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 40, -2, 30, 2147483647 })); | |
| 27 | ||
| 28 | // Upcasting of b | |
| 29 | var v2: Vector(2, i32) = [2]i32{ 2147483647, undefined }; | |
| 30 | const mask3: Vector(4, i32) = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 }; | |
| 31 | res = @shuffle(i32, x, v2, mask3); | |
| 32 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, 2147483647, 4 })); | |
| 33 | ||
| 34 | // Upcasting of a | |
| 35 | var v3: Vector(2, i32) = [2]i32{ 2147483647, -2 }; | |
| 36 | const mask4: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) }; | |
| 37 | res = @shuffle(i32, v3, x, mask4); | |
| 38 | expect(mem.eql(i32, &@as([4]i32, res), &[4]i32{ 2147483647, 3, -2, 4 })); | |
| 39 | ||
| 40 | // bool | |
| 41 | // https://github.com/ziglang/zig/issues/3317 | |
| 42 | if (builtin.target.cpu.arch != .mipsel and builtin.target.cpu.arch != .mips) { | |
| 43 | var x2: Vector(4, bool) = [4]bool{ false, true, false, true }; | |
| 44 | var v4: Vector(2, bool) = [2]bool{ true, false }; | |
| 45 | const mask5: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 46 | var res2 = @shuffle(bool, x2, v4, mask5); | |
| 47 | expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); | |
| 48 | } | |
| 49 | ||
| 50 | // TODO re-enable when LLVM codegen is fixed | |
| 51 | // https://github.com/ziglang/zig/issues/3246 | |
| 52 | if (false) { | |
| 53 | var x2: Vector(3, bool) = [3]bool{ false, true, false }; | |
| 54 | var v4: Vector(2, bool) = [2]bool{ true, false }; | |
| 55 | const mask5: Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 }; | |
| 56 | var res2 = @shuffle(bool, x2, v4, mask5); | |
| 57 | expect(mem.eql(bool, &@as([4]bool, res2), &[4]bool{ false, false, true, false })); | |
| 58 | } | |
| 59 | } | |
| 60 | }; | |
| 61 | S.doTheTest(); | |
| 62 | comptime S.doTheTest(); | |
| 63 | } |
test/stage1/behavior/sizeof_and_typeof.zig deleted-264| ... | ... | @@ -1,264 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = std.builtin; | |
| 3 | const expect = std.testing.expect; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | ||
| 6 | test "@sizeOf and @TypeOf" { | |
| 7 | const y: @TypeOf(x) = 120; | |
| 8 | expect(@sizeOf(@TypeOf(y)) == 2); | |
| 9 | } | |
| 10 | const x: u16 = 13; | |
| 11 | const z: @TypeOf(x) = 19; | |
| 12 | ||
| 13 | const A = struct { | |
| 14 | a: u8, | |
| 15 | b: u32, | |
| 16 | c: u8, | |
| 17 | d: u3, | |
| 18 | e: u5, | |
| 19 | f: u16, | |
| 20 | g: u16, | |
| 21 | h: u9, | |
| 22 | i: u7, | |
| 23 | }; | |
| 24 | ||
| 25 | const P = packed struct { | |
| 26 | a: u8, | |
| 27 | b: u32, | |
| 28 | c: u8, | |
| 29 | d: u3, | |
| 30 | e: u5, | |
| 31 | f: u16, | |
| 32 | g: u16, | |
| 33 | h: u9, | |
| 34 | i: u7, | |
| 35 | }; | |
| 36 | ||
| 37 | test "@byteOffsetOf" { | |
| 38 | // Packed structs have fixed memory layout | |
| 39 | expect(@byteOffsetOf(P, "a") == 0); | |
| 40 | expect(@byteOffsetOf(P, "b") == 1); | |
| 41 | expect(@byteOffsetOf(P, "c") == 5); | |
| 42 | expect(@byteOffsetOf(P, "d") == 6); | |
| 43 | expect(@byteOffsetOf(P, "e") == 6); | |
| 44 | expect(@byteOffsetOf(P, "f") == 7); | |
| 45 | expect(@byteOffsetOf(P, "g") == 9); | |
| 46 | expect(@byteOffsetOf(P, "h") == 11); | |
| 47 | expect(@byteOffsetOf(P, "i") == 12); | |
| 48 | ||
| 49 | // Normal struct fields can be moved/padded | |
| 50 | var a: A = undefined; | |
| 51 | expect(@ptrToInt(&a.a) - @ptrToInt(&a) == @byteOffsetOf(A, "a")); | |
| 52 | expect(@ptrToInt(&a.b) - @ptrToInt(&a) == @byteOffsetOf(A, "b")); | |
| 53 | expect(@ptrToInt(&a.c) - @ptrToInt(&a) == @byteOffsetOf(A, "c")); | |
| 54 | expect(@ptrToInt(&a.d) - @ptrToInt(&a) == @byteOffsetOf(A, "d")); | |
| 55 | expect(@ptrToInt(&a.e) - @ptrToInt(&a) == @byteOffsetOf(A, "e")); | |
| 56 | expect(@ptrToInt(&a.f) - @ptrToInt(&a) == @byteOffsetOf(A, "f")); | |
| 57 | expect(@ptrToInt(&a.g) - @ptrToInt(&a) == @byteOffsetOf(A, "g")); | |
| 58 | expect(@ptrToInt(&a.h) - @ptrToInt(&a) == @byteOffsetOf(A, "h")); | |
| 59 | expect(@ptrToInt(&a.i) - @ptrToInt(&a) == @byteOffsetOf(A, "i")); | |
| 60 | } | |
| 61 | ||
| 62 | test "@byteOffsetOf packed struct, array length not power of 2 or multiple of native pointer width in bytes" { | |
| 63 | const p3a_len = 3; | |
| 64 | const P3 = packed struct { | |
| 65 | a: [p3a_len]u8, | |
| 66 | b: usize, | |
| 67 | }; | |
| 68 | std.testing.expectEqual(0, @byteOffsetOf(P3, "a")); | |
| 69 | std.testing.expectEqual(p3a_len, @byteOffsetOf(P3, "b")); | |
| 70 | ||
| 71 | const p5a_len = 5; | |
| 72 | const P5 = packed struct { | |
| 73 | a: [p5a_len]u8, | |
| 74 | b: usize, | |
| 75 | }; | |
| 76 | std.testing.expectEqual(0, @byteOffsetOf(P5, "a")); | |
| 77 | std.testing.expectEqual(p5a_len, @byteOffsetOf(P5, "b")); | |
| 78 | ||
| 79 | const p6a_len = 6; | |
| 80 | const P6 = packed struct { | |
| 81 | a: [p6a_len]u8, | |
| 82 | b: usize, | |
| 83 | }; | |
| 84 | std.testing.expectEqual(0, @byteOffsetOf(P6, "a")); | |
| 85 | std.testing.expectEqual(p6a_len, @byteOffsetOf(P6, "b")); | |
| 86 | ||
| 87 | const p7a_len = 7; | |
| 88 | const P7 = packed struct { | |
| 89 | a: [p7a_len]u8, | |
| 90 | b: usize, | |
| 91 | }; | |
| 92 | std.testing.expectEqual(0, @byteOffsetOf(P7, "a")); | |
| 93 | std.testing.expectEqual(p7a_len, @byteOffsetOf(P7, "b")); | |
| 94 | ||
| 95 | const p9a_len = 9; | |
| 96 | const P9 = packed struct { | |
| 97 | a: [p9a_len]u8, | |
| 98 | b: usize, | |
| 99 | }; | |
| 100 | std.testing.expectEqual(0, @byteOffsetOf(P9, "a")); | |
| 101 | std.testing.expectEqual(p9a_len, @byteOffsetOf(P9, "b")); | |
| 102 | ||
| 103 | // 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 25 etc. are further cases | |
| 104 | } | |
| 105 | ||
| 106 | test "@bitOffsetOf" { | |
| 107 | // Packed structs have fixed memory layout | |
| 108 | expect(@bitOffsetOf(P, "a") == 0); | |
| 109 | expect(@bitOffsetOf(P, "b") == 8); | |
| 110 | expect(@bitOffsetOf(P, "c") == 40); | |
| 111 | expect(@bitOffsetOf(P, "d") == 48); | |
| 112 | expect(@bitOffsetOf(P, "e") == 51); | |
| 113 | expect(@bitOffsetOf(P, "f") == 56); | |
| 114 | expect(@bitOffsetOf(P, "g") == 72); | |
| 115 | ||
| 116 | expect(@byteOffsetOf(A, "a") * 8 == @bitOffsetOf(A, "a")); | |
| 117 | expect(@byteOffsetOf(A, "b") * 8 == @bitOffsetOf(A, "b")); | |
| 118 | expect(@byteOffsetOf(A, "c") * 8 == @bitOffsetOf(A, "c")); | |
| 119 | expect(@byteOffsetOf(A, "d") * 8 == @bitOffsetOf(A, "d")); | |
| 120 | expect(@byteOffsetOf(A, "e") * 8 == @bitOffsetOf(A, "e")); | |
| 121 | expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f")); | |
| 122 | expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g")); | |
| 123 | } | |
| 124 | ||
| 125 | test "@sizeOf on compile-time types" { | |
| 126 | expect(@sizeOf(comptime_int) == 0); | |
| 127 | expect(@sizeOf(comptime_float) == 0); | |
| 128 | expect(@sizeOf(@TypeOf(.hi)) == 0); | |
| 129 | expect(@sizeOf(@TypeOf(type)) == 0); | |
| 130 | } | |
| 131 | ||
| 132 | test "@sizeOf(T) == 0 doesn't force resolving struct size" { | |
| 133 | const S = struct { | |
| 134 | const Foo = struct { | |
| 135 | y: if (@sizeOf(Foo) == 0) u64 else u32, | |
| 136 | }; | |
| 137 | const Bar = struct { | |
| 138 | x: i32, | |
| 139 | y: if (0 == @sizeOf(Bar)) u64 else u32, | |
| 140 | }; | |
| 141 | }; | |
| 142 | ||
| 143 | expect(@sizeOf(S.Foo) == 4); | |
| 144 | expect(@sizeOf(S.Bar) == 8); | |
| 145 | } | |
| 146 | ||
| 147 | test "@TypeOf() has no runtime side effects" { | |
| 148 | const S = struct { | |
| 149 | fn foo(comptime T: type, ptr: *T) T { | |
| 150 | ptr.* += 1; | |
| 151 | return ptr.*; | |
| 152 | } | |
| 153 | }; | |
| 154 | var data: i32 = 0; | |
| 155 | const T = @TypeOf(S.foo(i32, &data)); | |
| 156 | comptime expect(T == i32); | |
| 157 | expect(data == 0); | |
| 158 | } | |
| 159 | ||
| 160 | test "@TypeOf() with multiple arguments" { | |
| 161 | { | |
| 162 | var var_1: u32 = undefined; | |
| 163 | var var_2: u8 = undefined; | |
| 164 | var var_3: u64 = undefined; | |
| 165 | comptime expect(@TypeOf(var_1, var_2, var_3) == u64); | |
| 166 | } | |
| 167 | { | |
| 168 | var var_1: f16 = undefined; | |
| 169 | var var_2: f32 = undefined; | |
| 170 | var var_3: f64 = undefined; | |
| 171 | comptime expect(@TypeOf(var_1, var_2, var_3) == f64); | |
| 172 | } | |
| 173 | { | |
| 174 | var var_1: u16 = undefined; | |
| 175 | comptime expect(@TypeOf(var_1, 0xffff) == u16); | |
| 176 | } | |
| 177 | { | |
| 178 | var var_1: f32 = undefined; | |
| 179 | comptime expect(@TypeOf(var_1, 3.1415) == f32); | |
| 180 | } | |
| 181 | } | |
| 182 | ||
| 183 | test "branching logic inside @TypeOf" { | |
| 184 | const S = struct { | |
| 185 | var data: i32 = 0; | |
| 186 | fn foo() anyerror!i32 { | |
| 187 | data += 1; | |
| 188 | return undefined; | |
| 189 | } | |
| 190 | }; | |
| 191 | const T = @TypeOf(S.foo() catch undefined); | |
| 192 | comptime expect(T == i32); | |
| 193 | expect(S.data == 0); | |
| 194 | } | |
| 195 | ||
| 196 | fn fn1(alpha: bool) void { | |
| 197 | const n: usize = 7; | |
| 198 | const v = if (alpha) n else @sizeOf(usize); | |
| 199 | } | |
| 200 | ||
| 201 | test "lazy @sizeOf result is checked for definedness" { | |
| 202 | const f = fn1; | |
| 203 | } | |
| 204 | ||
| 205 | test "@bitSizeOf" { | |
| 206 | expect(@bitSizeOf(u2) == 2); | |
| 207 | expect(@bitSizeOf(u8) == @sizeOf(u8) * 8); | |
| 208 | expect(@bitSizeOf(struct { | |
| 209 | a: u2, | |
| 210 | }) == 8); | |
| 211 | expect(@bitSizeOf(packed struct { | |
| 212 | a: u2, | |
| 213 | }) == 2); | |
| 214 | } | |
| 215 | ||
| 216 | test "@sizeOf comparison against zero" { | |
| 217 | const S0 = struct { | |
| 218 | f: *@This(), | |
| 219 | }; | |
| 220 | const U0 = union { | |
| 221 | f: *@This(), | |
| 222 | }; | |
| 223 | const S1 = struct { | |
| 224 | fn H(comptime T: type) type { | |
| 225 | return struct { | |
| 226 | x: T, | |
| 227 | }; | |
| 228 | } | |
| 229 | f0: H(*@This()), | |
| 230 | f1: H(**@This()), | |
| 231 | f2: H(***@This()), | |
| 232 | }; | |
| 233 | const U1 = union { | |
| 234 | fn H(comptime T: type) type { | |
| 235 | return struct { | |
| 236 | x: T, | |
| 237 | }; | |
| 238 | } | |
| 239 | f0: H(*@This()), | |
| 240 | f1: H(**@This()), | |
| 241 | f2: H(***@This()), | |
| 242 | }; | |
| 243 | const S = struct { | |
| 244 | fn doTheTest(comptime T: type, comptime result: bool) void { | |
| 245 | expectEqual(result, @sizeOf(T) > 0); | |
| 246 | } | |
| 247 | }; | |
| 248 | // Zero-sized type | |
| 249 | S.doTheTest(u0, false); | |
| 250 | S.doTheTest(*u0, false); | |
| 251 | // Non byte-sized type | |
| 252 | S.doTheTest(u1, true); | |
| 253 | S.doTheTest(*u1, true); | |
| 254 | // Regular type | |
| 255 | S.doTheTest(u8, true); | |
| 256 | S.doTheTest(*u8, true); | |
| 257 | S.doTheTest(f32, true); | |
| 258 | S.doTheTest(*f32, true); | |
| 259 | // Container with ptr pointing to themselves | |
| 260 | S.doTheTest(S0, true); | |
| 261 | S.doTheTest(U0, true); | |
| 262 | S.doTheTest(S1, true); | |
| 263 | S.doTheTest(U1, true); | |
| 264 | } |
test/stage1/behavior/slice.zig deleted-337| ... | ... | @@ -1,337 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | const mem = std.mem; | |
| 6 | ||
| 7 | const x = @intToPtr([*]i32, 0x1000)[0..0x500]; | |
| 8 | const y = x[0x100..]; | |
| 9 | test "compile time slice of pointer to hard coded address" { | |
| 10 | expect(@ptrToInt(x) == 0x1000); | |
| 11 | expect(x.len == 0x500); | |
| 12 | ||
| 13 | expect(@ptrToInt(y) == 0x1100); | |
| 14 | expect(y.len == 0x400); | |
| 15 | } | |
| 16 | ||
| 17 | test "runtime safety lets us slice from len..len" { | |
| 18 | var an_array = [_]u8{ | |
| 19 | 1, | |
| 20 | 2, | |
| 21 | 3, | |
| 22 | }; | |
| 23 | expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), "")); | |
| 24 | } | |
| 25 | ||
| 26 | fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { | |
| 27 | return a_slice[start..end]; | |
| 28 | } | |
| 29 | ||
| 30 | test "implicitly cast array of size 0 to slice" { | |
| 31 | var msg = [_]u8{}; | |
| 32 | assertLenIsZero(&msg); | |
| 33 | } | |
| 34 | ||
| 35 | fn assertLenIsZero(msg: []const u8) void { | |
| 36 | expect(msg.len == 0); | |
| 37 | } | |
| 38 | ||
| 39 | test "C pointer" { | |
| 40 | var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; | |
| 41 | var len: u32 = 10; | |
| 42 | var slice = buf[0..len]; | |
| 43 | expectEqualSlices(u8, "kjdhfkjdhf", slice); | |
| 44 | } | |
| 45 | ||
| 46 | test "C pointer slice access" { | |
| 47 | var buf: [10]u32 = [1]u32{42} ** 10; | |
| 48 | const c_ptr = @ptrCast([*c]const u32, &buf); | |
| 49 | ||
| 50 | var runtime_zero: usize = 0; | |
| 51 | comptime expectEqual([]const u32, @TypeOf(c_ptr[runtime_zero..1])); | |
| 52 | comptime expectEqual(*const [1]u32, @TypeOf(c_ptr[0..1])); | |
| 53 | ||
| 54 | for (c_ptr[0..5]) |*cl| { | |
| 55 | expectEqual(@as(u32, 42), cl.*); | |
| 56 | } | |
| 57 | } | |
| 58 | ||
| 59 | fn sliceSum(comptime q: []const u8) i32 { | |
| 60 | comptime var result = 0; | |
| 61 | inline for (q) |item| { | |
| 62 | result += item; | |
| 63 | } | |
| 64 | return result; | |
| 65 | } | |
| 66 | ||
| 67 | test "comptime slices are disambiguated" { | |
| 68 | expect(sliceSum(&[_]u8{ 1, 2 }) == 3); | |
| 69 | expect(sliceSum(&[_]u8{ 3, 4 }) == 7); | |
| 70 | } | |
| 71 | ||
| 72 | test "slice type with custom alignment" { | |
| 73 | const LazilyResolvedType = struct { | |
| 74 | anything: i32, | |
| 75 | }; | |
| 76 | var slice: []align(32) LazilyResolvedType = undefined; | |
| 77 | var array: [10]LazilyResolvedType align(32) = undefined; | |
| 78 | slice = &array; | |
| 79 | slice[1].anything = 42; | |
| 80 | expect(array[1].anything == 42); | |
| 81 | } | |
| 82 | ||
| 83 | test "access len index of sentinel-terminated slice" { | |
| 84 | const S = struct { | |
| 85 | fn doTheTest() void { | |
| 86 | var slice: [:0]const u8 = "hello"; | |
| 87 | ||
| 88 | expect(slice.len == 5); | |
| 89 | expect(slice[5] == 0); | |
| 90 | } | |
| 91 | }; | |
| 92 | S.doTheTest(); | |
| 93 | comptime S.doTheTest(); | |
| 94 | } | |
| 95 | ||
| 96 | test "obtaining a null terminated slice" { | |
| 97 | // here we have a normal array | |
| 98 | var buf: [50]u8 = undefined; | |
| 99 | ||
| 100 | buf[0] = 'a'; | |
| 101 | buf[1] = 'b'; | |
| 102 | buf[2] = 'c'; | |
| 103 | buf[3] = 0; | |
| 104 | ||
| 105 | // now we obtain a null terminated slice: | |
| 106 | const ptr = buf[0..3 :0]; | |
| 107 | ||
| 108 | var runtime_len: usize = 3; | |
| 109 | const ptr2 = buf[0..runtime_len :0]; | |
| 110 | // ptr2 is a null-terminated slice | |
| 111 | comptime expect(@TypeOf(ptr2) == [:0]u8); | |
| 112 | comptime expect(@TypeOf(ptr2[0..2]) == *[2]u8); | |
| 113 | var runtime_zero: usize = 0; | |
| 114 | comptime expect(@TypeOf(ptr2[runtime_zero..2]) == []u8); | |
| 115 | } | |
| 116 | ||
| 117 | test "empty array to slice" { | |
| 118 | const S = struct { | |
| 119 | fn doTheTest() void { | |
| 120 | const empty: []align(16) u8 = &[_]u8{}; | |
| 121 | const align_1: []align(1) u8 = empty; | |
| 122 | const align_4: []align(4) u8 = empty; | |
| 123 | const align_16: []align(16) u8 = empty; | |
| 124 | expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment); | |
| 125 | expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment); | |
| 126 | expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment); | |
| 127 | } | |
| 128 | }; | |
| 129 | ||
| 130 | S.doTheTest(); | |
| 131 | comptime S.doTheTest(); | |
| 132 | } | |
| 133 | ||
| 134 | test "@ptrCast slice to pointer" { | |
| 135 | const S = struct { | |
| 136 | fn doTheTest() void { | |
| 137 | var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff }; | |
| 138 | var slice: []u8 = &array; | |
| 139 | var ptr = @ptrCast(*u16, slice); | |
| 140 | expect(ptr.* == 65535); | |
| 141 | } | |
| 142 | }; | |
| 143 | ||
| 144 | S.doTheTest(); | |
| 145 | comptime S.doTheTest(); | |
| 146 | } | |
| 147 | ||
| 148 | test "slice syntax resulting in pointer-to-array" { | |
| 149 | const S = struct { | |
| 150 | fn doTheTest() void { | |
| 151 | testArray(); | |
| 152 | testArrayZ(); | |
| 153 | testArray0(); | |
| 154 | testArrayAlign(); | |
| 155 | testPointer(); | |
| 156 | testPointerZ(); | |
| 157 | testPointer0(); | |
| 158 | testPointerAlign(); | |
| 159 | testSlice(); | |
| 160 | testSliceZ(); | |
| 161 | testSlice0(); | |
| 162 | testSliceOpt(); | |
| 163 | testSliceAlign(); | |
| 164 | } | |
| 165 | ||
| 166 | fn testArray() void { | |
| 167 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 168 | var slice = array[1..3]; | |
| 169 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 170 | expect(slice[0] == 2); | |
| 171 | expect(slice[1] == 3); | |
| 172 | } | |
| 173 | ||
| 174 | fn testArrayZ() void { | |
| 175 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 176 | comptime expect(@TypeOf(array[1..3]) == *[2]u8); | |
| 177 | comptime expect(@TypeOf(array[1..5]) == *[4:0]u8); | |
| 178 | comptime expect(@TypeOf(array[1..]) == *[4:0]u8); | |
| 179 | comptime expect(@TypeOf(array[1..3 :4]) == *[2:4]u8); | |
| 180 | } | |
| 181 | ||
| 182 | fn testArray0() void { | |
| 183 | { | |
| 184 | var array = [0]u8{}; | |
| 185 | var slice = array[0..0]; | |
| 186 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 187 | } | |
| 188 | { | |
| 189 | var array = [0:0]u8{}; | |
| 190 | var slice = array[0..0]; | |
| 191 | comptime expect(@TypeOf(slice) == *[0:0]u8); | |
| 192 | expect(slice[0] == 0); | |
| 193 | } | |
| 194 | } | |
| 195 | ||
| 196 | fn testArrayAlign() void { | |
| 197 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 198 | var slice = array[4..5]; | |
| 199 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 200 | expect(slice[0] == 5); | |
| 201 | comptime expect(@TypeOf(array[0..2]) == *align(4) [2]u8); | |
| 202 | } | |
| 203 | ||
| 204 | fn testPointer() void { | |
| 205 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 206 | var pointer: [*]u8 = &array; | |
| 207 | var slice = pointer[1..3]; | |
| 208 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 209 | expect(slice[0] == 2); | |
| 210 | expect(slice[1] == 3); | |
| 211 | } | |
| 212 | ||
| 213 | fn testPointerZ() void { | |
| 214 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 215 | var pointer: [*:0]u8 = &array; | |
| 216 | comptime expect(@TypeOf(pointer[1..3]) == *[2]u8); | |
| 217 | comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8); | |
| 218 | } | |
| 219 | ||
| 220 | fn testPointer0() void { | |
| 221 | var pointer: [*]const u0 = &[1]u0{0}; | |
| 222 | var slice = pointer[0..1]; | |
| 223 | comptime expect(@TypeOf(slice) == *const [1]u0); | |
| 224 | expect(slice[0] == 0); | |
| 225 | } | |
| 226 | ||
| 227 | fn testPointerAlign() void { | |
| 228 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 229 | var pointer: [*]align(4) u8 = &array; | |
| 230 | var slice = pointer[4..5]; | |
| 231 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 232 | expect(slice[0] == 5); | |
| 233 | comptime expect(@TypeOf(pointer[0..2]) == *align(4) [2]u8); | |
| 234 | } | |
| 235 | ||
| 236 | fn testSlice() void { | |
| 237 | var array = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 238 | var src_slice: []u8 = &array; | |
| 239 | var slice = src_slice[1..3]; | |
| 240 | comptime expect(@TypeOf(slice) == *[2]u8); | |
| 241 | expect(slice[0] == 2); | |
| 242 | expect(slice[1] == 3); | |
| 243 | } | |
| 244 | ||
| 245 | fn testSliceZ() void { | |
| 246 | var array = [5:0]u8{ 1, 2, 3, 4, 5 }; | |
| 247 | var slice: [:0]u8 = &array; | |
| 248 | comptime expect(@TypeOf(slice[1..3]) == *[2]u8); | |
| 249 | comptime expect(@TypeOf(slice[1..]) == [:0]u8); | |
| 250 | comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8); | |
| 251 | } | |
| 252 | ||
| 253 | fn testSliceOpt() void { | |
| 254 | var array: [2]u8 = [2]u8{ 1, 2 }; | |
| 255 | var slice: ?[]u8 = &array; | |
| 256 | comptime expect(@TypeOf(&array, slice) == ?[]u8); | |
| 257 | comptime expect(@TypeOf(slice.?[0..2]) == *[2]u8); | |
| 258 | } | |
| 259 | ||
| 260 | fn testSlice0() void { | |
| 261 | { | |
| 262 | var array = [0]u8{}; | |
| 263 | var src_slice: []u8 = &array; | |
| 264 | var slice = src_slice[0..0]; | |
| 265 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 266 | } | |
| 267 | { | |
| 268 | var array = [0:0]u8{}; | |
| 269 | var src_slice: [:0]u8 = &array; | |
| 270 | var slice = src_slice[0..0]; | |
| 271 | comptime expect(@TypeOf(slice) == *[0]u8); | |
| 272 | } | |
| 273 | } | |
| 274 | ||
| 275 | fn testSliceAlign() void { | |
| 276 | var array align(4) = [5]u8{ 1, 2, 3, 4, 5 }; | |
| 277 | var src_slice: []align(4) u8 = &array; | |
| 278 | var slice = src_slice[4..5]; | |
| 279 | comptime expect(@TypeOf(slice) == *align(4) [1]u8); | |
| 280 | expect(slice[0] == 5); | |
| 281 | comptime expect(@TypeOf(src_slice[0..2]) == *align(4) [2]u8); | |
| 282 | } | |
| 283 | ||
| 284 | fn testConcatStrLiterals() void { | |
| 285 | expectEqualSlices("a"[0..] ++ "b"[0..], "ab"); | |
| 286 | expectEqualSlices("a"[0..:0] ++ "b"[0..:0], "ab"); | |
| 287 | } | |
| 288 | }; | |
| 289 | ||
| 290 | S.doTheTest(); | |
| 291 | comptime S.doTheTest(); | |
| 292 | } | |
| 293 | ||
| 294 | test "slice of hardcoded address to pointer" { | |
| 295 | const S = struct { | |
| 296 | fn doTheTest() void { | |
| 297 | const pointer = @intToPtr([*]u8, 0x04)[0..2]; | |
| 298 | comptime expect(@TypeOf(pointer) == *[2]u8); | |
| 299 | const slice: []const u8 = pointer; | |
| 300 | expect(@ptrToInt(slice.ptr) == 4); | |
| 301 | expect(slice.len == 2); | |
| 302 | } | |
| 303 | }; | |
| 304 | ||
| 305 | S.doTheTest(); | |
| 306 | } | |
| 307 | ||
| 308 | test "type coercion of pointer to anon struct literal to pointer to slice" { | |
| 309 | const S = struct { | |
| 310 | const U = union{ | |
| 311 | a: u32, | |
| 312 | b: bool, | |
| 313 | c: []const u8, | |
| 314 | }; | |
| 315 | ||
| 316 | fn doTheTest() void { | |
| 317 | var x1: u8 = 42; | |
| 318 | const t1 = &.{ x1, 56, 54 }; | |
| 319 | var slice1: []const u8 = t1; | |
| 320 | expect(slice1.len == 3); | |
| 321 | expect(slice1[0] == 42); | |
| 322 | expect(slice1[1] == 56); | |
| 323 | expect(slice1[2] == 54); | |
| 324 | ||
| 325 | var x2: []const u8 = "hello"; | |
| 326 | const t2 = &.{ x2, ", ", "world!" }; | |
| 327 | // @compileLog(@TypeOf(t2)); | |
| 328 | var slice2: []const []const u8 = t2; | |
| 329 | expect(slice2.len == 3); | |
| 330 | expect(mem.eql(u8, slice2[0], "hello")); | |
| 331 | expect(mem.eql(u8, slice2[1], ", ")); | |
| 332 | expect(mem.eql(u8, slice2[2], "world!")); | |
| 333 | } | |
| 334 | }; | |
| 335 | // S.doTheTest(); | |
| 336 | comptime S.doTheTest(); | |
| 337 | } |
test/stage1/behavior/slice_sentinel_comptime.zig deleted-199| ... | ... | @@ -1,199 +0,0 @@ |
| 1 | test "comptime slice-sentinel in bounds (unterminated)" { | |
| 2 | // array | |
| 3 | comptime { | |
| 4 | var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 5 | const slice = target[0..3 :'d']; | |
| 6 | } | |
| 7 | ||
| 8 | // ptr_array | |
| 9 | comptime { | |
| 10 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 11 | var target = &buf; | |
| 12 | const slice = target[0..3 :'d']; | |
| 13 | } | |
| 14 | ||
| 15 | // vector_ConstPtrSpecialBaseArray | |
| 16 | comptime { | |
| 17 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 18 | var target: [*]u8 = &buf; | |
| 19 | const slice = target[0..3 :'d']; | |
| 20 | } | |
| 21 | ||
| 22 | // vector_ConstPtrSpecialRef | |
| 23 | comptime { | |
| 24 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 25 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 26 | const slice = target[0..3 :'d']; | |
| 27 | } | |
| 28 | ||
| 29 | // cvector_ConstPtrSpecialBaseArray | |
| 30 | comptime { | |
| 31 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 32 | var target: [*c]u8 = &buf; | |
| 33 | const slice = target[0..3 :'d']; | |
| 34 | } | |
| 35 | ||
| 36 | // cvector_ConstPtrSpecialRef | |
| 37 | comptime { | |
| 38 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 39 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 40 | const slice = target[0..3 :'d']; | |
| 41 | } | |
| 42 | ||
| 43 | // slice | |
| 44 | comptime { | |
| 45 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 46 | var target: []u8 = &buf; | |
| 47 | const slice = target[0..3 :'d']; | |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 51 | test "comptime slice-sentinel in bounds (end,unterminated)" { | |
| 52 | // array | |
| 53 | comptime { | |
| 54 | var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 55 | const slice = target[0..13 :0xff]; | |
| 56 | } | |
| 57 | ||
| 58 | // ptr_array | |
| 59 | comptime { | |
| 60 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 61 | var target = &buf; | |
| 62 | const slice = target[0..13 :0xff]; | |
| 63 | } | |
| 64 | ||
| 65 | // vector_ConstPtrSpecialBaseArray | |
| 66 | comptime { | |
| 67 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 68 | var target: [*]u8 = &buf; | |
| 69 | const slice = target[0..13 :0xff]; | |
| 70 | } | |
| 71 | ||
| 72 | // vector_ConstPtrSpecialRef | |
| 73 | comptime { | |
| 74 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 75 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 76 | const slice = target[0..13 :0xff]; | |
| 77 | } | |
| 78 | ||
| 79 | // cvector_ConstPtrSpecialBaseArray | |
| 80 | comptime { | |
| 81 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 82 | var target: [*c]u8 = &buf; | |
| 83 | const slice = target[0..13 :0xff]; | |
| 84 | } | |
| 85 | ||
| 86 | // cvector_ConstPtrSpecialRef | |
| 87 | comptime { | |
| 88 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 89 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 90 | const slice = target[0..13 :0xff]; | |
| 91 | } | |
| 92 | ||
| 93 | // slice | |
| 94 | comptime { | |
| 95 | var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10; | |
| 96 | var target: []u8 = &buf; | |
| 97 | const slice = target[0..13 :0xff]; | |
| 98 | } | |
| 99 | } | |
| 100 | ||
| 101 | test "comptime slice-sentinel in bounds (terminated)" { | |
| 102 | // array | |
| 103 | comptime { | |
| 104 | var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 105 | const slice = target[0..3 :'d']; | |
| 106 | } | |
| 107 | ||
| 108 | // ptr_array | |
| 109 | comptime { | |
| 110 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 111 | var target = &buf; | |
| 112 | const slice = target[0..3 :'d']; | |
| 113 | } | |
| 114 | ||
| 115 | // vector_ConstPtrSpecialBaseArray | |
| 116 | comptime { | |
| 117 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 118 | var target: [*]u8 = &buf; | |
| 119 | const slice = target[0..3 :'d']; | |
| 120 | } | |
| 121 | ||
| 122 | // vector_ConstPtrSpecialRef | |
| 123 | comptime { | |
| 124 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 125 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 126 | const slice = target[0..3 :'d']; | |
| 127 | } | |
| 128 | ||
| 129 | // cvector_ConstPtrSpecialBaseArray | |
| 130 | comptime { | |
| 131 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 132 | var target: [*c]u8 = &buf; | |
| 133 | const slice = target[0..3 :'d']; | |
| 134 | } | |
| 135 | ||
| 136 | // cvector_ConstPtrSpecialRef | |
| 137 | comptime { | |
| 138 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 139 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 140 | const slice = target[0..3 :'d']; | |
| 141 | } | |
| 142 | ||
| 143 | // slice | |
| 144 | comptime { | |
| 145 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 146 | var target: []u8 = &buf; | |
| 147 | const slice = target[0..3 :'d']; | |
| 148 | } | |
| 149 | } | |
| 150 | ||
| 151 | test "comptime slice-sentinel in bounds (on target sentinel)" { | |
| 152 | // array | |
| 153 | comptime { | |
| 154 | var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 155 | const slice = target[0..14 :0]; | |
| 156 | } | |
| 157 | ||
| 158 | // ptr_array | |
| 159 | comptime { | |
| 160 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 161 | var target = &buf; | |
| 162 | const slice = target[0..14 :0]; | |
| 163 | } | |
| 164 | ||
| 165 | // vector_ConstPtrSpecialBaseArray | |
| 166 | comptime { | |
| 167 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 168 | var target: [*]u8 = &buf; | |
| 169 | const slice = target[0..14 :0]; | |
| 170 | } | |
| 171 | ||
| 172 | // vector_ConstPtrSpecialRef | |
| 173 | comptime { | |
| 174 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 175 | var target: [*]u8 = @ptrCast([*]u8, &buf); | |
| 176 | const slice = target[0..14 :0]; | |
| 177 | } | |
| 178 | ||
| 179 | // cvector_ConstPtrSpecialBaseArray | |
| 180 | comptime { | |
| 181 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 182 | var target: [*c]u8 = &buf; | |
| 183 | const slice = target[0..14 :0]; | |
| 184 | } | |
| 185 | ||
| 186 | // cvector_ConstPtrSpecialRef | |
| 187 | comptime { | |
| 188 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 189 | var target: [*c]u8 = @ptrCast([*c]u8, &buf); | |
| 190 | const slice = target[0..14 :0]; | |
| 191 | } | |
| 192 | ||
| 193 | // slice | |
| 194 | comptime { | |
| 195 | var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; | |
| 196 | var target: []u8 = &buf; | |
| 197 | const slice = target[0..14 :0]; | |
| 198 | } | |
| 199 | } |
test/stage1/behavior/src.zig deleted-17| ... | ... | @@ -1,17 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@src" { | |
| 5 | doTheTest(); | |
| 6 | } | |
| 7 | ||
| 8 | fn doTheTest() void { | |
| 9 | const src = @src(); | |
| 10 | ||
| 11 | expect(src.line == 9); | |
| 12 | expect(src.column == 17); | |
| 13 | expect(std.mem.endsWith(u8, src.fn_name, "doTheTest")); | |
| 14 | expect(std.mem.endsWith(u8, src.file, "src.zig")); | |
| 15 | expect(src.fn_name[src.fn_name.len] == 0); | |
| 16 | expect(src.file[src.file.len] == 0); | |
| 17 | } |
test/stage1/behavior/struct.zig deleted-945| ... | ... | @@ -1,945 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const native_endian = builtin.target.cpu.arch.endian(); | |
| 4 | const expect = std.testing.expect; | |
| 5 | const expectEqual = std.testing.expectEqual; | |
| 6 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 7 | const maxInt = std.math.maxInt; | |
| 8 | const StructWithNoFields = struct { | |
| 9 | fn add(a: i32, b: i32) i32 { | |
| 10 | return a + b; | |
| 11 | } | |
| 12 | }; | |
| 13 | const empty_global_instance = StructWithNoFields{}; | |
| 14 | ||
| 15 | top_level_field: i32, | |
| 16 | ||
| 17 | test "top level fields" { | |
| 18 | var instance = @This(){ | |
| 19 | .top_level_field = 1234, | |
| 20 | }; | |
| 21 | instance.top_level_field += 1; | |
| 22 | expectEqual(@as(i32, 1235), instance.top_level_field); | |
| 23 | } | |
| 24 | ||
| 25 | test "call struct static method" { | |
| 26 | const result = StructWithNoFields.add(3, 4); | |
| 27 | expect(result == 7); | |
| 28 | } | |
| 29 | ||
| 30 | test "return empty struct instance" { | |
| 31 | _ = returnEmptyStructInstance(); | |
| 32 | } | |
| 33 | fn returnEmptyStructInstance() StructWithNoFields { | |
| 34 | return empty_global_instance; | |
| 35 | } | |
| 36 | ||
| 37 | const should_be_11 = StructWithNoFields.add(5, 6); | |
| 38 | ||
| 39 | test "invoke static method in global scope" { | |
| 40 | expect(should_be_11 == 11); | |
| 41 | } | |
| 42 | ||
| 43 | test "void struct fields" { | |
| 44 | const foo = VoidStructFieldsFoo{ | |
| 45 | .a = void{}, | |
| 46 | .b = 1, | |
| 47 | .c = void{}, | |
| 48 | }; | |
| 49 | expect(foo.b == 1); | |
| 50 | expect(@sizeOf(VoidStructFieldsFoo) == 4); | |
| 51 | } | |
| 52 | const VoidStructFieldsFoo = struct { | |
| 53 | a: void, | |
| 54 | b: i32, | |
| 55 | c: void, | |
| 56 | }; | |
| 57 | ||
| 58 | test "structs" { | |
| 59 | var foo: StructFoo = undefined; | |
| 60 | @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); | |
| 61 | foo.a += 1; | |
| 62 | foo.b = foo.a == 1; | |
| 63 | testFoo(foo); | |
| 64 | testMutation(&foo); | |
| 65 | expect(foo.c == 100); | |
| 66 | } | |
| 67 | const StructFoo = struct { | |
| 68 | a: i32, | |
| 69 | b: bool, | |
| 70 | c: f32, | |
| 71 | }; | |
| 72 | fn testFoo(foo: StructFoo) void { | |
| 73 | expect(foo.b); | |
| 74 | } | |
| 75 | fn testMutation(foo: *StructFoo) void { | |
| 76 | foo.c = 100; | |
| 77 | } | |
| 78 | ||
| 79 | const Node = struct { | |
| 80 | val: Val, | |
| 81 | next: *Node, | |
| 82 | }; | |
| 83 | ||
| 84 | const Val = struct { | |
| 85 | x: i32, | |
| 86 | }; | |
| 87 | ||
| 88 | test "struct point to self" { | |
| 89 | var root: Node = undefined; | |
| 90 | root.val.x = 1; | |
| 91 | ||
| 92 | var node: Node = undefined; | |
| 93 | node.next = &root; | |
| 94 | node.val.x = 2; | |
| 95 | ||
| 96 | root.next = &node; | |
| 97 | ||
| 98 | expect(node.next.next.next.val.x == 1); | |
| 99 | } | |
| 100 | ||
| 101 | test "struct byval assign" { | |
| 102 | var foo1: StructFoo = undefined; | |
| 103 | var foo2: StructFoo = undefined; | |
| 104 | ||
| 105 | foo1.a = 1234; | |
| 106 | foo2.a = 0; | |
| 107 | expect(foo2.a == 0); | |
| 108 | foo2 = foo1; | |
| 109 | expect(foo2.a == 1234); | |
| 110 | } | |
| 111 | ||
| 112 | fn structInitializer() void { | |
| 113 | const val = Val{ .x = 42 }; | |
| 114 | expect(val.x == 42); | |
| 115 | } | |
| 116 | ||
| 117 | test "fn call of struct field" { | |
| 118 | const Foo = struct { | |
| 119 | ptr: fn () i32, | |
| 120 | }; | |
| 121 | const S = struct { | |
| 122 | fn aFunc() i32 { | |
| 123 | return 13; | |
| 124 | } | |
| 125 | ||
| 126 | fn callStructField(foo: Foo) i32 { | |
| 127 | return foo.ptr(); | |
| 128 | } | |
| 129 | }; | |
| 130 | ||
| 131 | expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13); | |
| 132 | } | |
| 133 | ||
| 134 | test "store member function in variable" { | |
| 135 | const instance = MemberFnTestFoo{ .x = 1234 }; | |
| 136 | const memberFn = MemberFnTestFoo.member; | |
| 137 | const result = memberFn(instance); | |
| 138 | expect(result == 1234); | |
| 139 | } | |
| 140 | const MemberFnTestFoo = struct { | |
| 141 | x: i32, | |
| 142 | fn member(foo: MemberFnTestFoo) i32 { | |
| 143 | return foo.x; | |
| 144 | } | |
| 145 | }; | |
| 146 | ||
| 147 | test "call member function directly" { | |
| 148 | const instance = MemberFnTestFoo{ .x = 1234 }; | |
| 149 | const result = MemberFnTestFoo.member(instance); | |
| 150 | expect(result == 1234); | |
| 151 | } | |
| 152 | ||
| 153 | test "member functions" { | |
| 154 | const r = MemberFnRand{ .seed = 1234 }; | |
| 155 | expect(r.getSeed() == 1234); | |
| 156 | } | |
| 157 | const MemberFnRand = struct { | |
| 158 | seed: u32, | |
| 159 | pub fn getSeed(r: *const MemberFnRand) u32 { | |
| 160 | return r.seed; | |
| 161 | } | |
| 162 | }; | |
| 163 | ||
| 164 | test "return struct byval from function" { | |
| 165 | const bar = makeBar(1234, 5678); | |
| 166 | expect(bar.y == 5678); | |
| 167 | } | |
| 168 | const Bar = struct { | |
| 169 | x: i32, | |
| 170 | y: i32, | |
| 171 | }; | |
| 172 | fn makeBar(x: i32, y: i32) Bar { | |
| 173 | return Bar{ | |
| 174 | .x = x, | |
| 175 | .y = y, | |
| 176 | }; | |
| 177 | } | |
| 178 | ||
| 179 | test "empty struct method call" { | |
| 180 | const es = EmptyStruct{}; | |
| 181 | expect(es.method() == 1234); | |
| 182 | } | |
| 183 | const EmptyStruct = struct { | |
| 184 | fn method(es: *const EmptyStruct) i32 { | |
| 185 | return 1234; | |
| 186 | } | |
| 187 | }; | |
| 188 | ||
| 189 | test "return empty struct from fn" { | |
| 190 | _ = testReturnEmptyStructFromFn(); | |
| 191 | } | |
| 192 | const EmptyStruct2 = struct {}; | |
| 193 | fn testReturnEmptyStructFromFn() EmptyStruct2 { | |
| 194 | return EmptyStruct2{}; | |
| 195 | } | |
| 196 | ||
| 197 | test "pass slice of empty struct to fn" { | |
| 198 | expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); | |
| 199 | } | |
| 200 | fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { | |
| 201 | return slice.len; | |
| 202 | } | |
| 203 | ||
| 204 | const APackedStruct = packed struct { | |
| 205 | x: u8, | |
| 206 | y: u8, | |
| 207 | }; | |
| 208 | ||
| 209 | test "packed struct" { | |
| 210 | var foo = APackedStruct{ | |
| 211 | .x = 1, | |
| 212 | .y = 2, | |
| 213 | }; | |
| 214 | foo.y += 1; | |
| 215 | const four = foo.x + foo.y; | |
| 216 | expect(four == 4); | |
| 217 | } | |
| 218 | ||
| 219 | const BitField1 = packed struct { | |
| 220 | a: u3, | |
| 221 | b: u3, | |
| 222 | c: u2, | |
| 223 | }; | |
| 224 | ||
| 225 | const bit_field_1 = BitField1{ | |
| 226 | .a = 1, | |
| 227 | .b = 2, | |
| 228 | .c = 3, | |
| 229 | }; | |
| 230 | ||
| 231 | test "bit field access" { | |
| 232 | var data = bit_field_1; | |
| 233 | expect(getA(&data) == 1); | |
| 234 | expect(getB(&data) == 2); | |
| 235 | expect(getC(&data) == 3); | |
| 236 | comptime expect(@sizeOf(BitField1) == 1); | |
| 237 | ||
| 238 | data.b += 1; | |
| 239 | expect(data.b == 3); | |
| 240 | ||
| 241 | data.a += 1; | |
| 242 | expect(data.a == 2); | |
| 243 | expect(data.b == 3); | |
| 244 | } | |
| 245 | ||
| 246 | fn getA(data: *const BitField1) u3 { | |
| 247 | return data.a; | |
| 248 | } | |
| 249 | ||
| 250 | fn getB(data: *const BitField1) u3 { | |
| 251 | return data.b; | |
| 252 | } | |
| 253 | ||
| 254 | fn getC(data: *const BitField1) u2 { | |
| 255 | return data.c; | |
| 256 | } | |
| 257 | ||
| 258 | const Foo24Bits = packed struct { | |
| 259 | field: u24, | |
| 260 | }; | |
| 261 | const Foo96Bits = packed struct { | |
| 262 | a: u24, | |
| 263 | b: u24, | |
| 264 | c: u24, | |
| 265 | d: u24, | |
| 266 | }; | |
| 267 | ||
| 268 | test "packed struct 24bits" { | |
| 269 | comptime { | |
| 270 | expect(@sizeOf(Foo24Bits) == 4); | |
| 271 | if (@sizeOf(usize) == 4) { | |
| 272 | expect(@sizeOf(Foo96Bits) == 12); | |
| 273 | } else { | |
| 274 | expect(@sizeOf(Foo96Bits) == 16); | |
| 275 | } | |
| 276 | } | |
| 277 | ||
| 278 | var value = Foo96Bits{ | |
| 279 | .a = 0, | |
| 280 | .b = 0, | |
| 281 | .c = 0, | |
| 282 | .d = 0, | |
| 283 | }; | |
| 284 | value.a += 1; | |
| 285 | expect(value.a == 1); | |
| 286 | expect(value.b == 0); | |
| 287 | expect(value.c == 0); | |
| 288 | expect(value.d == 0); | |
| 289 | ||
| 290 | value.b += 1; | |
| 291 | expect(value.a == 1); | |
| 292 | expect(value.b == 1); | |
| 293 | expect(value.c == 0); | |
| 294 | expect(value.d == 0); | |
| 295 | ||
| 296 | value.c += 1; | |
| 297 | expect(value.a == 1); | |
| 298 | expect(value.b == 1); | |
| 299 | expect(value.c == 1); | |
| 300 | expect(value.d == 0); | |
| 301 | ||
| 302 | value.d += 1; | |
| 303 | expect(value.a == 1); | |
| 304 | expect(value.b == 1); | |
| 305 | expect(value.c == 1); | |
| 306 | expect(value.d == 1); | |
| 307 | } | |
| 308 | ||
| 309 | const Foo32Bits = packed struct { | |
| 310 | field: u24, | |
| 311 | pad: u8, | |
| 312 | }; | |
| 313 | ||
| 314 | const FooArray24Bits = packed struct { | |
| 315 | a: u16, | |
| 316 | b: [2]Foo32Bits, | |
| 317 | c: u16, | |
| 318 | }; | |
| 319 | ||
| 320 | // TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512 | |
| 321 | test "packed array 24bits" { | |
| 322 | comptime { | |
| 323 | expect(@sizeOf([9]Foo32Bits) == 9 * 4); | |
| 324 | expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2); | |
| 325 | } | |
| 326 | ||
| 327 | var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); | |
| 328 | bytes[bytes.len - 1] = 0xaa; | |
| 329 | const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; | |
| 330 | expect(ptr.a == 0); | |
| 331 | expect(ptr.b[0].field == 0); | |
| 332 | expect(ptr.b[1].field == 0); | |
| 333 | expect(ptr.c == 0); | |
| 334 | ||
| 335 | ptr.a = maxInt(u16); | |
| 336 | expect(ptr.a == maxInt(u16)); | |
| 337 | expect(ptr.b[0].field == 0); | |
| 338 | expect(ptr.b[1].field == 0); | |
| 339 | expect(ptr.c == 0); | |
| 340 | ||
| 341 | ptr.b[0].field = maxInt(u24); | |
| 342 | expect(ptr.a == maxInt(u16)); | |
| 343 | expect(ptr.b[0].field == maxInt(u24)); | |
| 344 | expect(ptr.b[1].field == 0); | |
| 345 | expect(ptr.c == 0); | |
| 346 | ||
| 347 | ptr.b[1].field = maxInt(u24); | |
| 348 | expect(ptr.a == maxInt(u16)); | |
| 349 | expect(ptr.b[0].field == maxInt(u24)); | |
| 350 | expect(ptr.b[1].field == maxInt(u24)); | |
| 351 | expect(ptr.c == 0); | |
| 352 | ||
| 353 | ptr.c = maxInt(u16); | |
| 354 | expect(ptr.a == maxInt(u16)); | |
| 355 | expect(ptr.b[0].field == maxInt(u24)); | |
| 356 | expect(ptr.b[1].field == maxInt(u24)); | |
| 357 | expect(ptr.c == maxInt(u16)); | |
| 358 | ||
| 359 | expect(bytes[bytes.len - 1] == 0xaa); | |
| 360 | } | |
| 361 | ||
| 362 | const FooStructAligned = packed struct { | |
| 363 | a: u8, | |
| 364 | b: u8, | |
| 365 | }; | |
| 366 | ||
| 367 | const FooArrayOfAligned = packed struct { | |
| 368 | a: [2]FooStructAligned, | |
| 369 | }; | |
| 370 | ||
| 371 | test "aligned array of packed struct" { | |
| 372 | comptime { | |
| 373 | expect(@sizeOf(FooStructAligned) == 2); | |
| 374 | expect(@sizeOf(FooArrayOfAligned) == 2 * 2); | |
| 375 | } | |
| 376 | ||
| 377 | var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned); | |
| 378 | const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0]; | |
| 379 | ||
| 380 | expect(ptr.a[0].a == 0xbb); | |
| 381 | expect(ptr.a[0].b == 0xbb); | |
| 382 | expect(ptr.a[1].a == 0xbb); | |
| 383 | expect(ptr.a[1].b == 0xbb); | |
| 384 | } | |
| 385 | ||
| 386 | test "runtime struct initialization of bitfield" { | |
| 387 | const s1 = Nibbles{ | |
| 388 | .x = x1, | |
| 389 | .y = x1, | |
| 390 | }; | |
| 391 | const s2 = Nibbles{ | |
| 392 | .x = @intCast(u4, x2), | |
| 393 | .y = @intCast(u4, x2), | |
| 394 | }; | |
| 395 | ||
| 396 | expect(s1.x == x1); | |
| 397 | expect(s1.y == x1); | |
| 398 | expect(s2.x == @intCast(u4, x2)); | |
| 399 | expect(s2.y == @intCast(u4, x2)); | |
| 400 | } | |
| 401 | ||
| 402 | var x1 = @as(u4, 1); | |
| 403 | var x2 = @as(u8, 2); | |
| 404 | ||
| 405 | const Nibbles = packed struct { | |
| 406 | x: u4, | |
| 407 | y: u4, | |
| 408 | }; | |
| 409 | ||
| 410 | const Bitfields = packed struct { | |
| 411 | f1: u16, | |
| 412 | f2: u16, | |
| 413 | f3: u8, | |
| 414 | f4: u8, | |
| 415 | f5: u4, | |
| 416 | f6: u4, | |
| 417 | f7: u8, | |
| 418 | }; | |
| 419 | ||
| 420 | test "native bit field understands endianness" { | |
| 421 | var all: u64 = if (native_endian != .Little) | |
| 422 | 0x1111222233445677 | |
| 423 | else | |
| 424 | 0x7765443322221111; | |
| 425 | var bytes: [8]u8 = undefined; | |
| 426 | @memcpy(&bytes, @ptrCast([*]u8, &all), 8); | |
| 427 | var bitfields = @ptrCast(*Bitfields, &bytes).*; | |
| 428 | ||
| 429 | expect(bitfields.f1 == 0x1111); | |
| 430 | expect(bitfields.f2 == 0x2222); | |
| 431 | expect(bitfields.f3 == 0x33); | |
| 432 | expect(bitfields.f4 == 0x44); | |
| 433 | expect(bitfields.f5 == 0x5); | |
| 434 | expect(bitfields.f6 == 0x6); | |
| 435 | expect(bitfields.f7 == 0x77); | |
| 436 | } | |
| 437 | ||
| 438 | test "align 1 field before self referential align 8 field as slice return type" { | |
| 439 | const result = alloc(Expr); | |
| 440 | expect(result.len == 0); | |
| 441 | } | |
| 442 | ||
| 443 | const Expr = union(enum) { | |
| 444 | Literal: u8, | |
| 445 | Question: *Expr, | |
| 446 | }; | |
| 447 | ||
| 448 | fn alloc(comptime T: type) []T { | |
| 449 | return &[_]T{}; | |
| 450 | } | |
| 451 | ||
| 452 | test "call method with mutable reference to struct with no fields" { | |
| 453 | const S = struct { | |
| 454 | fn doC(s: *const @This()) bool { | |
| 455 | return true; | |
| 456 | } | |
| 457 | fn do(s: *@This()) bool { | |
| 458 | return true; | |
| 459 | } | |
| 460 | }; | |
| 461 | ||
| 462 | var s = S{}; | |
| 463 | expect(S.doC(&s)); | |
| 464 | expect(s.doC()); | |
| 465 | expect(S.do(&s)); | |
| 466 | expect(s.do()); | |
| 467 | } | |
| 468 | ||
| 469 | test "implicit cast packed struct field to const ptr" { | |
| 470 | const LevelUpMove = packed struct { | |
| 471 | move_id: u9, | |
| 472 | level: u7, | |
| 473 | ||
| 474 | fn toInt(value: u7) u7 { | |
| 475 | return value; | |
| 476 | } | |
| 477 | }; | |
| 478 | ||
| 479 | var lup: LevelUpMove = undefined; | |
| 480 | lup.level = 12; | |
| 481 | const res = LevelUpMove.toInt(lup.level); | |
| 482 | expect(res == 12); | |
| 483 | } | |
| 484 | ||
| 485 | test "pointer to packed struct member in a stack variable" { | |
| 486 | const S = packed struct { | |
| 487 | a: u2, | |
| 488 | b: u2, | |
| 489 | }; | |
| 490 | ||
| 491 | var s = S{ .a = 2, .b = 0 }; | |
| 492 | var b_ptr = &s.b; | |
| 493 | expect(s.b == 0); | |
| 494 | b_ptr.* = 2; | |
| 495 | expect(s.b == 2); | |
| 496 | } | |
| 497 | ||
| 498 | test "non-byte-aligned array inside packed struct" { | |
| 499 | const Foo = packed struct { | |
| 500 | a: bool, | |
| 501 | b: [0x16]u8, | |
| 502 | }; | |
| 503 | const S = struct { | |
| 504 | fn bar(slice: []const u8) void { | |
| 505 | expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu"); | |
| 506 | } | |
| 507 | fn doTheTest() void { | |
| 508 | var foo = Foo{ | |
| 509 | .a = true, | |
| 510 | .b = "abcdefghijklmnopqurstu".*, | |
| 511 | }; | |
| 512 | const value = foo.b; | |
| 513 | bar(&value); | |
| 514 | } | |
| 515 | }; | |
| 516 | S.doTheTest(); | |
| 517 | comptime S.doTheTest(); | |
| 518 | } | |
| 519 | ||
| 520 | test "packed struct with u0 field access" { | |
| 521 | const S = packed struct { | |
| 522 | f0: u0, | |
| 523 | }; | |
| 524 | var s = S{ .f0 = 0 }; | |
| 525 | comptime expect(s.f0 == 0); | |
| 526 | } | |
| 527 | ||
| 528 | const S0 = struct { | |
| 529 | bar: S1, | |
| 530 | ||
| 531 | pub const S1 = struct { | |
| 532 | value: u8, | |
| 533 | }; | |
| 534 | ||
| 535 | fn init() @This() { | |
| 536 | return S0{ .bar = S1{ .value = 123 } }; | |
| 537 | } | |
| 538 | }; | |
| 539 | ||
| 540 | var g_foo: S0 = S0.init(); | |
| 541 | ||
| 542 | test "access to global struct fields" { | |
| 543 | g_foo.bar.value = 42; | |
| 544 | expect(g_foo.bar.value == 42); | |
| 545 | } | |
| 546 | ||
| 547 | test "packed struct with fp fields" { | |
| 548 | const S = packed struct { | |
| 549 | data: [3]f32, | |
| 550 | ||
| 551 | pub fn frob(self: *@This()) void { | |
| 552 | self.data[0] += self.data[1] + self.data[2]; | |
| 553 | self.data[1] += self.data[0] + self.data[2]; | |
| 554 | self.data[2] += self.data[0] + self.data[1]; | |
| 555 | } | |
| 556 | }; | |
| 557 | ||
| 558 | var s: S = undefined; | |
| 559 | s.data[0] = 1.0; | |
| 560 | s.data[1] = 2.0; | |
| 561 | s.data[2] = 3.0; | |
| 562 | s.frob(); | |
| 563 | expectEqual(@as(f32, 6.0), s.data[0]); | |
| 564 | expectEqual(@as(f32, 11.0), s.data[1]); | |
| 565 | expectEqual(@as(f32, 20.0), s.data[2]); | |
| 566 | } | |
| 567 | ||
| 568 | test "use within struct scope" { | |
| 569 | const S = struct { | |
| 570 | usingnamespace struct { | |
| 571 | pub fn inner() i32 { | |
| 572 | return 42; | |
| 573 | } | |
| 574 | }; | |
| 575 | }; | |
| 576 | expectEqual(@as(i32, 42), S.inner()); | |
| 577 | } | |
| 578 | ||
| 579 | test "default struct initialization fields" { | |
| 580 | const S = struct { | |
| 581 | a: i32 = 1234, | |
| 582 | b: i32, | |
| 583 | }; | |
| 584 | const x = S{ | |
| 585 | .b = 5, | |
| 586 | }; | |
| 587 | if (x.a + x.b != 1239) { | |
| 588 | @compileError("it should be comptime known"); | |
| 589 | } | |
| 590 | var five: i32 = 5; | |
| 591 | const y = S{ | |
| 592 | .b = five, | |
| 593 | }; | |
| 594 | expectEqual(1239, x.a + x.b); | |
| 595 | } | |
| 596 | ||
| 597 | test "fn with C calling convention returns struct by value" { | |
| 598 | const S = struct { | |
| 599 | fn entry() void { | |
| 600 | var x = makeBar(10); | |
| 601 | expectEqual(@as(i32, 10), x.handle); | |
| 602 | } | |
| 603 | ||
| 604 | const ExternBar = extern struct { | |
| 605 | handle: i32, | |
| 606 | }; | |
| 607 | ||
| 608 | fn makeBar(t: i32) callconv(.C) ExternBar { | |
| 609 | return ExternBar{ | |
| 610 | .handle = t, | |
| 611 | }; | |
| 612 | } | |
| 613 | }; | |
| 614 | S.entry(); | |
| 615 | comptime S.entry(); | |
| 616 | } | |
| 617 | ||
| 618 | test "for loop over pointers to struct, getting field from struct pointer" { | |
| 619 | const S = struct { | |
| 620 | const Foo = struct { | |
| 621 | name: []const u8, | |
| 622 | }; | |
| 623 | ||
| 624 | var ok = true; | |
| 625 | ||
| 626 | fn eql(a: []const u8) bool { | |
| 627 | return true; | |
| 628 | } | |
| 629 | ||
| 630 | const ArrayList = struct { | |
| 631 | fn toSlice(self: *ArrayList) []*Foo { | |
| 632 | return @as([*]*Foo, undefined)[0..0]; | |
| 633 | } | |
| 634 | }; | |
| 635 | ||
| 636 | fn doTheTest() void { | |
| 637 | var objects: ArrayList = undefined; | |
| 638 | ||
| 639 | for (objects.toSlice()) |obj| { | |
| 640 | if (eql(obj.name)) { | |
| 641 | ok = false; | |
| 642 | } | |
| 643 | } | |
| 644 | ||
| 645 | expect(ok); | |
| 646 | } | |
| 647 | }; | |
| 648 | S.doTheTest(); | |
| 649 | } | |
| 650 | ||
| 651 | test "zero-bit field in packed struct" { | |
| 652 | const S = packed struct { | |
| 653 | x: u10, | |
| 654 | y: void, | |
| 655 | }; | |
| 656 | var x: S = undefined; | |
| 657 | } | |
| 658 | ||
| 659 | test "struct field init with catch" { | |
| 660 | const S = struct { | |
| 661 | fn doTheTest() void { | |
| 662 | var x: anyerror!isize = 1; | |
| 663 | var req = Foo{ | |
| 664 | .field = x catch undefined, | |
| 665 | }; | |
| 666 | expect(req.field == 1); | |
| 667 | } | |
| 668 | ||
| 669 | pub const Foo = extern struct { | |
| 670 | field: isize, | |
| 671 | }; | |
| 672 | }; | |
| 673 | S.doTheTest(); | |
| 674 | comptime S.doTheTest(); | |
| 675 | } | |
| 676 | ||
| 677 | test "packed struct with non-ABI-aligned field" { | |
| 678 | const S = packed struct { | |
| 679 | x: u9, | |
| 680 | y: u183, | |
| 681 | }; | |
| 682 | var s: S = undefined; | |
| 683 | s.x = 1; | |
| 684 | s.y = 42; | |
| 685 | expect(s.x == 1); | |
| 686 | expect(s.y == 42); | |
| 687 | } | |
| 688 | ||
| 689 | test "non-packed struct with u128 entry in union" { | |
| 690 | const U = union(enum) { | |
| 691 | Num: u128, | |
| 692 | Void, | |
| 693 | }; | |
| 694 | ||
| 695 | const S = struct { | |
| 696 | f1: U, | |
| 697 | f2: U, | |
| 698 | }; | |
| 699 | ||
| 700 | var sx: S = undefined; | |
| 701 | var s = &sx; | |
| 702 | std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @byteOffsetOf(S, "f2")); | |
| 703 | var v2 = U{ .Num = 123 }; | |
| 704 | s.f2 = v2; | |
| 705 | std.testing.expect(s.f2.Num == 123); | |
| 706 | } | |
| 707 | ||
| 708 | test "packed struct field passed to generic function" { | |
| 709 | const S = struct { | |
| 710 | const P = packed struct { | |
| 711 | b: u5, | |
| 712 | g: u5, | |
| 713 | r: u5, | |
| 714 | a: u1, | |
| 715 | }; | |
| 716 | ||
| 717 | fn genericReadPackedField(ptr: anytype) u5 { | |
| 718 | return ptr.*; | |
| 719 | } | |
| 720 | }; | |
| 721 | ||
| 722 | var p: S.P = undefined; | |
| 723 | p.b = 29; | |
| 724 | var loaded = S.genericReadPackedField(&p.b); | |
| 725 | expect(loaded == 29); | |
| 726 | } | |
| 727 | ||
| 728 | test "anonymous struct literal syntax" { | |
| 729 | const S = struct { | |
| 730 | const Point = struct { | |
| 731 | x: i32, | |
| 732 | y: i32, | |
| 733 | }; | |
| 734 | ||
| 735 | fn doTheTest() void { | |
| 736 | var p: Point = .{ | |
| 737 | .x = 1, | |
| 738 | .y = 2, | |
| 739 | }; | |
| 740 | expect(p.x == 1); | |
| 741 | expect(p.y == 2); | |
| 742 | } | |
| 743 | }; | |
| 744 | S.doTheTest(); | |
| 745 | comptime S.doTheTest(); | |
| 746 | } | |
| 747 | ||
| 748 | test "fully anonymous struct" { | |
| 749 | const S = struct { | |
| 750 | fn doTheTest() void { | |
| 751 | dump(.{ | |
| 752 | .int = @as(u32, 1234), | |
| 753 | .float = @as(f64, 12.34), | |
| 754 | .b = true, | |
| 755 | .s = "hi", | |
| 756 | }); | |
| 757 | } | |
| 758 | fn dump(args: anytype) void { | |
| 759 | expect(args.int == 1234); | |
| 760 | expect(args.float == 12.34); | |
| 761 | expect(args.b); | |
| 762 | expect(args.s[0] == 'h'); | |
| 763 | expect(args.s[1] == 'i'); | |
| 764 | } | |
| 765 | }; | |
| 766 | S.doTheTest(); | |
| 767 | comptime S.doTheTest(); | |
| 768 | } | |
| 769 | ||
| 770 | test "fully anonymous list literal" { | |
| 771 | const S = struct { | |
| 772 | fn doTheTest() void { | |
| 773 | dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); | |
| 774 | } | |
| 775 | fn dump(args: anytype) void { | |
| 776 | expect(args.@"0" == 1234); | |
| 777 | expect(args.@"1" == 12.34); | |
| 778 | expect(args.@"2"); | |
| 779 | expect(args.@"3"[0] == 'h'); | |
| 780 | expect(args.@"3"[1] == 'i'); | |
| 781 | } | |
| 782 | }; | |
| 783 | S.doTheTest(); | |
| 784 | comptime S.doTheTest(); | |
| 785 | } | |
| 786 | ||
| 787 | test "anonymous struct literal assigned to variable" { | |
| 788 | var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) }; | |
| 789 | expect(vec.@"0" == 22); | |
| 790 | expect(vec.@"1" == 55); | |
| 791 | expect(vec.@"2" == 99); | |
| 792 | } | |
| 793 | ||
| 794 | test "struct with var field" { | |
| 795 | const Point = struct { | |
| 796 | x: anytype, | |
| 797 | y: anytype, | |
| 798 | }; | |
| 799 | const pt = Point{ | |
| 800 | .x = 1, | |
| 801 | .y = 2, | |
| 802 | }; | |
| 803 | expect(pt.x == 1); | |
| 804 | expect(pt.y == 2); | |
| 805 | } | |
| 806 | ||
| 807 | test "comptime struct field" { | |
| 808 | const T = struct { | |
| 809 | a: i32, | |
| 810 | comptime b: i32 = 1234, | |
| 811 | }; | |
| 812 | ||
| 813 | var foo: T = undefined; | |
| 814 | comptime expect(foo.b == 1234); | |
| 815 | } | |
| 816 | ||
| 817 | test "anon struct literal field value initialized with fn call" { | |
| 818 | const S = struct { | |
| 819 | fn doTheTest() void { | |
| 820 | var x = .{foo()}; | |
| 821 | expectEqualSlices(u8, x[0], "hi"); | |
| 822 | } | |
| 823 | fn foo() []const u8 { | |
| 824 | return "hi"; | |
| 825 | } | |
| 826 | }; | |
| 827 | S.doTheTest(); | |
| 828 | comptime S.doTheTest(); | |
| 829 | } | |
| 830 | ||
| 831 | test "self-referencing struct via array member" { | |
| 832 | const T = struct { | |
| 833 | children: [1]*@This(), | |
| 834 | }; | |
| 835 | var x: T = undefined; | |
| 836 | x = T{ .children = .{&x} }; | |
| 837 | expect(x.children[0] == &x); | |
| 838 | } | |
| 839 | ||
| 840 | test "struct with union field" { | |
| 841 | const Value = struct { | |
| 842 | ref: u32 = 2, | |
| 843 | kind: union(enum) { | |
| 844 | None: usize, | |
| 845 | Bool: bool, | |
| 846 | }, | |
| 847 | }; | |
| 848 | ||
| 849 | var True = Value{ | |
| 850 | .kind = .{ .Bool = true }, | |
| 851 | }; | |
| 852 | expectEqual(@as(u32, 2), True.ref); | |
| 853 | expectEqual(true, True.kind.Bool); | |
| 854 | } | |
| 855 | ||
| 856 | test "type coercion of anon struct literal to struct" { | |
| 857 | const S = struct { | |
| 858 | const S2 = struct { | |
| 859 | A: u32, | |
| 860 | B: []const u8, | |
| 861 | C: void, | |
| 862 | D: Foo = .{}, | |
| 863 | }; | |
| 864 | ||
| 865 | const Foo = struct { | |
| 866 | field: i32 = 1234, | |
| 867 | }; | |
| 868 | ||
| 869 | fn doTheTest() void { | |
| 870 | var y: u32 = 42; | |
| 871 | const t0 = .{ .A = 123, .B = "foo", .C = {} }; | |
| 872 | const t1 = .{ .A = y, .B = "foo", .C = {} }; | |
| 873 | const y0: S2 = t0; | |
| 874 | var y1: S2 = t1; | |
| 875 | expect(y0.A == 123); | |
| 876 | expect(std.mem.eql(u8, y0.B, "foo")); | |
| 877 | expect(y0.C == {}); | |
| 878 | expect(y0.D.field == 1234); | |
| 879 | expect(y1.A == y); | |
| 880 | expect(std.mem.eql(u8, y1.B, "foo")); | |
| 881 | expect(y1.C == {}); | |
| 882 | expect(y1.D.field == 1234); | |
| 883 | } | |
| 884 | }; | |
| 885 | S.doTheTest(); | |
| 886 | comptime S.doTheTest(); | |
| 887 | } | |
| 888 | ||
| 889 | test "type coercion of pointer to anon struct literal to pointer to struct" { | |
| 890 | const S = struct { | |
| 891 | const S2 = struct { | |
| 892 | A: u32, | |
| 893 | B: []const u8, | |
| 894 | C: void, | |
| 895 | D: Foo = .{}, | |
| 896 | }; | |
| 897 | ||
| 898 | const Foo = struct { | |
| 899 | field: i32 = 1234, | |
| 900 | }; | |
| 901 | ||
| 902 | fn doTheTest() void { | |
| 903 | var y: u32 = 42; | |
| 904 | const t0 = &.{ .A = 123, .B = "foo", .C = {} }; | |
| 905 | const t1 = &.{ .A = y, .B = "foo", .C = {} }; | |
| 906 | const y0: *const S2 = t0; | |
| 907 | var y1: *const S2 = t1; | |
| 908 | expect(y0.A == 123); | |
| 909 | expect(std.mem.eql(u8, y0.B, "foo")); | |
| 910 | expect(y0.C == {}); | |
| 911 | expect(y0.D.field == 1234); | |
| 912 | expect(y1.A == y); | |
| 913 | expect(std.mem.eql(u8, y1.B, "foo")); | |
| 914 | expect(y1.C == {}); | |
| 915 | expect(y1.D.field == 1234); | |
| 916 | } | |
| 917 | }; | |
| 918 | S.doTheTest(); | |
| 919 | comptime S.doTheTest(); | |
| 920 | } | |
| 921 | ||
| 922 | test "packed struct with undefined initializers" { | |
| 923 | const S = struct { | |
| 924 | const P = packed struct { | |
| 925 | a: u3, | |
| 926 | _a: u3 = undefined, | |
| 927 | b: u3, | |
| 928 | _b: u3 = undefined, | |
| 929 | c: u3, | |
| 930 | _c: u3 = undefined, | |
| 931 | }; | |
| 932 | ||
| 933 | fn doTheTest() void { | |
| 934 | var p: P = undefined; | |
| 935 | p = P{ .a = 2, .b = 4, .c = 6 }; | |
| 936 | // Make sure the compiler doesn't touch the unprefixed fields. | |
| 937 | expectEqual(@as(u3, 2), p.a); | |
| 938 | expectEqual(@as(u3, 4), p.b); | |
| 939 | expectEqual(@as(u3, 6), p.c); | |
| 940 | } | |
| 941 | }; | |
| 942 | ||
| 943 | S.doTheTest(); | |
| 944 | comptime S.doTheTest(); | |
| 945 | } |
test/stage1/behavior/struct_contains_null_ptr_itself.zig deleted-21| ... | ... | @@ -1,21 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "struct contains null pointer which contains original struct" { | |
| 5 | var x: ?*NodeLineComment = null; | |
| 6 | expect(x == null); | |
| 7 | } | |
| 8 | ||
| 9 | pub const Node = struct { | |
| 10 | id: Id, | |
| 11 | comment: ?*NodeLineComment, | |
| 12 | ||
| 13 | pub const Id = enum { | |
| 14 | Root, | |
| 15 | LineComment, | |
| 16 | }; | |
| 17 | }; | |
| 18 | ||
| 19 | pub const NodeLineComment = struct { | |
| 20 | base: Node, | |
| 21 | }; |
test/stage1/behavior/struct_contains_slice_of_itself.zig deleted-85| ... | ... | @@ -1,85 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Node = struct { | |
| 4 | payload: i32, | |
| 5 | children: []Node, | |
| 6 | }; | |
| 7 | ||
| 8 | const NodeAligned = struct { | |
| 9 | payload: i32, | |
| 10 | children: []align(@alignOf(NodeAligned)) NodeAligned, | |
| 11 | }; | |
| 12 | ||
| 13 | test "struct contains slice of itself" { | |
| 14 | var other_nodes = [_]Node{ | |
| 15 | Node{ | |
| 16 | .payload = 31, | |
| 17 | .children = &[_]Node{}, | |
| 18 | }, | |
| 19 | Node{ | |
| 20 | .payload = 32, | |
| 21 | .children = &[_]Node{}, | |
| 22 | }, | |
| 23 | }; | |
| 24 | var nodes = [_]Node{ | |
| 25 | Node{ | |
| 26 | .payload = 1, | |
| 27 | .children = &[_]Node{}, | |
| 28 | }, | |
| 29 | Node{ | |
| 30 | .payload = 2, | |
| 31 | .children = &[_]Node{}, | |
| 32 | }, | |
| 33 | Node{ | |
| 34 | .payload = 3, | |
| 35 | .children = other_nodes[0..], | |
| 36 | }, | |
| 37 | }; | |
| 38 | const root = Node{ | |
| 39 | .payload = 1234, | |
| 40 | .children = nodes[0..], | |
| 41 | }; | |
| 42 | expect(root.payload == 1234); | |
| 43 | expect(root.children[0].payload == 1); | |
| 44 | expect(root.children[1].payload == 2); | |
| 45 | expect(root.children[2].payload == 3); | |
| 46 | expect(root.children[2].children[0].payload == 31); | |
| 47 | expect(root.children[2].children[1].payload == 32); | |
| 48 | } | |
| 49 | ||
| 50 | test "struct contains aligned slice of itself" { | |
| 51 | var other_nodes = [_]NodeAligned{ | |
| 52 | NodeAligned{ | |
| 53 | .payload = 31, | |
| 54 | .children = &[_]NodeAligned{}, | |
| 55 | }, | |
| 56 | NodeAligned{ | |
| 57 | .payload = 32, | |
| 58 | .children = &[_]NodeAligned{}, | |
| 59 | }, | |
| 60 | }; | |
| 61 | var nodes = [_]NodeAligned{ | |
| 62 | NodeAligned{ | |
| 63 | .payload = 1, | |
| 64 | .children = &[_]NodeAligned{}, | |
| 65 | }, | |
| 66 | NodeAligned{ | |
| 67 | .payload = 2, | |
| 68 | .children = &[_]NodeAligned{}, | |
| 69 | }, | |
| 70 | NodeAligned{ | |
| 71 | .payload = 3, | |
| 72 | .children = other_nodes[0..], | |
| 73 | }, | |
| 74 | }; | |
| 75 | const root = NodeAligned{ | |
| 76 | .payload = 1234, | |
| 77 | .children = nodes[0..], | |
| 78 | }; | |
| 79 | expect(root.payload == 1234); | |
| 80 | expect(root.children[0].payload == 1); | |
| 81 | expect(root.children[1].payload == 2); | |
| 82 | expect(root.children[2].payload == 3); | |
| 83 | expect(root.children[2].children[0].payload == 31); | |
| 84 | expect(root.children[2].children[1].payload == 32); | |
| 85 | } |
test/stage1/behavior/switch.zig deleted-537| ... | ... | @@ -1,537 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectError = std.testing.expectError; | |
| 4 | const expectEqual = std.testing.expectEqual; | |
| 5 | ||
| 6 | test "switch with numbers" { | |
| 7 | testSwitchWithNumbers(13); | |
| 8 | } | |
| 9 | ||
| 10 | fn testSwitchWithNumbers(x: u32) void { | |
| 11 | const result = switch (x) { | |
| 12 | 1, 2, 3, 4...8 => false, | |
| 13 | 13 => true, | |
| 14 | else => false, | |
| 15 | }; | |
| 16 | expect(result); | |
| 17 | } | |
| 18 | ||
| 19 | test "switch with all ranges" { | |
| 20 | expect(testSwitchWithAllRanges(50, 3) == 1); | |
| 21 | expect(testSwitchWithAllRanges(101, 0) == 2); | |
| 22 | expect(testSwitchWithAllRanges(300, 5) == 3); | |
| 23 | expect(testSwitchWithAllRanges(301, 6) == 6); | |
| 24 | } | |
| 25 | ||
| 26 | fn testSwitchWithAllRanges(x: u32, y: u32) u32 { | |
| 27 | return switch (x) { | |
| 28 | 0...100 => 1, | |
| 29 | 101...200 => 2, | |
| 30 | 201...300 => 3, | |
| 31 | else => y, | |
| 32 | }; | |
| 33 | } | |
| 34 | ||
| 35 | test "implicit comptime switch" { | |
| 36 | const x = 3 + 4; | |
| 37 | const result = switch (x) { | |
| 38 | 3 => 10, | |
| 39 | 4 => 11, | |
| 40 | 5, 6 => 12, | |
| 41 | 7, 8 => 13, | |
| 42 | else => 14, | |
| 43 | }; | |
| 44 | ||
| 45 | comptime { | |
| 46 | expect(result + 1 == 14); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | test "switch on enum" { | |
| 51 | const fruit = Fruit.Orange; | |
| 52 | nonConstSwitchOnEnum(fruit); | |
| 53 | } | |
| 54 | const Fruit = enum { | |
| 55 | Apple, | |
| 56 | Orange, | |
| 57 | Banana, | |
| 58 | }; | |
| 59 | fn nonConstSwitchOnEnum(fruit: Fruit) void { | |
| 60 | switch (fruit) { | |
| 61 | Fruit.Apple => unreachable, | |
| 62 | Fruit.Orange => {}, | |
| 63 | Fruit.Banana => unreachable, | |
| 64 | } | |
| 65 | } | |
| 66 | ||
| 67 | test "switch statement" { | |
| 68 | nonConstSwitch(SwitchStatmentFoo.C); | |
| 69 | } | |
| 70 | fn nonConstSwitch(foo: SwitchStatmentFoo) void { | |
| 71 | const val = switch (foo) { | |
| 72 | SwitchStatmentFoo.A => @as(i32, 1), | |
| 73 | SwitchStatmentFoo.B => 2, | |
| 74 | SwitchStatmentFoo.C => 3, | |
| 75 | SwitchStatmentFoo.D => 4, | |
| 76 | }; | |
| 77 | expect(val == 3); | |
| 78 | } | |
| 79 | const SwitchStatmentFoo = enum { | |
| 80 | A, | |
| 81 | B, | |
| 82 | C, | |
| 83 | D, | |
| 84 | }; | |
| 85 | ||
| 86 | test "switch prong with variable" { | |
| 87 | switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 }); | |
| 88 | switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 }); | |
| 89 | switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} }); | |
| 90 | } | |
| 91 | const SwitchProngWithVarEnum = union(enum) { | |
| 92 | One: i32, | |
| 93 | Two: f32, | |
| 94 | Meh: void, | |
| 95 | }; | |
| 96 | fn switchProngWithVarFn(a: SwitchProngWithVarEnum) void { | |
| 97 | switch (a) { | |
| 98 | SwitchProngWithVarEnum.One => |x| { | |
| 99 | expect(x == 13); | |
| 100 | }, | |
| 101 | SwitchProngWithVarEnum.Two => |x| { | |
| 102 | expect(x == 13.0); | |
| 103 | }, | |
| 104 | SwitchProngWithVarEnum.Meh => |x| { | |
| 105 | const v: void = x; | |
| 106 | }, | |
| 107 | } | |
| 108 | } | |
| 109 | ||
| 110 | test "switch on enum using pointer capture" { | |
| 111 | testSwitchEnumPtrCapture(); | |
| 112 | comptime testSwitchEnumPtrCapture(); | |
| 113 | } | |
| 114 | ||
| 115 | fn testSwitchEnumPtrCapture() void { | |
| 116 | var value = SwitchProngWithVarEnum{ .One = 1234 }; | |
| 117 | switch (value) { | |
| 118 | SwitchProngWithVarEnum.One => |*x| x.* += 1, | |
| 119 | else => unreachable, | |
| 120 | } | |
| 121 | switch (value) { | |
| 122 | SwitchProngWithVarEnum.One => |x| expect(x == 1235), | |
| 123 | else => unreachable, | |
| 124 | } | |
| 125 | } | |
| 126 | ||
| 127 | test "switch with multiple expressions" { | |
| 128 | const x = switch (returnsFive()) { | |
| 129 | 1, 2, 3 => 1, | |
| 130 | 4, 5, 6 => 2, | |
| 131 | else => @as(i32, 3), | |
| 132 | }; | |
| 133 | expect(x == 2); | |
| 134 | } | |
| 135 | fn returnsFive() i32 { | |
| 136 | return 5; | |
| 137 | } | |
| 138 | ||
| 139 | const Number = union(enum) { | |
| 140 | One: u64, | |
| 141 | Two: u8, | |
| 142 | Three: f32, | |
| 143 | }; | |
| 144 | ||
| 145 | const number = Number{ .Three = 1.23 }; | |
| 146 | ||
| 147 | fn returnsFalse() bool { | |
| 148 | switch (number) { | |
| 149 | Number.One => |x| return x > 1234, | |
| 150 | Number.Two => |x| return x == 'a', | |
| 151 | Number.Three => |x| return x > 12.34, | |
| 152 | } | |
| 153 | } | |
| 154 | test "switch on const enum with var" { | |
| 155 | expect(!returnsFalse()); | |
| 156 | } | |
| 157 | ||
| 158 | test "switch on type" { | |
| 159 | expect(trueIfBoolFalseOtherwise(bool)); | |
| 160 | expect(!trueIfBoolFalseOtherwise(i32)); | |
| 161 | } | |
| 162 | ||
| 163 | fn trueIfBoolFalseOtherwise(comptime T: type) bool { | |
| 164 | return switch (T) { | |
| 165 | bool => true, | |
| 166 | else => false, | |
| 167 | }; | |
| 168 | } | |
| 169 | ||
| 170 | test "switch handles all cases of number" { | |
| 171 | testSwitchHandleAllCases(); | |
| 172 | comptime testSwitchHandleAllCases(); | |
| 173 | } | |
| 174 | ||
| 175 | fn testSwitchHandleAllCases() void { | |
| 176 | expect(testSwitchHandleAllCasesExhaustive(0) == 3); | |
| 177 | expect(testSwitchHandleAllCasesExhaustive(1) == 2); | |
| 178 | expect(testSwitchHandleAllCasesExhaustive(2) == 1); | |
| 179 | expect(testSwitchHandleAllCasesExhaustive(3) == 0); | |
| 180 | ||
| 181 | expect(testSwitchHandleAllCasesRange(100) == 0); | |
| 182 | expect(testSwitchHandleAllCasesRange(200) == 1); | |
| 183 | expect(testSwitchHandleAllCasesRange(201) == 2); | |
| 184 | expect(testSwitchHandleAllCasesRange(202) == 4); | |
| 185 | expect(testSwitchHandleAllCasesRange(230) == 3); | |
| 186 | } | |
| 187 | ||
| 188 | fn testSwitchHandleAllCasesExhaustive(x: u2) u2 { | |
| 189 | return switch (x) { | |
| 190 | 0 => @as(u2, 3), | |
| 191 | 1 => 2, | |
| 192 | 2 => 1, | |
| 193 | 3 => 0, | |
| 194 | }; | |
| 195 | } | |
| 196 | ||
| 197 | fn testSwitchHandleAllCasesRange(x: u8) u8 { | |
| 198 | return switch (x) { | |
| 199 | 0...100 => @as(u8, 0), | |
| 200 | 101...200 => 1, | |
| 201 | 201, 203 => 2, | |
| 202 | 202 => 4, | |
| 203 | 204...255 => 3, | |
| 204 | }; | |
| 205 | } | |
| 206 | ||
| 207 | test "switch all prongs unreachable" { | |
| 208 | testAllProngsUnreachable(); | |
| 209 | comptime testAllProngsUnreachable(); | |
| 210 | } | |
| 211 | ||
| 212 | fn testAllProngsUnreachable() void { | |
| 213 | expect(switchWithUnreachable(1) == 2); | |
| 214 | expect(switchWithUnreachable(2) == 10); | |
| 215 | } | |
| 216 | ||
| 217 | fn switchWithUnreachable(x: i32) i32 { | |
| 218 | while (true) { | |
| 219 | switch (x) { | |
| 220 | 1 => return 2, | |
| 221 | 2 => break, | |
| 222 | else => continue, | |
| 223 | } | |
| 224 | } | |
| 225 | return 10; | |
| 226 | } | |
| 227 | ||
| 228 | fn return_a_number() anyerror!i32 { | |
| 229 | return 1; | |
| 230 | } | |
| 231 | ||
| 232 | test "capture value of switch with all unreachable prongs" { | |
| 233 | const x = return_a_number() catch |err| switch (err) { | |
| 234 | else => unreachable, | |
| 235 | }; | |
| 236 | expect(x == 1); | |
| 237 | } | |
| 238 | ||
| 239 | test "switching on booleans" { | |
| 240 | testSwitchOnBools(); | |
| 241 | comptime testSwitchOnBools(); | |
| 242 | } | |
| 243 | ||
| 244 | fn testSwitchOnBools() void { | |
| 245 | expect(testSwitchOnBoolsTrueAndFalse(true) == false); | |
| 246 | expect(testSwitchOnBoolsTrueAndFalse(false) == true); | |
| 247 | ||
| 248 | expect(testSwitchOnBoolsTrueWithElse(true) == false); | |
| 249 | expect(testSwitchOnBoolsTrueWithElse(false) == true); | |
| 250 | ||
| 251 | expect(testSwitchOnBoolsFalseWithElse(true) == false); | |
| 252 | expect(testSwitchOnBoolsFalseWithElse(false) == true); | |
| 253 | } | |
| 254 | ||
| 255 | fn testSwitchOnBoolsTrueAndFalse(x: bool) bool { | |
| 256 | return switch (x) { | |
| 257 | true => false, | |
| 258 | false => true, | |
| 259 | }; | |
| 260 | } | |
| 261 | ||
| 262 | fn testSwitchOnBoolsTrueWithElse(x: bool) bool { | |
| 263 | return switch (x) { | |
| 264 | true => false, | |
| 265 | else => true, | |
| 266 | }; | |
| 267 | } | |
| 268 | ||
| 269 | fn testSwitchOnBoolsFalseWithElse(x: bool) bool { | |
| 270 | return switch (x) { | |
| 271 | false => true, | |
| 272 | else => false, | |
| 273 | }; | |
| 274 | } | |
| 275 | ||
| 276 | test "u0" { | |
| 277 | var val: u0 = 0; | |
| 278 | switch (val) { | |
| 279 | 0 => expect(val == 0), | |
| 280 | } | |
| 281 | } | |
| 282 | ||
| 283 | test "undefined.u0" { | |
| 284 | var val: u0 = undefined; | |
| 285 | switch (val) { | |
| 286 | 0 => expect(val == 0), | |
| 287 | } | |
| 288 | } | |
| 289 | ||
| 290 | test "anon enum literal used in switch on union enum" { | |
| 291 | const Foo = union(enum) { | |
| 292 | a: i32, | |
| 293 | }; | |
| 294 | ||
| 295 | var foo = Foo{ .a = 1234 }; | |
| 296 | switch (foo) { | |
| 297 | .a => |x| { | |
| 298 | expect(x == 1234); | |
| 299 | }, | |
| 300 | } | |
| 301 | } | |
| 302 | ||
| 303 | test "else prong of switch on error set excludes other cases" { | |
| 304 | const S = struct { | |
| 305 | fn doTheTest() void { | |
| 306 | expectError(error.C, bar()); | |
| 307 | } | |
| 308 | const E = error{ | |
| 309 | A, | |
| 310 | B, | |
| 311 | } || E2; | |
| 312 | ||
| 313 | const E2 = error{ | |
| 314 | C, | |
| 315 | D, | |
| 316 | }; | |
| 317 | ||
| 318 | fn foo() E!void { | |
| 319 | return error.C; | |
| 320 | } | |
| 321 | ||
| 322 | fn bar() E2!void { | |
| 323 | foo() catch |err| switch (err) { | |
| 324 | error.A, error.B => {}, | |
| 325 | else => |e| return e, | |
| 326 | }; | |
| 327 | } | |
| 328 | }; | |
| 329 | S.doTheTest(); | |
| 330 | comptime S.doTheTest(); | |
| 331 | } | |
| 332 | ||
| 333 | test "switch prongs with error set cases make a new error set type for capture value" { | |
| 334 | const S = struct { | |
| 335 | fn doTheTest() void { | |
| 336 | expectError(error.B, bar()); | |
| 337 | } | |
| 338 | const E = E1 || E2; | |
| 339 | ||
| 340 | const E1 = error{ | |
| 341 | A, | |
| 342 | B, | |
| 343 | }; | |
| 344 | ||
| 345 | const E2 = error{ | |
| 346 | C, | |
| 347 | D, | |
| 348 | }; | |
| 349 | ||
| 350 | fn foo() E!void { | |
| 351 | return error.B; | |
| 352 | } | |
| 353 | ||
| 354 | fn bar() E1!void { | |
| 355 | foo() catch |err| switch (err) { | |
| 356 | error.A, error.B => |e| return e, | |
| 357 | else => {}, | |
| 358 | }; | |
| 359 | } | |
| 360 | }; | |
| 361 | S.doTheTest(); | |
| 362 | comptime S.doTheTest(); | |
| 363 | } | |
| 364 | ||
| 365 | test "return result loc and then switch with range implicit casted to error union" { | |
| 366 | const S = struct { | |
| 367 | fn doTheTest() void { | |
| 368 | expect((func(0xb) catch unreachable) == 0xb); | |
| 369 | } | |
| 370 | fn func(d: u8) anyerror!u8 { | |
| 371 | return switch (d) { | |
| 372 | 0xa...0xf => d, | |
| 373 | else => unreachable, | |
| 374 | }; | |
| 375 | } | |
| 376 | }; | |
| 377 | S.doTheTest(); | |
| 378 | comptime S.doTheTest(); | |
| 379 | } | |
| 380 | ||
| 381 | test "switch with null and T peer types and inferred result location type" { | |
| 382 | const S = struct { | |
| 383 | fn doTheTest(c: u8) void { | |
| 384 | if (switch (c) { | |
| 385 | 0 => true, | |
| 386 | else => null, | |
| 387 | }) |v| { | |
| 388 | @panic("fail"); | |
| 389 | } | |
| 390 | } | |
| 391 | }; | |
| 392 | S.doTheTest(1); | |
| 393 | comptime S.doTheTest(1); | |
| 394 | } | |
| 395 | ||
| 396 | test "switch prongs with cases with identical payload types" { | |
| 397 | const Union = union(enum) { | |
| 398 | A: usize, | |
| 399 | B: isize, | |
| 400 | C: usize, | |
| 401 | }; | |
| 402 | const S = struct { | |
| 403 | fn doTheTest() void { | |
| 404 | doTheSwitch1(Union{ .A = 8 }); | |
| 405 | doTheSwitch2(Union{ .B = -8 }); | |
| 406 | } | |
| 407 | fn doTheSwitch1(u: Union) void { | |
| 408 | switch (u) { | |
| 409 | .A, .C => |e| { | |
| 410 | expect(@TypeOf(e) == usize); | |
| 411 | expect(e == 8); | |
| 412 | }, | |
| 413 | .B => |e| @panic("fail"), | |
| 414 | } | |
| 415 | } | |
| 416 | fn doTheSwitch2(u: Union) void { | |
| 417 | switch (u) { | |
| 418 | .A, .C => |e| @panic("fail"), | |
| 419 | .B => |e| { | |
| 420 | expect(@TypeOf(e) == isize); | |
| 421 | expect(e == -8); | |
| 422 | }, | |
| 423 | } | |
| 424 | } | |
| 425 | }; | |
| 426 | S.doTheTest(); | |
| 427 | comptime S.doTheTest(); | |
| 428 | } | |
| 429 | ||
| 430 | test "switch with disjoint range" { | |
| 431 | var q: u8 = 0; | |
| 432 | switch (q) { | |
| 433 | 0...125 => {}, | |
| 434 | 127...255 => {}, | |
| 435 | 126...126 => {}, | |
| 436 | } | |
| 437 | } | |
| 438 | ||
| 439 | test "switch variable for range and multiple prongs" { | |
| 440 | const S = struct { | |
| 441 | fn doTheTest() void { | |
| 442 | var u: u8 = 16; | |
| 443 | doTheSwitch(u); | |
| 444 | comptime doTheSwitch(u); | |
| 445 | var v: u8 = 42; | |
| 446 | doTheSwitch(v); | |
| 447 | comptime doTheSwitch(v); | |
| 448 | } | |
| 449 | fn doTheSwitch(q: u8) void { | |
| 450 | switch (q) { | |
| 451 | 0...40 => |x| expect(x == 16), | |
| 452 | 41, 42, 43 => |x| expect(x == 42), | |
| 453 | else => expect(false), | |
| 454 | } | |
| 455 | } | |
| 456 | }; | |
| 457 | } | |
| 458 | ||
| 459 | var state: u32 = 0; | |
| 460 | fn poll() void { | |
| 461 | switch (state) { | |
| 462 | 0 => { | |
| 463 | state = 1; | |
| 464 | }, | |
| 465 | else => { | |
| 466 | state += 1; | |
| 467 | }, | |
| 468 | } | |
| 469 | } | |
| 470 | ||
| 471 | test "switch on global mutable var isn't constant-folded" { | |
| 472 | while (state < 2) { | |
| 473 | poll(); | |
| 474 | } | |
| 475 | } | |
| 476 | ||
| 477 | test "switch on pointer type" { | |
| 478 | const S = struct { | |
| 479 | const X = struct { | |
| 480 | field: u32, | |
| 481 | }; | |
| 482 | ||
| 483 | const P1 = @intToPtr(*X, 0x400); | |
| 484 | const P2 = @intToPtr(*X, 0x800); | |
| 485 | const P3 = @intToPtr(*X, 0xC00); | |
| 486 | ||
| 487 | fn doTheTest(arg: *X) i32 { | |
| 488 | switch (arg) { | |
| 489 | P1 => return 1, | |
| 490 | P2 => return 2, | |
| 491 | else => return 3, | |
| 492 | } | |
| 493 | } | |
| 494 | }; | |
| 495 | ||
| 496 | expect(1 == S.doTheTest(S.P1)); | |
| 497 | expect(2 == S.doTheTest(S.P2)); | |
| 498 | expect(3 == S.doTheTest(S.P3)); | |
| 499 | comptime expect(1 == S.doTheTest(S.P1)); | |
| 500 | comptime expect(2 == S.doTheTest(S.P2)); | |
| 501 | comptime expect(3 == S.doTheTest(S.P3)); | |
| 502 | } | |
| 503 | ||
| 504 | test "switch on error set with single else" { | |
| 505 | const S = struct { | |
| 506 | fn doTheTest() void { | |
| 507 | var some: error{Foo} = error.Foo; | |
| 508 | expect(switch (some) { | |
| 509 | else => |a| true, | |
| 510 | }); | |
| 511 | } | |
| 512 | }; | |
| 513 | ||
| 514 | S.doTheTest(); | |
| 515 | comptime S.doTheTest(); | |
| 516 | } | |
| 517 | ||
| 518 | test "while copies its payload" { | |
| 519 | const S = struct { | |
| 520 | fn doTheTest() void { | |
| 521 | var tmp: union(enum) { | |
| 522 | A: u8, | |
| 523 | B: u32, | |
| 524 | } = .{ .A = 42 }; | |
| 525 | switch (tmp) { | |
| 526 | .A => |value| { | |
| 527 | // Modify the original union | |
| 528 | tmp = .{ .B = 0x10101010 }; | |
| 529 | expectEqual(@as(u8, 42), value); | |
| 530 | }, | |
| 531 | else => unreachable, | |
| 532 | } | |
| 533 | } | |
| 534 | }; | |
| 535 | S.doTheTest(); | |
| 536 | comptime S.doTheTest(); | |
| 537 | } |
test/stage1/behavior/switch_prong_err_enum.zig deleted-30| ... | ... | @@ -1,30 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | var read_count: u64 = 0; | |
| 4 | ||
| 5 | fn readOnce() anyerror!u64 { | |
| 6 | read_count += 1; | |
| 7 | return read_count; | |
| 8 | } | |
| 9 | ||
| 10 | const FormValue = union(enum) { | |
| 11 | Address: u64, | |
| 12 | Other: bool, | |
| 13 | }; | |
| 14 | ||
| 15 | fn doThing(form_id: u64) anyerror!FormValue { | |
| 16 | return switch (form_id) { | |
| 17 | 17 => FormValue{ .Address = try readOnce() }, | |
| 18 | else => error.InvalidDebugInfo, | |
| 19 | }; | |
| 20 | } | |
| 21 | ||
| 22 | test "switch prong returns error enum" { | |
| 23 | switch (doThing(17) catch unreachable) { | |
| 24 | FormValue.Address => |payload| { | |
| 25 | expect(payload == 1); | |
| 26 | }, | |
| 27 | else => unreachable, | |
| 28 | } | |
| 29 | expect(read_count == 1); | |
| 30 | } |
test/stage1/behavior/switch_prong_implicit_cast.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const FormValue = union(enum) { | |
| 4 | One: void, | |
| 5 | Two: bool, | |
| 6 | }; | |
| 7 | ||
| 8 | fn foo(id: u64) !FormValue { | |
| 9 | return switch (id) { | |
| 10 | 2 => FormValue{ .Two = true }, | |
| 11 | 1 => FormValue{ .One = {} }, | |
| 12 | else => return error.Whatever, | |
| 13 | }; | |
| 14 | } | |
| 15 | ||
| 16 | test "switch prong implicit cast" { | |
| 17 | const result = switch (foo(2) catch unreachable) { | |
| 18 | FormValue.One => false, | |
| 19 | FormValue.Two => |x| x, | |
| 20 | }; | |
| 21 | expect(result); | |
| 22 | } |
test/stage1/behavior/syntax.zig deleted-68| ... | ... | @@ -1,68 +0,0 @@ |
| 1 | // Test trailing comma syntax | |
| 2 | // zig fmt: off | |
| 3 | ||
| 4 | extern var a: c_int; | |
| 5 | extern "c" var b: c_int; | |
| 6 | export var c: c_int = 0; | |
| 7 | threadlocal var d: c_int; | |
| 8 | extern threadlocal var e: c_int; | |
| 9 | extern "c" threadlocal var f: c_int; | |
| 10 | export threadlocal var g: c_int = 0; | |
| 11 | ||
| 12 | const struct_trailing_comma = struct { x: i32, y: i32, }; | |
| 13 | const struct_no_comma = struct { x: i32, y: i32 }; | |
| 14 | const struct_fn_no_comma = struct { fn m() void {} y: i32 }; | |
| 15 | ||
| 16 | const enum_no_comma = enum { A, B }; | |
| 17 | ||
| 18 | fn container_init() void { | |
| 19 | const S = struct { x: i32, y: i32 }; | |
| 20 | _ = S { .x = 1, .y = 2 }; | |
| 21 | _ = S { .x = 1, .y = 2, }; | |
| 22 | } | |
| 23 | ||
| 24 | fn type_expr_return1() if (true) A {} | |
| 25 | fn type_expr_return2() for (true) |_| A {} | |
| 26 | fn type_expr_return3() while (true) A {} | |
| 27 | fn type_expr_return4() comptime A {} | |
| 28 | ||
| 29 | fn switch_cases(x: i32) void { | |
| 30 | switch (x) { | |
| 31 | 1,2,3 => {}, | |
| 32 | 4,5, => {}, | |
| 33 | 6...8, => {}, | |
| 34 | else => {}, | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | fn switch_prongs(x: i32) void { | |
| 39 | switch (x) { | |
| 40 | 0 => {}, | |
| 41 | else => {}, | |
| 42 | } | |
| 43 | switch (x) { | |
| 44 | 0 => {}, | |
| 45 | else => {} | |
| 46 | } | |
| 47 | } | |
| 48 | ||
| 49 | const fn_no_comma = fn(i32, i32)void; | |
| 50 | const fn_trailing_comma = fn(i32, i32,)void; | |
| 51 | ||
| 52 | fn fn_calls() void { | |
| 53 | fn add(x: i32, y: i32,) i32 { x + y }; | |
| 54 | _ = add(1, 2); | |
| 55 | _ = add(1, 2,); | |
| 56 | } | |
| 57 | ||
| 58 | fn asm_lists() void { | |
| 59 | if (false) { // Build AST but don't analyze | |
| 60 | asm ("not real assembly" | |
| 61 | :[a] "x" (x),); | |
| 62 | asm ("not real assembly" | |
| 63 | :[a] "x" (->i32),:[a] "x" (1),); | |
| 64 | asm ("still not real assembly" | |
| 65 | :::"a","b",); | |
| 66 | } | |
| 67 | } | |
| 68 |
test/stage1/behavior/this.zig deleted-34| ... | ... | @@ -1,34 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const module = @This(); | |
| 4 | ||
| 5 | fn Point(comptime T: type) type { | |
| 6 | return struct { | |
| 7 | const Self = @This(); | |
| 8 | x: T, | |
| 9 | y: T, | |
| 10 | ||
| 11 | fn addOne(self: *Self) void { | |
| 12 | self.x += 1; | |
| 13 | self.y += 1; | |
| 14 | } | |
| 15 | }; | |
| 16 | } | |
| 17 | ||
| 18 | fn add(x: i32, y: i32) i32 { | |
| 19 | return x + y; | |
| 20 | } | |
| 21 | ||
| 22 | test "this refer to module call private fn" { | |
| 23 | expect(module.add(1, 2) == 3); | |
| 24 | } | |
| 25 | ||
| 26 | test "this refer to container" { | |
| 27 | var pt = Point(i32){ | |
| 28 | .x = 12, | |
| 29 | .y = 34, | |
| 30 | }; | |
| 31 | pt.addOne(); | |
| 32 | expect(pt.x == 13); | |
| 33 | expect(pt.y == 35); | |
| 34 | } |
test/stage1/behavior/translate_c_macros.h deleted-18| ... | ... | @@ -1,18 +0,0 @@ |
| 1 | // initializer list expression | |
| 2 | typedef struct Color { | |
| 3 | unsigned char r; | |
| 4 | unsigned char g; | |
| 5 | unsigned char b; | |
| 6 | unsigned char a; | |
| 7 | } Color; | |
| 8 | #define CLITERAL(type) (type) | |
| 9 | #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray | |
| 10 | ||
| 11 | #define MY_SIZEOF(x) ((int)sizeof(x)) | |
| 12 | #define MY_SIZEOF2(x) ((int)sizeof x) | |
| 13 | ||
| 14 | struct Foo { | |
| 15 | int a; | |
| 16 | }; | |
| 17 | ||
| 18 | #define SIZE_OF_FOO sizeof(struct Foo) |
test/stage1/behavior/translate_c_macros.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | const expectEqual = @import("std").testing.expectEqual; | |
| 3 | ||
| 4 | const h = @cImport(@cInclude("stage1/behavior/translate_c_macros.h")); | |
| 5 | ||
| 6 | test "initializer list expression" { | |
| 7 | expectEqual(h.Color{ | |
| 8 | .r = 200, | |
| 9 | .g = 200, | |
| 10 | .b = 200, | |
| 11 | .a = 255, | |
| 12 | }, h.LIGHTGRAY); | |
| 13 | } | |
| 14 | ||
| 15 | test "sizeof in macros" { | |
| 16 | expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF(u32)); | |
| 17 | expectEqual(@as(c_int, @sizeOf(u32)), h.MY_SIZEOF2(u32)); | |
| 18 | } | |
| 19 | ||
| 20 | test "reference to a struct type" { | |
| 21 | expectEqual(@sizeOf(h.struct_Foo), h.SIZE_OF_FOO); | |
| 22 | } |
test/stage1/behavior/truncate.zig deleted-36| ... | ... | @@ -1,36 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "truncate u0 to larger integer allowed and has comptime known result" { | |
| 5 | var x: u0 = 0; | |
| 6 | const y = @truncate(u8, x); | |
| 7 | comptime expect(y == 0); | |
| 8 | } | |
| 9 | ||
| 10 | test "truncate.u0.literal" { | |
| 11 | var z = @truncate(u0, 0); | |
| 12 | expect(z == 0); | |
| 13 | } | |
| 14 | ||
| 15 | test "truncate.u0.const" { | |
| 16 | const c0: usize = 0; | |
| 17 | var z = @truncate(u0, c0); | |
| 18 | expect(z == 0); | |
| 19 | } | |
| 20 | ||
| 21 | test "truncate.u0.var" { | |
| 22 | var d: u8 = 2; | |
| 23 | var z = @truncate(u0, d); | |
| 24 | expect(z == 0); | |
| 25 | } | |
| 26 | ||
| 27 | test "truncate sign mismatch but comptime known so it works anyway" { | |
| 28 | const x: u32 = 10; | |
| 29 | var result = @truncate(i8, x); | |
| 30 | expect(result == 10); | |
| 31 | } | |
| 32 | ||
| 33 | test "truncate on comptime integer" { | |
| 34 | var x = @truncate(u16, 9999); | |
| 35 | expect(x == 9999); | |
| 36 | } |
test/stage1/behavior/try.zig deleted-43| ... | ... | @@ -1,43 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | test "try on error union" { | |
| 4 | tryOnErrorUnionImpl(); | |
| 5 | comptime tryOnErrorUnionImpl(); | |
| 6 | } | |
| 7 | ||
| 8 | fn tryOnErrorUnionImpl() void { | |
| 9 | const x = if (returnsTen()) |val| val + 1 else |err| switch (err) { | |
| 10 | error.ItBroke, error.NoMem => 1, | |
| 11 | error.CrappedOut => @as(i32, 2), | |
| 12 | else => unreachable, | |
| 13 | }; | |
| 14 | expect(x == 11); | |
| 15 | } | |
| 16 | ||
| 17 | fn returnsTen() anyerror!i32 { | |
| 18 | return 10; | |
| 19 | } | |
| 20 | ||
| 21 | test "try without vars" { | |
| 22 | const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2); | |
| 23 | expect(result1 == 2); | |
| 24 | ||
| 25 | const result2 = if (failIfTrue(false)) 1 else |_| @as(i32, 2); | |
| 26 | expect(result2 == 1); | |
| 27 | } | |
| 28 | ||
| 29 | fn failIfTrue(ok: bool) anyerror!void { | |
| 30 | if (ok) { | |
| 31 | return error.ItBroke; | |
| 32 | } else { | |
| 33 | return; | |
| 34 | } | |
| 35 | } | |
| 36 | ||
| 37 | test "try then not executed with assignment" { | |
| 38 | if (failIfTrue(true)) { | |
| 39 | unreachable; | |
| 40 | } else |err| { | |
| 41 | expect(err == error.ItBroke); | |
| 42 | } | |
| 43 | } |
test/stage1/behavior/tuple.zig deleted-113| ... | ... | @@ -1,113 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const testing = std.testing; | |
| 3 | const expect = testing.expect; | |
| 4 | const expectEqual = testing.expectEqual; | |
| 5 | ||
| 6 | test "tuple concatenation" { | |
| 7 | const S = struct { | |
| 8 | fn doTheTest() void { | |
| 9 | var a: i32 = 1; | |
| 10 | var b: i32 = 2; | |
| 11 | var x = .{a}; | |
| 12 | var y = .{b}; | |
| 13 | var c = x ++ y; | |
| 14 | expectEqual(@as(i32, 1), c[0]); | |
| 15 | expectEqual(@as(i32, 2), c[1]); | |
| 16 | } | |
| 17 | }; | |
| 18 | S.doTheTest(); | |
| 19 | comptime S.doTheTest(); | |
| 20 | } | |
| 21 | ||
| 22 | test "tuple multiplication" { | |
| 23 | const S = struct { | |
| 24 | fn doTheTest() void { | |
| 25 | { | |
| 26 | const t = .{} ** 4; | |
| 27 | expectEqual(0, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 28 | } | |
| 29 | { | |
| 30 | const t = .{'a'} ** 4; | |
| 31 | expectEqual(4, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 32 | inline for (t) |x| expectEqual('a', x); | |
| 33 | } | |
| 34 | { | |
| 35 | const t = .{ 1, 2, 3 } ** 4; | |
| 36 | expectEqual(12, @typeInfo(@TypeOf(t)).Struct.fields.len); | |
| 37 | inline for (t) |x, i| expectEqual(1 + i % 3, x); | |
| 38 | } | |
| 39 | } | |
| 40 | }; | |
| 41 | S.doTheTest(); | |
| 42 | comptime S.doTheTest(); | |
| 43 | ||
| 44 | const T = struct { | |
| 45 | fn consume_tuple(tuple: anytype, len: usize) void { | |
| 46 | expect(tuple.len == len); | |
| 47 | } | |
| 48 | ||
| 49 | fn doTheTest() void { | |
| 50 | const t1 = .{}; | |
| 51 | ||
| 52 | var rt_var: u8 = 42; | |
| 53 | const t2 = .{rt_var} ++ .{}; | |
| 54 | ||
| 55 | expect(t2.len == 1); | |
| 56 | expect(t2.@"0" == rt_var); | |
| 57 | expect(t2.@"0" == 42); | |
| 58 | expect(&t2.@"0" != &rt_var); | |
| 59 | ||
| 60 | consume_tuple(t1 ++ t1, 0); | |
| 61 | consume_tuple(.{} ++ .{}, 0); | |
| 62 | consume_tuple(.{0} ++ .{}, 1); | |
| 63 | consume_tuple(.{0} ++ .{1}, 2); | |
| 64 | consume_tuple(.{ 0, 1, 2 } ++ .{ u8, 1, noreturn }, 6); | |
| 65 | consume_tuple(t2 ++ t1, 1); | |
| 66 | consume_tuple(t1 ++ t2, 1); | |
| 67 | consume_tuple(t2 ++ t2, 2); | |
| 68 | consume_tuple(.{rt_var} ++ .{}, 1); | |
| 69 | consume_tuple(.{rt_var} ++ t1, 1); | |
| 70 | consume_tuple(.{} ++ .{rt_var}, 1); | |
| 71 | consume_tuple(t2 ++ .{void}, 2); | |
| 72 | consume_tuple(t2 ++ .{0}, 2); | |
| 73 | consume_tuple(.{0} ++ t2, 2); | |
| 74 | consume_tuple(.{void} ++ t2, 2); | |
| 75 | consume_tuple(.{u8} ++ .{rt_var} ++ .{true}, 3); | |
| 76 | } | |
| 77 | }; | |
| 78 | ||
| 79 | T.doTheTest(); | |
| 80 | comptime T.doTheTest(); | |
| 81 | } | |
| 82 | ||
| 83 | test "pass tuple to comptime var parameter" { | |
| 84 | const S = struct { | |
| 85 | fn Foo(comptime args: anytype) void { | |
| 86 | expect(args[0] == 1); | |
| 87 | } | |
| 88 | ||
| 89 | fn doTheTest() void { | |
| 90 | Foo(.{1}); | |
| 91 | } | |
| 92 | }; | |
| 93 | S.doTheTest(); | |
| 94 | comptime S.doTheTest(); | |
| 95 | } | |
| 96 | ||
| 97 | test "tuple initializer for var" { | |
| 98 | const S = struct { | |
| 99 | fn doTheTest() void { | |
| 100 | const Bytes = struct { | |
| 101 | id: usize, | |
| 102 | }; | |
| 103 | ||
| 104 | var tmp = .{ | |
| 105 | .id = @as(usize, 2), | |
| 106 | .name = Bytes{ .id = 20 }, | |
| 107 | }; | |
| 108 | } | |
| 109 | }; | |
| 110 | ||
| 111 | S.doTheTest(); | |
| 112 | comptime S.doTheTest(); | |
| 113 | } |
test/stage1/behavior/type.zig deleted-453| ... | ... | @@ -1,453 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const TypeInfo = std.builtin.TypeInfo; | |
| 4 | const testing = std.testing; | |
| 5 | ||
| 6 | fn testTypes(comptime types: []const type) void { | |
| 7 | inline for (types) |testType| { | |
| 8 | testing.expect(testType == @Type(@typeInfo(testType))); | |
| 9 | } | |
| 10 | } | |
| 11 | ||
| 12 | test "Type.MetaType" { | |
| 13 | testing.expect(type == @Type(TypeInfo{ .Type = undefined })); | |
| 14 | testTypes(&[_]type{type}); | |
| 15 | } | |
| 16 | ||
| 17 | test "Type.Void" { | |
| 18 | testing.expect(void == @Type(TypeInfo{ .Void = undefined })); | |
| 19 | testTypes(&[_]type{void}); | |
| 20 | } | |
| 21 | ||
| 22 | test "Type.Bool" { | |
| 23 | testing.expect(bool == @Type(TypeInfo{ .Bool = undefined })); | |
| 24 | testTypes(&[_]type{bool}); | |
| 25 | } | |
| 26 | ||
| 27 | test "Type.NoReturn" { | |
| 28 | testing.expect(noreturn == @Type(TypeInfo{ .NoReturn = undefined })); | |
| 29 | testTypes(&[_]type{noreturn}); | |
| 30 | } | |
| 31 | ||
| 32 | test "Type.Int" { | |
| 33 | testing.expect(u1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 1 } })); | |
| 34 | testing.expect(i1 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 1 } })); | |
| 35 | testing.expect(u8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 8 } })); | |
| 36 | testing.expect(i8 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 8 } })); | |
| 37 | testing.expect(u64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .unsigned, .bits = 64 } })); | |
| 38 | testing.expect(i64 == @Type(TypeInfo{ .Int = TypeInfo.Int{ .signedness = .signed, .bits = 64 } })); | |
| 39 | testTypes(&[_]type{ u8, u32, i64 }); | |
| 40 | } | |
| 41 | ||
| 42 | test "Type.Float" { | |
| 43 | testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } })); | |
| 44 | testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } })); | |
| 45 | testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } })); | |
| 46 | testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } })); | |
| 47 | testTypes(&[_]type{ f16, f32, f64, f128 }); | |
| 48 | } | |
| 49 | ||
| 50 | test "Type.Pointer" { | |
| 51 | testTypes(&[_]type{ | |
| 52 | // One Value Pointer Types | |
| 53 | *u8, *const u8, | |
| 54 | *volatile u8, *const volatile u8, | |
| 55 | *align(4) u8, *align(4) const u8, | |
| 56 | *align(4) volatile u8, *align(4) const volatile u8, | |
| 57 | *align(8) u8, *align(8) const u8, | |
| 58 | *align(8) volatile u8, *align(8) const volatile u8, | |
| 59 | *allowzero u8, *allowzero const u8, | |
| 60 | *allowzero volatile u8, *allowzero const volatile u8, | |
| 61 | *allowzero align(4) u8, *allowzero align(4) const u8, | |
| 62 | *allowzero align(4) volatile u8, *allowzero align(4) const volatile u8, | |
| 63 | // Many Values Pointer Types | |
| 64 | [*]u8, [*]const u8, | |
| 65 | [*]volatile u8, [*]const volatile u8, | |
| 66 | [*]align(4) u8, [*]align(4) const u8, | |
| 67 | [*]align(4) volatile u8, [*]align(4) const volatile u8, | |
| 68 | [*]align(8) u8, [*]align(8) const u8, | |
| 69 | [*]align(8) volatile u8, [*]align(8) const volatile u8, | |
| 70 | [*]allowzero u8, [*]allowzero const u8, | |
| 71 | [*]allowzero volatile u8, [*]allowzero const volatile u8, | |
| 72 | [*]allowzero align(4) u8, [*]allowzero align(4) const u8, | |
| 73 | [*]allowzero align(4) volatile u8, [*]allowzero align(4) const volatile u8, | |
| 74 | // Slice Types | |
| 75 | []u8, []const u8, | |
| 76 | []volatile u8, []const volatile u8, | |
| 77 | []align(4) u8, []align(4) const u8, | |
| 78 | []align(4) volatile u8, []align(4) const volatile u8, | |
| 79 | []align(8) u8, []align(8) const u8, | |
| 80 | []align(8) volatile u8, []align(8) const volatile u8, | |
| 81 | []allowzero u8, []allowzero const u8, | |
| 82 | []allowzero volatile u8, []allowzero const volatile u8, | |
| 83 | []allowzero align(4) u8, []allowzero align(4) const u8, | |
| 84 | []allowzero align(4) volatile u8, []allowzero align(4) const volatile u8, | |
| 85 | // C Pointer Types | |
| 86 | [*c]u8, [*c]const u8, | |
| 87 | [*c]volatile u8, [*c]const volatile u8, | |
| 88 | [*c]align(4) u8, [*c]align(4) const u8, | |
| 89 | [*c]align(4) volatile u8, [*c]align(4) const volatile u8, | |
| 90 | [*c]align(8) u8, [*c]align(8) const u8, | |
| 91 | [*c]align(8) volatile u8, [*c]align(8) const volatile u8, | |
| 92 | }); | |
| 93 | } | |
| 94 | ||
| 95 | test "Type.Array" { | |
| 96 | testing.expect([123]u8 == @Type(TypeInfo{ | |
| 97 | .Array = TypeInfo.Array{ | |
| 98 | .len = 123, | |
| 99 | .child = u8, | |
| 100 | .sentinel = null, | |
| 101 | }, | |
| 102 | })); | |
| 103 | testing.expect([2]u32 == @Type(TypeInfo{ | |
| 104 | .Array = TypeInfo.Array{ | |
| 105 | .len = 2, | |
| 106 | .child = u32, | |
| 107 | .sentinel = null, | |
| 108 | }, | |
| 109 | })); | |
| 110 | testing.expect([2:0]u32 == @Type(TypeInfo{ | |
| 111 | .Array = TypeInfo.Array{ | |
| 112 | .len = 2, | |
| 113 | .child = u32, | |
| 114 | .sentinel = 0, | |
| 115 | }, | |
| 116 | })); | |
| 117 | testTypes(&[_]type{ [1]u8, [30]usize, [7]bool }); | |
| 118 | } | |
| 119 | ||
| 120 | test "Type.ComptimeFloat" { | |
| 121 | testTypes(&[_]type{comptime_float}); | |
| 122 | } | |
| 123 | test "Type.ComptimeInt" { | |
| 124 | testTypes(&[_]type{comptime_int}); | |
| 125 | } | |
| 126 | test "Type.Undefined" { | |
| 127 | testTypes(&[_]type{@TypeOf(undefined)}); | |
| 128 | } | |
| 129 | test "Type.Null" { | |
| 130 | testTypes(&[_]type{@TypeOf(null)}); | |
| 131 | } | |
| 132 | test "@Type create slice with null sentinel" { | |
| 133 | const Slice = @Type(TypeInfo{ | |
| 134 | .Pointer = .{ | |
| 135 | .size = .Slice, | |
| 136 | .is_const = true, | |
| 137 | .is_volatile = false, | |
| 138 | .is_allowzero = false, | |
| 139 | .alignment = 8, | |
| 140 | .child = *i32, | |
| 141 | .sentinel = null, | |
| 142 | }, | |
| 143 | }); | |
| 144 | testing.expect(Slice == []align(8) const *i32); | |
| 145 | } | |
| 146 | test "@Type picks up the sentinel value from TypeInfo" { | |
| 147 | testTypes(&[_]type{ | |
| 148 | [11:0]u8, [4:10]u8, | |
| 149 | [*:0]u8, [*:0]const u8, | |
| 150 | [*:0]volatile u8, [*:0]const volatile u8, | |
| 151 | [*:0]align(4) u8, [*:0]align(4) const u8, | |
| 152 | [*:0]align(4) volatile u8, [*:0]align(4) const volatile u8, | |
| 153 | [*:0]align(8) u8, [*:0]align(8) const u8, | |
| 154 | [*:0]align(8) volatile u8, [*:0]align(8) const volatile u8, | |
| 155 | [*:0]allowzero u8, [*:0]allowzero const u8, | |
| 156 | [*:0]allowzero volatile u8, [*:0]allowzero const volatile u8, | |
| 157 | [*:0]allowzero align(4) u8, [*:0]allowzero align(4) const u8, | |
| 158 | [*:0]allowzero align(4) volatile u8, [*:0]allowzero align(4) const volatile u8, | |
| 159 | [*:5]allowzero align(4) volatile u8, [*:5]allowzero align(4) const volatile u8, | |
| 160 | [:0]u8, [:0]const u8, | |
| 161 | [:0]volatile u8, [:0]const volatile u8, | |
| 162 | [:0]align(4) u8, [:0]align(4) const u8, | |
| 163 | [:0]align(4) volatile u8, [:0]align(4) const volatile u8, | |
| 164 | [:0]align(8) u8, [:0]align(8) const u8, | |
| 165 | [:0]align(8) volatile u8, [:0]align(8) const volatile u8, | |
| 166 | [:0]allowzero u8, [:0]allowzero const u8, | |
| 167 | [:0]allowzero volatile u8, [:0]allowzero const volatile u8, | |
| 168 | [:0]allowzero align(4) u8, [:0]allowzero align(4) const u8, | |
| 169 | [:0]allowzero align(4) volatile u8, [:0]allowzero align(4) const volatile u8, | |
| 170 | [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8, | |
| 171 | }); | |
| 172 | } | |
| 173 | ||
| 174 | test "Type.Optional" { | |
| 175 | testTypes(&[_]type{ | |
| 176 | ?u8, | |
| 177 | ?*u8, | |
| 178 | ?[]u8, | |
| 179 | ?[*]u8, | |
| 180 | ?[*c]u8, | |
| 181 | }); | |
| 182 | } | |
| 183 | ||
| 184 | test "Type.ErrorUnion" { | |
| 185 | testTypes(&[_]type{ | |
| 186 | error{}!void, | |
| 187 | error{Error}!void, | |
| 188 | }); | |
| 189 | } | |
| 190 | ||
| 191 | test "Type.Opaque" { | |
| 192 | const Opaque = @Type(.{ | |
| 193 | .Opaque = .{ | |
| 194 | .decls = &[_]TypeInfo.Declaration{}, | |
| 195 | }, | |
| 196 | }); | |
| 197 | testing.expect(Opaque != opaque {}); | |
| 198 | testing.expectEqualSlices( | |
| 199 | TypeInfo.Declaration, | |
| 200 | &[_]TypeInfo.Declaration{}, | |
| 201 | @typeInfo(Opaque).Opaque.decls, | |
| 202 | ); | |
| 203 | } | |
| 204 | ||
| 205 | test "Type.Vector" { | |
| 206 | testTypes(&[_]type{ | |
| 207 | @Vector(0, u8), | |
| 208 | @Vector(4, u8), | |
| 209 | @Vector(8, *u8), | |
| 210 | std.meta.Vector(0, u8), | |
| 211 | std.meta.Vector(4, u8), | |
| 212 | std.meta.Vector(8, *u8), | |
| 213 | }); | |
| 214 | } | |
| 215 | ||
| 216 | test "Type.AnyFrame" { | |
| 217 | testTypes(&[_]type{ | |
| 218 | anyframe, | |
| 219 | anyframe->u8, | |
| 220 | anyframe->anyframe->u8, | |
| 221 | }); | |
| 222 | } | |
| 223 | ||
| 224 | test "Type.EnumLiteral" { | |
| 225 | testTypes(&[_]type{ | |
| 226 | @TypeOf(.Dummy), | |
| 227 | }); | |
| 228 | } | |
| 229 | ||
| 230 | fn add(a: i32, b: i32) i32 { | |
| 231 | return a + b; | |
| 232 | } | |
| 233 | ||
| 234 | test "Type.Frame" { | |
| 235 | testTypes(&[_]type{ | |
| 236 | @Frame(add), | |
| 237 | }); | |
| 238 | } | |
| 239 | ||
| 240 | test "Type.ErrorSet" { | |
| 241 | // error sets don't compare equal so just check if they compile | |
| 242 | _ = @Type(@typeInfo(error{})); | |
| 243 | _ = @Type(@typeInfo(error{A})); | |
| 244 | _ = @Type(@typeInfo(error{ A, B, C })); | |
| 245 | } | |
| 246 | ||
| 247 | test "Type.Struct" { | |
| 248 | const A = @Type(@typeInfo(struct { x: u8, y: u32 })); | |
| 249 | const infoA = @typeInfo(A).Struct; | |
| 250 | testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout); | |
| 251 | testing.expectEqualSlices(u8, "x", infoA.fields[0].name); | |
| 252 | testing.expectEqual(u8, infoA.fields[0].field_type); | |
| 253 | testing.expectEqual(@as(?u8, null), infoA.fields[0].default_value); | |
| 254 | testing.expectEqualSlices(u8, "y", infoA.fields[1].name); | |
| 255 | testing.expectEqual(u32, infoA.fields[1].field_type); | |
| 256 | testing.expectEqual(@as(?u32, null), infoA.fields[1].default_value); | |
| 257 | testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls); | |
| 258 | testing.expectEqual(@as(bool, false), infoA.is_tuple); | |
| 259 | ||
| 260 | var a = A{ .x = 0, .y = 1 }; | |
| 261 | testing.expectEqual(@as(u8, 0), a.x); | |
| 262 | testing.expectEqual(@as(u32, 1), a.y); | |
| 263 | a.y += 1; | |
| 264 | testing.expectEqual(@as(u32, 2), a.y); | |
| 265 | ||
| 266 | const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 })); | |
| 267 | const infoB = @typeInfo(B).Struct; | |
| 268 | testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout); | |
| 269 | testing.expectEqualSlices(u8, "x", infoB.fields[0].name); | |
| 270 | testing.expectEqual(u8, infoB.fields[0].field_type); | |
| 271 | testing.expectEqual(@as(?u8, null), infoB.fields[0].default_value); | |
| 272 | testing.expectEqualSlices(u8, "y", infoB.fields[1].name); | |
| 273 | testing.expectEqual(u32, infoB.fields[1].field_type); | |
| 274 | testing.expectEqual(@as(?u32, 5), infoB.fields[1].default_value); | |
| 275 | testing.expectEqual(@as(usize, 0), infoB.decls.len); | |
| 276 | testing.expectEqual(@as(bool, false), infoB.is_tuple); | |
| 277 | ||
| 278 | const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 })); | |
| 279 | const infoC = @typeInfo(C).Struct; | |
| 280 | testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout); | |
| 281 | testing.expectEqualSlices(u8, "x", infoC.fields[0].name); | |
| 282 | testing.expectEqual(u8, infoC.fields[0].field_type); | |
| 283 | testing.expectEqual(@as(?u8, 3), infoC.fields[0].default_value); | |
| 284 | testing.expectEqualSlices(u8, "y", infoC.fields[1].name); | |
| 285 | testing.expectEqual(u32, infoC.fields[1].field_type); | |
| 286 | testing.expectEqual(@as(?u32, 5), infoC.fields[1].default_value); | |
| 287 | testing.expectEqual(@as(usize, 0), infoC.decls.len); | |
| 288 | testing.expectEqual(@as(bool, false), infoC.is_tuple); | |
| 289 | } | |
| 290 | ||
| 291 | test "Type.Enum" { | |
| 292 | const Foo = @Type(.{ | |
| 293 | .Enum = .{ | |
| 294 | .layout = .Auto, | |
| 295 | .tag_type = u8, | |
| 296 | .fields = &[_]TypeInfo.EnumField{ | |
| 297 | .{ .name = "a", .value = 1 }, | |
| 298 | .{ .name = "b", .value = 5 }, | |
| 299 | }, | |
| 300 | .decls = &[_]TypeInfo.Declaration{}, | |
| 301 | .is_exhaustive = true, | |
| 302 | }, | |
| 303 | }); | |
| 304 | testing.expectEqual(true, @typeInfo(Foo).Enum.is_exhaustive); | |
| 305 | testing.expectEqual(@as(u8, 1), @enumToInt(Foo.a)); | |
| 306 | testing.expectEqual(@as(u8, 5), @enumToInt(Foo.b)); | |
| 307 | const Bar = @Type(.{ | |
| 308 | .Enum = .{ | |
| 309 | .layout = .Extern, | |
| 310 | .tag_type = u32, | |
| 311 | .fields = &[_]TypeInfo.EnumField{ | |
| 312 | .{ .name = "a", .value = 1 }, | |
| 313 | .{ .name = "b", .value = 5 }, | |
| 314 | }, | |
| 315 | .decls = &[_]TypeInfo.Declaration{}, | |
| 316 | .is_exhaustive = false, | |
| 317 | }, | |
| 318 | }); | |
| 319 | testing.expectEqual(false, @typeInfo(Bar).Enum.is_exhaustive); | |
| 320 | testing.expectEqual(@as(u32, 1), @enumToInt(Bar.a)); | |
| 321 | testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b)); | |
| 322 | testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6))); | |
| 323 | } | |
| 324 | ||
| 325 | test "Type.Union" { | |
| 326 | const Untagged = @Type(.{ | |
| 327 | .Union = .{ | |
| 328 | .layout = .Auto, | |
| 329 | .tag_type = null, | |
| 330 | .fields = &[_]TypeInfo.UnionField{ | |
| 331 | .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) }, | |
| 332 | .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) }, | |
| 333 | }, | |
| 334 | .decls = &[_]TypeInfo.Declaration{}, | |
| 335 | }, | |
| 336 | }); | |
| 337 | var untagged = Untagged{ .int = 1 }; | |
| 338 | untagged.float = 2.0; | |
| 339 | untagged.int = 3; | |
| 340 | testing.expectEqual(@as(i32, 3), untagged.int); | |
| 341 | ||
| 342 | const PackedUntagged = @Type(.{ | |
| 343 | .Union = .{ | |
| 344 | .layout = .Packed, | |
| 345 | .tag_type = null, | |
| 346 | .fields = &[_]TypeInfo.UnionField{ | |
| 347 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 348 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 349 | }, | |
| 350 | .decls = &[_]TypeInfo.Declaration{}, | |
| 351 | }, | |
| 352 | }); | |
| 353 | var packed_untagged = PackedUntagged{ .signed = -1 }; | |
| 354 | testing.expectEqual(@as(i32, -1), packed_untagged.signed); | |
| 355 | testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned); | |
| 356 | ||
| 357 | const Tag = @Type(.{ | |
| 358 | .Enum = .{ | |
| 359 | .layout = .Auto, | |
| 360 | .tag_type = u1, | |
| 361 | .fields = &[_]TypeInfo.EnumField{ | |
| 362 | .{ .name = "signed", .value = 0 }, | |
| 363 | .{ .name = "unsigned", .value = 1 }, | |
| 364 | }, | |
| 365 | .decls = &[_]TypeInfo.Declaration{}, | |
| 366 | .is_exhaustive = true, | |
| 367 | }, | |
| 368 | }); | |
| 369 | const Tagged = @Type(.{ | |
| 370 | .Union = .{ | |
| 371 | .layout = .Auto, | |
| 372 | .tag_type = Tag, | |
| 373 | .fields = &[_]TypeInfo.UnionField{ | |
| 374 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 375 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 376 | }, | |
| 377 | .decls = &[_]TypeInfo.Declaration{}, | |
| 378 | }, | |
| 379 | }); | |
| 380 | var tagged = Tagged{ .signed = -1 }; | |
| 381 | testing.expectEqual(Tag.signed, tagged); | |
| 382 | tagged = .{ .unsigned = 1 }; | |
| 383 | testing.expectEqual(Tag.unsigned, tagged); | |
| 384 | } | |
| 385 | ||
| 386 | test "Type.Union from Type.Enum" { | |
| 387 | const Tag = @Type(.{ | |
| 388 | .Enum = .{ | |
| 389 | .layout = .Auto, | |
| 390 | .tag_type = u0, | |
| 391 | .fields = &[_]TypeInfo.EnumField{ | |
| 392 | .{ .name = "working_as_expected", .value = 0 }, | |
| 393 | }, | |
| 394 | .decls = &[_]TypeInfo.Declaration{}, | |
| 395 | .is_exhaustive = true, | |
| 396 | }, | |
| 397 | }); | |
| 398 | const T = @Type(.{ | |
| 399 | .Union = .{ | |
| 400 | .layout = .Auto, | |
| 401 | .tag_type = Tag, | |
| 402 | .fields = &[_]TypeInfo.UnionField{ | |
| 403 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 404 | }, | |
| 405 | .decls = &[_]TypeInfo.Declaration{}, | |
| 406 | }, | |
| 407 | }); | |
| 408 | _ = T; | |
| 409 | _ = @typeInfo(T).Union; | |
| 410 | } | |
| 411 | ||
| 412 | test "Type.Union from regular enum" { | |
| 413 | const E = enum { working_as_expected = 0 }; | |
| 414 | const T = @Type(.{ | |
| 415 | .Union = .{ | |
| 416 | .layout = .Auto, | |
| 417 | .tag_type = E, | |
| 418 | .fields = &[_]TypeInfo.UnionField{ | |
| 419 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 420 | }, | |
| 421 | .decls = &[_]TypeInfo.Declaration{}, | |
| 422 | }, | |
| 423 | }); | |
| 424 | _ = T; | |
| 425 | _ = @typeInfo(T).Union; | |
| 426 | } | |
| 427 | ||
| 428 | test "Type.Fn" { | |
| 429 | // wasm doesn't support align attributes on functions | |
| 430 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 431 | ||
| 432 | const foo = struct { | |
| 433 | fn func(a: usize, b: bool) align(4) callconv(.C) usize { | |
| 434 | return 0; | |
| 435 | } | |
| 436 | }.func; | |
| 437 | const Foo = @Type(@typeInfo(@TypeOf(foo))); | |
| 438 | const foo_2: Foo = foo; | |
| 439 | } | |
| 440 | ||
| 441 | test "Type.BoundFn" { | |
| 442 | // wasm doesn't support align attributes on functions | |
| 443 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 444 | ||
| 445 | const TestStruct = packed struct { | |
| 446 | pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void {} | |
| 447 | }; | |
| 448 | const test_instance: TestStruct = undefined; | |
| 449 | testing.expect(std.meta.eql( | |
| 450 | @typeName(@TypeOf(test_instance.foo)), | |
| 451 | @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))), | |
| 452 | )); | |
| 453 | } |
test/stage1/behavior/type_info.zig deleted-485| ... | ... | @@ -1,485 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | const TypeInfo = std.builtin.TypeInfo; | |
| 6 | const TypeId = std.builtin.TypeId; | |
| 7 | ||
| 8 | const expect = std.testing.expect; | |
| 9 | const expectEqualStrings = std.testing.expectEqualStrings; | |
| 10 | ||
| 11 | test "type info: tag type, void info" { | |
| 12 | testBasic(); | |
| 13 | comptime testBasic(); | |
| 14 | } | |
| 15 | ||
| 16 | fn testBasic() void { | |
| 17 | expect(@typeInfo(TypeInfo).Union.tag_type == TypeId); | |
| 18 | const void_info = @typeInfo(void); | |
| 19 | expect(void_info == TypeId.Void); | |
| 20 | expect(void_info.Void == {}); | |
| 21 | } | |
| 22 | ||
| 23 | test "type info: integer, floating point type info" { | |
| 24 | testIntFloat(); | |
| 25 | comptime testIntFloat(); | |
| 26 | } | |
| 27 | ||
| 28 | fn testIntFloat() void { | |
| 29 | const u8_info = @typeInfo(u8); | |
| 30 | expect(u8_info == .Int); | |
| 31 | expect(u8_info.Int.signedness == .unsigned); | |
| 32 | expect(u8_info.Int.bits == 8); | |
| 33 | ||
| 34 | const f64_info = @typeInfo(f64); | |
| 35 | expect(f64_info == .Float); | |
| 36 | expect(f64_info.Float.bits == 64); | |
| 37 | } | |
| 38 | ||
| 39 | test "type info: pointer type info" { | |
| 40 | testPointer(); | |
| 41 | comptime testPointer(); | |
| 42 | } | |
| 43 | ||
| 44 | fn testPointer() void { | |
| 45 | const u32_ptr_info = @typeInfo(*u32); | |
| 46 | expect(u32_ptr_info == .Pointer); | |
| 47 | expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One); | |
| 48 | expect(u32_ptr_info.Pointer.is_const == false); | |
| 49 | expect(u32_ptr_info.Pointer.is_volatile == false); | |
| 50 | expect(u32_ptr_info.Pointer.alignment == @alignOf(u32)); | |
| 51 | expect(u32_ptr_info.Pointer.child == u32); | |
| 52 | expect(u32_ptr_info.Pointer.sentinel == null); | |
| 53 | } | |
| 54 | ||
| 55 | test "type info: unknown length pointer type info" { | |
| 56 | testUnknownLenPtr(); | |
| 57 | comptime testUnknownLenPtr(); | |
| 58 | } | |
| 59 | ||
| 60 | fn testUnknownLenPtr() void { | |
| 61 | const u32_ptr_info = @typeInfo([*]const volatile f64); | |
| 62 | expect(u32_ptr_info == .Pointer); | |
| 63 | expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); | |
| 64 | expect(u32_ptr_info.Pointer.is_const == true); | |
| 65 | expect(u32_ptr_info.Pointer.is_volatile == true); | |
| 66 | expect(u32_ptr_info.Pointer.sentinel == null); | |
| 67 | expect(u32_ptr_info.Pointer.alignment == @alignOf(f64)); | |
| 68 | expect(u32_ptr_info.Pointer.child == f64); | |
| 69 | } | |
| 70 | ||
| 71 | test "type info: null terminated pointer type info" { | |
| 72 | testNullTerminatedPtr(); | |
| 73 | comptime testNullTerminatedPtr(); | |
| 74 | } | |
| 75 | ||
| 76 | fn testNullTerminatedPtr() void { | |
| 77 | const ptr_info = @typeInfo([*:0]u8); | |
| 78 | expect(ptr_info == .Pointer); | |
| 79 | expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many); | |
| 80 | expect(ptr_info.Pointer.is_const == false); | |
| 81 | expect(ptr_info.Pointer.is_volatile == false); | |
| 82 | expect(ptr_info.Pointer.sentinel.? == 0); | |
| 83 | ||
| 84 | expect(@typeInfo([:0]u8).Pointer.sentinel != null); | |
| 85 | } | |
| 86 | ||
| 87 | test "type info: C pointer type info" { | |
| 88 | testCPtr(); | |
| 89 | comptime testCPtr(); | |
| 90 | } | |
| 91 | ||
| 92 | fn testCPtr() void { | |
| 93 | const ptr_info = @typeInfo([*c]align(4) const i8); | |
| 94 | expect(ptr_info == .Pointer); | |
| 95 | expect(ptr_info.Pointer.size == .C); | |
| 96 | expect(ptr_info.Pointer.is_const); | |
| 97 | expect(!ptr_info.Pointer.is_volatile); | |
| 98 | expect(ptr_info.Pointer.alignment == 4); | |
| 99 | expect(ptr_info.Pointer.child == i8); | |
| 100 | } | |
| 101 | ||
| 102 | test "type info: slice type info" { | |
| 103 | testSlice(); | |
| 104 | comptime testSlice(); | |
| 105 | } | |
| 106 | ||
| 107 | fn testSlice() void { | |
| 108 | const u32_slice_info = @typeInfo([]u32); | |
| 109 | expect(u32_slice_info == .Pointer); | |
| 110 | expect(u32_slice_info.Pointer.size == .Slice); | |
| 111 | expect(u32_slice_info.Pointer.is_const == false); | |
| 112 | expect(u32_slice_info.Pointer.is_volatile == false); | |
| 113 | expect(u32_slice_info.Pointer.alignment == 4); | |
| 114 | expect(u32_slice_info.Pointer.child == u32); | |
| 115 | } | |
| 116 | ||
| 117 | test "type info: array type info" { | |
| 118 | testArray(); | |
| 119 | comptime testArray(); | |
| 120 | } | |
| 121 | ||
| 122 | fn testArray() void { | |
| 123 | { | |
| 124 | const info = @typeInfo([42]u8); | |
| 125 | expect(info == .Array); | |
| 126 | expect(info.Array.len == 42); | |
| 127 | expect(info.Array.child == u8); | |
| 128 | expect(info.Array.sentinel == null); | |
| 129 | } | |
| 130 | ||
| 131 | { | |
| 132 | const info = @typeInfo([10:0]u8); | |
| 133 | expect(info.Array.len == 10); | |
| 134 | expect(info.Array.child == u8); | |
| 135 | expect(info.Array.sentinel.? == @as(u8, 0)); | |
| 136 | expect(@sizeOf([10:0]u8) == info.Array.len + 1); | |
| 137 | } | |
| 138 | } | |
| 139 | ||
| 140 | test "type info: optional type info" { | |
| 141 | testOptional(); | |
| 142 | comptime testOptional(); | |
| 143 | } | |
| 144 | ||
| 145 | fn testOptional() void { | |
| 146 | const null_info = @typeInfo(?void); | |
| 147 | expect(null_info == .Optional); | |
| 148 | expect(null_info.Optional.child == void); | |
| 149 | } | |
| 150 | ||
| 151 | test "type info: error set, error union info" { | |
| 152 | testErrorSet(); | |
| 153 | comptime testErrorSet(); | |
| 154 | } | |
| 155 | ||
| 156 | fn testErrorSet() void { | |
| 157 | const TestErrorSet = error{ | |
| 158 | First, | |
| 159 | Second, | |
| 160 | Third, | |
| 161 | }; | |
| 162 | ||
| 163 | const error_set_info = @typeInfo(TestErrorSet); | |
| 164 | expect(error_set_info == .ErrorSet); | |
| 165 | expect(error_set_info.ErrorSet.?.len == 3); | |
| 166 | expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "First")); | |
| 167 | ||
| 168 | const error_union_info = @typeInfo(TestErrorSet!usize); | |
| 169 | expect(error_union_info == .ErrorUnion); | |
| 170 | expect(error_union_info.ErrorUnion.error_set == TestErrorSet); | |
| 171 | expect(error_union_info.ErrorUnion.payload == usize); | |
| 172 | ||
| 173 | const global_info = @typeInfo(anyerror); | |
| 174 | expect(global_info == .ErrorSet); | |
| 175 | expect(global_info.ErrorSet == null); | |
| 176 | } | |
| 177 | ||
| 178 | test "type info: enum info" { | |
| 179 | testEnum(); | |
| 180 | comptime testEnum(); | |
| 181 | } | |
| 182 | ||
| 183 | fn testEnum() void { | |
| 184 | const Os = enum { | |
| 185 | Windows, | |
| 186 | Macos, | |
| 187 | Linux, | |
| 188 | FreeBSD, | |
| 189 | }; | |
| 190 | ||
| 191 | const os_info = @typeInfo(Os); | |
| 192 | expect(os_info == .Enum); | |
| 193 | expect(os_info.Enum.layout == .Auto); | |
| 194 | expect(os_info.Enum.fields.len == 4); | |
| 195 | expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos")); | |
| 196 | expect(os_info.Enum.fields[3].value == 3); | |
| 197 | expect(os_info.Enum.tag_type == u2); | |
| 198 | expect(os_info.Enum.decls.len == 0); | |
| 199 | } | |
| 200 | ||
| 201 | test "type info: union info" { | |
| 202 | testUnion(); | |
| 203 | comptime testUnion(); | |
| 204 | } | |
| 205 | ||
| 206 | fn testUnion() void { | |
| 207 | const typeinfo_info = @typeInfo(TypeInfo); | |
| 208 | expect(typeinfo_info == .Union); | |
| 209 | expect(typeinfo_info.Union.layout == .Auto); | |
| 210 | expect(typeinfo_info.Union.tag_type.? == TypeId); | |
| 211 | expect(typeinfo_info.Union.fields.len == 25); | |
| 212 | expect(typeinfo_info.Union.fields[4].field_type == @TypeOf(@typeInfo(u8).Int)); | |
| 213 | expect(typeinfo_info.Union.decls.len == 22); | |
| 214 | ||
| 215 | const TestNoTagUnion = union { | |
| 216 | Foo: void, | |
| 217 | Bar: u32, | |
| 218 | }; | |
| 219 | ||
| 220 | const notag_union_info = @typeInfo(TestNoTagUnion); | |
| 221 | expect(notag_union_info == .Union); | |
| 222 | expect(notag_union_info.Union.tag_type == null); | |
| 223 | expect(notag_union_info.Union.layout == .Auto); | |
| 224 | expect(notag_union_info.Union.fields.len == 2); | |
| 225 | expect(notag_union_info.Union.fields[0].alignment == @alignOf(void)); | |
| 226 | expect(notag_union_info.Union.fields[1].field_type == u32); | |
| 227 | expect(notag_union_info.Union.fields[1].alignment == @alignOf(u32)); | |
| 228 | ||
| 229 | const TestExternUnion = extern union { | |
| 230 | foo: *c_void, | |
| 231 | }; | |
| 232 | ||
| 233 | const extern_union_info = @typeInfo(TestExternUnion); | |
| 234 | expect(extern_union_info.Union.layout == .Extern); | |
| 235 | expect(extern_union_info.Union.tag_type == null); | |
| 236 | expect(extern_union_info.Union.fields[0].field_type == *c_void); | |
| 237 | } | |
| 238 | ||
| 239 | test "type info: struct info" { | |
| 240 | testStruct(); | |
| 241 | comptime testStruct(); | |
| 242 | } | |
| 243 | ||
| 244 | fn testStruct() void { | |
| 245 | const unpacked_struct_info = @typeInfo(TestUnpackedStruct); | |
| 246 | expect(unpacked_struct_info.Struct.is_tuple == false); | |
| 247 | expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); | |
| 248 | expect(unpacked_struct_info.Struct.fields[0].default_value.? == 4); | |
| 249 | expectEqualStrings("foobar", unpacked_struct_info.Struct.fields[1].default_value.?); | |
| 250 | ||
| 251 | const struct_info = @typeInfo(TestStruct); | |
| 252 | expect(struct_info == .Struct); | |
| 253 | expect(struct_info.Struct.is_tuple == false); | |
| 254 | expect(struct_info.Struct.layout == .Packed); | |
| 255 | expect(struct_info.Struct.fields.len == 4); | |
| 256 | expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize)); | |
| 257 | expect(struct_info.Struct.fields[2].field_type == *TestStruct); | |
| 258 | expect(struct_info.Struct.fields[2].default_value == null); | |
| 259 | expect(struct_info.Struct.fields[3].default_value.? == 4); | |
| 260 | expect(struct_info.Struct.fields[3].alignment == 1); | |
| 261 | expect(struct_info.Struct.decls.len == 2); | |
| 262 | expect(struct_info.Struct.decls[0].is_pub); | |
| 263 | expect(!struct_info.Struct.decls[0].data.Fn.is_extern); | |
| 264 | expect(struct_info.Struct.decls[0].data.Fn.lib_name == null); | |
| 265 | expect(struct_info.Struct.decls[0].data.Fn.return_type == void); | |
| 266 | expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void); | |
| 267 | } | |
| 268 | ||
| 269 | const TestUnpackedStruct = struct { | |
| 270 | fieldA: u32 = 4, | |
| 271 | fieldB: *const [6:0]u8 = "foobar", | |
| 272 | }; | |
| 273 | ||
| 274 | const TestStruct = packed struct { | |
| 275 | fieldA: usize align(2 * @alignOf(usize)), | |
| 276 | fieldB: void, | |
| 277 | fieldC: *Self, | |
| 278 | fieldD: u32 = 4, | |
| 279 | ||
| 280 | pub fn foo(self: *const Self) void {} | |
| 281 | const Self = @This(); | |
| 282 | }; | |
| 283 | ||
| 284 | test "type info: opaque info" { | |
| 285 | testOpaque(); | |
| 286 | comptime testOpaque(); | |
| 287 | } | |
| 288 | ||
| 289 | fn testOpaque() void { | |
| 290 | const Foo = opaque { | |
| 291 | const A = 1; | |
| 292 | fn b() void {} | |
| 293 | }; | |
| 294 | ||
| 295 | const foo_info = @typeInfo(Foo); | |
| 296 | expect(foo_info.Opaque.decls.len == 2); | |
| 297 | } | |
| 298 | ||
| 299 | test "type info: function type info" { | |
| 300 | // wasm doesn't support align attributes on functions | |
| 301 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | |
| 302 | testFunction(); | |
| 303 | comptime testFunction(); | |
| 304 | } | |
| 305 | ||
| 306 | fn testFunction() void { | |
| 307 | const fn_info = @typeInfo(@TypeOf(foo)); | |
| 308 | expect(fn_info == .Fn); | |
| 309 | // TODO Fix this before merging the branch | |
| 310 | //expect(fn_info.Fn.alignment > 0); | |
| 311 | expect(fn_info.Fn.calling_convention == .C); | |
| 312 | expect(!fn_info.Fn.is_generic); | |
| 313 | expect(fn_info.Fn.args.len == 2); | |
| 314 | expect(fn_info.Fn.is_var_args); | |
| 315 | expect(fn_info.Fn.return_type.? == usize); | |
| 316 | const fn_aligned_info = @typeInfo(@TypeOf(fooAligned)); | |
| 317 | expect(fn_aligned_info.Fn.alignment == 4); | |
| 318 | ||
| 319 | const test_instance: TestStruct = undefined; | |
| 320 | const bound_fn_info = @typeInfo(@TypeOf(test_instance.foo)); | |
| 321 | expect(bound_fn_info == .BoundFn); | |
| 322 | expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct); | |
| 323 | } | |
| 324 | ||
| 325 | extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; | |
| 326 | extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; | |
| 327 | ||
| 328 | test "typeInfo with comptime parameter in struct fn def" { | |
| 329 | const S = struct { | |
| 330 | pub fn func(comptime x: f32) void {} | |
| 331 | }; | |
| 332 | comptime var info = @typeInfo(S); | |
| 333 | } | |
| 334 | ||
| 335 | test "type info: vectors" { | |
| 336 | testVector(); | |
| 337 | comptime testVector(); | |
| 338 | } | |
| 339 | ||
| 340 | fn testVector() void { | |
| 341 | const vec_info = @typeInfo(std.meta.Vector(4, i32)); | |
| 342 | expect(vec_info == .Vector); | |
| 343 | expect(vec_info.Vector.len == 4); | |
| 344 | expect(vec_info.Vector.child == i32); | |
| 345 | } | |
| 346 | ||
| 347 | test "type info: anyframe and anyframe->T" { | |
| 348 | testAnyFrame(); | |
| 349 | comptime testAnyFrame(); | |
| 350 | } | |
| 351 | ||
| 352 | fn testAnyFrame() void { | |
| 353 | { | |
| 354 | const anyframe_info = @typeInfo(anyframe->i32); | |
| 355 | expect(anyframe_info == .AnyFrame); | |
| 356 | expect(anyframe_info.AnyFrame.child.? == i32); | |
| 357 | } | |
| 358 | ||
| 359 | { | |
| 360 | const anyframe_info = @typeInfo(anyframe); | |
| 361 | expect(anyframe_info == .AnyFrame); | |
| 362 | expect(anyframe_info.AnyFrame.child == null); | |
| 363 | } | |
| 364 | } | |
| 365 | ||
| 366 | test "type info: pass to function" { | |
| 367 | _ = passTypeInfo(@typeInfo(void)); | |
| 368 | _ = comptime passTypeInfo(@typeInfo(void)); | |
| 369 | } | |
| 370 | ||
| 371 | fn passTypeInfo(comptime info: TypeInfo) type { | |
| 372 | return void; | |
| 373 | } | |
| 374 | ||
| 375 | test "type info: TypeId -> TypeInfo impl cast" { | |
| 376 | _ = passTypeInfo(TypeId.Void); | |
| 377 | _ = comptime passTypeInfo(TypeId.Void); | |
| 378 | } | |
| 379 | ||
| 380 | test "type info: extern fns with and without lib names" { | |
| 381 | const S = struct { | |
| 382 | extern fn bar1() void; | |
| 383 | extern "cool" fn bar2() void; | |
| 384 | }; | |
| 385 | const info = @typeInfo(S); | |
| 386 | comptime { | |
| 387 | for (info.Struct.decls) |decl| { | |
| 388 | if (std.mem.eql(u8, decl.name, "bar1")) { | |
| 389 | expect(decl.data.Fn.lib_name == null); | |
| 390 | } else { | |
| 391 | expectEqualStrings("cool", decl.data.Fn.lib_name.?); | |
| 392 | } | |
| 393 | } | |
| 394 | } | |
| 395 | } | |
| 396 | ||
| 397 | test "data field is a compile-time value" { | |
| 398 | const S = struct { | |
| 399 | const Bar = @as(isize, -1); | |
| 400 | }; | |
| 401 | comptime expect(@typeInfo(S).Struct.decls[0].data.Var == isize); | |
| 402 | } | |
| 403 | ||
| 404 | test "sentinel of opaque pointer type" { | |
| 405 | const c_void_info = @typeInfo(*c_void); | |
| 406 | expect(c_void_info.Pointer.sentinel == null); | |
| 407 | } | |
| 408 | ||
| 409 | test "@typeInfo does not force declarations into existence" { | |
| 410 | const S = struct { | |
| 411 | x: i32, | |
| 412 | ||
| 413 | fn doNotReferenceMe() void { | |
| 414 | @compileError("test failed"); | |
| 415 | } | |
| 416 | }; | |
| 417 | comptime expect(@typeInfo(S).Struct.fields.len == 1); | |
| 418 | } | |
| 419 | ||
| 420 | test "defaut value for a var-typed field" { | |
| 421 | const S = struct { x: anytype }; | |
| 422 | expect(@typeInfo(S).Struct.fields[0].default_value == null); | |
| 423 | } | |
| 424 | ||
| 425 | fn add(a: i32, b: i32) i32 { | |
| 426 | return a + b; | |
| 427 | } | |
| 428 | ||
| 429 | test "type info for async frames" { | |
| 430 | switch (@typeInfo(@Frame(add))) { | |
| 431 | .Frame => |frame| { | |
| 432 | expect(frame.function == add); | |
| 433 | }, | |
| 434 | else => unreachable, | |
| 435 | } | |
| 436 | } | |
| 437 | ||
| 438 | test "type info: value is correctly copied" { | |
| 439 | comptime { | |
| 440 | var ptrInfo = @typeInfo([]u32); | |
| 441 | ptrInfo.Pointer.size = .One; | |
| 442 | expect(@typeInfo([]u32).Pointer.size == .Slice); | |
| 443 | } | |
| 444 | } | |
| 445 | ||
| 446 | test "Declarations are returned in declaration order" { | |
| 447 | const S = struct { | |
| 448 | const a = 1; | |
| 449 | const b = 2; | |
| 450 | const c = 3; | |
| 451 | const d = 4; | |
| 452 | const e = 5; | |
| 453 | }; | |
| 454 | const d = @typeInfo(S).Struct.decls; | |
| 455 | expect(std.mem.eql(u8, d[0].name, "a")); | |
| 456 | expect(std.mem.eql(u8, d[1].name, "b")); | |
| 457 | expect(std.mem.eql(u8, d[2].name, "c")); | |
| 458 | expect(std.mem.eql(u8, d[3].name, "d")); | |
| 459 | expect(std.mem.eql(u8, d[4].name, "e")); | |
| 460 | } | |
| 461 | ||
| 462 | test "Struct.is_tuple" { | |
| 463 | expect(@typeInfo(@TypeOf(.{0})).Struct.is_tuple); | |
| 464 | expect(!@typeInfo(@TypeOf(.{ .a = 0 })).Struct.is_tuple); | |
| 465 | } | |
| 466 | ||
| 467 | test "StructField.is_comptime" { | |
| 468 | const info = @typeInfo(struct { x: u8 = 3, comptime y: u32 = 5 }).Struct; | |
| 469 | expect(!info.fields[0].is_comptime); | |
| 470 | expect(info.fields[1].is_comptime); | |
| 471 | } | |
| 472 | ||
| 473 | test "typeInfo resolves usingnamespace declarations" { | |
| 474 | const A = struct { | |
| 475 | pub const f1 = 42; | |
| 476 | }; | |
| 477 | ||
| 478 | const B = struct { | |
| 479 | const f0 = 42; | |
| 480 | usingnamespace A; | |
| 481 | }; | |
| 482 | ||
| 483 | expect(@typeInfo(B).Struct.decls.len == 2); | |
| 484 | //a | |
| 485 | } |
test/stage1/behavior/typename.zig deleted-7| ... | ... | @@ -1,7 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqualSlices = std.testing.expectEqualSlices; | |
| 4 | ||
| 5 | test "slice" { | |
| 6 | expectEqualSlices(u8, "[]u8", @typeName([]u8)); | |
| 7 | } |
test/stage1/behavior/undefined.zig deleted-69| ... | ... | @@ -1,69 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | fn initStaticArray() [10]i32 { | |
| 6 | var array: [10]i32 = undefined; | |
| 7 | array[0] = 1; | |
| 8 | array[4] = 2; | |
| 9 | array[7] = 3; | |
| 10 | array[9] = 4; | |
| 11 | return array; | |
| 12 | } | |
| 13 | const static_array = initStaticArray(); | |
| 14 | test "init static array to undefined" { | |
| 15 | expect(static_array[0] == 1); | |
| 16 | expect(static_array[4] == 2); | |
| 17 | expect(static_array[7] == 3); | |
| 18 | expect(static_array[9] == 4); | |
| 19 | ||
| 20 | comptime { | |
| 21 | expect(static_array[0] == 1); | |
| 22 | expect(static_array[4] == 2); | |
| 23 | expect(static_array[7] == 3); | |
| 24 | expect(static_array[9] == 4); | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | const Foo = struct { | |
| 29 | x: i32, | |
| 30 | ||
| 31 | fn setFooXMethod(foo: *Foo) void { | |
| 32 | foo.x = 3; | |
| 33 | } | |
| 34 | }; | |
| 35 | ||
| 36 | fn setFooX(foo: *Foo) void { | |
| 37 | foo.x = 2; | |
| 38 | } | |
| 39 | ||
| 40 | test "assign undefined to struct" { | |
| 41 | comptime { | |
| 42 | var foo: Foo = undefined; | |
| 43 | setFooX(&foo); | |
| 44 | expect(foo.x == 2); | |
| 45 | } | |
| 46 | { | |
| 47 | var foo: Foo = undefined; | |
| 48 | setFooX(&foo); | |
| 49 | expect(foo.x == 2); | |
| 50 | } | |
| 51 | } | |
| 52 | ||
| 53 | test "assign undefined to struct with method" { | |
| 54 | comptime { | |
| 55 | var foo: Foo = undefined; | |
| 56 | foo.setFooXMethod(); | |
| 57 | expect(foo.x == 3); | |
| 58 | } | |
| 59 | { | |
| 60 | var foo: Foo = undefined; | |
| 61 | foo.setFooXMethod(); | |
| 62 | expect(foo.x == 3); | |
| 63 | } | |
| 64 | } | |
| 65 | ||
| 66 | test "type name of undefined" { | |
| 67 | const x = undefined; | |
| 68 | expect(mem.eql(u8, @typeName(@TypeOf(x)), "(undefined)")); | |
| 69 | } |
test/stage1/behavior/underscore.zig deleted-28| ... | ... | @@ -1,28 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "ignore lval with underscore" { | |
| 5 | _ = false; | |
| 6 | } | |
| 7 | ||
| 8 | test "ignore lval with underscore (for loop)" { | |
| 9 | for ([_]void{}) |_, i| { | |
| 10 | for ([_]void{}) |_, j| { | |
| 11 | break; | |
| 12 | } | |
| 13 | break; | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 17 | test "ignore lval with underscore (while loop)" { | |
| 18 | while (optionalReturnError()) |_| { | |
| 19 | while (optionalReturnError()) |_| { | |
| 20 | break; | |
| 21 | } else |_| {} | |
| 22 | break; | |
| 23 | } else |_| {} | |
| 24 | } | |
| 25 | ||
| 26 | fn optionalReturnError() !?u32 { | |
| 27 | return error.optionalReturnError; | |
| 28 | } |
test/stage1/behavior/union.zig deleted-806| ... | ... | @@ -1,806 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const expectEqual = std.testing.expectEqual; | |
| 4 | const Tag = std.meta.Tag; | |
| 5 | ||
| 6 | const Value = union(enum) { | |
| 7 | Int: u64, | |
| 8 | Array: [9]u8, | |
| 9 | }; | |
| 10 | ||
| 11 | const Agg = struct { | |
| 12 | val1: Value, | |
| 13 | val2: Value, | |
| 14 | }; | |
| 15 | ||
| 16 | const v1 = Value{ .Int = 1234 }; | |
| 17 | const v2 = Value{ .Array = [_]u8{3} ** 9 }; | |
| 18 | ||
| 19 | const err = @as(anyerror!Agg, Agg{ | |
| 20 | .val1 = v1, | |
| 21 | .val2 = v2, | |
| 22 | }); | |
| 23 | ||
| 24 | const array = [_]Value{ | |
| 25 | v1, | |
| 26 | v2, | |
| 27 | v1, | |
| 28 | v2, | |
| 29 | }; | |
| 30 | ||
| 31 | test "unions embedded in aggregate types" { | |
| 32 | switch (array[1]) { | |
| 33 | Value.Array => |arr| expect(arr[4] == 3), | |
| 34 | else => unreachable, | |
| 35 | } | |
| 36 | switch ((err catch unreachable).val1) { | |
| 37 | Value.Int => |x| expect(x == 1234), | |
| 38 | else => unreachable, | |
| 39 | } | |
| 40 | } | |
| 41 | ||
| 42 | const Foo = union { | |
| 43 | float: f64, | |
| 44 | int: i32, | |
| 45 | }; | |
| 46 | ||
| 47 | test "basic unions" { | |
| 48 | var foo = Foo{ .int = 1 }; | |
| 49 | expect(foo.int == 1); | |
| 50 | foo = Foo{ .float = 12.34 }; | |
| 51 | expect(foo.float == 12.34); | |
| 52 | } | |
| 53 | ||
| 54 | test "comptime union field access" { | |
| 55 | comptime { | |
| 56 | var foo = Foo{ .int = 0 }; | |
| 57 | expect(foo.int == 0); | |
| 58 | ||
| 59 | foo = Foo{ .float = 42.42 }; | |
| 60 | expect(foo.float == 42.42); | |
| 61 | } | |
| 62 | } | |
| 63 | ||
| 64 | test "init union with runtime value" { | |
| 65 | var foo: Foo = undefined; | |
| 66 | ||
| 67 | setFloat(&foo, 12.34); | |
| 68 | expect(foo.float == 12.34); | |
| 69 | ||
| 70 | setInt(&foo, 42); | |
| 71 | expect(foo.int == 42); | |
| 72 | } | |
| 73 | ||
| 74 | fn setFloat(foo: *Foo, x: f64) void { | |
| 75 | foo.* = Foo{ .float = x }; | |
| 76 | } | |
| 77 | ||
| 78 | fn setInt(foo: *Foo, x: i32) void { | |
| 79 | foo.* = Foo{ .int = x }; | |
| 80 | } | |
| 81 | ||
| 82 | const FooExtern = extern union { | |
| 83 | float: f64, | |
| 84 | int: i32, | |
| 85 | }; | |
| 86 | ||
| 87 | test "basic extern unions" { | |
| 88 | var foo = FooExtern{ .int = 1 }; | |
| 89 | expect(foo.int == 1); | |
| 90 | foo.float = 12.34; | |
| 91 | expect(foo.float == 12.34); | |
| 92 | } | |
| 93 | ||
| 94 | const Letter = enum { | |
| 95 | A, | |
| 96 | B, | |
| 97 | C, | |
| 98 | }; | |
| 99 | const Payload = union(Letter) { | |
| 100 | A: i32, | |
| 101 | B: f64, | |
| 102 | C: bool, | |
| 103 | }; | |
| 104 | ||
| 105 | test "union with specified enum tag" { | |
| 106 | doTest(); | |
| 107 | comptime doTest(); | |
| 108 | } | |
| 109 | ||
| 110 | fn doTest() void { | |
| 111 | expect(bar(Payload{ .A = 1234 }) == -10); | |
| 112 | } | |
| 113 | ||
| 114 | fn bar(value: Payload) i32 { | |
| 115 | expect(@as(Letter, value) == Letter.A); | |
| 116 | return switch (value) { | |
| 117 | Payload.A => |x| return x - 1244, | |
| 118 | Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21, | |
| 119 | Payload.C => |x| if (x) @as(i32, 30) else 31, | |
| 120 | }; | |
| 121 | } | |
| 122 | ||
| 123 | const MultipleChoice = union(enum(u32)) { | |
| 124 | A = 20, | |
| 125 | B = 40, | |
| 126 | C = 60, | |
| 127 | D = 1000, | |
| 128 | }; | |
| 129 | test "simple union(enum(u32))" { | |
| 130 | var x = MultipleChoice.C; | |
| 131 | expect(x == MultipleChoice.C); | |
| 132 | expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60); | |
| 133 | } | |
| 134 | ||
| 135 | const MultipleChoice2 = union(enum(u32)) { | |
| 136 | Unspecified1: i32, | |
| 137 | A: f32 = 20, | |
| 138 | Unspecified2: void, | |
| 139 | B: bool = 40, | |
| 140 | Unspecified3: i32, | |
| 141 | C: i8 = 60, | |
| 142 | Unspecified4: void, | |
| 143 | D: void = 1000, | |
| 144 | Unspecified5: i32, | |
| 145 | }; | |
| 146 | ||
| 147 | test "union(enum(u32)) with specified and unspecified tag values" { | |
| 148 | comptime expect(Tag(Tag(MultipleChoice2)) == u32); | |
| 149 | testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 150 | comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); | |
| 151 | } | |
| 152 | ||
| 153 | fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void { | |
| 154 | expect(@enumToInt(@as(Tag(MultipleChoice2), x)) == 60); | |
| 155 | expect(1123 == switch (x) { | |
| 156 | MultipleChoice2.A => 1, | |
| 157 | MultipleChoice2.B => 2, | |
| 158 | MultipleChoice2.C => |v| @as(i32, 1000) + v, | |
| 159 | MultipleChoice2.D => 4, | |
| 160 | MultipleChoice2.Unspecified1 => 5, | |
| 161 | MultipleChoice2.Unspecified2 => 6, | |
| 162 | MultipleChoice2.Unspecified3 => 7, | |
| 163 | MultipleChoice2.Unspecified4 => 8, | |
| 164 | MultipleChoice2.Unspecified5 => 9, | |
| 165 | }); | |
| 166 | } | |
| 167 | ||
| 168 | const ExternPtrOrInt = extern union { | |
| 169 | ptr: *u8, | |
| 170 | int: u64, | |
| 171 | }; | |
| 172 | test "extern union size" { | |
| 173 | comptime expect(@sizeOf(ExternPtrOrInt) == 8); | |
| 174 | } | |
| 175 | ||
| 176 | const PackedPtrOrInt = packed union { | |
| 177 | ptr: *u8, | |
| 178 | int: u64, | |
| 179 | }; | |
| 180 | test "extern union size" { | |
| 181 | comptime expect(@sizeOf(PackedPtrOrInt) == 8); | |
| 182 | } | |
| 183 | ||
| 184 | const ZeroBits = union { | |
| 185 | OnlyField: void, | |
| 186 | }; | |
| 187 | test "union with only 1 field which is void should be zero bits" { | |
| 188 | comptime expect(@sizeOf(ZeroBits) == 0); | |
| 189 | } | |
| 190 | ||
| 191 | const TheTag = enum { | |
| 192 | A, | |
| 193 | B, | |
| 194 | C, | |
| 195 | }; | |
| 196 | const TheUnion = union(TheTag) { | |
| 197 | A: i32, | |
| 198 | B: i32, | |
| 199 | C: i32, | |
| 200 | }; | |
| 201 | test "union field access gives the enum values" { | |
| 202 | expect(TheUnion.A == TheTag.A); | |
| 203 | expect(TheUnion.B == TheTag.B); | |
| 204 | expect(TheUnion.C == TheTag.C); | |
| 205 | } | |
| 206 | ||
| 207 | test "cast union to tag type of union" { | |
| 208 | testCastUnionToTag(TheUnion{ .B = 1234 }); | |
| 209 | comptime testCastUnionToTag(TheUnion{ .B = 1234 }); | |
| 210 | } | |
| 211 | ||
| 212 | fn testCastUnionToTag(x: TheUnion) void { | |
| 213 | expect(@as(TheTag, x) == TheTag.B); | |
| 214 | } | |
| 215 | ||
| 216 | test "cast tag type of union to union" { | |
| 217 | var x: Value2 = Letter2.B; | |
| 218 | expect(@as(Letter2, x) == Letter2.B); | |
| 219 | } | |
| 220 | const Letter2 = enum { | |
| 221 | A, | |
| 222 | B, | |
| 223 | C, | |
| 224 | }; | |
| 225 | const Value2 = union(Letter2) { | |
| 226 | A: i32, | |
| 227 | B, | |
| 228 | C, | |
| 229 | }; | |
| 230 | ||
| 231 | test "implicit cast union to its tag type" { | |
| 232 | var x: Value2 = Letter2.B; | |
| 233 | expect(x == Letter2.B); | |
| 234 | giveMeLetterB(x); | |
| 235 | } | |
| 236 | fn giveMeLetterB(x: Letter2) void { | |
| 237 | expect(x == Value2.B); | |
| 238 | } | |
| 239 | ||
| 240 | pub const PackThis = union(enum) { | |
| 241 | Invalid: bool, | |
| 242 | StringLiteral: u2, | |
| 243 | }; | |
| 244 | ||
| 245 | test "constant packed union" { | |
| 246 | testConstPackedUnion(&[_]PackThis{PackThis{ .StringLiteral = 1 }}); | |
| 247 | } | |
| 248 | ||
| 249 | fn testConstPackedUnion(expected_tokens: []const PackThis) void { | |
| 250 | expect(expected_tokens[0].StringLiteral == 1); | |
| 251 | } | |
| 252 | ||
| 253 | test "switch on union with only 1 field" { | |
| 254 | var r: PartialInst = undefined; | |
| 255 | r = PartialInst.Compiled; | |
| 256 | switch (r) { | |
| 257 | PartialInst.Compiled => { | |
| 258 | var z: PartialInstWithPayload = undefined; | |
| 259 | z = PartialInstWithPayload{ .Compiled = 1234 }; | |
| 260 | switch (z) { | |
| 261 | PartialInstWithPayload.Compiled => |x| { | |
| 262 | expect(x == 1234); | |
| 263 | return; | |
| 264 | }, | |
| 265 | } | |
| 266 | }, | |
| 267 | } | |
| 268 | unreachable; | |
| 269 | } | |
| 270 | ||
| 271 | const PartialInst = union(enum) { | |
| 272 | Compiled, | |
| 273 | }; | |
| 274 | ||
| 275 | const PartialInstWithPayload = union(enum) { | |
| 276 | Compiled: i32, | |
| 277 | }; | |
| 278 | ||
| 279 | test "access a member of tagged union with conflicting enum tag name" { | |
| 280 | const Bar = union(enum) { | |
| 281 | A: A, | |
| 282 | B: B, | |
| 283 | ||
| 284 | const A = u8; | |
| 285 | const B = void; | |
| 286 | }; | |
| 287 | ||
| 288 | comptime expect(Bar.A == u8); | |
| 289 | } | |
| 290 | ||
| 291 | test "tagged union initialization with runtime void" { | |
| 292 | expect(testTaggedUnionInit({})); | |
| 293 | } | |
| 294 | ||
| 295 | const TaggedUnionWithAVoid = union(enum) { | |
| 296 | A, | |
| 297 | B: i32, | |
| 298 | }; | |
| 299 | ||
| 300 | fn testTaggedUnionInit(x: anytype) bool { | |
| 301 | const y = TaggedUnionWithAVoid{ .A = x }; | |
| 302 | return @as(Tag(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A; | |
| 303 | } | |
| 304 | ||
| 305 | pub const UnionEnumNoPayloads = union(enum) { | |
| 306 | A, | |
| 307 | B, | |
| 308 | }; | |
| 309 | ||
| 310 | test "tagged union with no payloads" { | |
| 311 | const a = UnionEnumNoPayloads{ .B = {} }; | |
| 312 | switch (a) { | |
| 313 | Tag(UnionEnumNoPayloads).A => @panic("wrong"), | |
| 314 | Tag(UnionEnumNoPayloads).B => {}, | |
| 315 | } | |
| 316 | } | |
| 317 | ||
| 318 | test "union with only 1 field casted to its enum type" { | |
| 319 | const Literal = union(enum) { | |
| 320 | Number: f64, | |
| 321 | Bool: bool, | |
| 322 | }; | |
| 323 | ||
| 324 | const Expr = union(enum) { | |
| 325 | Literal: Literal, | |
| 326 | }; | |
| 327 | ||
| 328 | var e = Expr{ .Literal = Literal{ .Bool = true } }; | |
| 329 | const ExprTag = Tag(Expr); | |
| 330 | comptime expect(Tag(ExprTag) == u0); | |
| 331 | var t = @as(ExprTag, e); | |
| 332 | expect(t == Expr.Literal); | |
| 333 | } | |
| 334 | ||
| 335 | test "union with only 1 field casted to its enum type which has enum value specified" { | |
| 336 | const Literal = union(enum) { | |
| 337 | Number: f64, | |
| 338 | Bool: bool, | |
| 339 | }; | |
| 340 | ||
| 341 | const ExprTag = enum(comptime_int) { | |
| 342 | Literal = 33, | |
| 343 | }; | |
| 344 | ||
| 345 | const Expr = union(ExprTag) { | |
| 346 | Literal: Literal, | |
| 347 | }; | |
| 348 | ||
| 349 | var e = Expr{ .Literal = Literal{ .Bool = true } }; | |
| 350 | comptime expect(Tag(ExprTag) == comptime_int); | |
| 351 | var t = @as(ExprTag, e); | |
| 352 | expect(t == Expr.Literal); | |
| 353 | expect(@enumToInt(t) == 33); | |
| 354 | comptime expect(@enumToInt(t) == 33); | |
| 355 | } | |
| 356 | ||
| 357 | test "@enumToInt works on unions" { | |
| 358 | const Bar = union(enum) { | |
| 359 | A: bool, | |
| 360 | B: u8, | |
| 361 | C, | |
| 362 | }; | |
| 363 | ||
| 364 | const a = Bar{ .A = true }; | |
| 365 | var b = Bar{ .B = undefined }; | |
| 366 | var c = Bar.C; | |
| 367 | expect(@enumToInt(a) == 0); | |
| 368 | expect(@enumToInt(b) == 1); | |
| 369 | expect(@enumToInt(c) == 2); | |
| 370 | } | |
| 371 | ||
| 372 | const Attribute = union(enum) { | |
| 373 | A: bool, | |
| 374 | B: u8, | |
| 375 | }; | |
| 376 | ||
| 377 | fn setAttribute(attr: Attribute) void {} | |
| 378 | ||
| 379 | fn Setter(attr: Attribute) type { | |
| 380 | return struct { | |
| 381 | fn set() void { | |
| 382 | setAttribute(attr); | |
| 383 | } | |
| 384 | }; | |
| 385 | } | |
| 386 | ||
| 387 | test "comptime union field value equality" { | |
| 388 | const a0 = Setter(Attribute{ .A = false }); | |
| 389 | const a1 = Setter(Attribute{ .A = true }); | |
| 390 | const a2 = Setter(Attribute{ .A = false }); | |
| 391 | ||
| 392 | const b0 = Setter(Attribute{ .B = 5 }); | |
| 393 | const b1 = Setter(Attribute{ .B = 9 }); | |
| 394 | const b2 = Setter(Attribute{ .B = 5 }); | |
| 395 | ||
| 396 | expect(a0 == a0); | |
| 397 | expect(a1 == a1); | |
| 398 | expect(a0 == a2); | |
| 399 | ||
| 400 | expect(b0 == b0); | |
| 401 | expect(b1 == b1); | |
| 402 | expect(b0 == b2); | |
| 403 | ||
| 404 | expect(a0 != b0); | |
| 405 | expect(a0 != a1); | |
| 406 | expect(b0 != b1); | |
| 407 | } | |
| 408 | ||
| 409 | test "return union init with void payload" { | |
| 410 | const S = struct { | |
| 411 | fn entry() void { | |
| 412 | expect(func().state == State.one); | |
| 413 | } | |
| 414 | const Outer = union(enum) { | |
| 415 | state: State, | |
| 416 | }; | |
| 417 | const State = union(enum) { | |
| 418 | one: void, | |
| 419 | two: u32, | |
| 420 | }; | |
| 421 | fn func() Outer { | |
| 422 | return Outer{ .state = State{ .one = {} } }; | |
| 423 | } | |
| 424 | }; | |
| 425 | S.entry(); | |
| 426 | comptime S.entry(); | |
| 427 | } | |
| 428 | ||
| 429 | test "@unionInit can modify a union type" { | |
| 430 | const UnionInitEnum = union(enum) { | |
| 431 | Boolean: bool, | |
| 432 | Byte: u8, | |
| 433 | }; | |
| 434 | ||
| 435 | var value: UnionInitEnum = undefined; | |
| 436 | ||
| 437 | value = @unionInit(UnionInitEnum, "Boolean", true); | |
| 438 | expect(value.Boolean == true); | |
| 439 | value.Boolean = false; | |
| 440 | expect(value.Boolean == false); | |
| 441 | ||
| 442 | value = @unionInit(UnionInitEnum, "Byte", 2); | |
| 443 | expect(value.Byte == 2); | |
| 444 | value.Byte = 3; | |
| 445 | expect(value.Byte == 3); | |
| 446 | } | |
| 447 | ||
| 448 | test "@unionInit can modify a pointer value" { | |
| 449 | const UnionInitEnum = union(enum) { | |
| 450 | Boolean: bool, | |
| 451 | Byte: u8, | |
| 452 | }; | |
| 453 | ||
| 454 | var value: UnionInitEnum = undefined; | |
| 455 | var value_ptr = &value; | |
| 456 | ||
| 457 | value_ptr.* = @unionInit(UnionInitEnum, "Boolean", true); | |
| 458 | expect(value.Boolean == true); | |
| 459 | ||
| 460 | value_ptr.* = @unionInit(UnionInitEnum, "Byte", 2); | |
| 461 | expect(value.Byte == 2); | |
| 462 | } | |
| 463 | ||
| 464 | test "union no tag with struct member" { | |
| 465 | const Struct = struct {}; | |
| 466 | const Union = union { | |
| 467 | s: Struct, | |
| 468 | pub fn foo(self: *@This()) void {} | |
| 469 | }; | |
| 470 | var u = Union{ .s = Struct{} }; | |
| 471 | u.foo(); | |
| 472 | } | |
| 473 | ||
| 474 | fn testComparison() void { | |
| 475 | var x = Payload{ .A = 42 }; | |
| 476 | expect(x == .A); | |
| 477 | expect(x != .B); | |
| 478 | expect(x != .C); | |
| 479 | expect((x == .B) == false); | |
| 480 | expect((x == .C) == false); | |
| 481 | expect((x != .A) == false); | |
| 482 | } | |
| 483 | ||
| 484 | test "comparison between union and enum literal" { | |
| 485 | testComparison(); | |
| 486 | comptime testComparison(); | |
| 487 | } | |
| 488 | ||
| 489 | test "packed union generates correctly aligned LLVM type" { | |
| 490 | const U = packed union { | |
| 491 | f1: fn () void, | |
| 492 | f2: u32, | |
| 493 | }; | |
| 494 | var foo = [_]U{ | |
| 495 | U{ .f1 = doTest }, | |
| 496 | U{ .f2 = 0 }, | |
| 497 | }; | |
| 498 | foo[0].f1(); | |
| 499 | } | |
| 500 | ||
| 501 | test "union with one member defaults to u0 tag type" { | |
| 502 | const U0 = union(enum) { | |
| 503 | X: u32, | |
| 504 | }; | |
| 505 | comptime expect(Tag(Tag(U0)) == u0); | |
| 506 | } | |
| 507 | ||
| 508 | test "union with comptime_int tag" { | |
| 509 | const Union = union(enum(comptime_int)) { | |
| 510 | X: u32, | |
| 511 | Y: u16, | |
| 512 | Z: u8, | |
| 513 | }; | |
| 514 | comptime expect(Tag(Tag(Union)) == comptime_int); | |
| 515 | } | |
| 516 | ||
| 517 | test "extern union doesn't trigger field check at comptime" { | |
| 518 | const U = extern union { | |
| 519 | x: u32, | |
| 520 | y: u8, | |
| 521 | }; | |
| 522 | ||
| 523 | const x = U{ .x = 0x55AAAA55 }; | |
| 524 | comptime expect(x.y == 0x55); | |
| 525 | } | |
| 526 | ||
| 527 | const Foo1 = union(enum) { | |
| 528 | f: struct { | |
| 529 | x: usize, | |
| 530 | }, | |
| 531 | }; | |
| 532 | var glbl: Foo1 = undefined; | |
| 533 | ||
| 534 | test "global union with single field is correctly initialized" { | |
| 535 | glbl = Foo1{ | |
| 536 | .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 }, | |
| 537 | }; | |
| 538 | expect(glbl.f.x == 123); | |
| 539 | } | |
| 540 | ||
| 541 | pub const FooUnion = union(enum) { | |
| 542 | U0: usize, | |
| 543 | U1: u8, | |
| 544 | }; | |
| 545 | ||
| 546 | var glbl_array: [2]FooUnion = undefined; | |
| 547 | ||
| 548 | test "initialize global array of union" { | |
| 549 | glbl_array[1] = FooUnion{ .U1 = 2 }; | |
| 550 | glbl_array[0] = FooUnion{ .U0 = 1 }; | |
| 551 | expect(glbl_array[0].U0 == 1); | |
| 552 | expect(glbl_array[1].U1 == 2); | |
| 553 | } | |
| 554 | ||
| 555 | test "anonymous union literal syntax" { | |
| 556 | const S = struct { | |
| 557 | const Number = union { | |
| 558 | int: i32, | |
| 559 | float: f64, | |
| 560 | }; | |
| 561 | ||
| 562 | fn doTheTest() void { | |
| 563 | var i: Number = .{ .int = 42 }; | |
| 564 | var f = makeNumber(); | |
| 565 | expect(i.int == 42); | |
| 566 | expect(f.float == 12.34); | |
| 567 | } | |
| 568 | ||
| 569 | fn makeNumber() Number { | |
| 570 | return .{ .float = 12.34 }; | |
| 571 | } | |
| 572 | }; | |
| 573 | S.doTheTest(); | |
| 574 | comptime S.doTheTest(); | |
| 575 | } | |
| 576 | ||
| 577 | test "update the tag value for zero-sized unions" { | |
| 578 | const S = union(enum) { | |
| 579 | U0: void, | |
| 580 | U1: void, | |
| 581 | }; | |
| 582 | var x = S{ .U0 = {} }; | |
| 583 | expect(x == .U0); | |
| 584 | x = S{ .U1 = {} }; | |
| 585 | expect(x == .U1); | |
| 586 | } | |
| 587 | ||
| 588 | test "function call result coerces from tagged union to the tag" { | |
| 589 | const S = struct { | |
| 590 | const Arch = union(enum) { | |
| 591 | One, | |
| 592 | Two: usize, | |
| 593 | }; | |
| 594 | ||
| 595 | const ArchTag = Tag(Arch); | |
| 596 | ||
| 597 | fn doTheTest() void { | |
| 598 | var x: ArchTag = getArch1(); | |
| 599 | expect(x == .One); | |
| 600 | ||
| 601 | var y: ArchTag = getArch2(); | |
| 602 | expect(y == .Two); | |
| 603 | } | |
| 604 | ||
| 605 | pub fn getArch1() Arch { | |
| 606 | return .One; | |
| 607 | } | |
| 608 | ||
| 609 | pub fn getArch2() Arch { | |
| 610 | return .{ .Two = 99 }; | |
| 611 | } | |
| 612 | }; | |
| 613 | S.doTheTest(); | |
| 614 | comptime S.doTheTest(); | |
| 615 | } | |
| 616 | ||
| 617 | test "0-sized extern union definition" { | |
| 618 | const U = extern union { | |
| 619 | a: void, | |
| 620 | const f = 1; | |
| 621 | }; | |
| 622 | ||
| 623 | expect(U.f == 1); | |
| 624 | } | |
| 625 | ||
| 626 | test "union initializer generates padding only if needed" { | |
| 627 | const U = union(enum) { | |
| 628 | A: u24, | |
| 629 | }; | |
| 630 | ||
| 631 | var v = U{ .A = 532 }; | |
| 632 | expect(v.A == 532); | |
| 633 | } | |
| 634 | ||
| 635 | test "runtime tag name with single field" { | |
| 636 | const U = union(enum) { | |
| 637 | A: i32, | |
| 638 | }; | |
| 639 | ||
| 640 | var v = U{ .A = 42 }; | |
| 641 | expect(std.mem.eql(u8, @tagName(v), "A")); | |
| 642 | } | |
| 643 | ||
| 644 | test "cast from anonymous struct to union" { | |
| 645 | const S = struct { | |
| 646 | const U = union(enum) { | |
| 647 | A: u32, | |
| 648 | B: []const u8, | |
| 649 | C: void, | |
| 650 | }; | |
| 651 | fn doTheTest() void { | |
| 652 | var y: u32 = 42; | |
| 653 | const t0 = .{ .A = 123 }; | |
| 654 | const t1 = .{ .B = "foo" }; | |
| 655 | const t2 = .{ .C = {} }; | |
| 656 | const t3 = .{ .A = y }; | |
| 657 | const x0: U = t0; | |
| 658 | var x1: U = t1; | |
| 659 | const x2: U = t2; | |
| 660 | var x3: U = t3; | |
| 661 | expect(x0.A == 123); | |
| 662 | expect(std.mem.eql(u8, x1.B, "foo")); | |
| 663 | expect(x2 == .C); | |
| 664 | expect(x3.A == y); | |
| 665 | } | |
| 666 | }; | |
| 667 | S.doTheTest(); | |
| 668 | comptime S.doTheTest(); | |
| 669 | } | |
| 670 | ||
| 671 | test "cast from pointer to anonymous struct to pointer to union" { | |
| 672 | const S = struct { | |
| 673 | const U = union(enum) { | |
| 674 | A: u32, | |
| 675 | B: []const u8, | |
| 676 | C: void, | |
| 677 | }; | |
| 678 | fn doTheTest() void { | |
| 679 | var y: u32 = 42; | |
| 680 | const t0 = &.{ .A = 123 }; | |
| 681 | const t1 = &.{ .B = "foo" }; | |
| 682 | const t2 = &.{ .C = {} }; | |
| 683 | const t3 = &.{ .A = y }; | |
| 684 | const x0: *const U = t0; | |
| 685 | var x1: *const U = t1; | |
| 686 | const x2: *const U = t2; | |
| 687 | var x3: *const U = t3; | |
| 688 | expect(x0.A == 123); | |
| 689 | expect(std.mem.eql(u8, x1.B, "foo")); | |
| 690 | expect(x2.* == .C); | |
| 691 | expect(x3.A == y); | |
| 692 | } | |
| 693 | }; | |
| 694 | S.doTheTest(); | |
| 695 | comptime S.doTheTest(); | |
| 696 | } | |
| 697 | ||
| 698 | test "method call on an empty union" { | |
| 699 | const S = struct { | |
| 700 | const MyUnion = union(MyUnionTag) { | |
| 701 | pub const MyUnionTag = enum { X1, X2 }; | |
| 702 | X1: [0]u8, | |
| 703 | X2: [0]u8, | |
| 704 | ||
| 705 | pub fn useIt(self: *@This()) bool { | |
| 706 | return true; | |
| 707 | } | |
| 708 | }; | |
| 709 | ||
| 710 | fn doTheTest() void { | |
| 711 | var u = MyUnion{ .X1 = [0]u8{} }; | |
| 712 | expect(u.useIt()); | |
| 713 | } | |
| 714 | }; | |
| 715 | S.doTheTest(); | |
| 716 | comptime S.doTheTest(); | |
| 717 | } | |
| 718 | ||
| 719 | test "switching on non exhaustive union" { | |
| 720 | const S = struct { | |
| 721 | const E = enum(u8) { | |
| 722 | a, | |
| 723 | b, | |
| 724 | _, | |
| 725 | }; | |
| 726 | const U = union(E) { | |
| 727 | a: i32, | |
| 728 | b: u32, | |
| 729 | }; | |
| 730 | fn doTheTest() void { | |
| 731 | var a = U{ .a = 2 }; | |
| 732 | switch (a) { | |
| 733 | .a => |val| expect(val == 2), | |
| 734 | .b => unreachable, | |
| 735 | } | |
| 736 | } | |
| 737 | }; | |
| 738 | S.doTheTest(); | |
| 739 | comptime S.doTheTest(); | |
| 740 | } | |
| 741 | ||
| 742 | test "containers with single-field enums" { | |
| 743 | const S = struct { | |
| 744 | const A = union(enum) { f1 }; | |
| 745 | const B = union(enum) { f1: void }; | |
| 746 | const C = struct { a: A }; | |
| 747 | const D = struct { a: B }; | |
| 748 | ||
| 749 | fn doTheTest() void { | |
| 750 | var array1 = [1]A{A{ .f1 = {} }}; | |
| 751 | var array2 = [1]B{B{ .f1 = {} }}; | |
| 752 | expect(array1[0] == .f1); | |
| 753 | expect(array2[0] == .f1); | |
| 754 | ||
| 755 | var struct1 = C{ .a = A{ .f1 = {} } }; | |
| 756 | var struct2 = D{ .a = B{ .f1 = {} } }; | |
| 757 | expect(struct1.a == .f1); | |
| 758 | expect(struct2.a == .f1); | |
| 759 | } | |
| 760 | }; | |
| 761 | ||
| 762 | S.doTheTest(); | |
| 763 | comptime S.doTheTest(); | |
| 764 | } | |
| 765 | ||
| 766 | test "@unionInit on union w/ tag but no fields" { | |
| 767 | const S = struct { | |
| 768 | const Type = enum(u8) { no_op = 105 }; | |
| 769 | ||
| 770 | const Data = union(Type) { | |
| 771 | no_op: void, | |
| 772 | ||
| 773 | pub fn decode(buf: []const u8) Data { | |
| 774 | return @unionInit(Data, "no_op", {}); | |
| 775 | } | |
| 776 | }; | |
| 777 | ||
| 778 | comptime { | |
| 779 | expect(@sizeOf(Data) != 0); | |
| 780 | } | |
| 781 | ||
| 782 | fn doTheTest() void { | |
| 783 | var data: Data = .{ .no_op = .{} }; | |
| 784 | var o = Data.decode(&[_]u8{}); | |
| 785 | expectEqual(Type.no_op, o); | |
| 786 | } | |
| 787 | }; | |
| 788 | ||
| 789 | S.doTheTest(); | |
| 790 | comptime S.doTheTest(); | |
| 791 | } | |
| 792 | ||
| 793 | test "union enum type gets a separate scope" { | |
| 794 | const S = struct { | |
| 795 | const U = union(enum) { | |
| 796 | a: u8, | |
| 797 | const foo = 1; | |
| 798 | }; | |
| 799 | ||
| 800 | fn doTheTest() void { | |
| 801 | expect(!@hasDecl(Tag(U), "foo")); | |
| 802 | } | |
| 803 | }; | |
| 804 | ||
| 805 | S.doTheTest(); | |
| 806 | } |
test/stage1/behavior/usingnamespace.zig deleted-22| ... | ... | @@ -1,22 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | ||
| 3 | fn Foo(comptime T: type) type { | |
| 4 | return struct { | |
| 5 | usingnamespace T; | |
| 6 | }; | |
| 7 | } | |
| 8 | ||
| 9 | test "usingnamespace inside a generic struct" { | |
| 10 | const std2 = Foo(std); | |
| 11 | const testing2 = Foo(std.testing); | |
| 12 | std2.testing.expect(true); | |
| 13 | testing2.expect(true); | |
| 14 | } | |
| 15 | ||
| 16 | usingnamespace struct { | |
| 17 | pub const foo = 42; | |
| 18 | }; | |
| 19 | ||
| 20 | test "usingnamespace does not redeclare an imported variable" { | |
| 21 | comptime std.testing.expect(foo == 42); | |
| 22 | } |
test/stage1/behavior/var_args.zig deleted-83| ... | ... | @@ -1,83 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | fn add(args: anytype) i32 { | |
| 4 | var sum = @as(i32, 0); | |
| 5 | { | |
| 6 | comptime var i: usize = 0; | |
| 7 | inline while (i < args.len) : (i += 1) { | |
| 8 | sum += args[i]; | |
| 9 | } | |
| 10 | } | |
| 11 | return sum; | |
| 12 | } | |
| 13 | ||
| 14 | test "add arbitrary args" { | |
| 15 | expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); | |
| 16 | expect(add(.{@as(i32, 1234)}) == 1234); | |
| 17 | expect(add(.{}) == 0); | |
| 18 | } | |
| 19 | ||
| 20 | fn readFirstVarArg(args: anytype) void { | |
| 21 | const value = args[0]; | |
| 22 | } | |
| 23 | ||
| 24 | test "send void arg to var args" { | |
| 25 | readFirstVarArg(.{{}}); | |
| 26 | } | |
| 27 | ||
| 28 | test "pass args directly" { | |
| 29 | expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10); | |
| 30 | expect(addSomeStuff(.{@as(i32, 1234)}) == 1234); | |
| 31 | expect(addSomeStuff(.{}) == 0); | |
| 32 | } | |
| 33 | ||
| 34 | fn addSomeStuff(args: anytype) i32 { | |
| 35 | return add(args); | |
| 36 | } | |
| 37 | ||
| 38 | test "runtime parameter before var args" { | |
| 39 | expect(extraFn(10, .{}) == 0); | |
| 40 | expect(extraFn(10, .{false}) == 1); | |
| 41 | expect(extraFn(10, .{ false, true }) == 2); | |
| 42 | ||
| 43 | comptime { | |
| 44 | expect(extraFn(10, .{}) == 0); | |
| 45 | expect(extraFn(10, .{false}) == 1); | |
| 46 | expect(extraFn(10, .{ false, true }) == 2); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | fn extraFn(extra: u32, args: anytype) usize { | |
| 51 | if (args.len >= 1) { | |
| 52 | expect(args[0] == false); | |
| 53 | } | |
| 54 | if (args.len >= 2) { | |
| 55 | expect(args[1] == true); | |
| 56 | } | |
| 57 | return args.len; | |
| 58 | } | |
| 59 | ||
| 60 | const foos = [_]fn (anytype) bool{ | |
| 61 | foo1, | |
| 62 | foo2, | |
| 63 | }; | |
| 64 | ||
| 65 | fn foo1(args: anytype) bool { | |
| 66 | return true; | |
| 67 | } | |
| 68 | fn foo2(args: anytype) bool { | |
| 69 | return false; | |
| 70 | } | |
| 71 | ||
| 72 | test "array of var args functions" { | |
| 73 | expect(foos[0](.{})); | |
| 74 | expect(!foos[1](.{})); | |
| 75 | } | |
| 76 | ||
| 77 | test "pass zero length array to var args param" { | |
| 78 | doNothingWithFirstArg(.{""}); | |
| 79 | } | |
| 80 | ||
| 81 | fn doNothingWithFirstArg(args: anytype) void { | |
| 82 | const a = args[0]; | |
| 83 | } |
test/stage1/behavior/vector.zig deleted-655| ... | ... | @@ -1,655 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const mem = std.mem; | |
| 4 | const math = std.math; | |
| 5 | const expect = std.testing.expect; | |
| 6 | const expectEqual = std.testing.expectEqual; | |
| 7 | const expectApproxEqRel = std.testing.expectApproxEqRel; | |
| 8 | const Vector = std.meta.Vector; | |
| 9 | ||
| 10 | test "implicit cast vector to array - bool" { | |
| 11 | const S = struct { | |
| 12 | fn doTheTest() void { | |
| 13 | const a: Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 14 | const result_array: [4]bool = a; | |
| 15 | expect(mem.eql(bool, &result_array, &[4]bool{ true, false, true, false })); | |
| 16 | } | |
| 17 | }; | |
| 18 | S.doTheTest(); | |
| 19 | comptime S.doTheTest(); | |
| 20 | } | |
| 21 | ||
| 22 | test "vector wrap operators" { | |
| 23 | const S = struct { | |
| 24 | fn doTheTest() void { | |
| 25 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 26 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 }; | |
| 27 | expect(mem.eql(i32, &@as([4]i32, v +% x), &[4]i32{ -2147483648, 2147483645, 33, 44 })); | |
| 28 | expect(mem.eql(i32, &@as([4]i32, v -% x), &[4]i32{ 2147483646, 2147483647, 27, 36 })); | |
| 29 | expect(mem.eql(i32, &@as([4]i32, v *% x), &[4]i32{ 2147483647, 2, 90, 160 })); | |
| 30 | var z: Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 }; | |
| 31 | expect(mem.eql(i32, &@as([4]i32, -%z), &[4]i32{ -1, -2, -3, -2147483648 })); | |
| 32 | } | |
| 33 | }; | |
| 34 | S.doTheTest(); | |
| 35 | comptime S.doTheTest(); | |
| 36 | } | |
| 37 | ||
| 38 | test "vector bin compares with mem.eql" { | |
| 39 | const S = struct { | |
| 40 | fn doTheTest() void { | |
| 41 | var v: Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 }; | |
| 42 | var x: Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 }; | |
| 43 | expect(mem.eql(bool, &@as([4]bool, v == x), &[4]bool{ false, false, true, false })); | |
| 44 | expect(mem.eql(bool, &@as([4]bool, v != x), &[4]bool{ true, true, false, true })); | |
| 45 | expect(mem.eql(bool, &@as([4]bool, v < x), &[4]bool{ false, true, false, false })); | |
| 46 | expect(mem.eql(bool, &@as([4]bool, v > x), &[4]bool{ true, false, false, true })); | |
| 47 | expect(mem.eql(bool, &@as([4]bool, v <= x), &[4]bool{ false, true, true, false })); | |
| 48 | expect(mem.eql(bool, &@as([4]bool, v >= x), &[4]bool{ true, false, true, true })); | |
| 49 | } | |
| 50 | }; | |
| 51 | S.doTheTest(); | |
| 52 | comptime S.doTheTest(); | |
| 53 | } | |
| 54 | ||
| 55 | test "vector int operators" { | |
| 56 | const S = struct { | |
| 57 | fn doTheTest() void { | |
| 58 | var v: Vector(4, i32) = [4]i32{ 10, 20, 30, 40 }; | |
| 59 | var x: Vector(4, i32) = [4]i32{ 1, 2, 3, 4 }; | |
| 60 | expect(mem.eql(i32, &@as([4]i32, v + x), &[4]i32{ 11, 22, 33, 44 })); | |
| 61 | expect(mem.eql(i32, &@as([4]i32, v - x), &[4]i32{ 9, 18, 27, 36 })); | |
| 62 | expect(mem.eql(i32, &@as([4]i32, v * x), &[4]i32{ 10, 40, 90, 160 })); | |
| 63 | expect(mem.eql(i32, &@as([4]i32, -v), &[4]i32{ -10, -20, -30, -40 })); | |
| 64 | } | |
| 65 | }; | |
| 66 | S.doTheTest(); | |
| 67 | comptime S.doTheTest(); | |
| 68 | } | |
| 69 | ||
| 70 | test "vector float operators" { | |
| 71 | const S = struct { | |
| 72 | fn doTheTest() void { | |
| 73 | var v: Vector(4, f32) = [4]f32{ 10, 20, 30, 40 }; | |
| 74 | var x: Vector(4, f32) = [4]f32{ 1, 2, 3, 4 }; | |
| 75 | expect(mem.eql(f32, &@as([4]f32, v + x), &[4]f32{ 11, 22, 33, 44 })); | |
| 76 | expect(mem.eql(f32, &@as([4]f32, v - x), &[4]f32{ 9, 18, 27, 36 })); | |
| 77 | expect(mem.eql(f32, &@as([4]f32, v * x), &[4]f32{ 10, 40, 90, 160 })); | |
| 78 | expect(mem.eql(f32, &@as([4]f32, -x), &[4]f32{ -1, -2, -3, -4 })); | |
| 79 | } | |
| 80 | }; | |
| 81 | S.doTheTest(); | |
| 82 | comptime S.doTheTest(); | |
| 83 | } | |
| 84 | ||
| 85 | test "vector bit operators" { | |
| 86 | const S = struct { | |
| 87 | fn doTheTest() void { | |
| 88 | var v: Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 }; | |
| 89 | var x: Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 }; | |
| 90 | expect(mem.eql(u8, &@as([4]u8, v ^ x), &[4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 })); | |
| 91 | expect(mem.eql(u8, &@as([4]u8, v | x), &[4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 })); | |
| 92 | expect(mem.eql(u8, &@as([4]u8, v & x), &[4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 })); | |
| 93 | } | |
| 94 | }; | |
| 95 | S.doTheTest(); | |
| 96 | comptime S.doTheTest(); | |
| 97 | } | |
| 98 | ||
| 99 | test "implicit cast vector to array" { | |
| 100 | const S = struct { | |
| 101 | fn doTheTest() void { | |
| 102 | var a: Vector(4, i32) = [_]i32{ 1, 2, 3, 4 }; | |
| 103 | var result_array: [4]i32 = a; | |
| 104 | result_array = a; | |
| 105 | expect(mem.eql(i32, &result_array, &[4]i32{ 1, 2, 3, 4 })); | |
| 106 | } | |
| 107 | }; | |
| 108 | S.doTheTest(); | |
| 109 | comptime S.doTheTest(); | |
| 110 | } | |
| 111 | ||
| 112 | test "array to vector" { | |
| 113 | var foo: f32 = 3.14; | |
| 114 | var arr = [4]f32{ foo, 1.5, 0.0, 0.0 }; | |
| 115 | var vec: Vector(4, f32) = arr; | |
| 116 | } | |
| 117 | ||
| 118 | test "vector casts of sizes not divisable by 8" { | |
| 119 | // https://github.com/ziglang/zig/issues/3563 | |
| 120 | if (std.Target.current.os.tag == .dragonfly) return error.SkipZigTest; | |
| 121 | ||
| 122 | const S = struct { | |
| 123 | fn doTheTest() void { | |
| 124 | { | |
| 125 | var v: Vector(4, u3) = [4]u3{ 5, 2, 3, 0 }; | |
| 126 | var x: [4]u3 = v; | |
| 127 | expect(mem.eql(u3, &x, &@as([4]u3, v))); | |
| 128 | } | |
| 129 | { | |
| 130 | var v: Vector(4, u2) = [4]u2{ 1, 2, 3, 0 }; | |
| 131 | var x: [4]u2 = v; | |
| 132 | expect(mem.eql(u2, &x, &@as([4]u2, v))); | |
| 133 | } | |
| 134 | { | |
| 135 | var v: Vector(4, u1) = [4]u1{ 1, 0, 1, 0 }; | |
| 136 | var x: [4]u1 = v; | |
| 137 | expect(mem.eql(u1, &x, &@as([4]u1, v))); | |
| 138 | } | |
| 139 | { | |
| 140 | var v: Vector(4, bool) = [4]bool{ false, false, true, false }; | |
| 141 | var x: [4]bool = v; | |
| 142 | expect(mem.eql(bool, &x, &@as([4]bool, v))); | |
| 143 | } | |
| 144 | } | |
| 145 | }; | |
| 146 | S.doTheTest(); | |
| 147 | comptime S.doTheTest(); | |
| 148 | } | |
| 149 | ||
| 150 | test "vector @splat" { | |
| 151 | const S = struct { | |
| 152 | fn testForT(comptime N: comptime_int, v: anytype) void { | |
| 153 | const T = @TypeOf(v); | |
| 154 | var vec = @splat(N, v); | |
| 155 | expectEqual(Vector(N, T), @TypeOf(vec)); | |
| 156 | var as_array = @as([N]T, vec); | |
| 157 | for (as_array) |elem| expectEqual(v, elem); | |
| 158 | } | |
| 159 | fn doTheTest() void { | |
| 160 | // Splats with multiple-of-8 bit types that fill a 128bit vector. | |
| 161 | testForT(16, @as(u8, 0xEE)); | |
| 162 | testForT(8, @as(u16, 0xBEEF)); | |
| 163 | testForT(4, @as(u32, 0xDEADBEEF)); | |
| 164 | testForT(2, @as(u64, 0xCAFEF00DDEADBEEF)); | |
| 165 | ||
| 166 | testForT(8, @as(f16, 3.1415)); | |
| 167 | testForT(4, @as(f32, 3.1415)); | |
| 168 | testForT(2, @as(f64, 3.1415)); | |
| 169 | ||
| 170 | // Same but fill more than 128 bits. | |
| 171 | testForT(16 * 2, @as(u8, 0xEE)); | |
| 172 | testForT(8 * 2, @as(u16, 0xBEEF)); | |
| 173 | testForT(4 * 2, @as(u32, 0xDEADBEEF)); | |
| 174 | testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF)); | |
| 175 | ||
| 176 | testForT(8 * 2, @as(f16, 3.1415)); | |
| 177 | testForT(4 * 2, @as(f32, 3.1415)); | |
| 178 | testForT(2 * 2, @as(f64, 3.1415)); | |
| 179 | } | |
| 180 | }; | |
| 181 | S.doTheTest(); | |
| 182 | comptime S.doTheTest(); | |
| 183 | } | |
| 184 | ||
| 185 | test "load vector elements via comptime index" { | |
| 186 | const S = struct { | |
| 187 | fn doTheTest() void { | |
| 188 | var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined }; | |
| 189 | expect(v[0] == 1); | |
| 190 | expect(v[1] == 2); | |
| 191 | expect(loadv(&v[2]) == 3); | |
| 192 | } | |
| 193 | fn loadv(ptr: anytype) i32 { | |
| 194 | return ptr.*; | |
| 195 | } | |
| 196 | }; | |
| 197 | ||
| 198 | S.doTheTest(); | |
| 199 | comptime S.doTheTest(); | |
| 200 | } | |
| 201 | ||
| 202 | test "store vector elements via comptime index" { | |
| 203 | const S = struct { | |
| 204 | fn doTheTest() void { | |
| 205 | var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; | |
| 206 | ||
| 207 | v[2] = 42; | |
| 208 | expect(v[1] == 5); | |
| 209 | v[3] = -364; | |
| 210 | expect(v[2] == 42); | |
| 211 | expect(-364 == v[3]); | |
| 212 | ||
| 213 | storev(&v[0], 100); | |
| 214 | expect(v[0] == 100); | |
| 215 | } | |
| 216 | fn storev(ptr: anytype, x: i32) void { | |
| 217 | ptr.* = x; | |
| 218 | } | |
| 219 | }; | |
| 220 | ||
| 221 | S.doTheTest(); | |
| 222 | comptime S.doTheTest(); | |
| 223 | } | |
| 224 | ||
| 225 | test "load vector elements via runtime index" { | |
| 226 | const S = struct { | |
| 227 | fn doTheTest() void { | |
| 228 | var v: Vector(4, i32) = [_]i32{ 1, 2, 3, undefined }; | |
| 229 | var i: u32 = 0; | |
| 230 | expect(v[i] == 1); | |
| 231 | i += 1; | |
| 232 | expect(v[i] == 2); | |
| 233 | i += 1; | |
| 234 | expect(v[i] == 3); | |
| 235 | } | |
| 236 | }; | |
| 237 | ||
| 238 | S.doTheTest(); | |
| 239 | comptime S.doTheTest(); | |
| 240 | } | |
| 241 | ||
| 242 | test "store vector elements via runtime index" { | |
| 243 | const S = struct { | |
| 244 | fn doTheTest() void { | |
| 245 | var v: Vector(4, i32) = [_]i32{ 1, 5, 3, undefined }; | |
| 246 | var i: u32 = 2; | |
| 247 | v[i] = 1; | |
| 248 | expect(v[1] == 5); | |
| 249 | expect(v[2] == 1); | |
| 250 | i += 1; | |
| 251 | v[i] = -364; | |
| 252 | expect(-364 == v[3]); | |
| 253 | } | |
| 254 | }; | |
| 255 | ||
| 256 | S.doTheTest(); | |
| 257 | comptime S.doTheTest(); | |
| 258 | } | |
| 259 | ||
| 260 | test "initialize vector which is a struct field" { | |
| 261 | const Vec4Obj = struct { | |
| 262 | data: Vector(4, f32), | |
| 263 | }; | |
| 264 | ||
| 265 | const S = struct { | |
| 266 | fn doTheTest() void { | |
| 267 | var foo = Vec4Obj{ | |
| 268 | .data = [_]f32{ 1, 2, 3, 4 }, | |
| 269 | }; | |
| 270 | } | |
| 271 | }; | |
| 272 | S.doTheTest(); | |
| 273 | comptime S.doTheTest(); | |
| 274 | } | |
| 275 | ||
| 276 | test "vector comparison operators" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | { | |
| 280 | const v1: Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 281 | const v2: Vector(4, bool) = [_]bool{ false, true, false, true }; | |
| 282 | expectEqual(@splat(4, true), v1 == v1); | |
| 283 | expectEqual(@splat(4, false), v1 == v2); | |
| 284 | expectEqual(@splat(4, true), v1 != v2); | |
| 285 | expectEqual(@splat(4, false), v2 != v2); | |
| 286 | } | |
| 287 | { | |
| 288 | const v1 = @splat(4, @as(u32, 0xc0ffeeee)); | |
| 289 | const v2: Vector(4, c_uint) = v1; | |
| 290 | const v3 = @splat(4, @as(u32, 0xdeadbeef)); | |
| 291 | expectEqual(@splat(4, true), v1 == v2); | |
| 292 | expectEqual(@splat(4, false), v1 == v3); | |
| 293 | expectEqual(@splat(4, true), v1 != v3); | |
| 294 | expectEqual(@splat(4, false), v1 != v2); | |
| 295 | } | |
| 296 | { | |
| 297 | // Comptime-known LHS/RHS | |
| 298 | var v1: @Vector(4, u32) = [_]u32{ 2, 1, 2, 1 }; | |
| 299 | const v2 = @splat(4, @as(u32, 2)); | |
| 300 | const v3: @Vector(4, bool) = [_]bool{ true, false, true, false }; | |
| 301 | expectEqual(v3, v1 == v2); | |
| 302 | expectEqual(v3, v2 == v1); | |
| 303 | } | |
| 304 | } | |
| 305 | }; | |
| 306 | S.doTheTest(); | |
| 307 | comptime S.doTheTest(); | |
| 308 | } | |
| 309 | ||
| 310 | test "vector division operators" { | |
| 311 | const S = struct { | |
| 312 | fn doTheTestDiv(comptime T: type, x: Vector(4, T), y: Vector(4, T)) void { | |
| 313 | if (!comptime std.meta.trait.isSignedInt(T)) { | |
| 314 | const d0 = x / y; | |
| 315 | for (@as([4]T, d0)) |v, i| { | |
| 316 | expectEqual(x[i] / y[i], v); | |
| 317 | } | |
| 318 | } | |
| 319 | const d1 = @divExact(x, y); | |
| 320 | for (@as([4]T, d1)) |v, i| { | |
| 321 | expectEqual(@divExact(x[i], y[i]), v); | |
| 322 | } | |
| 323 | const d2 = @divFloor(x, y); | |
| 324 | for (@as([4]T, d2)) |v, i| { | |
| 325 | expectEqual(@divFloor(x[i], y[i]), v); | |
| 326 | } | |
| 327 | const d3 = @divTrunc(x, y); | |
| 328 | for (@as([4]T, d3)) |v, i| { | |
| 329 | expectEqual(@divTrunc(x[i], y[i]), v); | |
| 330 | } | |
| 331 | } | |
| 332 | ||
| 333 | fn doTheTestMod(comptime T: type, x: Vector(4, T), y: Vector(4, T)) void { | |
| 334 | if ((!comptime std.meta.trait.isSignedInt(T)) and @typeInfo(T) != .Float) { | |
| 335 | const r0 = x % y; | |
| 336 | for (@as([4]T, r0)) |v, i| { | |
| 337 | expectEqual(x[i] % y[i], v); | |
| 338 | } | |
| 339 | } | |
| 340 | const r1 = @mod(x, y); | |
| 341 | for (@as([4]T, r1)) |v, i| { | |
| 342 | expectEqual(@mod(x[i], y[i]), v); | |
| 343 | } | |
| 344 | const r2 = @rem(x, y); | |
| 345 | for (@as([4]T, r2)) |v, i| { | |
| 346 | expectEqual(@rem(x[i], y[i]), v); | |
| 347 | } | |
| 348 | } | |
| 349 | ||
| 350 | fn doTheTest() void { | |
| 351 | // https://github.com/ziglang/zig/issues/4952 | |
| 352 | if (builtin.target.os.tag != .windows) { | |
| 353 | doTheTestDiv(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, -1.0, -2.0 }); | |
| 354 | } | |
| 355 | ||
| 356 | doTheTestDiv(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, -1.0, -2.0 }); | |
| 357 | doTheTestDiv(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, -1.0, -2.0 }); | |
| 358 | ||
| 359 | // https://github.com/ziglang/zig/issues/4952 | |
| 360 | if (builtin.target.os.tag != .windows) { | |
| 361 | doTheTestMod(f16, [4]f16{ 4.0, -4.0, 4.0, -4.0 }, [4]f16{ 1.0, 2.0, 0.5, 3.0 }); | |
| 362 | } | |
| 363 | doTheTestMod(f32, [4]f32{ 4.0, -4.0, 4.0, -4.0 }, [4]f32{ 1.0, 2.0, 0.5, 3.0 }); | |
| 364 | doTheTestMod(f64, [4]f64{ 4.0, -4.0, 4.0, -4.0 }, [4]f64{ 1.0, 2.0, 0.5, 3.0 }); | |
| 365 | ||
| 366 | doTheTestDiv(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, -1, -2 }); | |
| 367 | doTheTestDiv(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, -1, -2 }); | |
| 368 | doTheTestDiv(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, -1, -2 }); | |
| 369 | doTheTestDiv(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, -1, -2 }); | |
| 370 | ||
| 371 | doTheTestMod(i8, [4]i8{ 4, -4, 4, -4 }, [4]i8{ 1, 2, 4, 8 }); | |
| 372 | doTheTestMod(i16, [4]i16{ 4, -4, 4, -4 }, [4]i16{ 1, 2, 4, 8 }); | |
| 373 | doTheTestMod(i32, [4]i32{ 4, -4, 4, -4 }, [4]i32{ 1, 2, 4, 8 }); | |
| 374 | doTheTestMod(i64, [4]i64{ 4, -4, 4, -4 }, [4]i64{ 1, 2, 4, 8 }); | |
| 375 | ||
| 376 | doTheTestDiv(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 }); | |
| 377 | doTheTestDiv(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 }); | |
| 378 | doTheTestDiv(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 }); | |
| 379 | doTheTestDiv(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 }); | |
| 380 | ||
| 381 | doTheTestMod(u8, [4]u8{ 1, 2, 4, 8 }, [4]u8{ 1, 1, 2, 4 }); | |
| 382 | doTheTestMod(u16, [4]u16{ 1, 2, 4, 8 }, [4]u16{ 1, 1, 2, 4 }); | |
| 383 | doTheTestMod(u32, [4]u32{ 1, 2, 4, 8 }, [4]u32{ 1, 1, 2, 4 }); | |
| 384 | doTheTestMod(u64, [4]u64{ 1, 2, 4, 8 }, [4]u64{ 1, 1, 2, 4 }); | |
| 385 | } | |
| 386 | }; | |
| 387 | ||
| 388 | S.doTheTest(); | |
| 389 | comptime S.doTheTest(); | |
| 390 | } | |
| 391 | ||
| 392 | test "vector bitwise not operator" { | |
| 393 | const S = struct { | |
| 394 | fn doTheTestNot(comptime T: type, x: Vector(4, T)) void { | |
| 395 | var y = ~x; | |
| 396 | for (@as([4]T, y)) |v, i| { | |
| 397 | expectEqual(~x[i], v); | |
| 398 | } | |
| 399 | } | |
| 400 | fn doTheTest() void { | |
| 401 | doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 }); | |
| 402 | doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 }); | |
| 403 | doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 }); | |
| 404 | doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 }); | |
| 405 | ||
| 406 | doTheTestNot(u8, [_]u8{ 0, 2, 4, 255 }); | |
| 407 | doTheTestNot(u16, [_]u16{ 0, 2, 4, 255 }); | |
| 408 | doTheTestNot(u32, [_]u32{ 0, 2, 4, 255 }); | |
| 409 | doTheTestNot(u64, [_]u64{ 0, 2, 4, 255 }); | |
| 410 | } | |
| 411 | }; | |
| 412 | ||
| 413 | S.doTheTest(); | |
| 414 | comptime S.doTheTest(); | |
| 415 | } | |
| 416 | ||
| 417 | test "vector shift operators" { | |
| 418 | // TODO investigate why this fails when cross-compiled to wasm. | |
| 419 | if (builtin.target.os.tag == .wasi) return error.SkipZigTest; | |
| 420 | ||
| 421 | const S = struct { | |
| 422 | fn doTheTestShift(x: anytype, y: anytype) void { | |
| 423 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 424 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 425 | const TY = @typeInfo(@TypeOf(y)).Array.child; | |
| 426 | ||
| 427 | var xv = @as(Vector(N, TX), x); | |
| 428 | var yv = @as(Vector(N, TY), y); | |
| 429 | ||
| 430 | var z0 = xv >> yv; | |
| 431 | for (@as([N]TX, z0)) |v, i| { | |
| 432 | expectEqual(x[i] >> y[i], v); | |
| 433 | } | |
| 434 | var z1 = xv << yv; | |
| 435 | for (@as([N]TX, z1)) |v, i| { | |
| 436 | expectEqual(x[i] << y[i], v); | |
| 437 | } | |
| 438 | } | |
| 439 | fn doTheTestShiftExact(x: anytype, y: anytype, dir: enum { Left, Right }) void { | |
| 440 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 441 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 442 | const TY = @typeInfo(@TypeOf(y)).Array.child; | |
| 443 | ||
| 444 | var xv = @as(Vector(N, TX), x); | |
| 445 | var yv = @as(Vector(N, TY), y); | |
| 446 | ||
| 447 | var z = if (dir == .Left) @shlExact(xv, yv) else @shrExact(xv, yv); | |
| 448 | for (@as([N]TX, z)) |v, i| { | |
| 449 | const check = if (dir == .Left) x[i] << y[i] else x[i] >> y[i]; | |
| 450 | expectEqual(check, v); | |
| 451 | } | |
| 452 | } | |
| 453 | fn doTheTest() void { | |
| 454 | doTheTestShift([_]u8{ 0, 2, 4, math.maxInt(u8) }, [_]u3{ 2, 0, 2, 7 }); | |
| 455 | doTheTestShift([_]u16{ 0, 2, 4, math.maxInt(u16) }, [_]u4{ 2, 0, 2, 15 }); | |
| 456 | doTheTestShift([_]u24{ 0, 2, 4, math.maxInt(u24) }, [_]u5{ 2, 0, 2, 23 }); | |
| 457 | doTheTestShift([_]u32{ 0, 2, 4, math.maxInt(u32) }, [_]u5{ 2, 0, 2, 31 }); | |
| 458 | doTheTestShift([_]u64{ 0xfe, math.maxInt(u64) }, [_]u6{ 0, 63 }); | |
| 459 | ||
| 460 | doTheTestShift([_]i8{ 0, 2, 4, math.maxInt(i8) }, [_]u3{ 2, 0, 2, 7 }); | |
| 461 | doTheTestShift([_]i16{ 0, 2, 4, math.maxInt(i16) }, [_]u4{ 2, 0, 2, 7 }); | |
| 462 | doTheTestShift([_]i24{ 0, 2, 4, math.maxInt(i24) }, [_]u5{ 2, 0, 2, 7 }); | |
| 463 | doTheTestShift([_]i32{ 0, 2, 4, math.maxInt(i32) }, [_]u5{ 2, 0, 2, 7 }); | |
| 464 | doTheTestShift([_]i64{ 0xfe, math.maxInt(i64) }, [_]u6{ 0, 63 }); | |
| 465 | ||
| 466 | doTheTestShiftExact([_]u8{ 0, 1, 1 << 7, math.maxInt(u8) ^ 1 }, [_]u3{ 4, 0, 7, 1 }, .Right); | |
| 467 | doTheTestShiftExact([_]u16{ 0, 1, 1 << 15, math.maxInt(u16) ^ 1 }, [_]u4{ 4, 0, 15, 1 }, .Right); | |
| 468 | doTheTestShiftExact([_]u24{ 0, 1, 1 << 23, math.maxInt(u24) ^ 1 }, [_]u5{ 4, 0, 23, 1 }, .Right); | |
| 469 | doTheTestShiftExact([_]u32{ 0, 1, 1 << 31, math.maxInt(u32) ^ 1 }, [_]u5{ 4, 0, 31, 1 }, .Right); | |
| 470 | doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 63, 0 }, .Right); | |
| 471 | ||
| 472 | doTheTestShiftExact([_]u8{ 0, 1, 1, math.maxInt(u8) ^ (1 << 7) }, [_]u3{ 4, 0, 7, 1 }, .Left); | |
| 473 | doTheTestShiftExact([_]u16{ 0, 1, 1, math.maxInt(u16) ^ (1 << 15) }, [_]u4{ 4, 0, 15, 1 }, .Left); | |
| 474 | doTheTestShiftExact([_]u24{ 0, 1, 1, math.maxInt(u24) ^ (1 << 23) }, [_]u5{ 4, 0, 23, 1 }, .Left); | |
| 475 | doTheTestShiftExact([_]u32{ 0, 1, 1, math.maxInt(u32) ^ (1 << 31) }, [_]u5{ 4, 0, 31, 1 }, .Left); | |
| 476 | doTheTestShiftExact([_]u64{ 1 << 63, 1 }, [_]u6{ 0, 63 }, .Left); | |
| 477 | } | |
| 478 | }; | |
| 479 | ||
| 480 | switch (builtin.target.cpu.arch) { | |
| 481 | .i386, | |
| 482 | .aarch64, | |
| 483 | .aarch64_be, | |
| 484 | .aarch64_32, | |
| 485 | .arm, | |
| 486 | .armeb, | |
| 487 | .thumb, | |
| 488 | .thumbeb, | |
| 489 | .mips, | |
| 490 | .mipsel, | |
| 491 | .mips64, | |
| 492 | .mips64el, | |
| 493 | .riscv64, | |
| 494 | .sparcv9, | |
| 495 | => { | |
| 496 | // LLVM miscompiles on this architecture | |
| 497 | // https://github.com/ziglang/zig/issues/4951 | |
| 498 | return error.SkipZigTest; | |
| 499 | }, | |
| 500 | else => {}, | |
| 501 | } | |
| 502 | ||
| 503 | S.doTheTest(); | |
| 504 | comptime S.doTheTest(); | |
| 505 | } | |
| 506 | ||
| 507 | test "vector reduce operation" { | |
| 508 | const S = struct { | |
| 509 | fn doTheTestReduce(comptime op: std.builtin.ReduceOp, x: anytype, expected: anytype) void { | |
| 510 | const N = @typeInfo(@TypeOf(x)).Array.len; | |
| 511 | const TX = @typeInfo(@TypeOf(x)).Array.child; | |
| 512 | ||
| 513 | // wasmtime: unknown import: `env::fminf` has not been defined | |
| 514 | // https://github.com/ziglang/zig/issues/8131 | |
| 515 | switch (builtin.target.cpu.arch) { | |
| 516 | .wasm32 => switch (@typeInfo(TX)) { | |
| 517 | .Float => switch (op) { | |
| 518 | .Min, | |
| 519 | .Max, | |
| 520 | => return, | |
| 521 | else => {}, | |
| 522 | }, | |
| 523 | else => {}, | |
| 524 | }, | |
| 525 | else => {}, | |
| 526 | } | |
| 527 | ||
| 528 | var r = @reduce(op, @as(Vector(N, TX), x)); | |
| 529 | switch (@typeInfo(TX)) { | |
| 530 | .Int, .Bool => expectEqual(expected, r), | |
| 531 | .Float => { | |
| 532 | const expected_nan = math.isNan(expected); | |
| 533 | const got_nan = math.isNan(r); | |
| 534 | ||
| 535 | if (expected_nan and got_nan) { | |
| 536 | // Do this check explicitly as two NaN values are never | |
| 537 | // equal. | |
| 538 | } else { | |
| 539 | expectApproxEqRel(expected, r, math.sqrt(math.epsilon(TX))); | |
| 540 | } | |
| 541 | }, | |
| 542 | else => unreachable, | |
| 543 | } | |
| 544 | } | |
| 545 | fn doTheTest() void { | |
| 546 | doTheTestReduce(.Add, [4]i16{ -9, -99, -999, -9999 }, @as(i32, -11106)); | |
| 547 | doTheTestReduce(.Add, [4]u16{ 9, 99, 999, 9999 }, @as(u32, 11106)); | |
| 548 | doTheTestReduce(.Add, [4]i32{ -9, -99, -999, -9999 }, @as(i32, -11106)); | |
| 549 | doTheTestReduce(.Add, [4]u32{ 9, 99, 999, 9999 }, @as(u32, 11106)); | |
| 550 | doTheTestReduce(.Add, [4]i64{ -9, -99, -999, -9999 }, @as(i64, -11106)); | |
| 551 | doTheTestReduce(.Add, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 11106)); | |
| 552 | doTheTestReduce(.Add, [4]i128{ -9, -99, -999, -9999 }, @as(i128, -11106)); | |
| 553 | doTheTestReduce(.Add, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 11106)); | |
| 554 | doTheTestReduce(.Add, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 42.9)); | |
| 555 | doTheTestReduce(.Add, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 42.9)); | |
| 556 | doTheTestReduce(.Add, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 42.9)); | |
| 557 | ||
| 558 | doTheTestReduce(.And, [4]bool{ true, false, true, true }, @as(bool, false)); | |
| 559 | doTheTestReduce(.And, [4]u1{ 1, 0, 1, 1 }, @as(u1, 0)); | |
| 560 | doTheTestReduce(.And, [4]u16{ 0xffff, 0xff55, 0xaaff, 0x1010 }, @as(u16, 0x10)); | |
| 561 | doTheTestReduce(.And, [4]u32{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u32, 0x1010)); | |
| 562 | doTheTestReduce(.And, [4]u64{ 0xffffffff, 0xffff5555, 0xaaaaffff, 0x10101010 }, @as(u64, 0x1010)); | |
| 563 | ||
| 564 | doTheTestReduce(.Min, [4]i16{ -1, 2, 3, 4 }, @as(i16, -1)); | |
| 565 | doTheTestReduce(.Min, [4]u16{ 1, 2, 3, 4 }, @as(u16, 1)); | |
| 566 | doTheTestReduce(.Min, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, -386)); | |
| 567 | doTheTestReduce(.Min, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 9)); | |
| 568 | ||
| 569 | // LLVM 11 ERROR: Cannot select type | |
| 570 | // https://github.com/ziglang/zig/issues/7138 | |
| 571 | if (builtin.target.cpu.arch != .aarch64) { | |
| 572 | doTheTestReduce(.Min, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, -386)); | |
| 573 | doTheTestReduce(.Min, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 9)); | |
| 574 | } | |
| 575 | ||
| 576 | doTheTestReduce(.Min, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, -386)); | |
| 577 | doTheTestReduce(.Min, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 9)); | |
| 578 | doTheTestReduce(.Min, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, -100.0)); | |
| 579 | doTheTestReduce(.Min, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, -100.0)); | |
| 580 | doTheTestReduce(.Min, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, -100.0)); | |
| 581 | ||
| 582 | doTheTestReduce(.Max, [4]i16{ -1, 2, 3, 4 }, @as(i16, 4)); | |
| 583 | doTheTestReduce(.Max, [4]u16{ 1, 2, 3, 4 }, @as(u16, 4)); | |
| 584 | doTheTestReduce(.Max, [4]i32{ 1234567, -386, 0, 3 }, @as(i32, 1234567)); | |
| 585 | doTheTestReduce(.Max, [4]u32{ 99, 9999, 9, 99999 }, @as(u32, 99999)); | |
| 586 | ||
| 587 | // LLVM 11 ERROR: Cannot select type | |
| 588 | // https://github.com/ziglang/zig/issues/7138 | |
| 589 | if (builtin.target.cpu.arch != .aarch64) { | |
| 590 | doTheTestReduce(.Max, [4]i64{ 1234567, -386, 0, 3 }, @as(i64, 1234567)); | |
| 591 | doTheTestReduce(.Max, [4]u64{ 99, 9999, 9, 99999 }, @as(u64, 99999)); | |
| 592 | } | |
| 593 | ||
| 594 | doTheTestReduce(.Max, [4]i128{ 1234567, -386, 0, 3 }, @as(i128, 1234567)); | |
| 595 | doTheTestReduce(.Max, [4]u128{ 99, 9999, 9, 99999 }, @as(u128, 99999)); | |
| 596 | doTheTestReduce(.Max, [4]f16{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f16, 10.0e9)); | |
| 597 | doTheTestReduce(.Max, [4]f32{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f32, 10.0e9)); | |
| 598 | doTheTestReduce(.Max, [4]f64{ -10.3, 10.0e9, 13.0, -100.0 }, @as(f64, 10.0e9)); | |
| 599 | ||
| 600 | doTheTestReduce(.Mul, [4]i16{ -1, 2, 3, 4 }, @as(i16, -24)); | |
| 601 | doTheTestReduce(.Mul, [4]u16{ 1, 2, 3, 4 }, @as(u16, 24)); | |
| 602 | doTheTestReduce(.Mul, [4]i32{ -9, -99, -999, 999 }, @as(i32, -889218891)); | |
| 603 | doTheTestReduce(.Mul, [4]u32{ 1, 2, 3, 4 }, @as(u32, 24)); | |
| 604 | doTheTestReduce(.Mul, [4]i64{ 9, 99, 999, 9999 }, @as(i64, 8900199891)); | |
| 605 | doTheTestReduce(.Mul, [4]u64{ 9, 99, 999, 9999 }, @as(u64, 8900199891)); | |
| 606 | doTheTestReduce(.Mul, [4]i128{ -9, -99, -999, 9999 }, @as(i128, -8900199891)); | |
| 607 | doTheTestReduce(.Mul, [4]u128{ 9, 99, 999, 9999 }, @as(u128, 8900199891)); | |
| 608 | doTheTestReduce(.Mul, [4]f16{ -1.9, 5.1, -60.3, 100.0 }, @as(f16, 58430.7)); | |
| 609 | doTheTestReduce(.Mul, [4]f32{ -1.9, 5.1, -60.3, 100.0 }, @as(f32, 58430.7)); | |
| 610 | doTheTestReduce(.Mul, [4]f64{ -1.9, 5.1, -60.3, 100.0 }, @as(f64, 58430.7)); | |
| 611 | ||
| 612 | doTheTestReduce(.Or, [4]bool{ false, true, false, false }, @as(bool, true)); | |
| 613 | doTheTestReduce(.Or, [4]u1{ 0, 1, 0, 0 }, @as(u1, 1)); | |
| 614 | doTheTestReduce(.Or, [4]u16{ 0xff00, 0xff00, 0xf0, 0xf }, ~@as(u16, 0)); | |
| 615 | doTheTestReduce(.Or, [4]u32{ 0xffff0000, 0xff00, 0xf0, 0xf }, ~@as(u32, 0)); | |
| 616 | doTheTestReduce(.Or, [4]u64{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u64, 0xffffffff)); | |
| 617 | doTheTestReduce(.Or, [4]u128{ 0xffff0000, 0xff00, 0xf0, 0xf }, @as(u128, 0xffffffff)); | |
| 618 | ||
| 619 | doTheTestReduce(.Xor, [4]bool{ true, true, true, false }, @as(bool, true)); | |
| 620 | doTheTestReduce(.Xor, [4]u1{ 1, 1, 1, 0 }, @as(u1, 1)); | |
| 621 | doTheTestReduce(.Xor, [4]u16{ 0x0000, 0x3333, 0x8888, 0x4444 }, ~@as(u16, 0)); | |
| 622 | doTheTestReduce(.Xor, [4]u32{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, ~@as(u32, 0)); | |
| 623 | doTheTestReduce(.Xor, [4]u64{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u64, 0xffffffff)); | |
| 624 | doTheTestReduce(.Xor, [4]u128{ 0x00000000, 0x33333333, 0x88888888, 0x44444444 }, @as(u128, 0xffffffff)); | |
| 625 | ||
| 626 | // Test the reduction on vectors containing NaNs. | |
| 627 | const f16_nan = math.nan(f16); | |
| 628 | const f32_nan = math.nan(f32); | |
| 629 | const f64_nan = math.nan(f64); | |
| 630 | ||
| 631 | doTheTestReduce(.Add, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 632 | doTheTestReduce(.Add, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 633 | doTheTestReduce(.Add, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 634 | ||
| 635 | // LLVM 11 ERROR: Cannot select type | |
| 636 | // https://github.com/ziglang/zig/issues/7138 | |
| 637 | if (false) { | |
| 638 | doTheTestReduce(.Min, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 639 | doTheTestReduce(.Min, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 640 | doTheTestReduce(.Min, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 641 | ||
| 642 | doTheTestReduce(.Max, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 643 | doTheTestReduce(.Max, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 644 | doTheTestReduce(.Max, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 645 | } | |
| 646 | ||
| 647 | doTheTestReduce(.Mul, [4]f16{ -1.9, 5.1, f16_nan, 100.0 }, f16_nan); | |
| 648 | doTheTestReduce(.Mul, [4]f32{ -1.9, 5.1, f32_nan, 100.0 }, f32_nan); | |
| 649 | doTheTestReduce(.Mul, [4]f64{ -1.9, 5.1, f64_nan, 100.0 }, f64_nan); | |
| 650 | } | |
| 651 | }; | |
| 652 | ||
| 653 | S.doTheTest(); | |
| 654 | comptime S.doTheTest(); | |
| 655 | } |
test/stage1/behavior/void.zig deleted-40| ... | ... | @@ -1,40 +0,0 @@ |
| 1 | const expect = @import("std").testing.expect; | |
| 2 | ||
| 3 | const Foo = struct { | |
| 4 | a: void, | |
| 5 | b: i32, | |
| 6 | c: void, | |
| 7 | }; | |
| 8 | ||
| 9 | test "compare void with void compile time known" { | |
| 10 | comptime { | |
| 11 | const foo = Foo{ | |
| 12 | .a = {}, | |
| 13 | .b = 1, | |
| 14 | .c = {}, | |
| 15 | }; | |
| 16 | expect(foo.a == {}); | |
| 17 | } | |
| 18 | } | |
| 19 | ||
| 20 | test "iterate over a void slice" { | |
| 21 | var j: usize = 0; | |
| 22 | for (times(10)) |_, i| { | |
| 23 | expect(i == j); | |
| 24 | j += 1; | |
| 25 | } | |
| 26 | } | |
| 27 | ||
| 28 | fn times(n: usize) []const void { | |
| 29 | return @as([*]void, undefined)[0..n]; | |
| 30 | } | |
| 31 | ||
| 32 | test "void optional" { | |
| 33 | var x: ?void = {}; | |
| 34 | expect(x != null); | |
| 35 | } | |
| 36 | ||
| 37 | test "void array as a local variable initializer" { | |
| 38 | var x = [_]void{{}} ** 1004; | |
| 39 | var y = x[0]; | |
| 40 | } |
test/stage1/behavior/wasm.zig deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "memory size and grow" { | |
| 5 | var prev = @wasmMemorySize(0); | |
| 6 | expect(prev == @wasmMemoryGrow(0, 1)); | |
| 7 | expect(prev + 1 == @wasmMemorySize(0)); | |
| 8 | } |
test/stage1/behavior/while.zig deleted-289| ... | ... | @@ -1,289 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "while loop" { | |
| 5 | var i: i32 = 0; | |
| 6 | while (i < 4) { | |
| 7 | i += 1; | |
| 8 | } | |
| 9 | expect(i == 4); | |
| 10 | expect(whileLoop1() == 1); | |
| 11 | } | |
| 12 | fn whileLoop1() i32 { | |
| 13 | return whileLoop2(); | |
| 14 | } | |
| 15 | fn whileLoop2() i32 { | |
| 16 | while (true) { | |
| 17 | return 1; | |
| 18 | } | |
| 19 | } | |
| 20 | ||
| 21 | test "static eval while" { | |
| 22 | expect(static_eval_while_number == 1); | |
| 23 | } | |
| 24 | const static_eval_while_number = staticWhileLoop1(); | |
| 25 | fn staticWhileLoop1() i32 { | |
| 26 | return whileLoop2(); | |
| 27 | } | |
| 28 | fn staticWhileLoop2() i32 { | |
| 29 | while (true) { | |
| 30 | return 1; | |
| 31 | } | |
| 32 | } | |
| 33 | ||
| 34 | test "continue and break" { | |
| 35 | runContinueAndBreakTest(); | |
| 36 | expect(continue_and_break_counter == 8); | |
| 37 | } | |
| 38 | var continue_and_break_counter: i32 = 0; | |
| 39 | fn runContinueAndBreakTest() void { | |
| 40 | var i: i32 = 0; | |
| 41 | while (true) { | |
| 42 | continue_and_break_counter += 2; | |
| 43 | i += 1; | |
| 44 | if (i < 4) { | |
| 45 | continue; | |
| 46 | } | |
| 47 | break; | |
| 48 | } | |
| 49 | expect(i == 4); | |
| 50 | } | |
| 51 | ||
| 52 | test "return with implicit cast from while loop" { | |
| 53 | returnWithImplicitCastFromWhileLoopTest() catch unreachable; | |
| 54 | } | |
| 55 | fn returnWithImplicitCastFromWhileLoopTest() anyerror!void { | |
| 56 | while (true) { | |
| 57 | return; | |
| 58 | } | |
| 59 | } | |
| 60 | ||
| 61 | test "while with continue expression" { | |
| 62 | var sum: i32 = 0; | |
| 63 | { | |
| 64 | var i: i32 = 0; | |
| 65 | while (i < 10) : (i += 1) { | |
| 66 | if (i == 5) continue; | |
| 67 | sum += i; | |
| 68 | } | |
| 69 | } | |
| 70 | expect(sum == 40); | |
| 71 | } | |
| 72 | ||
| 73 | test "while with else" { | |
| 74 | var sum: i32 = 0; | |
| 75 | var i: i32 = 0; | |
| 76 | var got_else: i32 = 0; | |
| 77 | while (i < 10) : (i += 1) { | |
| 78 | sum += 1; | |
| 79 | } else { | |
| 80 | got_else += 1; | |
| 81 | } | |
| 82 | expect(sum == 10); | |
| 83 | expect(got_else == 1); | |
| 84 | } | |
| 85 | ||
| 86 | test "while with optional as condition" { | |
| 87 | numbers_left = 10; | |
| 88 | var sum: i32 = 0; | |
| 89 | while (getNumberOrNull()) |value| { | |
| 90 | sum += value; | |
| 91 | } | |
| 92 | expect(sum == 45); | |
| 93 | } | |
| 94 | ||
| 95 | test "while with optional as condition with else" { | |
| 96 | numbers_left = 10; | |
| 97 | var sum: i32 = 0; | |
| 98 | var got_else: i32 = 0; | |
| 99 | while (getNumberOrNull()) |value| { | |
| 100 | sum += value; | |
| 101 | expect(got_else == 0); | |
| 102 | } else { | |
| 103 | got_else += 1; | |
| 104 | } | |
| 105 | expect(sum == 45); | |
| 106 | expect(got_else == 1); | |
| 107 | } | |
| 108 | ||
| 109 | test "while with error union condition" { | |
| 110 | numbers_left = 10; | |
| 111 | var sum: i32 = 0; | |
| 112 | var got_else: i32 = 0; | |
| 113 | while (getNumberOrErr()) |value| { | |
| 114 | sum += value; | |
| 115 | } else |err| { | |
| 116 | expect(err == error.OutOfNumbers); | |
| 117 | got_else += 1; | |
| 118 | } | |
| 119 | expect(sum == 45); | |
| 120 | expect(got_else == 1); | |
| 121 | } | |
| 122 | ||
| 123 | var numbers_left: i32 = undefined; | |
| 124 | fn getNumberOrErr() anyerror!i32 { | |
| 125 | return if (numbers_left == 0) error.OutOfNumbers else x: { | |
| 126 | numbers_left -= 1; | |
| 127 | break :x numbers_left; | |
| 128 | }; | |
| 129 | } | |
| 130 | fn getNumberOrNull() ?i32 { | |
| 131 | return if (numbers_left == 0) null else x: { | |
| 132 | numbers_left -= 1; | |
| 133 | break :x numbers_left; | |
| 134 | }; | |
| 135 | } | |
| 136 | ||
| 137 | test "while on optional with else result follow else prong" { | |
| 138 | const result = while (returnNull()) |value| { | |
| 139 | break value; | |
| 140 | } else | |
| 141 | @as(i32, 2); | |
| 142 | expect(result == 2); | |
| 143 | } | |
| 144 | ||
| 145 | test "while on optional with else result follow break prong" { | |
| 146 | const result = while (returnOptional(10)) |value| { | |
| 147 | break value; | |
| 148 | } else | |
| 149 | @as(i32, 2); | |
| 150 | expect(result == 10); | |
| 151 | } | |
| 152 | ||
| 153 | test "while on error union with else result follow else prong" { | |
| 154 | const result = while (returnError()) |value| { | |
| 155 | break value; | |
| 156 | } else |err| | |
| 157 | @as(i32, 2); | |
| 158 | expect(result == 2); | |
| 159 | } | |
| 160 | ||
| 161 | test "while on error union with else result follow break prong" { | |
| 162 | const result = while (returnSuccess(10)) |value| { | |
| 163 | break value; | |
| 164 | } else |err| | |
| 165 | @as(i32, 2); | |
| 166 | expect(result == 10); | |
| 167 | } | |
| 168 | ||
| 169 | test "while on bool with else result follow else prong" { | |
| 170 | const result = while (returnFalse()) { | |
| 171 | break @as(i32, 10); | |
| 172 | } else | |
| 173 | @as(i32, 2); | |
| 174 | expect(result == 2); | |
| 175 | } | |
| 176 | ||
| 177 | test "while on bool with else result follow break prong" { | |
| 178 | const result = while (returnTrue()) { | |
| 179 | break @as(i32, 10); | |
| 180 | } else | |
| 181 | @as(i32, 2); | |
| 182 | expect(result == 10); | |
| 183 | } | |
| 184 | ||
| 185 | test "break from outer while loop" { | |
| 186 | testBreakOuter(); | |
| 187 | comptime testBreakOuter(); | |
| 188 | } | |
| 189 | ||
| 190 | fn testBreakOuter() void { | |
| 191 | outer: while (true) { | |
| 192 | while (true) { | |
| 193 | break :outer; | |
| 194 | } | |
| 195 | } | |
| 196 | } | |
| 197 | ||
| 198 | test "continue outer while loop" { | |
| 199 | testContinueOuter(); | |
| 200 | comptime testContinueOuter(); | |
| 201 | } | |
| 202 | ||
| 203 | fn testContinueOuter() void { | |
| 204 | var i: usize = 0; | |
| 205 | outer: while (i < 10) : (i += 1) { | |
| 206 | while (true) { | |
| 207 | continue :outer; | |
| 208 | } | |
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | fn returnNull() ?i32 { | |
| 213 | return null; | |
| 214 | } | |
| 215 | fn returnOptional(x: i32) ?i32 { | |
| 216 | return x; | |
| 217 | } | |
| 218 | fn returnError() anyerror!i32 { | |
| 219 | return error.YouWantedAnError; | |
| 220 | } | |
| 221 | fn returnSuccess(x: i32) anyerror!i32 { | |
| 222 | return x; | |
| 223 | } | |
| 224 | fn returnFalse() bool { | |
| 225 | return false; | |
| 226 | } | |
| 227 | fn returnTrue() bool { | |
| 228 | return true; | |
| 229 | } | |
| 230 | ||
| 231 | test "while bool 2 break statements and an else" { | |
| 232 | const S = struct { | |
| 233 | fn entry(t: bool, f: bool) void { | |
| 234 | var ok = false; | |
| 235 | ok = while (t) { | |
| 236 | if (f) break false; | |
| 237 | if (t) break true; | |
| 238 | } else false; | |
| 239 | expect(ok); | |
| 240 | } | |
| 241 | }; | |
| 242 | S.entry(true, false); | |
| 243 | comptime S.entry(true, false); | |
| 244 | } | |
| 245 | ||
| 246 | test "while optional 2 break statements and an else" { | |
| 247 | const S = struct { | |
| 248 | fn entry(opt_t: ?bool, f: bool) void { | |
| 249 | var ok = false; | |
| 250 | ok = while (opt_t) |t| { | |
| 251 | if (f) break false; | |
| 252 | if (t) break true; | |
| 253 | } else false; | |
| 254 | expect(ok); | |
| 255 | } | |
| 256 | }; | |
| 257 | S.entry(true, false); | |
| 258 | comptime S.entry(true, false); | |
| 259 | } | |
| 260 | ||
| 261 | test "while error 2 break statements and an else" { | |
| 262 | const S = struct { | |
| 263 | fn entry(opt_t: anyerror!bool, f: bool) void { | |
| 264 | var ok = false; | |
| 265 | ok = while (opt_t) |t| { | |
| 266 | if (f) break false; | |
| 267 | if (t) break true; | |
| 268 | } else |_| false; | |
| 269 | expect(ok); | |
| 270 | } | |
| 271 | }; | |
| 272 | S.entry(true, false); | |
| 273 | comptime S.entry(true, false); | |
| 274 | } | |
| 275 | ||
| 276 | test "while copies its payload" { | |
| 277 | const S = struct { | |
| 278 | fn doTheTest() void { | |
| 279 | var tmp: ?i32 = 10; | |
| 280 | while (tmp) |value| { | |
| 281 | // Modify the original variable | |
| 282 | tmp = null; | |
| 283 | expect(value == 10); | |
| 284 | } | |
| 285 | } | |
| 286 | }; | |
| 287 | S.doTheTest(); | |
| 288 | comptime S.doTheTest(); | |
| 289 | } |
test/stage1/behavior/widening.zig deleted-39| ... | ... | @@ -1,39 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | test "integer widening" { | |
| 6 | var a: u8 = 250; | |
| 7 | var b: u16 = a; | |
| 8 | var c: u32 = b; | |
| 9 | var d: u64 = c; | |
| 10 | var e: u64 = d; | |
| 11 | var f: u128 = e; | |
| 12 | expect(f == a); | |
| 13 | } | |
| 14 | ||
| 15 | test "implicit unsigned integer to signed integer" { | |
| 16 | var a: u8 = 250; | |
| 17 | var b: i16 = a; | |
| 18 | expect(b == 250); | |
| 19 | } | |
| 20 | ||
| 21 | test "float widening" { | |
| 22 | var a: f16 = 12.34; | |
| 23 | var b: f32 = a; | |
| 24 | var c: f64 = b; | |
| 25 | var d: f128 = c; | |
| 26 | expect(a == b); | |
| 27 | expect(b == c); | |
| 28 | expect(c == d); | |
| 29 | } | |
| 30 | ||
| 31 | test "float widening f16 to f128" { | |
| 32 | // TODO https://github.com/ziglang/zig/issues/3282 | |
| 33 | if (@import("builtin").target.cpu.arch == .aarch64) return error.SkipZigTest; | |
| 34 | if (@import("builtin").target.cpu.arch == .powerpc64le) return error.SkipZigTest; | |
| 35 | ||
| 36 | var x: f16 = 12.34; | |
| 37 | var y: f128 = x; | |
| 38 | expect(x == y); | |
| 39 | } |