Date: Fri, 1 Feb 2019 17:49:29 -0500
Subject: [PATCH 131/218] introduce --single-threaded build option
closes #1764
This adds another boolean to the test matrix; hopefully it does not
inflate the time too much.
std.event.Loop does not work with this option yet. See #1908
---
doc/langref.html.in | 19 +++++++
src/all_types.hpp | 1 +
src/codegen.cpp | 4 ++
src/main.cpp | 6 +++
std/atomic/queue.zig | 42 ++++++++++-----
std/atomic/stack.zig | 78 +++++++++++++++++++---------
std/event/channel.zig | 3 ++
std/event/future.zig | 3 ++
std/event/group.zig | 3 ++
std/event/lock.zig | 3 ++
std/event/loop.zig | 22 ++++++++
std/event/net.zig | 3 ++
std/event/rwlock.zig | 3 ++
std/mutex.zig | 66 ++++++++++++++++-------
std/os/index.zig | 1 +
std/os/test.zig | 4 ++
std/statically_initialized_mutex.zig | 21 +++++---
test/tests.zig | 43 ++++++++-------
18 files changed, 244 insertions(+), 81 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index e192dbbf76..144c8571c4 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6714,6 +6714,25 @@ pub fn build(b: *Builder) void {
{#header_close#}
{#see_also|Compile Variables|Zig Build System|Undefined Behavior#}
{#header_close#}
+
+ {#header_open|Single Threaded Builds#}
+ Zig has a compile option --single-threaded which has the following effects:
+
+ - {#link|@atomicLoad#} is emitted as a normal load.
+ - {#link|@atomicRmw#} is emitted as a normal memory load, modify, store.
+ - {#link|@fence#} becomes a no-op.
+ - Variables which have Thread Local Storage instead become globals. TODO thread local variables
+ are not implemented yet.
+ - The overhead of {#link|Coroutines#} becomes equivalent to function call overhead.
+ TODO: please note this will not be implemented until the upcoming Coroutine Rewrite
+ - The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}
+ and therefore various userland APIs which read this variable become more efficient.
+ For example {#syntax#}std.Mutex{#endsyntax#} becomes
+ an empty data structure and all of its functions become no-ops.
+
+
+ {#header_close#}
+
{#header_open|Undefined Behavior#}
Zig has many instances of undefined behavior. If undefined behavior is
diff --git a/src/all_types.hpp b/src/all_types.hpp
index f6fe72891d..3fc6772b31 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1808,6 +1808,7 @@ struct CodeGen {
bool is_static;
bool strip_debug_symbols;
bool is_test_build;
+ bool is_single_threaded;
bool is_native_target;
bool linker_rdynamic;
bool no_rosegment_workaround;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index e2576f5335..b73fda59d1 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -118,6 +118,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
g->string_literals_table.init(16);
g->type_info_cache.init(32);
g->is_test_build = false;
+ g->is_single_threaded = false;
buf_resize(&g->global_asm, 0);
for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) {
@@ -7377,6 +7378,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
buf_appendf(contents, "pub const endian = %s;\n", endian_str);
}
buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
+ buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
buf_appendf(contents, "pub const environ = Environ.%s;\n", cur_environ);
@@ -7411,6 +7413,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
cache_buf(&cache_hash, compiler_id);
cache_int(&cache_hash, g->build_mode);
cache_bool(&cache_hash, g->is_test_build);
+ cache_bool(&cache_hash, g->is_single_threaded);
cache_int(&cache_hash, g->zig_target.arch.arch);
cache_int(&cache_hash, g->zig_target.arch.sub_arch);
cache_int(&cache_hash, g->zig_target.vendor);
@@ -8329,6 +8332,7 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
cache_bool(ch, g->is_static);
cache_bool(ch, g->strip_debug_symbols);
cache_bool(ch, g->is_test_build);
+ cache_bool(ch, g->is_single_threaded);
cache_bool(ch, g->is_native_target);
cache_bool(ch, g->linker_rdynamic);
cache_bool(ch, g->no_rosegment_workaround);
diff --git a/src/main.cpp b/src/main.cpp
index fd8e3db2fa..81f49089be 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -59,6 +59,7 @@ static int print_full_usage(const char *arg0) {
" --release-fast build with optimizations on and safety off\n"
" --release-safe build with optimizations on and safety on\n"
" --release-small build with size optimizations on and safety off\n"
+ " --single-threaded source may assume it is only used single-threaded\n"
" --static output will be statically linked\n"
" --strip exclude debug symbols\n"
" --target-arch [name] specify target architecture\n"
@@ -393,6 +394,7 @@ int main(int argc, char **argv) {
bool no_rosegment_workaround = false;
bool system_linker_hack = false;
TargetSubsystem subsystem = TargetSubsystemAuto;
+ bool is_single_threaded = false;
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
Buf zig_exe_path_buf = BUF_INIT;
@@ -550,6 +552,8 @@ int main(int argc, char **argv) {
disable_pic = true;
} else if (strcmp(arg, "--system-linker-hack") == 0) {
system_linker_hack = true;
+ } else if (strcmp(arg, "--single-threaded") == 0) {
+ is_single_threaded = true;
} else if (strcmp(arg, "--test-cmd-bin") == 0) {
test_exec_args.append(nullptr);
} else if (arg[1] == 'L' && arg[2] != 0) {
@@ -816,6 +820,7 @@ int main(int argc, char **argv) {
switch (cmd) {
case CmdBuiltin: {
CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir());
+ g->is_single_threaded = is_single_threaded;
Buf *builtin_source = codegen_generate_builtin_source(g);
if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));
@@ -889,6 +894,7 @@ int main(int argc, char **argv) {
codegen_set_out_name(g, buf_out_name);
codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
codegen_set_is_test(g, cmd == CmdTest);
+ g->is_single_threaded = is_single_threaded;
codegen_set_linker_script(g, linker_script);
if (each_lib_rpath)
codegen_set_each_lib_rpath(g, each_lib_rpath);
diff --git a/std/atomic/queue.zig b/std/atomic/queue.zig
index 1aab4c32de..6c61bcc048 100644
--- a/std/atomic/queue.zig
+++ b/std/atomic/queue.zig
@@ -170,20 +170,36 @@ test "std.atomic.Queue" {
.get_count = 0,
};
- var putters: [put_thread_count]*std.os.Thread = undefined;
- for (putters) |*t| {
- t.* = try std.os.spawnThread(&context, startPuts);
- }
- var getters: [put_thread_count]*std.os.Thread = undefined;
- for (getters) |*t| {
- t.* = try std.os.spawnThread(&context, startGets);
- }
+ if (builtin.single_threaded) {
+ {
+ var i: usize = 0;
+ while (i < put_thread_count) : (i += 1) {
+ std.debug.assertOrPanic(startPuts(&context) == 0);
+ }
+ }
+ context.puts_done = 1;
+ {
+ var i: usize = 0;
+ while (i < put_thread_count) : (i += 1) {
+ std.debug.assertOrPanic(startGets(&context) == 0);
+ }
+ }
+ } else {
+ var putters: [put_thread_count]*std.os.Thread = undefined;
+ for (putters) |*t| {
+ t.* = try std.os.spawnThread(&context, startPuts);
+ }
+ var getters: [put_thread_count]*std.os.Thread = undefined;
+ for (getters) |*t| {
+ t.* = try std.os.spawnThread(&context, startGets);
+ }
- for (putters) |t|
- t.wait();
- _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
- for (getters) |t|
- t.wait();
+ for (putters) |t|
+ t.wait();
+ _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
+ for (getters) |t|
+ t.wait();
+ }
if (context.put_sum != context.get_sum) {
std.debug.panic("failure\nput_sum:{} != get_sum:{}", context.put_sum, context.get_sum);
diff --git a/std/atomic/stack.zig b/std/atomic/stack.zig
index b69a93733c..1e4981353b 100644
--- a/std/atomic/stack.zig
+++ b/std/atomic/stack.zig
@@ -4,10 +4,13 @@ const AtomicOrder = builtin.AtomicOrder;
/// Many reader, many writer, non-allocating, thread-safe
/// Uses a spinlock to protect push() and pop()
+/// When building in single threaded mode, this is a simple linked list.
pub fn Stack(comptime T: type) type {
return struct {
root: ?*Node,
- lock: u8,
+ lock: @typeOf(lock_init),
+
+ const lock_init = if (builtin.single_threaded) {} else u8(0);
pub const Self = @This();
@@ -19,7 +22,7 @@ pub fn Stack(comptime T: type) type {
pub fn init() Self {
return Self{
.root = null,
- .lock = 0,
+ .lock = lock_init,
};
}
@@ -31,20 +34,31 @@ pub fn Stack(comptime T: type) type {
}
pub fn push(self: *Self, node: *Node) void {
- while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
- defer assert(@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
+ if (builtin.single_threaded) {
+ node.next = self.root;
+ self.root = node;
+ } else {
+ while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
+ defer assert(@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
- node.next = self.root;
- self.root = node;
+ node.next = self.root;
+ self.root = node;
+ }
}
pub fn pop(self: *Self) ?*Node {
- while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
- defer assert(@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
+ if (builtin.single_threaded) {
+ const root = self.root orelse return null;
+ self.root = root.next;
+ return root;
+ } else {
+ while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}
+ defer assert(@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);
- const root = self.root orelse return null;
- self.root = root.next;
- return root;
+ const root = self.root orelse return null;
+ self.root = root.next;
+ return root;
+ }
}
pub fn isEmpty(self: *Self) bool {
@@ -90,20 +104,36 @@ test "std.atomic.stack" {
.get_count = 0,
};
- var putters: [put_thread_count]*std.os.Thread = undefined;
- for (putters) |*t| {
- t.* = try std.os.spawnThread(&context, startPuts);
- }
- var getters: [put_thread_count]*std.os.Thread = undefined;
- for (getters) |*t| {
- t.* = try std.os.spawnThread(&context, startGets);
- }
+ if (builtin.single_threaded) {
+ {
+ var i: usize = 0;
+ while (i < put_thread_count) : (i += 1) {
+ std.debug.assertOrPanic(startPuts(&context) == 0);
+ }
+ }
+ context.puts_done = 1;
+ {
+ var i: usize = 0;
+ while (i < put_thread_count) : (i += 1) {
+ std.debug.assertOrPanic(startGets(&context) == 0);
+ }
+ }
+ } else {
+ var putters: [put_thread_count]*std.os.Thread = undefined;
+ for (putters) |*t| {
+ t.* = try std.os.spawnThread(&context, startPuts);
+ }
+ var getters: [put_thread_count]*std.os.Thread = undefined;
+ for (getters) |*t| {
+ t.* = try std.os.spawnThread(&context, startGets);
+ }
- for (putters) |t|
- t.wait();
- _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
- for (getters) |t|
- t.wait();
+ for (putters) |t|
+ t.wait();
+ _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
+ for (getters) |t|
+ t.wait();
+ }
if (context.put_sum != context.get_sum) {
std.debug.panic("failure\nput_sum:{} != get_sum:{}", context.put_sum, context.get_sum);
diff --git a/std/event/channel.zig b/std/event/channel.zig
index 133ce1c69c..f04ad1604e 100644
--- a/std/event/channel.zig
+++ b/std/event/channel.zig
@@ -319,6 +319,9 @@ pub fn Channel(comptime T: type) type {
}
test "std.event.Channel" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/event/future.zig b/std/event/future.zig
index d61768b198..55ed01046d 100644
--- a/std/event/future.zig
+++ b/std/event/future.zig
@@ -84,6 +84,9 @@ pub fn Future(comptime T: type) type {
}
test "std.event.Future" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/event/group.zig b/std/event/group.zig
index 9f2687a5b3..0e9c2d9655 100644
--- a/std/event/group.zig
+++ b/std/event/group.zig
@@ -121,6 +121,9 @@ pub fn Group(comptime ReturnType: type) type {
}
test "std.event.Group" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/event/lock.zig b/std/event/lock.zig
index 46e0d13468..01978e1909 100644
--- a/std/event/lock.zig
+++ b/std/event/lock.zig
@@ -122,6 +122,9 @@ pub const Lock = struct {
};
test "std.event.Lock" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/event/loop.zig b/std/event/loop.zig
index 43965e8293..d5228db604 100644
--- a/std/event/loop.zig
+++ b/std/event/loop.zig
@@ -97,6 +97,7 @@ pub const Loop = struct {
/// TODO copy elision / named return values so that the threads referencing *Loop
/// have the correct pointer value.
pub fn initMultiThreaded(self: *Loop, allocator: *mem.Allocator) !void {
+ if (builtin.single_threaded) @compileError("initMultiThreaded unavailable when building in single-threaded mode");
const core_count = try os.cpuCount(allocator);
return self.initInternal(allocator, core_count);
}
@@ -201,6 +202,11 @@ pub const Loop = struct {
self.os_data.fs_thread.wait();
}
+ if (builtin.single_threaded) {
+ assert(extra_thread_count == 0);
+ return;
+ }
+
var extra_thread_index: usize = 0;
errdefer {
// writing 8 bytes to an eventfd cannot fail
@@ -301,6 +307,11 @@ pub const Loop = struct {
self.os_data.fs_thread.wait();
}
+ if (builtin.single_threaded) {
+ assert(extra_thread_count == 0);
+ return;
+ }
+
var extra_thread_index: usize = 0;
errdefer {
_ = os.bsdKEvent(self.os_data.kqfd, final_kev_arr, empty_kevs, null) catch unreachable;
@@ -338,6 +349,11 @@ pub const Loop = struct {
self.available_eventfd_resume_nodes.push(eventfd_node);
}
+ if (builtin.single_threaded) {
+ assert(extra_thread_count == 0);
+ return;
+ }
+
var extra_thread_index: usize = 0;
errdefer {
var i: usize = 0;
@@ -845,6 +861,9 @@ pub const Loop = struct {
};
test "std.event.Loop - basic" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
@@ -858,6 +877,9 @@ test "std.event.Loop - basic" {
}
test "std.event.Loop - call" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/event/net.zig b/std/event/net.zig
index 6838704084..9dac6aa566 100644
--- a/std/event/net.zig
+++ b/std/event/net.zig
@@ -269,6 +269,9 @@ pub async fn connect(loop: *Loop, _address: *const std.net.Address) !os.File {
}
test "listen on a port, send bytes, receive bytes" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
if (builtin.os != builtin.Os.linux) {
// TODO build abstractions for other operating systems
return error.SkipZigTest;
diff --git a/std/event/rwlock.zig b/std/event/rwlock.zig
index 5d48ea893e..f272ac71ea 100644
--- a/std/event/rwlock.zig
+++ b/std/event/rwlock.zig
@@ -211,6 +211,9 @@ pub const RwLock = struct {
};
test "std.event.RwLock" {
+ // https://github.com/ziglang/zig/issues/1908
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var da = std.heap.DirectAllocator.init();
defer da.deinit();
diff --git a/std/mutex.zig b/std/mutex.zig
index 723581cbef..54173fa38a 100644
--- a/std/mutex.zig
+++ b/std/mutex.zig
@@ -14,7 +14,36 @@ const windows = std.os.windows;
/// If you need static initialization, use std.StaticallyInitializedMutex.
/// The Linux implementation is based on mutex3 from
/// https://www.akkadia.org/drepper/futex.pdf
-pub const Mutex = switch(builtin.os) {
+/// When an application is built in single threaded release mode, all the functions are
+/// no-ops. In single threaded debug mode, there is deadlock detection.
+pub const Mutex = if (builtin.single_threaded)
+ struct {
+ lock: @typeOf(lock_init),
+
+ const lock_init = if (std.debug.runtime_safety) false else {};
+
+ pub const Held = struct {
+ mutex: *Mutex,
+
+ pub fn release(self: Held) void {
+ if (std.debug.runtime_safety) {
+ self.mutex.lock = false;
+ }
+ }
+ };
+ pub fn init() Mutex {
+ return Mutex{ .lock = lock_init };
+ }
+ pub fn deinit(self: *Mutex) void {}
+
+ pub fn acquire(self: *Mutex) Held {
+ if (std.debug.runtime_safety and self.lock) {
+ @panic("deadlock detected");
+ }
+ return Held{ .mutex = self };
+ }
+ }
+else switch (builtin.os) {
builtin.Os.linux => struct {
/// 0: unlocked
/// 1: locked, no waiters
@@ -39,9 +68,7 @@ pub const Mutex = switch(builtin.os) {
};
pub fn init() Mutex {
- return Mutex {
- .lock = 0,
- };
+ return Mutex{ .lock = 0 };
}
pub fn deinit(self: *Mutex) void {}
@@ -60,7 +87,7 @@ pub const Mutex = switch(builtin.os) {
}
c = @atomicRmw(i32, &self.lock, AtomicRmwOp.Xchg, 2, AtomicOrder.Acquire);
}
- return Held { .mutex = self };
+ return Held{ .mutex = self };
}
},
// TODO once https://github.com/ziglang/zig/issues/287 (copy elision) is solved, we can make a
@@ -78,21 +105,19 @@ pub const Mutex = switch(builtin.os) {
mutex: *Mutex,
pub fn release(self: Held) void {
- SpinLock.Held.release(SpinLock.Held { .spinlock = &self.mutex.lock });
+ SpinLock.Held.release(SpinLock.Held{ .spinlock = &self.mutex.lock });
}
};
pub fn init() Mutex {
- return Mutex {
- .lock = SpinLock.init(),
- };
+ return Mutex{ .lock = SpinLock.init() };
}
pub fn deinit(self: *Mutex) void {}
pub fn acquire(self: *Mutex) Held {
_ = self.lock.acquire();
- return Held { .mutex = self };
+ return Held{ .mutex = self };
}
},
};
@@ -122,15 +147,20 @@ test "std.Mutex" {
.data = 0,
};
- const thread_count = 10;
- var threads: [thread_count]*std.os.Thread = undefined;
- for (threads) |*t| {
- t.* = try std.os.spawnThread(&context, worker);
- }
- for (threads) |t|
- t.wait();
+ if (builtin.single_threaded) {
+ worker(&context);
+ std.debug.assertOrPanic(context.data == TestContext.incr_count);
+ } else {
+ const thread_count = 10;
+ var threads: [thread_count]*std.os.Thread = undefined;
+ for (threads) |*t| {
+ t.* = try std.os.spawnThread(&context, worker);
+ }
+ for (threads) |t|
+ t.wait();
- std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ }
}
fn worker(ctx: *TestContext) void {
diff --git a/std/os/index.zig b/std/os/index.zig
index 78d543583d..75abe3bbde 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -3013,6 +3013,7 @@ pub const SpawnThreadError = error{
/// where T is u8, noreturn, void, or !void
/// caller must call wait on the returned thread
pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread {
+ if (builtin.single_threaded) @compileError("cannot spawn thread when building in single-threaded mode");
// TODO compile-time call graph analysis to determine stack upper bound
// https://github.com/ziglang/zig/issues/157
const default_stack_size = 8 * 1024 * 1024;
diff --git a/std/os/test.zig b/std/os/test.zig
index 5142920687..f14cf47786 100644
--- a/std/os/test.zig
+++ b/std/os/test.zig
@@ -40,6 +40,8 @@ fn testThreadIdFn(thread_id: *os.Thread.Id) void {
}
test "std.os.Thread.getCurrentId" {
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var thread_current_id: os.Thread.Id = undefined;
const thread = try os.spawnThread(&thread_current_id, testThreadIdFn);
const thread_id = thread.handle();
@@ -53,6 +55,8 @@ test "std.os.Thread.getCurrentId" {
}
test "spawn threads" {
+ if (builtin.single_threaded) return error.SkipZigTest;
+
var shared_ctx: i32 = 1;
const thread1 = try std.os.spawnThread({}, start1);
diff --git a/std/statically_initialized_mutex.zig b/std/statically_initialized_mutex.zig
index dd875eeaf9..37582d49c1 100644
--- a/std/statically_initialized_mutex.zig
+++ b/std/statically_initialized_mutex.zig
@@ -93,13 +93,18 @@ test "std.StaticallyInitializedMutex" {
.data = 0,
};
- const thread_count = 10;
- var threads: [thread_count]*std.os.Thread = undefined;
- for (threads) |*t| {
- t.* = try std.os.spawnThread(&context, TestContext.worker);
- }
- for (threads) |t|
- t.wait();
+ if (builtin.single_threaded) {
+ TestContext.worker(&context);
+ std.debug.assertOrPanic(context.data == TestContext.incr_count);
+ } else {
+ const thread_count = 10;
+ var threads: [thread_count]*std.os.Thread = undefined;
+ for (threads) |*t| {
+ t.* = try std.os.spawnThread(&context, TestContext.worker);
+ }
+ for (threads) |t|
+ t.wait();
- std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ }
}
diff --git a/test/tests.zig b/test/tests.zig
index 1ca06b4b34..73d4644d18 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -163,25 +163,32 @@ pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []cons
for (test_targets) |test_target| {
const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);
for (modes) |mode| {
- for ([]bool{
- false,
- true,
- }) |link_libc| {
- if (link_libc and !is_native) {
- // don't assume we have a cross-compiling libc set up
- continue;
+ for ([]bool{ false, true }) |link_libc| {
+ for ([]bool{ false, true }) |single_threaded| {
+ if (link_libc and !is_native) {
+ // don't assume we have a cross-compiling libc set up
+ continue;
+ }
+ const these_tests = b.addTest(root_src);
+ these_tests.setNamePrefix(b.fmt(
+ "{}-{}-{}-{}-{}-{} ",
+ name,
+ @tagName(test_target.os),
+ @tagName(test_target.arch),
+ @tagName(mode),
+ if (link_libc) "c" else "bare",
+ if (single_threaded) "single" else "multi",
+ ));
+ these_tests.setFilter(test_filter);
+ these_tests.setBuildMode(mode);
+ if (!is_native) {
+ these_tests.setTarget(test_target.arch, test_target.os, test_target.environ);
+ }
+ if (link_libc) {
+ these_tests.linkSystemLibrary("c");
+ }
+ step.dependOn(&these_tests.step);
}
- const these_tests = b.addTest(root_src);
- these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os), @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
- these_tests.setFilter(test_filter);
- these_tests.setBuildMode(mode);
- if (!is_native) {
- these_tests.setTarget(test_target.arch, test_target.os, test_target.environ);
- }
- if (link_libc) {
- these_tests.linkSystemLibrary("c");
- }
- step.dependOn(&these_tests.step);
}
}
}
From c90c256868a80cd35e9ba679ba082330592620c9 Mon Sep 17 00:00:00 2001
From: Matthew McAllister
Date: Sat, 2 Feb 2019 13:57:53 -0800
Subject: [PATCH 132/218] Fix slice concatenation
This was causing an underflow error
---
src/ir.cpp | 33 ++++++++++++---------------------
test/stage1/behavior/eval.zig | 4 ++--
2 files changed, 14 insertions(+), 23 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index d676e7a6c5..3d3c501df3 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -12369,7 +12369,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index];
- op1_array_end = bigint_as_unsigned(&len_val->data.x_bigint);
+ op1_array_end = op1_array_index + bigint_as_unsigned(&len_val->data.x_bigint);
} else {
ir_add_error(ira, op1,
buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name)));
@@ -12379,13 +12379,9 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
ConstExprValue *op2_array_val;
size_t op2_array_index;
size_t op2_array_end;
+ bool op2_type_valid;
if (op2_type->id == ZigTypeIdArray) {
- if (op2_type->data.array.child_type != child_type) {
- ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
- buf_ptr(&child_type->name),
- buf_ptr(&op2->value.type->name)));
- return ira->codegen->invalid_instruction;
- }
+ op2_type_valid = op2_type->data.array.child_type == child_type;
op2_array_val = op2_val;
op2_array_index = 0;
op2_array_end = op2_array_val->type->data.array.len;
@@ -12394,35 +12390,30 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray &&
op2_val->data.x_ptr.data.base_array.is_cstr)
{
- if (child_type != ira->codegen->builtin_types.entry_u8) {
- ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
- buf_ptr(&child_type->name),
- buf_ptr(&op2->value.type->name)));
- return ira->codegen->invalid_instruction;
- }
+ op2_type_valid = child_type == ira->codegen->builtin_types.entry_u8;
op2_array_val = op2_val->data.x_ptr.data.base_array.array_val;
op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;
op2_array_end = op2_array_val->type->data.array.len - 1;
} else if (is_slice(op2_type)) {
ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;
- if (ptr_type->data.pointer.child_type != child_type) {
- ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
- buf_ptr(&child_type->name),
- buf_ptr(&op2->value.type->name)));
- return ira->codegen->invalid_instruction;
- }
+ op2_type_valid = ptr_type->data.pointer.child_type == child_type;
ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index];
assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
- op2_array_end = op2_array_val->type->data.array.len;
ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index];
- op2_array_end = bigint_as_unsigned(&len_val->data.x_bigint);
+ op2_array_end = op2_array_index + bigint_as_unsigned(&len_val->data.x_bigint);
} else {
ir_add_error(ira, op2,
buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name)));
return ira->codegen->invalid_instruction;
}
+ if (!op2_type_valid) {
+ ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'",
+ buf_ptr(&child_type->name),
+ buf_ptr(&op2->value.type->name)));
+ return ira->codegen->invalid_instruction;
+ }
// The type of result is populated in the following if blocks
IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig
index 2d8494eb0b..3e8af0524f 100644
--- a/test/stage1/behavior/eval.zig
+++ b/test/stage1/behavior/eval.zig
@@ -728,8 +728,8 @@ test "comptime pointer cast array and then slice" {
test "slice bounds in comptime concatenation" {
const bs = comptime blk: {
- const b = c"11";
- break :blk b[0..1];
+ const b = c"........1........";
+ break :blk b[8..9];
};
const str = "" ++ bs;
assertOrPanic(str.len == 1);
From dfbc063f79dc1358208216b466c1bf8c44baa430 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 3 Feb 2019 16:13:28 -0500
Subject: [PATCH 133/218] `std.mem.Allocator.create` replaced with better API
`std.mem.Allocator.createOne` is renamed to `std.mem.Allocator.create`.
The problem with the previous API is that even after copy elision,
the initalization value passed as a parameter would always be a copy.
With the new API, once copy elision is done, initialization
functions can directly initialize allocated memory in place.
Related:
* #1872
* #1873
---
src-self-hosted/compilation.zig | 72 +++---
src-self-hosted/errmsg.zig | 20 +-
src-self-hosted/ir.zig | 15 +-
src-self-hosted/main.zig | 5 +-
src-self-hosted/package.zig | 6 +-
src-self-hosted/scope.zig | 18 +-
src-self-hosted/type.zig | 17 +-
src-self-hosted/value.zig | 35 +--
std/atomic/queue.zig | 5 +-
std/atomic/stack.zig | 5 +-
std/build.zig | 56 +++--
std/debug/index.zig | 7 +-
std/event/channel.zig | 5 +-
std/event/fs.zig | 8 +-
std/event/group.zig | 5 +-
std/heap.zig | 3 +-
std/io.zig | 5 +-
std/linked_list.zig | 2 +-
std/mem.zig | 13 +-
std/os/child_process.zig | 5 +-
std/os/index.zig | 5 +-
std/zig/parse.zig | 376 +++++++++++++++++++-------------
test/tests.zig | 75 ++++---
23 files changed, 451 insertions(+), 312 deletions(-)
diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig
index c00c7c1d41..d60892432e 100644
--- a/src-self-hosted/compilation.zig
+++ b/src-self-hosted/compilation.zig
@@ -83,10 +83,11 @@ pub const ZigCompiler = struct {
const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
errdefer c.LLVMContextDispose(context_ref);
- const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node{
+ const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node);
+ node.* = std.atomic.Stack(llvm.ContextRef).Node{
.next = undefined,
.data = context_ref,
- });
+ };
errdefer self.loop.allocator.destroy(node);
return LlvmHandle{ .node = node };
@@ -596,7 +597,8 @@ pub const Compilation = struct {
}
fn initTypes(comp: *Compilation) !void {
- comp.meta_type = try comp.arena().create(Type.MetaType{
+ comp.meta_type = try comp.arena().create(Type.MetaType);
+ comp.meta_type.* = Type.MetaType{
.base = Type{
.name = "type",
.base = Value{
@@ -608,12 +610,13 @@ pub const Compilation = struct {
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
.value = undefined,
- });
+ };
comp.meta_type.value = &comp.meta_type.base;
comp.meta_type.base.base.typ = &comp.meta_type.base;
assert((try comp.primitive_type_table.put(comp.meta_type.base.name, &comp.meta_type.base)) == null);
- comp.void_type = try comp.arena().create(Type.Void{
+ comp.void_type = try comp.arena().create(Type.Void);
+ comp.void_type.* = Type.Void{
.base = Type{
.name = "void",
.base = Value{
@@ -624,10 +627,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.Void,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
- });
+ };
assert((try comp.primitive_type_table.put(comp.void_type.base.name, &comp.void_type.base)) == null);
- comp.noreturn_type = try comp.arena().create(Type.NoReturn{
+ comp.noreturn_type = try comp.arena().create(Type.NoReturn);
+ comp.noreturn_type.* = Type.NoReturn{
.base = Type{
.name = "noreturn",
.base = Value{
@@ -638,10 +642,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.NoReturn,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
- });
+ };
assert((try comp.primitive_type_table.put(comp.noreturn_type.base.name, &comp.noreturn_type.base)) == null);
- comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt{
+ comp.comptime_int_type = try comp.arena().create(Type.ComptimeInt);
+ comp.comptime_int_type.* = Type.ComptimeInt{
.base = Type{
.name = "comptime_int",
.base = Value{
@@ -652,10 +657,11 @@ pub const Compilation = struct {
.id = builtin.TypeId.ComptimeInt,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
- });
+ };
assert((try comp.primitive_type_table.put(comp.comptime_int_type.base.name, &comp.comptime_int_type.base)) == null);
- comp.bool_type = try comp.arena().create(Type.Bool{
+ comp.bool_type = try comp.arena().create(Type.Bool);
+ comp.bool_type.* = Type.Bool{
.base = Type{
.name = "bool",
.base = Value{
@@ -666,45 +672,50 @@ pub const Compilation = struct {
.id = builtin.TypeId.Bool,
.abi_alignment = Type.AbiAlignment.init(comp.loop),
},
- });
+ };
assert((try comp.primitive_type_table.put(comp.bool_type.base.name, &comp.bool_type.base)) == null);
- comp.void_value = try comp.arena().create(Value.Void{
+ comp.void_value = try comp.arena().create(Value.Void);
+ comp.void_value.* = Value.Void{
.base = Value{
.id = Value.Id.Void,
.typ = &Type.Void.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
- });
+ };
- comp.true_value = try comp.arena().create(Value.Bool{
+ comp.true_value = try comp.arena().create(Value.Bool);
+ comp.true_value.* = Value.Bool{
.base = Value{
.id = Value.Id.Bool,
.typ = &Type.Bool.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
.x = true,
- });
+ };
- comp.false_value = try comp.arena().create(Value.Bool{
+ comp.false_value = try comp.arena().create(Value.Bool);
+ comp.false_value.* = Value.Bool{
.base = Value{
.id = Value.Id.Bool,
.typ = &Type.Bool.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
.x = false,
- });
+ };
- comp.noreturn_value = try comp.arena().create(Value.NoReturn{
+ comp.noreturn_value = try comp.arena().create(Value.NoReturn);
+ comp.noreturn_value.* = Value.NoReturn{
.base = Value{
.id = Value.Id.NoReturn,
.typ = &Type.NoReturn.get(comp).base,
.ref_count = std.atomic.Int(usize).init(1),
},
- });
+ };
for (CInt.list) |cint, i| {
- const c_int_type = try comp.arena().create(Type.Int{
+ const c_int_type = try comp.arena().create(Type.Int);
+ c_int_type.* = Type.Int{
.base = Type{
.name = cint.zig_name,
.base = Value{
@@ -720,11 +731,12 @@ pub const Compilation = struct {
.bit_count = comp.target.cIntTypeSizeInBits(cint.id),
},
.garbage_node = undefined,
- });
+ };
comp.c_int_types[i] = c_int_type;
assert((try comp.primitive_type_table.put(cint.zig_name, &c_int_type.base)) == null);
}
- comp.u8_type = try comp.arena().create(Type.Int{
+ comp.u8_type = try comp.arena().create(Type.Int);
+ comp.u8_type.* = Type.Int{
.base = Type{
.name = "u8",
.base = Value{
@@ -740,7 +752,7 @@ pub const Compilation = struct {
.bit_count = 8,
},
.garbage_node = undefined,
- });
+ };
assert((try comp.primitive_type_table.put(comp.u8_type.base.name, &comp.u8_type.base)) == null);
}
@@ -829,7 +841,7 @@ pub const Compilation = struct {
};
errdefer self.gpa().free(source_code);
- const tree = try self.gpa().createOne(ast.Tree);
+ const tree = try self.gpa().create(ast.Tree);
tree.* = try std.zig.parse(self.gpa(), source_code);
errdefer {
tree.deinit();
@@ -925,7 +937,8 @@ pub const Compilation = struct {
}
} else {
// add new decl
- const fn_decl = try self.gpa().create(Decl.Fn{
+ const fn_decl = try self.gpa().create(Decl.Fn);
+ fn_decl.* = Decl.Fn{
.base = Decl{
.id = Decl.Id.Fn,
.name = name,
@@ -936,7 +949,7 @@ pub const Compilation = struct {
},
.value = Decl.Fn.Val{ .Unresolved = {} },
.fn_proto = fn_proto,
- });
+ };
tree_scope.base.ref();
errdefer self.gpa().destroy(fn_decl);
@@ -1140,12 +1153,13 @@ pub const Compilation = struct {
}
}
- const link_lib = try self.gpa().create(LinkLib{
+ const link_lib = try self.gpa().create(LinkLib);
+ link_lib.* = LinkLib{
.name = name,
.path = null,
.provided_explicitly = provided_explicitly,
.symbols = ArrayList([]u8).init(self.gpa()),
- });
+ };
try self.link_libs_list.append(link_lib);
if (is_libc) {
self.libc_link_lib = link_lib;
diff --git a/src-self-hosted/errmsg.zig b/src-self-hosted/errmsg.zig
index 0e552fde7e..fc49fad410 100644
--- a/src-self-hosted/errmsg.zig
+++ b/src-self-hosted/errmsg.zig
@@ -118,7 +118,8 @@ pub const Msg = struct {
const realpath = try mem.dupe(comp.gpa(), u8, tree_scope.root().realpath);
errdefer comp.gpa().free(realpath);
- const msg = try comp.gpa().create(Msg{
+ const msg = try comp.gpa().create(Msg);
+ msg.* = Msg{
.text = text,
.realpath = realpath,
.data = Data{
@@ -128,7 +129,7 @@ pub const Msg = struct {
.span = span,
},
},
- });
+ };
tree_scope.base.ref();
return msg;
}
@@ -139,13 +140,14 @@ pub const Msg = struct {
const realpath_copy = try mem.dupe(comp.gpa(), u8, realpath);
errdefer comp.gpa().free(realpath_copy);
- const msg = try comp.gpa().create(Msg{
+ const msg = try comp.gpa().create(Msg);
+ msg.* = Msg{
.text = text,
.realpath = realpath_copy,
.data = Data{
.Cli = Cli{ .allocator = comp.gpa() },
},
- });
+ };
return msg;
}
@@ -164,7 +166,8 @@ pub const Msg = struct {
var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
try parse_error.render(&tree_scope.tree.tokens, out_stream);
- const msg = try comp.gpa().create(Msg{
+ const msg = try comp.gpa().create(Msg);
+ msg.* = Msg{
.text = undefined,
.realpath = realpath_copy,
.data = Data{
@@ -177,7 +180,7 @@ pub const Msg = struct {
},
},
},
- });
+ };
tree_scope.base.ref();
msg.text = text_buf.toOwnedSlice();
return msg;
@@ -203,7 +206,8 @@ pub const Msg = struct {
var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
try parse_error.render(&tree.tokens, out_stream);
- const msg = try allocator.create(Msg{
+ const msg = try allocator.create(Msg);
+ msg.* = Msg{
.text = undefined,
.realpath = realpath_copy,
.data = Data{
@@ -216,7 +220,7 @@ pub const Msg = struct {
},
},
},
- });
+ };
msg.text = text_buf.toOwnedSlice();
errdefer allocator.destroy(msg);
diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig
index 562765b354..0362bb4ef8 100644
--- a/src-self-hosted/ir.zig
+++ b/src-self-hosted/ir.zig
@@ -1021,12 +1021,13 @@ pub const Builder = struct {
pub const Error = Analyze.Error;
pub fn init(comp: *Compilation, tree_scope: *Scope.AstTree, begin_scope: ?*Scope) !Builder {
- const code = try comp.gpa().create(Code{
+ const code = try comp.gpa().create(Code);
+ code.* = Code{
.basic_block_list = undefined,
.arena = std.heap.ArenaAllocator.init(comp.gpa()),
.return_type = null,
.tree_scope = tree_scope,
- });
+ };
code.basic_block_list = std.ArrayList(*BasicBlock).init(&code.arena.allocator);
errdefer code.destroy(comp.gpa());
@@ -1052,7 +1053,8 @@ pub const Builder = struct {
/// No need to clean up resources thanks to the arena allocator.
pub fn createBasicBlock(self: *Builder, scope: *Scope, name_hint: [*]const u8) !*BasicBlock {
- const basic_block = try self.arena().create(BasicBlock{
+ const basic_block = try self.arena().create(BasicBlock);
+ basic_block.* = BasicBlock{
.ref_count = 0,
.name_hint = name_hint,
.debug_id = self.next_debug_id,
@@ -1063,7 +1065,7 @@ pub const Builder = struct {
.ref_instruction = null,
.llvm_block = undefined,
.llvm_exit_block = undefined,
- });
+ };
self.next_debug_id += 1;
return basic_block;
}
@@ -1774,7 +1776,8 @@ pub const Builder = struct {
params: I.Params,
is_generated: bool,
) !*Inst {
- const inst = try self.arena().create(I{
+ const inst = try self.arena().create(I);
+ inst.* = I{
.base = Inst{
.id = Inst.typeToId(I),
.is_generated = is_generated,
@@ -1793,7 +1796,7 @@ pub const Builder = struct {
.owner_bb = self.current_basic_block,
},
.params = params,
- });
+ };
// Look at the params and ref() other instructions
comptime var i = 0;
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 0742cbfe65..1403ab860d 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -944,12 +944,13 @@ const CliPkg = struct {
parent: ?*CliPkg,
pub fn init(allocator: *mem.Allocator, name: []const u8, path: []const u8, parent: ?*CliPkg) !*CliPkg {
- var pkg = try allocator.create(CliPkg{
+ var pkg = try allocator.create(CliPkg);
+ pkg.* = CliPkg{
.name = name,
.path = path,
.children = ArrayList(*CliPkg).init(allocator),
.parent = parent,
- });
+ };
return pkg;
}
diff --git a/src-self-hosted/package.zig b/src-self-hosted/package.zig
index 720b279651..0d31731b55 100644
--- a/src-self-hosted/package.zig
+++ b/src-self-hosted/package.zig
@@ -15,11 +15,13 @@ pub const Package = struct {
/// makes internal copies of root_src_dir and root_src_path
/// allocator should be an arena allocator because Package never frees anything
pub fn create(allocator: *mem.Allocator, root_src_dir: []const u8, root_src_path: []const u8) !*Package {
- return allocator.create(Package{
+ const ptr = try allocator.create(Package);
+ ptr.* = Package{
.root_src_dir = try Buffer.init(allocator, root_src_dir),
.root_src_path = try Buffer.init(allocator, root_src_path),
.table = Table.init(allocator),
- });
+ };
+ return ptr;
}
pub fn add(self: *Package, name: []const u8, package: *Package) !void {
diff --git a/src-self-hosted/scope.zig b/src-self-hosted/scope.zig
index 43d3b5a784..b14c073a9e 100644
--- a/src-self-hosted/scope.zig
+++ b/src-self-hosted/scope.zig
@@ -120,7 +120,7 @@ pub const Scope = struct {
/// Creates a Root scope with 1 reference
/// Takes ownership of realpath
pub fn create(comp: *Compilation, realpath: []u8) !*Root {
- const self = try comp.gpa().createOne(Root);
+ const self = try comp.gpa().create(Root);
self.* = Root{
.base = Scope{
.id = Id.Root,
@@ -150,7 +150,7 @@ pub const Scope = struct {
/// Creates a scope with 1 reference
/// Takes ownership of tree, will deinit and destroy when done.
pub fn create(comp: *Compilation, tree: *ast.Tree, root_scope: *Root) !*AstTree {
- const self = try comp.gpa().createOne(AstTree);
+ const self = try comp.gpa().create(AstTree);
self.* = AstTree{
.base = undefined,
.tree = tree,
@@ -182,7 +182,7 @@ pub const Scope = struct {
/// Creates a Decls scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*Decls {
- const self = try comp.gpa().createOne(Decls);
+ const self = try comp.gpa().create(Decls);
self.* = Decls{
.base = undefined,
.table = event.RwLocked(Decl.Table).init(comp.loop, Decl.Table.init(comp.gpa())),
@@ -235,7 +235,7 @@ pub const Scope = struct {
/// Creates a Block scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*Block {
- const self = try comp.gpa().createOne(Block);
+ const self = try comp.gpa().create(Block);
self.* = Block{
.base = undefined,
.incoming_values = undefined,
@@ -262,7 +262,7 @@ pub const Scope = struct {
/// Creates a FnDef scope with 1 reference
/// Must set the fn_val later
pub fn create(comp: *Compilation, parent: *Scope) !*FnDef {
- const self = try comp.gpa().createOne(FnDef);
+ const self = try comp.gpa().create(FnDef);
self.* = FnDef{
.base = undefined,
.fn_val = null,
@@ -281,7 +281,7 @@ pub const Scope = struct {
/// Creates a CompTime scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope) !*CompTime {
- const self = try comp.gpa().createOne(CompTime);
+ const self = try comp.gpa().create(CompTime);
self.* = CompTime{ .base = undefined };
self.base.init(Id.CompTime, parent);
return self;
@@ -309,7 +309,7 @@ pub const Scope = struct {
kind: Kind,
defer_expr_scope: *DeferExpr,
) !*Defer {
- const self = try comp.gpa().createOne(Defer);
+ const self = try comp.gpa().create(Defer);
self.* = Defer{
.base = undefined,
.defer_expr_scope = defer_expr_scope,
@@ -333,7 +333,7 @@ pub const Scope = struct {
/// Creates a DeferExpr scope with 1 reference
pub fn create(comp: *Compilation, parent: *Scope, expr_node: *ast.Node) !*DeferExpr {
- const self = try comp.gpa().createOne(DeferExpr);
+ const self = try comp.gpa().create(DeferExpr);
self.* = DeferExpr{
.base = undefined,
.expr_node = expr_node,
@@ -398,7 +398,7 @@ pub const Scope = struct {
}
fn create(comp: *Compilation, parent: *Scope, name: []const u8, src_node: *ast.Node) !*Var {
- const self = try comp.gpa().createOne(Var);
+ const self = try comp.gpa().create(Var);
self.* = Var{
.base = undefined,
.name = name,
diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig
index fa31343902..8a05594b30 100644
--- a/src-self-hosted/type.zig
+++ b/src-self-hosted/type.zig
@@ -413,7 +413,7 @@ pub const Type = struct {
key.ref();
errdefer key.deref(comp);
- const self = try comp.gpa().createOne(Fn);
+ const self = try comp.gpa().create(Fn);
self.* = Fn{
.base = undefined,
.key = key,
@@ -615,11 +615,12 @@ pub const Type = struct {
}
}
- const self = try comp.gpa().create(Int{
+ const self = try comp.gpa().create(Int);
+ self.* = Int{
.base = undefined,
.key = key,
.garbage_node = undefined,
- });
+ };
errdefer comp.gpa().destroy(self);
const u_or_i = "ui"[@boolToInt(key.is_signed)];
@@ -781,11 +782,12 @@ pub const Type = struct {
}
}
- const self = try comp.gpa().create(Pointer{
+ const self = try comp.gpa().create(Pointer);
+ self.* = Pointer{
.base = undefined,
.key = normal_key,
.garbage_node = undefined,
- });
+ };
errdefer comp.gpa().destroy(self);
const size_str = switch (self.key.size) {
@@ -879,11 +881,12 @@ pub const Type = struct {
}
}
- const self = try comp.gpa().create(Array{
+ const self = try comp.gpa().create(Array);
+ self.* = Array{
.base = undefined,
.key = key,
.garbage_node = undefined,
- });
+ };
errdefer comp.gpa().destroy(self);
const name = try std.fmt.allocPrint(comp.gpa(), "[{}]{}", key.len, key.elem_type.name);
diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig
index e6dca4eff7..9431c614b9 100644
--- a/src-self-hosted/value.zig
+++ b/src-self-hosted/value.zig
@@ -135,14 +135,15 @@ pub const Value = struct {
symbol_name: Buffer,
pub fn create(comp: *Compilation, fn_type: *Type.Fn, symbol_name: Buffer) !*FnProto {
- const self = try comp.gpa().create(FnProto{
+ const self = try comp.gpa().create(FnProto);
+ self.* = FnProto{
.base = Value{
.id = Value.Id.FnProto,
.typ = &fn_type.base,
.ref_count = std.atomic.Int(usize).init(1),
},
.symbol_name = symbol_name,
- });
+ };
fn_type.base.base.ref();
return self;
}
@@ -190,14 +191,16 @@ pub const Value = struct {
/// Creates a Fn value with 1 ref
/// Takes ownership of symbol_name
pub fn create(comp: *Compilation, fn_type: *Type.Fn, fndef_scope: *Scope.FnDef, symbol_name: Buffer) !*Fn {
- const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node{
+ const link_set_node = try comp.gpa().create(Compilation.FnLinkSet.Node);
+ link_set_node.* = Compilation.FnLinkSet.Node{
.data = null,
.next = undefined,
.prev = undefined,
- });
+ };
errdefer comp.gpa().destroy(link_set_node);
- const self = try comp.gpa().create(Fn{
+ const self = try comp.gpa().create(Fn);
+ self.* = Fn{
.base = Value{
.id = Value.Id.Fn,
.typ = &fn_type.base,
@@ -209,7 +212,7 @@ pub const Value = struct {
.symbol_name = symbol_name,
.containing_object = Buffer.initNull(comp.gpa()),
.link_set_node = link_set_node,
- });
+ };
fn_type.base.base.ref();
fndef_scope.fn_val = self;
fndef_scope.base.ref();
@@ -353,7 +356,8 @@ pub const Value = struct {
var ptr_type_consumed = false;
errdefer if (!ptr_type_consumed) ptr_type.base.base.deref(comp);
- const self = try comp.gpa().create(Value.Ptr{
+ const self = try comp.gpa().create(Value.Ptr);
+ self.* = Value.Ptr{
.base = Value{
.id = Value.Id.Ptr,
.typ = &ptr_type.base,
@@ -366,7 +370,7 @@ pub const Value = struct {
},
},
.mut = Mut.CompTimeConst,
- });
+ };
ptr_type_consumed = true;
errdefer comp.gpa().destroy(self);
@@ -430,14 +434,15 @@ pub const Value = struct {
}) catch unreachable);
errdefer array_type.base.base.deref(comp);
- const self = try comp.gpa().create(Value.Array{
+ const self = try comp.gpa().create(Value.Array);
+ self.* = Value.Array{
.base = Value{
.id = Value.Id.Array,
.typ = &array_type.base,
.ref_count = std.atomic.Int(usize).init(1),
},
.special = Special{ .OwnedBuffer = buffer },
- });
+ };
errdefer comp.gpa().destroy(self);
return self;
@@ -509,14 +514,15 @@ pub const Value = struct {
big_int: std.math.big.Int,
pub fn createFromString(comp: *Compilation, typ: *Type, base: u8, value: []const u8) !*Int {
- const self = try comp.gpa().create(Value.Int{
+ const self = try comp.gpa().create(Value.Int);
+ self.* = Value.Int{
.base = Value{
.id = Value.Id.Int,
.typ = typ,
.ref_count = std.atomic.Int(usize).init(1),
},
.big_int = undefined,
- });
+ };
typ.base.ref();
errdefer comp.gpa().destroy(self);
@@ -557,14 +563,15 @@ pub const Value = struct {
old.base.typ.base.ref();
errdefer old.base.typ.base.deref(comp);
- const new = try comp.gpa().create(Value.Int{
+ const new = try comp.gpa().create(Value.Int);
+ new.* = Value.Int{
.base = Value{
.id = Value.Id.Int,
.typ = old.base.typ,
.ref_count = std.atomic.Int(usize).init(1),
},
.big_int = undefined,
- });
+ };
errdefer comp.gpa().destroy(new);
new.big_int = try old.big_int.clone();
diff --git a/std/atomic/queue.zig b/std/atomic/queue.zig
index 6c61bcc048..183c434dc5 100644
--- a/std/atomic/queue.zig
+++ b/std/atomic/queue.zig
@@ -221,11 +221,12 @@ fn startPuts(ctx: *Context) u8 {
while (put_count != 0) : (put_count -= 1) {
std.os.time.sleep(1); // let the os scheduler be our fuzz
const x = @bitCast(i32, r.random.scalar(u32));
- const node = ctx.allocator.create(Queue(i32).Node{
+ const node = ctx.allocator.create(Queue(i32).Node) catch unreachable;
+ node.* = Queue(i32).Node{
.prev = undefined,
.next = undefined,
.data = x,
- }) catch unreachable;
+ };
ctx.queue.put(node);
_ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
}
diff --git a/std/atomic/stack.zig b/std/atomic/stack.zig
index 1e4981353b..503fa0c0ce 100644
--- a/std/atomic/stack.zig
+++ b/std/atomic/stack.zig
@@ -155,10 +155,11 @@ fn startPuts(ctx: *Context) u8 {
while (put_count != 0) : (put_count -= 1) {
std.os.time.sleep(1); // let the os scheduler be our fuzz
const x = @bitCast(i32, r.random.scalar(u32));
- const node = ctx.allocator.create(Stack(i32).Node{
+ const node = ctx.allocator.create(Stack(i32).Node) catch unreachable;
+ node.* = Stack(i32).Node{
.next = undefined,
.data = x,
- }) catch unreachable;
+ };
ctx.stack.push(node);
_ = @atomicRmw(isize, &ctx.put_sum, builtin.AtomicRmwOp.Add, x, AtomicOrder.SeqCst);
}
diff --git a/std/build.zig b/std/build.zig
index 90f5bec656..6f58594190 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -89,7 +89,7 @@ pub const Builder = struct {
};
pub fn init(allocator: *Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
- const env_map = allocator.createOne(BufMap) catch unreachable;
+ const env_map = allocator.create(BufMap) catch unreachable;
env_map.* = os.getEnvMap(allocator) catch unreachable;
var self = Builder{
.zig_exe = zig_exe,
@@ -170,7 +170,8 @@ pub const Builder = struct {
}
pub fn addTest(self: *Builder, root_src: []const u8) *TestStep {
- const test_step = self.allocator.create(TestStep.init(self, root_src)) catch unreachable;
+ const test_step = self.allocator.create(TestStep) catch unreachable;
+ test_step.* = TestStep.init(self, root_src);
return test_step;
}
@@ -202,18 +203,21 @@ pub const Builder = struct {
}
pub fn addWriteFile(self: *Builder, file_path: []const u8, data: []const u8) *WriteFileStep {
- const write_file_step = self.allocator.create(WriteFileStep.init(self, file_path, data)) catch unreachable;
+ const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
+ write_file_step.* = WriteFileStep.init(self, file_path, data);
return write_file_step;
}
pub fn addLog(self: *Builder, comptime format: []const u8, args: ...) *LogStep {
const data = self.fmt(format, args);
- const log_step = self.allocator.create(LogStep.init(self, data)) catch unreachable;
+ const log_step = self.allocator.create(LogStep) catch unreachable;
+ log_step.* = LogStep.init(self, data);
return log_step;
}
pub fn addRemoveDirTree(self: *Builder, dir_path: []const u8) *RemoveDirStep {
- const remove_dir_step = self.allocator.create(RemoveDirStep.init(self, dir_path)) catch unreachable;
+ const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
+ remove_dir_step.* = RemoveDirStep.init(self, dir_path);
return remove_dir_step;
}
@@ -414,10 +418,11 @@ pub const Builder = struct {
}
pub fn step(self: *Builder, name: []const u8, description: []const u8) *Step {
- const step_info = self.allocator.create(TopLevelStep{
+ const step_info = self.allocator.create(TopLevelStep) catch unreachable;
+ step_info.* = TopLevelStep{
.step = Step.initNoOp(name, self.allocator),
.description = description,
- }) catch unreachable;
+ };
self.top_level_steps.append(step_info) catch unreachable;
return &step_info.step;
}
@@ -616,7 +621,8 @@ pub const Builder = struct {
const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
self.pushInstalledFile(full_dest_path);
- const install_step = self.allocator.create(InstallFileStep.init(self, src_path, full_dest_path)) catch unreachable;
+ const install_step = self.allocator.create(InstallFileStep) catch unreachable;
+ install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
return install_step;
}
@@ -865,43 +871,51 @@ pub const LibExeObjStep = struct {
};
pub fn createSharedLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8, ver: Version) *LibExeObjStep {
- const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, false, ver)) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
return self;
}
pub fn createCSharedLibrary(builder: *Builder, name: []const u8, version: Version) *LibExeObjStep {
- const self = builder.allocator.create(initC(builder, name, Kind.Lib, version, false)) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initC(builder, name, Kind.Lib, version, false);
return self;
}
pub fn createStaticLibrary(builder: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
- const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0))) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
return self;
}
pub fn createCStaticLibrary(builder: *Builder, name: []const u8) *LibExeObjStep {
- const self = builder.allocator.create(initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true)) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
return self;
}
pub fn createObject(builder: *Builder, name: []const u8, root_src: []const u8) *LibExeObjStep {
- const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0))) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
return self;
}
pub fn createCObject(builder: *Builder, name: []const u8, src: []const u8) *LibExeObjStep {
- const self = builder.allocator.create(initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false)) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
self.object_src = src;
return self;
}
pub fn createExecutable(builder: *Builder, name: []const u8, root_src: ?[]const u8, static: bool) *LibExeObjStep {
- const self = builder.allocator.create(initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0))) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initExtraArgs(builder, name, root_src, Kind.Exe, static, builder.version(0, 0, 0));
return self;
}
pub fn createCExecutable(builder: *Builder, name: []const u8) *LibExeObjStep {
- const self = builder.allocator.create(initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false)) catch unreachable;
+ const self = builder.allocator.create(LibExeObjStep) catch unreachable;
+ self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
return self;
}
@@ -1914,13 +1928,14 @@ pub const CommandStep = struct {
/// ::argv is copied.
pub fn create(builder: *Builder, cwd: ?[]const u8, env_map: *const BufMap, argv: []const []const u8) *CommandStep {
- const self = builder.allocator.create(CommandStep{
+ const self = builder.allocator.create(CommandStep) catch unreachable;
+ self.* = CommandStep{
.builder = builder,
.step = Step.init(argv[0], builder.allocator, make),
.argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
.cwd = cwd,
.env_map = env_map,
- }) catch unreachable;
+ };
mem.copy([]const u8, self.argv, argv);
self.step.name = self.argv[0];
@@ -1949,12 +1964,13 @@ const InstallArtifactStep = struct {
LibExeObjStep.Kind.Exe => builder.exe_dir,
LibExeObjStep.Kind.Lib => builder.lib_dir,
};
- const self = builder.allocator.create(Self{
+ const self = builder.allocator.create(Self) catch unreachable;
+ self.* = Self{
.builder = builder,
.step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
.artifact = artifact,
.dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,
- }) catch unreachable;
+ };
self.step.dependOn(&artifact.step);
builder.pushInstalledFile(self.dest_file);
if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
diff --git a/std/debug/index.zig b/std/debug/index.zig
index 445f943594..838bd0c166 100644
--- a/std/debug/index.zig
+++ b/std/debug/index.zig
@@ -751,7 +751,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
const self_file = try os.openSelfExe();
defer self_file.close();
- const coff_obj = try allocator.createOne(coff.Coff);
+ const coff_obj = try allocator.create(coff.Coff);
coff_obj.* = coff.Coff{
.in_file = self_file,
.allocator = allocator,
@@ -1036,7 +1036,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo {
}
}
}
- const sentinel = try allocator.createOne(macho.nlist_64);
+ const sentinel = try allocator.create(macho.nlist_64);
sentinel.* = macho.nlist_64{
.n_strx = 0,
.n_type = 36,
@@ -1949,7 +1949,8 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
try di.dwarf_seekable_stream.seekTo(compile_unit_pos);
- const compile_unit_die = try di.allocator().create(try parseDie(di, abbrev_table, is_64));
+ const compile_unit_die = try di.allocator().create(Die);
+ compile_unit_die.* = try parseDie(di, abbrev_table, is_64);
if (compile_unit_die.tag_id != DW.TAG_compile_unit) return error.InvalidDebugInfo;
diff --git a/std/event/channel.zig b/std/event/channel.zig
index f04ad1604e..f8cdae6208 100644
--- a/std/event/channel.zig
+++ b/std/event/channel.zig
@@ -54,7 +54,8 @@ pub fn Channel(comptime T: type) type {
const buffer_nodes = try loop.allocator.alloc(T, capacity);
errdefer loop.allocator.free(buffer_nodes);
- const self = try loop.allocator.create(SelfChannel{
+ const self = try loop.allocator.create(SelfChannel);
+ self.* = SelfChannel{
.loop = loop,
.buffer_len = 0,
.buffer_nodes = buffer_nodes,
@@ -66,7 +67,7 @@ pub fn Channel(comptime T: type) type {
.or_null_queue = std.atomic.Queue(*std.atomic.Queue(GetNode).Node).init(),
.get_count = 0,
.put_count = 0,
- });
+ };
errdefer loop.allocator.destroy(self);
return self;
diff --git a/std/event/fs.zig b/std/event/fs.zig
index 7e77b3e6e2..097f2beddc 100644
--- a/std/event/fs.zig
+++ b/std/event/fs.zig
@@ -495,7 +495,7 @@ pub const CloseOperation = struct {
};
pub fn start(loop: *Loop) (error{OutOfMemory}!*CloseOperation) {
- const self = try loop.allocator.createOne(CloseOperation);
+ const self = try loop.allocator.create(CloseOperation);
self.* = CloseOperation{
.loop = loop,
.os_data = switch (builtin.os) {
@@ -787,7 +787,7 @@ pub fn Watch(comptime V: type) type {
},
builtin.Os.windows => {
- const self = try loop.allocator.createOne(Self);
+ const self = try loop.allocator.create(Self);
errdefer loop.allocator.destroy(self);
self.* = Self{
.channel = channel,
@@ -802,7 +802,7 @@ pub fn Watch(comptime V: type) type {
},
builtin.Os.macosx, builtin.Os.freebsd => {
- const self = try loop.allocator.createOne(Self);
+ const self = try loop.allocator.create(Self);
errdefer loop.allocator.destroy(self);
self.* = Self{
@@ -1068,7 +1068,7 @@ pub fn Watch(comptime V: type) type {
}
} else {
errdefer _ = self.os_data.dir_table.remove(dirname);
- const dir = try self.channel.loop.allocator.createOne(OsData.Dir);
+ const dir = try self.channel.loop.allocator.create(OsData.Dir);
errdefer self.channel.loop.allocator.destroy(dir);
dir.* = OsData.Dir{
diff --git a/std/event/group.zig b/std/event/group.zig
index 0e9c2d9655..7f6b5d953b 100644
--- a/std/event/group.zig
+++ b/std/event/group.zig
@@ -42,10 +42,11 @@ pub fn Group(comptime ReturnType: type) type {
/// Add a promise to the group. Thread-safe.
pub fn add(self: *Self, handle: promise->ReturnType) (error{OutOfMemory}!void) {
- const node = try self.lock.loop.allocator.create(Stack.Node{
+ const node = try self.lock.loop.allocator.create(Stack.Node);
+ node.* = Stack.Node{
.next = undefined,
.data = handle,
- });
+ };
self.alloc_stack.push(node);
}
diff --git a/std/heap.zig b/std/heap.zig
index 46b247fa7e..fd2ce1e965 100644
--- a/std/heap.zig
+++ b/std/heap.zig
@@ -518,7 +518,8 @@ fn testAllocator(allocator: *mem.Allocator) !void {
var slice = try allocator.alloc(*i32, 100);
assert(slice.len == 100);
for (slice) |*item, i| {
- item.* = try allocator.create(@intCast(i32, i));
+ item.* = try allocator.create(i32);
+ item.*.* = @intCast(i32, i);
}
slice = try allocator.realloc(*i32, slice, 20000);
diff --git a/std/io.zig b/std/io.zig
index 46625cd34b..c8701aeda6 100644
--- a/std/io.zig
+++ b/std/io.zig
@@ -944,12 +944,13 @@ pub const BufferedAtomicFile = struct {
pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {
// TODO with well defined copy elision we don't need this allocation
- var self = try allocator.create(BufferedAtomicFile{
+ var self = try allocator.create(BufferedAtomicFile);
+ self.* = BufferedAtomicFile{
.atomic_file = undefined,
.file_stream = undefined,
.buffered_stream = undefined,
.allocator = allocator,
- });
+ };
errdefer allocator.destroy(self);
self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode);
diff --git a/std/linked_list.zig b/std/linked_list.zig
index c3db55b5a6..7021cac707 100644
--- a/std/linked_list.zig
+++ b/std/linked_list.zig
@@ -190,7 +190,7 @@ pub fn LinkedList(comptime T: type) type {
/// Returns:
/// A pointer to the new node.
pub fn allocateNode(list: *Self, allocator: *Allocator) !*Node {
- return allocator.create(Node(undefined));
+ return allocator.create(Node);
}
/// Deallocate a node.
diff --git a/std/mem.zig b/std/mem.zig
index fb5f6fd5da..a403d80453 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -36,20 +36,9 @@ pub const Allocator = struct {
/// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
freeFn: fn (self: *Allocator, old_mem: []u8) void,
- /// Call `destroy` with the result
- /// TODO this is deprecated. use createOne instead
- pub fn create(self: *Allocator, init: var) Error!*@typeOf(init) {
- const T = @typeOf(init);
- if (@sizeOf(T) == 0) return &(T{});
- const slice = try self.alloc(T, 1);
- const ptr = &slice[0];
- ptr.* = init;
- return ptr;
- }
-
/// Call `destroy` with the result.
/// Returns undefined memory.
- pub fn createOne(self: *Allocator, comptime T: type) Error!*T {
+ pub fn create(self: *Allocator, comptime T: type) Error!*T {
if (@sizeOf(T) == 0) return &(T{});
const slice = try self.alloc(T, 1);
return &slice[0];
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 0aa896ff1b..9f33bee905 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -88,7 +88,8 @@ pub const ChildProcess = struct {
/// First argument in argv is the executable.
/// On success must call deinit.
pub fn init(argv: []const []const u8, allocator: *mem.Allocator) !*ChildProcess {
- const child = try allocator.create(ChildProcess{
+ const child = try allocator.create(ChildProcess);
+ child.* = ChildProcess{
.allocator = allocator,
.argv = argv,
.pid = undefined,
@@ -109,7 +110,7 @@ pub const ChildProcess = struct {
.stdin_behavior = StdIo.Inherit,
.stdout_behavior = StdIo.Inherit,
.stderr_behavior = StdIo.Inherit,
- });
+ };
errdefer allocator.destroy(child);
return child;
}
diff --git a/std/os/index.zig b/std/os/index.zig
index 75abe3bbde..0d0e07bfa3 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -3047,7 +3047,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
const bytes_ptr = windows.HeapAlloc(heap_handle, 0, byte_count) orelse return SpawnThreadError.OutOfMemory;
errdefer assert(windows.HeapFree(heap_handle, 0, bytes_ptr) != 0);
const bytes = @ptrCast([*]u8, bytes_ptr)[0..byte_count];
- const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext{
+ const outer_context = std.heap.FixedBufferAllocator.init(bytes).allocator.create(WinThread.OuterContext) catch unreachable;
+ outer_context.* = WinThread.OuterContext{
.thread = Thread{
.data = Thread.Data{
.heap_handle = heap_handle,
@@ -3056,7 +3057,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
},
},
.inner = context,
- }) catch unreachable;
+ };
const parameter = if (@sizeOf(Context) == 0) null else @ptrCast(*c_void, &outer_context.inner);
outer_context.thread.data.handle = windows.CreateThread(null, default_stack_size, WinThread.threadMain, parameter, 0, null) orelse {
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index a216484d7d..783464c620 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -17,14 +17,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
defer stack.deinit();
const arena = &tree_arena.allocator;
- const root_node = try arena.create(ast.Node.Root{
+ const root_node = try arena.create(ast.Node.Root);
+ root_node.* = ast.Node.Root{
.base = ast.Node{ .id = ast.Node.Id.Root },
.decls = ast.Node.Root.DeclList.init(arena),
.doc_comments = null,
.shebang = null,
// initialized when we get the eof token
.eof_token = undefined,
- });
+ };
var tree = ast.Tree{
.source = source,
@@ -75,20 +76,22 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
Token.Id.Keyword_test => {
stack.append(State.TopLevel) catch unreachable;
- const block = try arena.create(ast.Node.Block{
+ const block = try arena.create(ast.Node.Block);
+ block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = null,
.lbrace = undefined,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
- const test_node = try arena.create(ast.Node.TestDecl{
+ };
+ const test_node = try arena.create(ast.Node.TestDecl);
+ test_node.* = ast.Node.TestDecl{
.base = ast.Node{ .id = ast.Node.Id.TestDecl },
.doc_comments = comments,
.test_token = token_index,
.name = undefined,
.body_node = &block.base,
- });
+ };
try root_node.decls.push(&test_node.base);
try stack.append(State{ .Block = block });
try stack.append(State{
@@ -119,19 +122,21 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_comptime => {
- const block = try arena.create(ast.Node.Block{
+ const block = try arena.create(ast.Node.Block);
+ block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = null,
.lbrace = undefined,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
- const node = try arena.create(ast.Node.Comptime{
+ };
+ const node = try arena.create(ast.Node.Comptime);
+ node.* = ast.Node.Comptime{
.base = ast.Node{ .id = ast.Node.Id.Comptime },
.comptime_token = token_index,
.expr = &block.base,
.doc_comments = comments,
- });
+ };
try root_node.decls.push(&node.base);
stack.append(State.TopLevel) catch unreachable;
@@ -235,14 +240,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
return tree;
}
- const node = try arena.create(ast.Node.Use{
+ const node = try arena.create(ast.Node.Use);
+ node.* = ast.Node.Use{
.base = ast.Node{ .id = ast.Node.Id.Use },
.use_token = token_index,
.visib_token = ctx.visib_token,
.expr = undefined,
.semicolon_token = undefined,
.doc_comments = ctx.comments,
- });
+ };
try ctx.decls.push(&node.base);
stack.append(State{
@@ -276,7 +282,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
- const fn_proto = try arena.create(ast.Node.FnProto{
+ const fn_proto = try arena.create(ast.Node.FnProto);
+ fn_proto.* = ast.Node.FnProto{
.base = ast.Node{ .id = ast.Node.Id.FnProto },
.doc_comments = ctx.comments,
.visib_token = ctx.visib_token,
@@ -292,7 +299,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.lib_name = ctx.lib_name,
.align_expr = null,
.section_expr = null,
- });
+ };
try ctx.decls.push(&fn_proto.base);
stack.append(State{ .FnDef = fn_proto }) catch unreachable;
try stack.append(State{ .FnProto = fn_proto });
@@ -309,12 +316,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_async => {
- const async_node = try arena.create(ast.Node.AsyncAttribute{
+ const async_node = try arena.create(ast.Node.AsyncAttribute);
+ async_node.* = ast.Node.AsyncAttribute{
.base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
.async_token = token_index,
.allocator_type = null,
.rangle_bracket = null,
- });
+ };
fn_proto.async_attr = async_node;
try stack.append(State{
@@ -341,13 +349,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
},
State.TopLevelExternOrField => |ctx| {
if (eatToken(&tok_it, &tree, Token.Id.Identifier)) |identifier| {
- const node = try arena.create(ast.Node.StructField{
+ const node = try arena.create(ast.Node.StructField);
+ node.* = ast.Node.StructField{
.base = ast.Node{ .id = ast.Node.Id.StructField },
.doc_comments = ctx.comments,
.visib_token = ctx.visib_token,
.name_token = identifier,
.type_expr = undefined,
- });
+ };
const node_ptr = try ctx.container_decl.fields_and_decls.addOne();
node_ptr.* = &node.base;
@@ -391,7 +400,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token = nextToken(&tok_it, &tree);
const token_index = token.index;
const token_ptr = token.ptr;
- const node = try arena.create(ast.Node.ContainerDecl{
+ const node = try arena.create(ast.Node.ContainerDecl);
+ node.* = ast.Node.ContainerDecl{
.base = ast.Node{ .id = ast.Node.Id.ContainerDecl },
.layout_token = ctx.layout_token,
.kind_token = switch (token_ptr.id) {
@@ -405,7 +415,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.fields_and_decls = ast.Node.ContainerDecl.DeclList.init(arena),
.lbrace_token = undefined,
.rbrace_token = undefined,
- });
+ };
ctx.opt_ctx.store(&node.base);
stack.append(State{ .ContainerDecl = node }) catch unreachable;
@@ -464,13 +474,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
Token.Id.Identifier => {
switch (tree.tokens.at(container_decl.kind_token).id) {
Token.Id.Keyword_struct => {
- const node = try arena.create(ast.Node.StructField{
+ const node = try arena.create(ast.Node.StructField);
+ node.* = ast.Node.StructField{
.base = ast.Node{ .id = ast.Node.Id.StructField },
.doc_comments = comments,
.visib_token = null,
.name_token = token_index,
.type_expr = undefined,
- });
+ };
const node_ptr = try container_decl.fields_and_decls.addOne();
node_ptr.* = &node.base;
@@ -485,13 +496,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_union => {
- const node = try arena.create(ast.Node.UnionTag{
+ const node = try arena.create(ast.Node.UnionTag);
+ node.* = ast.Node.UnionTag{
.base = ast.Node{ .id = ast.Node.Id.UnionTag },
.name_token = token_index,
.type_expr = null,
.value_expr = null,
.doc_comments = comments,
- });
+ };
try container_decl.fields_and_decls.push(&node.base);
try stack.append(State{
@@ -506,12 +518,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_enum => {
- const node = try arena.create(ast.Node.EnumTag{
+ const node = try arena.create(ast.Node.EnumTag);
+ node.* = ast.Node.EnumTag{
.base = ast.Node{ .id = ast.Node.Id.EnumTag },
.name_token = token_index,
.value = null,
.doc_comments = comments,
- });
+ };
try container_decl.fields_and_decls.push(&node.base);
try stack.append(State{
@@ -593,7 +606,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
},
State.VarDecl => |ctx| {
- const var_decl = try arena.create(ast.Node.VarDecl{
+ const var_decl = try arena.create(ast.Node.VarDecl);
+ var_decl.* = ast.Node.VarDecl{
.base = ast.Node{ .id = ast.Node.Id.VarDecl },
.doc_comments = ctx.comments,
.visib_token = ctx.visib_token,
@@ -609,7 +623,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.name_token = undefined,
.eq_token = undefined,
.semicolon_token = undefined,
- });
+ };
try ctx.list.push(&var_decl.base);
try stack.append(State{ .VarDeclAlign = var_decl });
@@ -708,13 +722,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_ptr = token.ptr;
switch (token_ptr.id) {
Token.Id.LBrace => {
- const block = try arena.create(ast.Node.Block{
+ const block = try arena.create(ast.Node.Block);
+ block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = null,
.lbrace = token_index,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
+ };
fn_proto.body_node = &block.base;
stack.append(State{ .Block = block }) catch unreachable;
continue;
@@ -770,10 +785,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
// TODO: this is a special case. Remove this when #760 is fixed
if (token_ptr.id == Token.Id.Keyword_anyerror) {
if (tok_it.peek().?.id == Token.Id.LBrace) {
- const error_type_node = try arena.create(ast.Node.ErrorType{
+ const error_type_node = try arena.create(ast.Node.ErrorType);
+ error_type_node.* = ast.Node.ErrorType{
.base = ast.Node{ .id = ast.Node.Id.ErrorType },
.token = token_index,
- });
+ };
fn_proto.return_type = ast.Node.FnProto.ReturnType{ .Explicit = &error_type_node.base };
continue;
}
@@ -791,14 +807,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
if (eatToken(&tok_it, &tree, Token.Id.RParen)) |_| {
continue;
}
- const param_decl = try arena.create(ast.Node.ParamDecl{
+ const param_decl = try arena.create(ast.Node.ParamDecl);
+ param_decl.* = ast.Node.ParamDecl{
.base = ast.Node{ .id = ast.Node.Id.ParamDecl },
.comptime_token = null,
.noalias_token = null,
.name_token = null,
.type_node = undefined,
.var_args_token = null,
- });
+ };
try fn_proto.params.push(¶m_decl.base);
stack.append(State{
@@ -877,13 +894,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_ptr = token.ptr;
switch (token_ptr.id) {
Token.Id.LBrace => {
- const block = try arena.create(ast.Node.Block{
+ const block = try arena.create(ast.Node.Block);
+ block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = ctx.label,
.lbrace = token_index,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
+ };
ctx.opt_ctx.store(&block.base);
stack.append(State{ .Block = block }) catch unreachable;
continue;
@@ -970,7 +988,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
}
},
State.While => |ctx| {
- const node = try arena.create(ast.Node.While{
+ const node = try arena.create(ast.Node.While);
+ node.* = ast.Node.While{
.base = ast.Node{ .id = ast.Node.Id.While },
.label = ctx.label,
.inline_token = ctx.inline_token,
@@ -980,7 +999,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.continue_expr = null,
.body = undefined,
.@"else" = null,
- });
+ };
ctx.opt_ctx.store(&node.base);
stack.append(State{ .Else = &node.@"else" }) catch unreachable;
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
@@ -999,7 +1018,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
State.For => |ctx| {
- const node = try arena.create(ast.Node.For{
+ const node = try arena.create(ast.Node.For);
+ node.* = ast.Node.For{
.base = ast.Node{ .id = ast.Node.Id.For },
.label = ctx.label,
.inline_token = ctx.inline_token,
@@ -1008,7 +1028,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.payload = null,
.body = undefined,
.@"else" = null,
- });
+ };
ctx.opt_ctx.store(&node.base);
stack.append(State{ .Else = &node.@"else" }) catch unreachable;
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } });
@@ -1020,12 +1040,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
},
State.Else => |dest| {
if (eatToken(&tok_it, &tree, Token.Id.Keyword_else)) |else_token| {
- const node = try arena.create(ast.Node.Else{
+ const node = try arena.create(ast.Node.Else);
+ node.* = ast.Node.Else{
.base = ast.Node{ .id = ast.Node.Id.Else },
.else_token = else_token,
.payload = null,
.body = undefined,
- });
+ };
dest.* = node;
stack.append(State{ .Expression = OptionalCtx{ .Required = &node.body } }) catch unreachable;
@@ -1083,11 +1104,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
- const node = try arena.create(ast.Node.Defer{
+ const node = try arena.create(ast.Node.Defer);
+ node.* = ast.Node.Defer{
.base = ast.Node{ .id = ast.Node.Id.Defer },
.defer_token = token_index,
.expr = undefined,
- });
+ };
const node_ptr = try block.statements.addOne();
node_ptr.* = &node.base;
@@ -1096,13 +1118,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.LBrace => {
- const inner_block = try arena.create(ast.Node.Block{
+ const inner_block = try arena.create(ast.Node.Block);
+ inner_block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = null,
.lbrace = token_index,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
+ };
try block.statements.push(&inner_block.base);
stack.append(State{ .Block = inner_block }) catch unreachable;
@@ -1164,14 +1187,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.AsmOutput{
+ const node = try arena.create(ast.Node.AsmOutput);
+ node.* = ast.Node.AsmOutput{
.base = ast.Node{ .id = ast.Node.Id.AsmOutput },
.lbracket = lbracket_index,
.symbolic_name = undefined,
.constraint = undefined,
.kind = undefined,
.rparen = undefined,
- });
+ };
try items.push(node);
stack.append(State{ .AsmOutputItems = items }) catch unreachable;
@@ -1218,14 +1242,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.AsmInput{
+ const node = try arena.create(ast.Node.AsmInput);
+ node.* = ast.Node.AsmInput{
.base = ast.Node{ .id = ast.Node.Id.AsmInput },
.lbracket = lbracket_index,
.symbolic_name = undefined,
.constraint = undefined,
.expr = undefined,
.rparen = undefined,
- });
+ };
try items.push(node);
stack.append(State{ .AsmInputItems = items }) catch unreachable;
@@ -1283,12 +1308,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.FieldInitializer{
+ const node = try arena.create(ast.Node.FieldInitializer);
+ node.* = ast.Node.FieldInitializer{
.base = ast.Node{ .id = ast.Node.Id.FieldInitializer },
.period_token = undefined,
.name_token = undefined,
.expr = undefined,
- });
+ };
try list_state.list.push(&node.base);
stack.append(State{ .FieldInitListCommaOrEnd = list_state }) catch unreachable;
@@ -1390,13 +1416,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
}
const comments = try eatDocComments(arena, &tok_it, &tree);
- const node = try arena.create(ast.Node.SwitchCase{
+ const node = try arena.create(ast.Node.SwitchCase);
+ node.* = ast.Node.SwitchCase{
.base = ast.Node{ .id = ast.Node.Id.SwitchCase },
.items = ast.Node.SwitchCase.ItemList.init(arena),
.payload = null,
.expr = undefined,
.arrow_token = undefined,
- });
+ };
try list_state.list.push(&node.base);
try stack.append(State{ .SwitchCaseCommaOrEnd = list_state });
try stack.append(State{ .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
@@ -1427,10 +1454,11 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (token_ptr.id == Token.Id.Keyword_else) {
- const else_node = try arena.create(ast.Node.SwitchElse{
+ const else_node = try arena.create(ast.Node.SwitchElse);
+ else_node.* = ast.Node.SwitchElse{
.base = ast.Node{ .id = ast.Node.Id.SwitchElse },
.token = token_index,
- });
+ };
try switch_case.items.push(&else_node.base);
try stack.append(State{
@@ -1537,7 +1565,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
State.ExternType => |ctx| {
if (eatToken(&tok_it, &tree, Token.Id.Keyword_fn)) |fn_token| {
- const fn_proto = try arena.create(ast.Node.FnProto{
+ const fn_proto = try arena.create(ast.Node.FnProto);
+ fn_proto.* = ast.Node.FnProto{
.base = ast.Node{ .id = ast.Node.Id.FnProto },
.doc_comments = ctx.comments,
.visib_token = null,
@@ -1553,7 +1582,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.lib_name = null,
.align_expr = null,
.section_expr = null,
- });
+ };
ctx.opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
continue;
@@ -1711,12 +1740,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.Payload{
+ const node = try arena.create(ast.Node.Payload);
+ node.* = ast.Node.Payload{
.base = ast.Node{ .id = ast.Node.Id.Payload },
.lpipe = token_index,
.error_symbol = undefined,
.rpipe = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{
@@ -1747,13 +1777,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.PointerPayload{
+ const node = try arena.create(ast.Node.PointerPayload);
+ node.* = ast.Node.PointerPayload{
.base = ast.Node{ .id = ast.Node.Id.PointerPayload },
.lpipe = token_index,
.ptr_token = null,
.value_symbol = undefined,
.rpipe = undefined,
- });
+ };
opt_ctx.store(&node.base);
try stack.append(State{
@@ -1790,14 +1821,15 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.PointerIndexPayload{
+ const node = try arena.create(ast.Node.PointerIndexPayload);
+ node.* = ast.Node.PointerIndexPayload{
.base = ast.Node{ .id = ast.Node.Id.PointerIndexPayload },
.lpipe = token_index,
.ptr_token = null,
.value_symbol = undefined,
.index_symbol = null,
.rpipe = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{
@@ -1824,12 +1856,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_ptr = token.ptr;
switch (token_ptr.id) {
Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
- const node = try arena.create(ast.Node.ControlFlowExpression{
+ const node = try arena.create(ast.Node.ControlFlowExpression);
+ node.* = ast.Node.ControlFlowExpression{
.base = ast.Node{ .id = ast.Node.Id.ControlFlowExpression },
.ltoken = token_index,
.kind = undefined,
.rhs = null,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .Expression = OptionalCtx{ .Optional = &node.rhs } }) catch unreachable;
@@ -1853,7 +1886,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
- const node = try arena.create(ast.Node.PrefixOp{
+ const node = try arena.create(ast.Node.PrefixOp);
+ node.* = ast.Node.PrefixOp{
.base = ast.Node{ .id = ast.Node.Id.PrefixOp },
.op_token = token_index,
.op = switch (token_ptr.id) {
@@ -1863,7 +1897,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
else => unreachable,
},
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
@@ -1887,13 +1921,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Ellipsis3)) |ellipsis3| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = ellipsis3,
.op = ast.Node.InfixOp.Op.Range,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
continue;
@@ -1912,13 +1947,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToAssignment(token_ptr.id)) |ass_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = ass_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .AssignmentExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.rhs } });
@@ -1942,13 +1978,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToUnwrapExpr(token_ptr.id)) |unwrap_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = unwrap_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -1974,13 +2011,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Keyword_or)) |or_token| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = or_token,
.op = ast.Node.InfixOp.Op.BoolOr,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BoolOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .BoolAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -1998,13 +2036,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Keyword_and)) |and_token| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = and_token,
.op = ast.Node.InfixOp.Op.BoolAnd,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BoolAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .ComparisonExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2025,13 +2064,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToComparison(token_ptr.id)) |comp_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = comp_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .ComparisonExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .BinaryOrExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2052,13 +2092,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Pipe)) |pipe| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = pipe,
.op = ast.Node.InfixOp.Op.BitOr,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BinaryOrExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .BinaryXorExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2076,13 +2117,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Caret)) |caret| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = caret,
.op = ast.Node.InfixOp.Op.BitXor,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BinaryXorExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .BinaryAndExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2100,13 +2142,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Ampersand)) |ampersand| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = ampersand,
.op = ast.Node.InfixOp.Op.BitAnd,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BinaryAndExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .BitShiftExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2127,13 +2170,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToBitShift(token_ptr.id)) |bitshift_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = bitshift_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .BitShiftExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .AdditionExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2157,13 +2201,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToAddition(token_ptr.id)) |add_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = add_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .AdditionExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .MultiplyExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2187,13 +2232,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToMultiply(token_ptr.id)) |mult_id| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = mult_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .MultiplyExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .CurlySuffixExpressionBegin = OptionalCtx{ .Required = &node.rhs } });
@@ -2215,12 +2261,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (tok_it.peek().?.id == Token.Id.Period) {
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op{ .StructInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
.rtoken = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2234,12 +2281,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op{ .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(arena) },
.rtoken = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .IfToken = Token.Id.LBrace });
@@ -2263,13 +2311,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const lhs = opt_ctx.get() orelse continue;
if (eatToken(&tok_it, &tree, Token.Id.Bang)) |bang| {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = bang,
.op = ast.Node.InfixOp.Op.ErrorUnion,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .TypeExprEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State{ .PrefixOpExpression = OptionalCtx{ .Required = &node.rhs } });
@@ -2282,22 +2331,24 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_index = token.index;
const token_ptr = token.ptr;
if (tokenIdToPrefixOp(token_ptr.id)) |prefix_id| {
- var node = try arena.create(ast.Node.PrefixOp{
+ var node = try arena.create(ast.Node.PrefixOp);
+ node.* = ast.Node.PrefixOp{
.base = ast.Node{ .id = ast.Node.Id.PrefixOp },
.op_token = token_index,
.op = prefix_id,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
// Treat '**' token as two pointer types
if (token_ptr.id == Token.Id.AsteriskAsterisk) {
- const child = try arena.create(ast.Node.PrefixOp{
+ const child = try arena.create(ast.Node.PrefixOp);
+ child.* = ast.Node.PrefixOp{
.base = ast.Node{ .id = ast.Node.Id.PrefixOp },
.op_token = token_index,
.op = prefix_id,
.rhs = undefined,
- });
+ };
node.rhs = &child.base;
node = child;
}
@@ -2316,12 +2367,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
State.SuffixOpExpressionBegin => |opt_ctx| {
if (eatToken(&tok_it, &tree, Token.Id.Keyword_async)) |async_token| {
- const async_node = try arena.create(ast.Node.AsyncAttribute{
+ const async_node = try arena.create(ast.Node.AsyncAttribute);
+ async_node.* = ast.Node.AsyncAttribute{
.base = ast.Node{ .id = ast.Node.Id.AsyncAttribute },
.async_token = async_token,
.allocator_type = null,
.rangle_bracket = null,
- });
+ };
stack.append(State{
.AsyncEnd = AsyncEndCtx{
.ctx = opt_ctx,
@@ -2347,7 +2399,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
const token_ptr = token.ptr;
switch (token_ptr.id) {
Token.Id.LParen => {
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op{
@@ -2357,7 +2410,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
},
},
.rtoken = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2371,12 +2424,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.LBracket => {
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op{ .ArrayAccess = undefined },
.rtoken = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2386,34 +2440,37 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
},
Token.Id.Period => {
if (eatToken(&tok_it, &tree, Token.Id.Asterisk)) |asterisk_token| {
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op.Deref,
.rtoken = asterisk_token,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
continue;
}
if (eatToken(&tok_it, &tree, Token.Id.QuestionMark)) |question_token| {
- const node = try arena.create(ast.Node.SuffixOp{
+ const node = try arena.create(ast.Node.SuffixOp);
+ node.* = ast.Node.SuffixOp{
.base = ast.Node{ .id = ast.Node.Id.SuffixOp },
.lhs = lhs,
.op = ast.Node.SuffixOp.Op.UnwrapOptional,
.rtoken = question_token,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
continue;
}
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = lhs,
.op_token = token_index,
.op = ast.Node.InfixOp.Op.Period,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SuffixOpExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
@@ -2467,11 +2524,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_promise => {
- const node = try arena.create(ast.Node.PromiseType{
+ const node = try arena.create(ast.Node.PromiseType);
+ node.* = ast.Node.PromiseType{
.base = ast.Node{ .id = ast.Node.Id.PromiseType },
.promise_token = token.index,
.result = null,
- });
+ };
opt_ctx.store(&node.base);
const next_token = nextToken(&tok_it, &tree);
const next_token_index = next_token.index;
@@ -2493,12 +2551,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.LParen => {
- const node = try arena.create(ast.Node.GroupedExpression{
+ const node = try arena.create(ast.Node.GroupedExpression);
+ node.* = ast.Node.GroupedExpression{
.base = ast.Node{ .id = ast.Node.Id.GroupedExpression },
.lparen = token.index,
.expr = undefined,
.rparen = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{
@@ -2511,12 +2570,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Builtin => {
- const node = try arena.create(ast.Node.BuiltinCall{
+ const node = try arena.create(ast.Node.BuiltinCall);
+ node.* = ast.Node.BuiltinCall{
.base = ast.Node{ .id = ast.Node.Id.BuiltinCall },
.builtin_token = token.index,
.params = ast.Node.BuiltinCall.ParamList.init(arena),
.rparen_token = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{
@@ -2530,12 +2590,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.LBracket => {
- const node = try arena.create(ast.Node.PrefixOp{
+ const node = try arena.create(ast.Node.PrefixOp);
+ node.* = ast.Node.PrefixOp{
.base = ast.Node{ .id = ast.Node.Id.PrefixOp },
.op_token = token.index,
.op = undefined,
.rhs = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{ .SliceOrArrayType = node }) catch unreachable;
@@ -2593,7 +2654,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_fn => {
- const fn_proto = try arena.create(ast.Node.FnProto{
+ const fn_proto = try arena.create(ast.Node.FnProto);
+ fn_proto.* = ast.Node.FnProto{
.base = ast.Node{ .id = ast.Node.Id.FnProto },
.doc_comments = null,
.visib_token = null,
@@ -2609,13 +2671,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.lib_name = null,
.align_expr = null,
.section_expr = null,
- });
+ };
opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
continue;
},
Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
- const fn_proto = try arena.create(ast.Node.FnProto{
+ const fn_proto = try arena.create(ast.Node.FnProto);
+ fn_proto.* = ast.Node.FnProto{
.base = ast.Node{ .id = ast.Node.Id.FnProto },
.doc_comments = null,
.visib_token = null,
@@ -2631,7 +2694,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.lib_name = null,
.align_expr = null,
.section_expr = null,
- });
+ };
opt_ctx.store(&fn_proto.base);
stack.append(State{ .FnProto = fn_proto }) catch unreachable;
try stack.append(State{
@@ -2643,7 +2706,8 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
},
Token.Id.Keyword_asm => {
- const node = try arena.create(ast.Node.Asm{
+ const node = try arena.create(ast.Node.Asm);
+ node.* = ast.Node.Asm{
.base = ast.Node{ .id = ast.Node.Id.Asm },
.asm_token = token.index,
.volatile_token = null,
@@ -2652,7 +2716,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.inputs = ast.Node.Asm.InputList.init(arena),
.clobbers = ast.Node.Asm.ClobberList.init(arena),
.rparen = undefined,
- });
+ };
opt_ctx.store(&node.base);
stack.append(State{
@@ -2701,13 +2765,14 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
State.ErrorTypeOrSetDecl => |ctx| {
if (eatToken(&tok_it, &tree, Token.Id.LBrace) == null) {
- const node = try arena.create(ast.Node.InfixOp{
+ const node = try arena.create(ast.Node.InfixOp);
+ node.* = ast.Node.InfixOp{
.base = ast.Node{ .id = ast.Node.Id.InfixOp },
.lhs = &(try createLiteral(arena, ast.Node.ErrorType, ctx.error_token)).base,
.op_token = undefined,
.op = ast.Node.InfixOp.Op.Period,
.rhs = undefined,
- });
+ };
ctx.opt_ctx.store(&node.base);
stack.append(State{ .Identifier = OptionalCtx{ .Required = &node.rhs } }) catch unreachable;
try stack.append(State{
@@ -2719,12 +2784,13 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
continue;
}
- const node = try arena.create(ast.Node.ErrorSetDecl{
+ const node = try arena.create(ast.Node.ErrorSetDecl);
+ node.* = ast.Node.ErrorSetDecl{
.base = ast.Node{ .id = ast.Node.Id.ErrorSetDecl },
.error_token = ctx.error_token,
.decls = ast.Node.ErrorSetDecl.DeclList.init(arena),
.rbrace_token = undefined,
- });
+ };
ctx.opt_ctx.store(&node.base);
stack.append(State{
@@ -2785,11 +2851,12 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
return tree;
}
- const node = try arena.create(ast.Node.ErrorTag{
+ const node = try arena.create(ast.Node.ErrorTag);
+ node.* = ast.Node.ErrorTag{
.base = ast.Node{ .id = ast.Node.Id.ErrorTag },
.doc_comments = comments,
.name_token = ident_token_index,
- });
+ };
node_ptr.* = &node.base;
continue;
},
@@ -3129,10 +3196,11 @@ fn pushDocComment(arena: *mem.Allocator, line_comment: TokenIndex, result: *?*as
if (result.*) |comment_node| {
break :blk comment_node;
} else {
- const comment_node = try arena.create(ast.Node.DocComment{
+ const comment_node = try arena.create(ast.Node.DocComment);
+ comment_node.* = ast.Node.DocComment{
.base = ast.Node{ .id = ast.Node.Id.DocComment },
.lines = ast.Node.DocComment.LineList.init(arena),
- });
+ };
result.* = comment_node;
break :blk comment_node;
}
@@ -3158,10 +3226,11 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
return &(try createLiteral(arena, ast.Node.StringLiteral, token_index)).base;
},
Token.Id.MultilineStringLiteralLine => {
- const node = try arena.create(ast.Node.MultilineStringLiteral{
+ const node = try arena.create(ast.Node.MultilineStringLiteral);
+ node.* = ast.Node.MultilineStringLiteral{
.base = ast.Node{ .id = ast.Node.Id.MultilineStringLiteral },
.lines = ast.Node.MultilineStringLiteral.LineList.init(arena),
- });
+ };
try node.lines.push(token_index);
while (true) {
const multiline_str = nextToken(tok_it, tree);
@@ -3186,25 +3255,27 @@ fn parseStringLiteral(arena: *mem.Allocator, tok_it: *ast.Tree.TokenList.Iterato
fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: OptionalCtx, token_ptr: Token, token_index: TokenIndex) !bool {
switch (token_ptr.id) {
Token.Id.Keyword_suspend => {
- const node = try arena.create(ast.Node.Suspend{
+ const node = try arena.create(ast.Node.Suspend);
+ node.* = ast.Node.Suspend{
.base = ast.Node{ .id = ast.Node.Id.Suspend },
.suspend_token = token_index,
.body = null,
- });
+ };
ctx.store(&node.base);
stack.append(State{ .SuspendBody = node }) catch unreachable;
return true;
},
Token.Id.Keyword_if => {
- const node = try arena.create(ast.Node.If{
+ const node = try arena.create(ast.Node.If);
+ node.* = ast.Node.If{
.base = ast.Node{ .id = ast.Node.Id.If },
.if_token = token_index,
.condition = undefined,
.payload = null,
.body = undefined,
.@"else" = null,
- });
+ };
ctx.store(&node.base);
stack.append(State{ .Else = &node.@"else" }) catch unreachable;
@@ -3238,13 +3309,14 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
return true;
},
Token.Id.Keyword_switch => {
- const node = try arena.create(ast.Node.Switch{
+ const node = try arena.create(ast.Node.Switch);
+ node.* = ast.Node.Switch{
.base = ast.Node{ .id = ast.Node.Id.Switch },
.switch_token = token_index,
.expr = undefined,
.cases = ast.Node.Switch.CaseList.init(arena),
.rbrace = undefined,
- });
+ };
ctx.store(&node.base);
stack.append(State{
@@ -3260,25 +3332,27 @@ fn parseBlockExpr(stack: *std.ArrayList(State), arena: *mem.Allocator, ctx: Opti
return true;
},
Token.Id.Keyword_comptime => {
- const node = try arena.create(ast.Node.Comptime{
+ const node = try arena.create(ast.Node.Comptime);
+ node.* = ast.Node.Comptime{
.base = ast.Node{ .id = ast.Node.Id.Comptime },
.comptime_token = token_index,
.expr = undefined,
.doc_comments = null,
- });
+ };
ctx.store(&node.base);
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
return true;
},
Token.Id.LBrace => {
- const block = try arena.create(ast.Node.Block{
+ const block = try arena.create(ast.Node.Block);
+ block.* = ast.Node.Block{
.base = ast.Node{ .id = ast.Node.Id.Block },
.label = null,
.lbrace = token_index,
.statements = ast.Node.Block.StatementList.init(arena),
.rbrace = undefined,
- });
+ };
ctx.store(&block.base);
stack.append(State{ .Block = block }) catch unreachable;
return true;
@@ -3412,10 +3486,12 @@ fn tokenIdToPrefixOp(id: Token.Id) ?ast.Node.PrefixOp.Op {
}
fn createLiteral(arena: *mem.Allocator, comptime T: type, token_index: TokenIndex) !*T {
- return arena.create(T{
+ const result = try arena.create(T);
+ result.* = T{
.base = ast.Node{ .id = ast.Node.typeToId(T) },
.token = token_index,
- });
+ };
+ return result;
}
fn createToCtxLiteral(arena: *mem.Allocator, opt_ctx: OptionalCtx, comptime T: type, token_index: TokenIndex) !*T {
diff --git a/test/tests.zig b/test/tests.zig
index 73d4644d18..548496fa2f 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -48,13 +48,14 @@ const test_targets = []TestTarget{
const max_stdout_size = 1 * 1024 * 1024; // 1 MB
pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(CompareOutputContext{
+ const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+ cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-compare-output", "Run the compare output tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
- }) catch unreachable;
+ };
compare_output.addCases(cases);
@@ -62,13 +63,14 @@ pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(CompareOutputContext{
+ const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+ cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-runtime-safety", "Run the runtime safety tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
- }) catch unreachable;
+ };
runtime_safety.addCases(cases);
@@ -76,13 +78,14 @@ pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(CompileErrorContext{
+ const cases = b.allocator.create(CompileErrorContext) catch unreachable;
+ cases.* = CompileErrorContext{
.b = b,
.step = b.step("test-compile-errors", "Run the compile error tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
- }) catch unreachable;
+ };
compile_errors.addCases(cases);
@@ -90,13 +93,14 @@ pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes:
}
pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(BuildExamplesContext{
+ const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
+ cases.* = BuildExamplesContext{
.b = b,
.step = b.step("test-build-examples", "Build the examples"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
- }) catch unreachable;
+ };
build_examples.addCases(cases);
@@ -119,13 +123,14 @@ pub fn addCliTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const M
}
pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
- const cases = b.allocator.create(CompareOutputContext{
+ const cases = b.allocator.create(CompareOutputContext) catch unreachable;
+ cases.* = CompareOutputContext{
.b = b,
.step = b.step("test-asm-link", "Run the assemble and link tests"),
.test_index = 0,
.test_filter = test_filter,
.modes = modes,
- }) catch unreachable;
+ };
assemble_and_link.addCases(cases);
@@ -133,12 +138,13 @@ pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, mode
}
pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
- const cases = b.allocator.create(TranslateCContext{
+ const cases = b.allocator.create(TranslateCContext) catch unreachable;
+ cases.* = TranslateCContext{
.b = b,
.step = b.step("test-translate-c", "Run the C transation tests"),
.test_index = 0,
.test_filter = test_filter,
- }) catch unreachable;
+ };
translate_c.addCases(cases);
@@ -146,12 +152,13 @@ pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.St
}
pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
- const cases = b.allocator.create(GenHContext{
+ const cases = b.allocator.create(GenHContext) catch unreachable;
+ cases.* = GenHContext{
.b = b,
.step = b.step("test-gen-h", "Run the C header file generation tests"),
.test_index = 0,
.test_filter = test_filter,
- }) catch unreachable;
+ };
gen_h.addCases(cases);
@@ -244,7 +251,8 @@ pub const CompareOutputContext = struct {
pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(RunCompareOutputStep{
+ const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
+ ptr.* = RunCompareOutputStep{
.context = context,
.exe_path = exe_path,
.name = name,
@@ -252,7 +260,7 @@ pub const CompareOutputContext = struct {
.test_index = context.test_index,
.step = build.Step.init("RunCompareOutput", allocator, make),
.cli_args = cli_args,
- }) catch unreachable;
+ };
context.test_index += 1;
return ptr;
}
@@ -331,13 +339,14 @@ pub const CompareOutputContext = struct {
pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(RuntimeSafetyRunStep{
+ const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
+ ptr.* = RuntimeSafetyRunStep{
.context = context,
.exe_path = exe_path,
.name = name,
.test_index = context.test_index,
.step = build.Step.init("RuntimeSafetyRun", allocator, make),
- }) catch unreachable;
+ };
context.test_index += 1;
return ptr;
@@ -542,14 +551,15 @@ pub const CompileErrorContext = struct {
pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(CompileCmpOutputStep{
+ const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
+ ptr.* = CompileCmpOutputStep{
.step = build.Step.init("CompileCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
.build_mode = build_mode,
- }) catch unreachable;
+ };
context.test_index += 1;
return ptr;
@@ -661,13 +671,14 @@ pub const CompileErrorContext = struct {
}
pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
- const tc = self.b.allocator.create(TestCase{
+ const tc = self.b.allocator.create(TestCase) catch unreachable;
+ tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_errors = ArrayList([]const u8).init(self.b.allocator),
.link_libc = false,
.is_exe = false,
- }) catch unreachable;
+ };
tc.addSourceFile(".tmp_source.zig", source);
comptime var arg_i = 0;
@@ -821,13 +832,14 @@ pub const TranslateCContext = struct {
pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(TranslateCCmpOutputStep{
+ const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
+ ptr.* = TranslateCCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
- }) catch unreachable;
+ };
context.test_index += 1;
return ptr;
@@ -928,12 +940,13 @@ pub const TranslateCContext = struct {
}
pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
- const tc = self.b.allocator.create(TestCase{
+ const tc = self.b.allocator.create(TestCase) catch unreachable;
+ tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
.allow_warnings = allow_warnings,
- }) catch unreachable;
+ };
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
@@ -1015,14 +1028,15 @@ pub const GenHContext = struct {
pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(GenHCmpOutputStep{
+ const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
+ ptr.* = GenHCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.h_path = h_path,
.name = name,
.test_index = context.test_index,
.case = case,
- }) catch unreachable;
+ };
context.test_index += 1;
return ptr;
@@ -1062,11 +1076,12 @@ pub const GenHContext = struct {
}
pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
- const tc = self.b.allocator.create(TestCase{
+ const tc = self.b.allocator.create(TestCase) catch unreachable;
+ tc.* = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
- }) catch unreachable;
+ };
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
From 67bd45f0cf1b452cf8de5a016bc6ff2f85393d70 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 4 Feb 2019 15:24:06 -0500
Subject: [PATCH 134/218] adjustments to std.mem split / separate
* rename std.mem.split to std.mem.tokenize
* add future deprecation notice to docs
* (unrelated) add note to std.os.path.resolve docs
* std.mem.separate - assert delimiter.len not zero
* fix implementation of std.mem.separate to respect the delimiter
* separate the two iterators to different structs
---
build.zig | 16 ++--
src-self-hosted/libc_installation.zig | 8 +-
src-self-hosted/main.zig | 2 +-
std/build.zig | 6 +-
std/mem.zig | 129 ++++++++++++++------------
std/os/child_process.zig | 2 +-
std/os/index.zig | 2 +-
std/os/path.zig | 44 ++++-----
8 files changed, 112 insertions(+), 97 deletions(-)
diff --git a/build.zig b/build.zig
index d99165a6de..a41a5f808b 100644
--- a/build.zig
+++ b/build.zig
@@ -189,14 +189,14 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
const prefix_output = try b.exec([][]const u8{ llvm_config_exe, "--prefix" });
var result = LibraryDep{
- .prefix = mem.split(prefix_output, " \r\n").next().?,
+ .prefix = mem.tokenize(prefix_output, " \r\n").next().?,
.libs = ArrayList([]const u8).init(b.allocator),
.system_libs = ArrayList([]const u8).init(b.allocator),
.includes = ArrayList([]const u8).init(b.allocator),
.libdirs = ArrayList([]const u8).init(b.allocator),
};
{
- var it = mem.split(libs_output, " \r\n");
+ var it = mem.tokenize(libs_output, " \r\n");
while (it.next()) |lib_arg| {
if (mem.startsWith(u8, lib_arg, "-l")) {
try result.system_libs.append(lib_arg[2..]);
@@ -210,7 +210,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
}
}
{
- var it = mem.split(includes_output, " \r\n");
+ var it = mem.tokenize(includes_output, " \r\n");
while (it.next()) |include_arg| {
if (mem.startsWith(u8, include_arg, "-I")) {
try result.includes.append(include_arg[2..]);
@@ -220,7 +220,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
}
}
{
- var it = mem.split(libdir_output, " \r\n");
+ var it = mem.tokenize(libdir_output, " \r\n");
while (it.next()) |libdir| {
if (mem.startsWith(u8, libdir, "-L")) {
try result.libdirs.append(libdir[2..]);
@@ -233,7 +233,7 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
}
pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
- var it = mem.split(stdlib_files, ";");
+ var it = mem.tokenize(stdlib_files, ";");
while (it.next()) |stdlib_file| {
const src_path = os.path.join(b.allocator, "std", stdlib_file) catch unreachable;
const dest_path = os.path.join(b.allocator, "lib", "zig", "std", stdlib_file) catch unreachable;
@@ -242,7 +242,7 @@ pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
}
pub fn installCHeaders(b: *Builder, c_header_files: []const u8) void {
- var it = mem.split(c_header_files, ";");
+ var it = mem.tokenize(c_header_files, ";");
while (it.next()) |c_header_file| {
const src_path = os.path.join(b.allocator, "c_headers", c_header_file) catch unreachable;
const dest_path = os.path.join(b.allocator, "lib", "zig", "include", c_header_file) catch unreachable;
@@ -277,7 +277,7 @@ fn configureStage2(b: *Builder, exe: var, ctx: Context) !void {
addCppLib(b, exe, ctx.cmake_binary_dir, "zig_cpp");
if (ctx.lld_include_dir.len != 0) {
exe.addIncludeDir(ctx.lld_include_dir);
- var it = mem.split(ctx.lld_libraries, ";");
+ var it = mem.tokenize(ctx.lld_libraries, ";");
while (it.next()) |lib| {
exe.addObjectFile(lib);
}
@@ -334,7 +334,7 @@ fn addCxxKnownPath(
ctx.cxx_compiler,
b.fmt("-print-file-name={}", objname),
});
- const path_unpadded = mem.split(path_padded, "\r\n").next().?;
+ const path_unpadded = mem.tokenize(path_padded, "\r\n").next().?;
if (mem.eql(u8, path_unpadded, objname)) {
if (errtxt) |msg| {
warn("{}", msg);
diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig
index 1c5d111c5a..18d2daf0c2 100644
--- a/src-self-hosted/libc_installation.zig
+++ b/src-self-hosted/libc_installation.zig
@@ -57,10 +57,10 @@ pub const LibCInstallation = struct {
const contents = try std.io.readFileAlloc(allocator, libc_file);
defer allocator.free(contents);
- var it = std.mem.split(contents, "\n");
+ var it = std.mem.tokenize(contents, "\n");
while (it.next()) |line| {
if (line.len == 0 or line[0] == '#') continue;
- var line_it = std.mem.split(line, "=");
+ var line_it = std.mem.separate(line, "=");
const name = line_it.next() orelse {
try stderr.print("missing equal sign after field name\n");
return error.ParseError;
@@ -213,7 +213,7 @@ pub const LibCInstallation = struct {
},
}
- var it = std.mem.split(exec_result.stderr, "\n\r");
+ var it = std.mem.tokenize(exec_result.stderr, "\n\r");
var search_paths = std.ArrayList([]const u8).init(loop.allocator);
defer search_paths.deinit();
while (it.next()) |line| {
@@ -410,7 +410,7 @@ async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bo
return error.CCompilerCrashed;
},
}
- var it = std.mem.split(exec_result.stdout, "\n\r");
+ var it = std.mem.tokenize(exec_result.stdout, "\n\r");
const line = it.next() orelse return error.LibCRuntimeNotFound;
const dirname = std.os.path.dirname(line) orelse return error.LibCRuntimeNotFound;
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 1403ab860d..f6ee9a0513 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -351,7 +351,7 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Co
const root_name = if (provided_name) |n| n else blk: {
if (root_source_file) |file| {
const basename = os.path.basename(file);
- var it = mem.split(basename, ".");
+ var it = mem.separate(basename, ".");
break :blk it.next() orelse basename;
} else {
try stderr.write("--name [name] not provided and unable to infer\n");
diff --git a/std/build.zig b/std/build.zig
index 6f58594190..5246d97339 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -324,7 +324,7 @@ pub const Builder = struct {
fn processNixOSEnvVars(self: *Builder) void {
if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
- var it = mem.split(nix_cflags_compile, " ");
+ var it = mem.tokenize(nix_cflags_compile, " ");
while (true) {
const word = it.next() orelse break;
if (mem.eql(u8, word, "-isystem")) {
@@ -342,7 +342,7 @@ pub const Builder = struct {
assert(err == error.EnvironmentVariableNotFound);
}
if (os.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
- var it = mem.split(nix_ldflags, " ");
+ var it = mem.tokenize(nix_ldflags, " ");
while (true) {
const word = it.next() orelse break;
if (mem.eql(u8, word, "-rpath")) {
@@ -689,7 +689,7 @@ pub const Builder = struct {
if (os.path.isAbsolute(name)) {
return name;
}
- var it = mem.split(PATH, []u8{os.path.delimiter});
+ var it = mem.tokenize(PATH, []u8{os.path.delimiter});
while (it.next()) |path| {
const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension));
if (os.path.real(self.allocator, full_path)) |real_path| {
diff --git a/std/mem.zig b/std/mem.zig
index bec3816d88..26ae4ef089 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -689,58 +689,57 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {
}
/// Returns an iterator that iterates over the slices of `buffer` that are not
-/// any of the bytes in `split_bytes`.
-/// split(" abc def ghi ", " ")
+/// any of the bytes in `delimiter_bytes`.
+/// tokenize(" abc def ghi ", " ")
/// Will return slices for "abc", "def", "ghi", null, in that order.
-/// If `split_bytes` does not exist in buffer,
+/// If `buffer` is empty, the iterator will return null.
+/// If `delimiter_bytes` does not exist in buffer,
/// the iterator will return `buffer`, null, in that order.
-pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {
- return SplitIterator{
+/// See also the related function `separate`.
+pub fn tokenize(buffer: []const u8, delimiter_bytes: []const u8) TokenIterator {
+ return TokenIterator{
.index = 0,
.buffer = buffer,
- .split_bytes = split_bytes,
- .glob = true,
- .spun = false,
+ .delimiter_bytes = delimiter_bytes,
};
}
-test "mem.split" {
- var it = split(" abc def ghi ", " ");
+test "mem.tokenize" {
+ var it = tokenize(" abc def ghi ", " ");
assert(eql(u8, it.next().?, "abc"));
assert(eql(u8, it.next().?, "def"));
assert(eql(u8, it.next().?, "ghi"));
assert(it.next() == null);
- it = split("..\\bob", "\\");
+ it = tokenize("..\\bob", "\\");
assert(eql(u8, it.next().?, ".."));
assert(eql(u8, "..", "..\\bob"[0..it.index]));
assert(eql(u8, it.next().?, "bob"));
assert(it.next() == null);
- it = split("//a/b", "/");
+ it = tokenize("//a/b", "/");
assert(eql(u8, it.next().?, "a"));
assert(eql(u8, it.next().?, "b"));
assert(eql(u8, "//a/b", "//a/b"[0..it.index]));
assert(it.next() == null);
- it = split("|", "|");
+ it = tokenize("|", "|");
assert(it.next() == null);
- it = split("", "|");
- assert(eql(u8, it.next().?, ""));
+ it = tokenize("", "|");
assert(it.next() == null);
- it = split("hello", "");
+ it = tokenize("hello", "");
assert(eql(u8, it.next().?, "hello"));
assert(it.next() == null);
- it = split("hello", " ");
+ it = tokenize("hello", " ");
assert(eql(u8, it.next().?, "hello"));
assert(it.next() == null);
}
-test "mem.split (multibyte)" {
- var it = split("a|b,c/d e", " /,|");
+test "mem.tokenize (multibyte)" {
+ var it = tokenize("a|b,c/d e", " /,|");
assert(eql(u8, it.next().?, "a"));
assert(eql(u8, it.next().?, "b"));
assert(eql(u8, it.next().?, "c"));
@@ -750,18 +749,21 @@ test "mem.split (multibyte)" {
}
/// Returns an iterator that iterates over the slices of `buffer` that
-/// seperates by bytes in `delimiter`.
+/// are separated by bytes in `delimiter`.
/// separate("abc|def||ghi", "|")
-/// Will return slices for "abc", "def", "", "ghi", null, in that order.
+/// will return slices for "abc", "def", "", "ghi", null, in that order.
/// If `delimiter` does not exist in buffer,
/// the iterator will return `buffer`, null, in that order.
+/// The delimiter length must not be zero.
+/// See also the related function `tokenize`.
+/// It is planned to rename this function to `split` before 1.0.0, like this:
+/// pub fn split(buffer: []const u8, delimiter: []const u8) SplitIterator {
pub fn separate(buffer: []const u8, delimiter: []const u8) SplitIterator {
+ assert(delimiter.len != 0);
return SplitIterator{
.index = 0,
.buffer = buffer,
- .split_bytes = delimiter,
- .glob = false,
- .spun = false,
+ .delimiter = delimiter,
};
}
@@ -782,19 +784,15 @@ test "mem.separate" {
assert(eql(u8, it.next().?, ""));
assert(it.next() == null);
- it = separate("hello", "");
- assert(eql(u8, it.next().?, "hello"));
- assert(it.next() == null);
-
it = separate("hello", " ");
assert(eql(u8, it.next().?, "hello"));
assert(it.next() == null);
}
test "mem.separate (multibyte)" {
- var it = separate("a|b,c/d e", " /,|");
+ var it = separate("a, b ,, c, d, e", ", ");
assert(eql(u8, it.next().?, "a"));
- assert(eql(u8, it.next().?, "b"));
+ assert(eql(u8, it.next().?, "b ,"));
assert(eql(u8, it.next().?, "c"));
assert(eql(u8, it.next().?, "d"));
assert(eql(u8, it.next().?, "e"));
@@ -819,49 +817,38 @@ test "mem.endsWith" {
assert(!endsWith(u8, "Bob", "Bo"));
}
-pub const SplitIterator = struct {
+pub const TokenIterator = struct {
buffer: []const u8,
- split_bytes: []const u8,
+ delimiter_bytes: []const u8,
index: usize,
- glob: bool,
- spun: bool,
- /// Iterates and returns null or optionally a slice the next split segment
- pub fn next(self: *SplitIterator) ?[]const u8 {
- if (self.spun) {
- if (self.index + 1 > self.buffer.len) return null;
- self.index += 1;
+ /// Returns a slice of the next token, or null if tokenization is complete.
+ pub fn next(self: *TokenIterator) ?[]const u8 {
+ // move to beginning of token
+ while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
+ const start = self.index;
+ if (start == self.buffer.len) {
+ return null;
}
- self.spun = true;
+ // move to end of token
+ while (self.index < self.buffer.len and !self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
+ const end = self.index;
- if (self.glob) {
- while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
- }
-
- var cursor = self.index;
- while (cursor < self.buffer.len and !self.isSplitByte(self.buffer[cursor])) : (cursor += 1) {}
-
- defer self.index = cursor;
-
- if (cursor == self.buffer.len) {
- return if (self.glob and self.index == cursor and self.index > 0) null else self.buffer[self.index..];
- }
-
- return self.buffer[self.index..cursor];
+ return self.buffer[start..end];
}
/// Returns a slice of the remaining bytes. Does not affect iterator state.
- pub fn rest(self: *const SplitIterator) []const u8 {
+ pub fn rest(self: TokenIterator) []const u8 {
// move to beginning of token
var index: usize = self.index;
while (index < self.buffer.len and self.isSplitByte(self.buffer[index])) : (index += 1) {}
return self.buffer[index..];
}
- fn isSplitByte(self: *const SplitIterator, byte: u8) bool {
- for (self.split_bytes) |split_byte| {
- if (byte == split_byte) {
+ fn isSplitByte(self: TokenIterator, byte: u8) bool {
+ for (self.delimiter_bytes) |delimiter_byte| {
+ if (byte == delimiter_byte) {
return true;
}
}
@@ -869,6 +856,32 @@ pub const SplitIterator = struct {
}
};
+pub const SplitIterator = struct {
+ buffer: []const u8,
+ index: ?usize,
+ delimiter: []const u8,
+
+ /// Returns a slice of the next field, or null if splitting is complete.
+ pub fn next(self: *SplitIterator) ?[]const u8 {
+ const start = self.index orelse return null;
+ const end = if (indexOfPos(u8, self.buffer, start, self.delimiter)) |delim_start| blk: {
+ self.index = delim_start + self.delimiter.len;
+ break :blk delim_start;
+ } else blk: {
+ self.index = null;
+ break :blk self.buffer.len;
+ };
+ return self.buffer[start..end];
+ }
+
+ /// Returns a slice of the remaining bytes. Does not affect iterator state.
+ pub fn rest(self: SplitIterator) []const u8 {
+ const end = self.buffer.len;
+ const start = self.index orelse end;
+ return self.buffer[start..end];
+ }
+};
+
/// Naively combines a series of strings with a separator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: *Allocator, sep: u8, strings: ...) ![]u8 {
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 9f33bee905..7aa8582369 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -595,7 +595,7 @@ pub const ChildProcess = struct {
const PATH = try os.getEnvVarOwned(self.allocator, "PATH");
defer self.allocator.free(PATH);
- var it = mem.split(PATH, ";");
+ var it = mem.tokenize(PATH, ";");
while (it.next()) |search_path| {
const joined_path = try os.path.join(self.allocator, search_path, app_name);
defer self.allocator.free(joined_path);
diff --git a/std/os/index.zig b/std/os/index.zig
index 0d0e07bfa3..451c0a3436 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -608,7 +608,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: *const BufMap, allocator:
// +1 for the null terminating byte
const path_buf = try allocator.alloc(u8, PATH.len + exe_path.len + 2);
defer allocator.free(path_buf);
- var it = mem.split(PATH, ":");
+ var it = mem.tokenize(PATH, ":");
var seen_eacces = false;
var err: usize = undefined;
while (it.next()) |search_path| {
diff --git a/std/os/path.zig b/std/os/path.zig
index 4d3d3d6a8b..0b960fa2da 100644
--- a/std/os/path.zig
+++ b/std/os/path.zig
@@ -184,7 +184,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
return relative_path;
}
- var it = mem.split(path, []u8{this_sep});
+ var it = mem.tokenize(path, []u8{this_sep});
_ = (it.next() orelse return relative_path);
_ = (it.next() orelse return relative_path);
return WindowsPath{
@@ -202,7 +202,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
return relative_path;
}
- var it = mem.split(path, []u8{this_sep});
+ var it = mem.tokenize(path, []u8{this_sep});
_ = (it.next() orelse return relative_path);
_ = (it.next() orelse return relative_path);
return WindowsPath{
@@ -264,8 +264,8 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) bool {
const sep1 = ns1[0];
const sep2 = ns2[0];
- var it1 = mem.split(ns1, []u8{sep1});
- var it2 = mem.split(ns2, []u8{sep2});
+ var it1 = mem.tokenize(ns1, []u8{sep1});
+ var it2 = mem.tokenize(ns2, []u8{sep2});
// TODO ASCII is wrong, we actually need full unicode support to compare paths.
return asciiEqlIgnoreCase(it1.next().?, it2.next().?);
@@ -285,8 +285,8 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8
const sep1 = p1[0];
const sep2 = p2[0];
- var it1 = mem.split(p1, []u8{sep1});
- var it2 = mem.split(p2, []u8{sep2});
+ var it1 = mem.tokenize(p1, []u8{sep1});
+ var it2 = mem.tokenize(p2, []u8{sep2});
// TODO ASCII is wrong, we actually need full unicode support to compare paths.
return asciiEqlIgnoreCase(it1.next().?, it2.next().?) and asciiEqlIgnoreCase(it1.next().?, it2.next().?);
@@ -337,6 +337,8 @@ pub fn resolveSlice(allocator: *Allocator, paths: []const []const u8) ![]u8 {
/// If all paths are relative it uses the current working directory as a starting point.
/// Each drive has its own current working directory.
/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
+/// Note: all usage of this function should be audited due to the existence of symlinks.
+/// Without performing actual syscalls, resolving `..` could be incorrect.
pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(is_windows); // resolveWindows called on non windows can't use getCwd
@@ -416,7 +418,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
},
WindowsPath.Kind.NetworkShare => {
result = try allocator.alloc(u8, max_size);
- var it = mem.split(paths[first_index], "/\\");
+ var it = mem.tokenize(paths[first_index], "/\\");
const server_name = it.next().?;
const other_name = it.next().?;
@@ -483,7 +485,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (!correct_disk_designator) {
continue;
}
- var it = mem.split(p[parsed.disk_designator.len..], "/\\");
+ var it = mem.tokenize(p[parsed.disk_designator.len..], "/\\");
while (it.next()) |component| {
if (mem.eql(u8, component, ".")) {
continue;
@@ -516,6 +518,8 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
/// It resolves "." and "..".
/// The result does not have a trailing path separator.
/// If all paths are relative it uses the current working directory as a starting point.
+/// Note: all usage of this function should be audited due to the existence of symlinks.
+/// Without performing actual syscalls, resolving `..` could be incorrect.
pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(!is_windows); // resolvePosix called on windows can't use getCwd
@@ -550,7 +554,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
errdefer allocator.free(result);
for (paths[first_index..]) |p, i| {
- var it = mem.split(p, "/");
+ var it = mem.tokenize(p, "/");
while (it.next()) |component| {
if (mem.eql(u8, component, ".")) {
continue;
@@ -937,8 +941,8 @@ pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8)
return resolved_to;
}
- var from_it = mem.split(resolved_from, "/\\");
- var to_it = mem.split(resolved_to, "/\\");
+ var from_it = mem.tokenize(resolved_from, "/\\");
+ var to_it = mem.tokenize(resolved_to, "/\\");
while (true) {
const from_component = from_it.next() orelse return mem.dupe(allocator, u8, to_it.rest());
const to_rest = to_it.rest();
@@ -967,14 +971,12 @@ pub fn relativeWindows(allocator: *Allocator, from: []const u8, to: []const u8)
// shave off the trailing slash
result_index -= 1;
- if (to_rest.len > 0) {
- var rest_it = mem.split(to_rest, "/\\");
- while (rest_it.next()) |to_component| {
- result[result_index] = '\\';
- result_index += 1;
- mem.copy(u8, result[result_index..], to_component);
- result_index += to_component.len;
- }
+ var rest_it = mem.tokenize(to_rest, "/\\");
+ while (rest_it.next()) |to_component| {
+ result[result_index] = '\\';
+ result_index += 1;
+ mem.copy(u8, result[result_index..], to_component);
+ result_index += to_component.len;
}
return result[0..result_index];
@@ -990,8 +992,8 @@ pub fn relativePosix(allocator: *Allocator, from: []const u8, to: []const u8) ![
const resolved_to = try resolvePosix(allocator, [][]const u8{to});
defer allocator.free(resolved_to);
- var from_it = mem.split(resolved_from, "/");
- var to_it = mem.split(resolved_to, "/");
+ var from_it = mem.tokenize(resolved_from, "/");
+ var to_it = mem.tokenize(resolved_to, "/");
while (true) {
const from_component = from_it.next() orelse return mem.dupe(allocator, u8, to_it.rest());
const to_rest = to_it.rest();
From 8c6fa982cd0a02775264b616c37da9907cc603bb Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 4 Feb 2019 20:30:00 -0500
Subject: [PATCH 135/218] SIMD: array to vector, vector to array, wrapping int
add
also vectors and arrays now use the same ConstExprVal representation
See #903
---
src/all_types.hpp | 20 ++-
src/analyze.cpp | 178 +++++++++----------
src/analyze.hpp | 1 +
src/codegen.cpp | 98 ++++++++---
src/ir.cpp | 291 ++++++++++++++++++++------------
src/ir_print.cpp | 18 ++
test/stage1/behavior.zig | 1 +
test/stage1/behavior/vector.zig | 20 +++
8 files changed, 403 insertions(+), 224 deletions(-)
create mode 100644 test/stage1/behavior/vector.zig
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 3fc6772b31..c4c9e13cfb 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -252,10 +252,6 @@ struct ConstArgTuple {
size_t end_index;
};
-struct ConstVector {
- ConstExprValue *elements;
-};
-
enum ConstValSpecial {
ConstValSpecialRuntime,
ConstValSpecialStatic,
@@ -322,7 +318,6 @@ struct ConstExprValue {
ConstPtrValue x_ptr;
ImportTableEntry *x_import;
ConstArgTuple x_arg_tuple;
- ConstVector x_vector;
// populated if special == ConstValSpecialRuntime
RuntimeHintErrorUnion rh_error_union;
@@ -2239,6 +2234,8 @@ enum IrInstructionId {
IrInstructionIdToBytes,
IrInstructionIdFromBytes,
IrInstructionIdCheckRuntimeScope,
+ IrInstructionIdVectorToArray,
+ IrInstructionIdArrayToVector,
};
struct IrInstruction {
@@ -3368,6 +3365,19 @@ struct IrInstructionBitReverse {
IrInstruction *op;
};
+struct IrInstructionArrayToVector {
+ IrInstruction base;
+
+ IrInstruction *array;
+};
+
+struct IrInstructionVectorToArray {
+ IrInstruction base;
+
+ IrInstruction *vector;
+ LLVMValueRef tmp_ptr;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 99378eb7a8..ff961a7044 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -4457,7 +4457,15 @@ ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
return new_entry;
}
+bool is_valid_vector_elem_type(ZigType *elem_type) {
+ return elem_type->id == ZigTypeIdInt ||
+ elem_type->id == ZigTypeIdFloat ||
+ get_codegen_ptr_type(elem_type) != nullptr;
+}
+
ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
+ assert(is_valid_vector_elem_type(elem_type));
+
TypeId type_id = {};
type_id.id = ZigTypeIdVector;
type_id.data.vector.len = len;
@@ -5749,6 +5757,28 @@ bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) {
zig_unreachable();
}
+static bool const_values_equal_array(CodeGen *g, ConstExprValue *a, ConstExprValue *b, size_t len) {
+ assert(a->data.x_array.special != ConstArraySpecialUndef);
+ assert(b->data.x_array.special != ConstArraySpecialUndef);
+ if (a->data.x_array.special == ConstArraySpecialBuf &&
+ b->data.x_array.special == ConstArraySpecialBuf)
+ {
+ return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
+ }
+ expand_undef_array(g, a);
+ expand_undef_array(g, b);
+
+ ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
+ ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
+
+ for (size_t i = 0; i < len; i += 1) {
+ if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
+ return false;
+ }
+
+ return true;
+}
+
bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
assert(a->type->id == b->type->id);
assert(a->special == ConstValSpecialStatic);
@@ -5803,28 +5833,12 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
case ZigTypeIdPointer:
case ZigTypeIdFn:
return const_values_equal_ptr(a, b);
+ case ZigTypeIdVector:
+ assert(a->type->data.vector.len == b->type->data.vector.len);
+ return const_values_equal_array(g, a, b, a->type->data.vector.len);
case ZigTypeIdArray: {
assert(a->type->data.array.len == b->type->data.array.len);
- assert(a->data.x_array.special != ConstArraySpecialUndef);
- assert(b->data.x_array.special != ConstArraySpecialUndef);
- if (a->data.x_array.special == ConstArraySpecialBuf &&
- b->data.x_array.special == ConstArraySpecialBuf)
- {
- return buf_eql_buf(a->data.x_array.data.s_buf, b->data.x_array.data.s_buf);
- }
- expand_undef_array(g, a);
- expand_undef_array(g, b);
-
- size_t len = a->type->data.array.len;
- ConstExprValue *a_elems = a->data.x_array.data.s_none.elements;
- ConstExprValue *b_elems = b->data.x_array.data.s_none.elements;
-
- for (size_t i = 0; i < len; i += 1) {
- if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
- return false;
- }
-
- return true;
+ return const_values_equal_array(g, a, b, a->type->data.array.len);
}
case ZigTypeIdStruct:
for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
@@ -5853,20 +5867,6 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
case ZigTypeIdArgTuple:
return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
- case ZigTypeIdVector: {
- assert(a->type->data.vector.len == b->type->data.vector.len);
-
- size_t len = a->type->data.vector.len;
- ConstExprValue *a_elems = a->data.x_vector.elements;
- ConstExprValue *b_elems = b->data.x_vector.elements;
-
- for (size_t i = 0; i < len; i += 1) {
- if (!const_values_equal(g, &a_elems[i], &b_elems[i]))
- return false;
- }
-
- return true;
- }
case ZigTypeIdBoundFn:
case ZigTypeIdInvalid:
case ZigTypeIdUnreachable:
@@ -5985,6 +5985,40 @@ static void render_const_val_err_set(CodeGen *g, Buf *buf, ConstExprValue *const
}
}
+static void render_const_val_array(CodeGen *g, Buf *buf, ConstExprValue *const_val, size_t len) {
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ buf_append_str(buf, "undefined");
+ return;
+ case ConstArraySpecialBuf: {
+ Buf *array_buf = const_val->data.x_array.data.s_buf;
+ buf_append_char(buf, '"');
+ for (size_t i = 0; i < buf_len(array_buf); i += 1) {
+ uint8_t c = buf_ptr(array_buf)[i];
+ if (c == '"') {
+ buf_append_str(buf, "\\\"");
+ } else {
+ buf_append_char(buf, c);
+ }
+ }
+ buf_append_char(buf, '"');
+ return;
+ }
+ case ConstArraySpecialNone: {
+ buf_appendf(buf, "%s{", buf_ptr(&const_val->type->name));
+ for (uint64_t i = 0; i < len; i += 1) {
+ if (i != 0)
+ buf_appendf(buf, ",");
+ ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
+ render_const_value(g, buf, child_value);
+ }
+ buf_appendf(buf, "}");
+ return;
+ }
+ }
+ zig_unreachable();
+}
+
void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
switch (const_val->special) {
case ConstValSpecialRuntime:
@@ -6065,51 +6099,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
}
case ZigTypeIdPointer:
return render_const_val_ptr(g, buf, const_val, type_entry);
+ case ZigTypeIdVector:
+ return render_const_val_array(g, buf, const_val, type_entry->data.vector.len);
case ZigTypeIdArray:
- switch (const_val->data.x_array.special) {
- case ConstArraySpecialUndef:
- buf_append_str(buf, "undefined");
- return;
- case ConstArraySpecialBuf: {
- Buf *array_buf = const_val->data.x_array.data.s_buf;
- buf_append_char(buf, '"');
- for (size_t i = 0; i < buf_len(array_buf); i += 1) {
- uint8_t c = buf_ptr(array_buf)[i];
- if (c == '"') {
- buf_append_str(buf, "\\\"");
- } else {
- buf_append_char(buf, c);
- }
- }
- buf_append_char(buf, '"');
- return;
- }
- case ConstArraySpecialNone: {
- buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
- uint64_t len = type_entry->data.array.len;
- for (uint64_t i = 0; i < len; i += 1) {
- if (i != 0)
- buf_appendf(buf, ",");
- ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
- render_const_value(g, buf, child_value);
- }
- buf_appendf(buf, "}");
- return;
- }
- }
- zig_unreachable();
- case ZigTypeIdVector: {
- buf_appendf(buf, "%s{", buf_ptr(&type_entry->name));
- uint64_t len = type_entry->data.vector.len;
- for (uint32_t i = 0; i < len; i += 1) {
- if (i != 0)
- buf_appendf(buf, ",");
- ConstExprValue *child_value = &const_val->data.x_vector.elements[i];
- render_const_value(g, buf, child_value);
- }
- buf_appendf(buf, "}");
- return;
- }
+ return render_const_val_array(g, buf, const_val, type_entry->data.array.len);
case ZigTypeIdNull:
{
buf_appendf(buf, "null");
@@ -6379,7 +6372,17 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
// Canonicalize the array value as ConstArraySpecialNone
void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
- assert(const_val->type->id == ZigTypeIdArray);
+ size_t elem_count;
+ ZigType *elem_type;
+ if (const_val->type->id == ZigTypeIdArray) {
+ elem_count = const_val->type->data.array.len;
+ elem_type = const_val->type->data.array.child_type;
+ } else if (const_val->type->id == ZigTypeIdVector) {
+ elem_count = const_val->type->data.vector.len;
+ elem_type = const_val->type->data.vector.elem_type;
+ } else {
+ zig_unreachable();
+ }
if (const_val->special == ConstValSpecialUndef) {
const_val->special = ConstValSpecialStatic;
const_val->data.x_array.special = ConstArraySpecialUndef;
@@ -6389,18 +6392,14 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
return;
case ConstArraySpecialUndef: {
const_val->data.x_array.special = ConstArraySpecialNone;
- size_t elem_count = const_val->type->data.array.len;
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
for (size_t i = 0; i < elem_count; i += 1) {
ConstExprValue *element_val = &const_val->data.x_array.data.s_none.elements[i];
- element_val->type = const_val->type->data.array.child_type;
+ element_val->type = elem_type;
init_const_undefined(g, element_val);
- ConstParent *parent = get_const_val_parent(g, element_val);
- if (parent != nullptr) {
- parent->id = ConstParentIdArray;
- parent->data.p_array.array_val = const_val;
- parent->data.p_array.elem_index = i;
- }
+ element_val->parent.id = ConstParentIdArray;
+ element_val->parent.data.p_array.array_val = const_val;
+ element_val->parent.data.p_array.elem_index = i;
}
return;
}
@@ -6411,7 +6410,6 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
g->string_literals_table.maybe_remove(buf);
const_val->data.x_array.special = ConstArraySpecialNone;
- size_t elem_count = const_val->type->data.array.len;
assert(elem_count == buf_len(buf));
const_val->data.x_array.data.s_none.elements = create_const_vals(elem_count);
for (size_t i = 0; i < elem_count; i += 1) {
@@ -6419,6 +6417,9 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
this_char->special = ConstValSpecialStatic;
this_char->type = g->builtin_types.entry_u8;
bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(buf)[i]);
+ this_char->parent.id = ConstParentIdArray;
+ this_char->parent.data.p_array.array_val = const_val;
+ this_char->parent.data.p_array.elem_index = i;
}
return;
}
@@ -6426,6 +6427,7 @@ void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
zig_unreachable();
}
+// Deprecated. Reference the parent field directly.
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
return &value->parent;
}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index da5265a594..f558fa44b0 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -74,6 +74,7 @@ TypeUnionField *find_union_field_by_tag(ZigType *type_entry, const BigInt *tag);
bool is_ref(ZigType *type_entry);
bool is_array_ref(ZigType *type_entry);
bool is_container_ref(ZigType *type_entry);
+bool is_valid_vector_elem_type(ZigType *elem_type);
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
void scan_import(CodeGen *g, ImportTableEntry *import);
void preview_use_decl(CodeGen *g, AstNode *node);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index b73fda59d1..de2222afb7 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1921,9 +1921,8 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {
}
static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment) {
- assert(alignment > 0);
LLVMValueRef result = LLVMBuildAlloca(g->builder, type_entry->type_ref, name);
- LLVMSetAlignment(result, alignment);
+ LLVMSetAlignment(result, (alignment == 0) ? get_abi_alignment(g, type_entry) : alignment);
return result;
}
@@ -3246,6 +3245,22 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, IrI
return LLVMBuildTrunc(g->builder, shifted_value, child_type->type_ref, "");
}
+static bool value_is_all_undef_array(ConstExprValue *const_val, size_t len) {
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ return true;
+ case ConstArraySpecialBuf:
+ return false;
+ case ConstArraySpecialNone:
+ for (size_t i = 0; i < len; i += 1) {
+ if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i]))
+ return false;
+ }
+ return true;
+ }
+ zig_unreachable();
+}
+
static bool value_is_all_undef(ConstExprValue *const_val) {
switch (const_val->special) {
case ConstValSpecialRuntime:
@@ -3260,19 +3275,9 @@ static bool value_is_all_undef(ConstExprValue *const_val) {
}
return true;
} else if (const_val->type->id == ZigTypeIdArray) {
- switch (const_val->data.x_array.special) {
- case ConstArraySpecialUndef:
- return true;
- case ConstArraySpecialBuf:
- return false;
- case ConstArraySpecialNone:
- for (size_t i = 0; i < const_val->type->data.array.len; i += 1) {
- if (!value_is_all_undef(&const_val->data.x_array.data.s_none.elements[i]))
- return false;
- }
- return true;
- }
- zig_unreachable();
+ return value_is_all_undef_array(const_val, const_val->type->data.array.len);
+ } else if (const_val->type->id == ZigTypeIdVector) {
+ return value_is_all_undef_array(const_val, const_val->type->data.vector.len);
} else {
return false;
}
@@ -5194,6 +5199,32 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable,
return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
}
+static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executable,
+ IrInstructionVectorToArray *instruction)
+{
+ ZigType *array_type = instruction->base.value.type;
+ assert(array_type->id == ZigTypeIdArray);
+ assert(handle_is_ptr(array_type));
+ assert(instruction->tmp_ptr);
+ LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
+ LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr,
+ LLVMPointerType(instruction->vector->value.type->type_ref, 0), "");
+ gen_store_untyped(g, vector, casted_ptr, 0, false);
+ return instruction->tmp_ptr;
+}
+
+static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable,
+ IrInstructionArrayToVector *instruction)
+{
+ ZigType *vector_type = instruction->base.value.type;
+ assert(vector_type->id == ZigTypeIdVector);
+ assert(!handle_is_ptr(vector_type));
+ LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array);
+ LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr,
+ LLVMPointerType(vector_type->type_ref, 0), "");
+ return gen_load_untyped(g, casted_ptr, 0, false, "");
+}
+
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
@@ -5439,6 +5470,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
case IrInstructionIdBitReverse:
return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
+ case IrInstructionIdArrayToVector:
+ return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
+ case IrInstructionIdVectorToArray:
+ return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
}
zig_unreachable();
}
@@ -6016,14 +6051,32 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), true);
}
}
+ zig_unreachable();
}
case ZigTypeIdVector: {
uint32_t len = type_entry->data.vector.len;
- LLVMValueRef *values = allocate(len);
- for (uint32_t i = 0; i < len; i += 1) {
- values[i] = gen_const_val(g, &const_val->data.x_vector.elements[i], "");
+ switch (const_val->data.x_array.special) {
+ case ConstArraySpecialUndef:
+ return LLVMGetUndef(type_entry->type_ref);
+ case ConstArraySpecialNone: {
+ LLVMValueRef *values = allocate(len);
+ for (uint64_t i = 0; i < len; i += 1) {
+ ConstExprValue *elem_value = &const_val->data.x_array.data.s_none.elements[i];
+ values[i] = gen_const_val(g, elem_value, "");
+ }
+ return LLVMConstVector(values, len);
+ }
+ case ConstArraySpecialBuf: {
+ Buf *buf = const_val->data.x_array.data.s_buf;
+ assert(buf_len(buf) == len);
+ LLVMValueRef *values = allocate(len);
+ for (uint64_t i = 0; i < len; i += 1) {
+ values[i] = LLVMConstInt(g->builtin_types.entry_u8->type_ref, buf_ptr(buf)[i], false);
+ }
+ return LLVMConstVector(values, len);
+ }
}
- return LLVMConstVector(values, len);
+ zig_unreachable();
}
case ZigTypeIdUnion:
{
@@ -6467,6 +6520,7 @@ static void do_code_gen(CodeGen *g) {
IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i);
LLVMValueRef *slot;
ZigType *slot_type = instruction->value.type;
+ uint32_t alignment_bytes = 0;
if (instruction->id == IrInstructionIdCast) {
IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction;
slot = &cast_instruction->tmp_ptr;
@@ -6502,10 +6556,14 @@ static void do_code_gen(CodeGen *g) {
} else if (instruction->id == IrInstructionIdCmpxchgGen) {
IrInstructionCmpxchgGen *cmpxchg_instruction = (IrInstructionCmpxchgGen *)instruction;
slot = &cmpxchg_instruction->tmp_ptr;
+ } else if (instruction->id == IrInstructionIdVectorToArray) {
+ IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
+ alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
+ slot = &vector_to_array_instruction->tmp_ptr;
} else {
zig_unreachable();
}
- *slot = build_alloca(g, slot_type, "", get_abi_alignment(g, slot_type));
+ *slot = build_alloca(g, slot_type, "", alignment_bytes);
}
ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
diff --git a/src/ir.cpp b/src/ir.cpp
index 3d3c501df3..3cbbdc8103 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -168,6 +168,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
+static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -899,6 +900,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScop
return IrInstructionIdCheckRuntimeScope;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorToArray *) {
+ return IrInstructionIdVectorToArray;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *) {
+ return IrInstructionIdArrayToVector;
+}
+
template
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate(1);
@@ -2821,6 +2830,34 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope,
return &instruction->base;
}
+static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction,
+ IrInstruction *vector, ZigType *result_type)
+{
+ IrInstructionVectorToArray *instruction = ir_build_instruction(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = result_type;
+ instruction->vector = vector;
+
+ ir_ref_instruction(vector, ira->new_irb.current_basic_block);
+
+ ir_add_alloca(ira, &instruction->base, result_type);
+
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *source_instruction,
+ IrInstruction *array, ZigType *result_type)
+{
+ IrInstructionArrayToVector *instruction = ir_build_instruction(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = result_type;
+ instruction->array = array;
+
+ ir_ref_instruction(array, ira->new_irb.current_basic_block);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -8270,6 +8307,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt);
bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat);
+ assert(const_val_is_int || const_val_is_float);
if (other_type->id == ZigTypeIdFloat) {
if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) {
@@ -10714,6 +10752,32 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
}
}
+static IrInstruction *ir_analyze_array_to_vector(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *array, ZigType *vector_type)
+{
+ if (instr_is_comptime(array)) {
+ // arrays and vectors have the same ConstExprValue representation
+ IrInstruction *result = ir_const(ira, source_instr, vector_type);
+ copy_const_val(&result->value, &array->value, false);
+ result->value.type = vector_type;
+ return result;
+ }
+ return ir_build_array_to_vector(ira, source_instr, array, vector_type);
+}
+
+static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *vector, ZigType *array_type)
+{
+ if (instr_is_comptime(vector)) {
+ // arrays and vectors have the same ConstExprValue representation
+ IrInstruction *result = ir_const(ira, source_instr, array_type);
+ copy_const_val(&result->value, &vector->value, false);
+ result->value.type = array_type;
+ return result;
+ }
+ return ir_build_vector_to_array(ira, source_instr, vector, array_type);
+}
+
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
ZigType *wanted_type, IrInstruction *value)
{
@@ -11102,6 +11166,23 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
}
}
+ // cast from @Vector(N, T) to [N]T
+ if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector &&
+ wanted_type->data.array.len == actual_type->data.vector.len &&
+ types_match_const_cast_only(ira, wanted_type->data.array.child_type,
+ actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
+ {
+ return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type);
+ }
+
+ // cast from [N]T to @Vector(N, T)
+ if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector &&
+ actual_type->data.array.len == wanted_type->data.vector.len &&
+ types_match_const_cast_only(ira, actual_type->data.array.child_type,
+ wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk)
+ {
+ return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
+ }
// cast from undefined to anything
if (actual_type->id == ZigTypeIdUndefined) {
@@ -11780,8 +11861,8 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
return result;
}
-static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
- IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val)
+static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_instr, ZigType *type_entry,
+ ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val)
{
bool is_int;
bool is_float;
@@ -11803,10 +11884,10 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod ||
op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ)
{
- return ErrorDivByZero;
+ return ir_add_error(ira, source_instr, buf_sprintf("division by zero"));
}
if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) {
- return ErrorNegativeDenominator;
+ return ir_add_error(ira, source_instr, buf_sprintf("negative denominator"));
}
switch (op_id) {
@@ -11852,7 +11933,7 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
BigInt orig_bigint;
bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint);
if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) {
- return ErrorShiftedOutOneBits;
+ return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits"));
}
break;
}
@@ -11920,14 +12001,14 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
BigInt remainder;
bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint);
if (bigint_cmp_zero(&remainder) != CmpEQ) {
- return ErrorExactDivRemainder;
+ return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
}
} else {
float_div_trunc(out_val, op1_val, op2_val);
ConstExprValue remainder;
float_rem(&remainder, op1_val, op2_val);
if (float_cmp_zero(&remainder) != CmpEQ) {
- return ErrorExactDivRemainder;
+ return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder"));
}
}
break;
@@ -11951,13 +12032,51 @@ static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val,
if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count,
type_entry->data.integral.is_signed))
{
- return ErrorOverflow;
+ return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow"));
}
}
out_val->type = type_entry;
out_val->special = ConstValSpecialStatic;
- return 0;
+ return nullptr;
+}
+
+// This works on operands that have already been checked to be comptime known.
+static IrInstruction *ir_analyze_math_op(IrAnalyze *ira, IrInstruction *source_instr,
+ ZigType *type_entry, ConstExprValue *op1_val, IrBinOp op_id, ConstExprValue *op2_val)
+{
+ IrInstruction *result_instruction = ir_const(ira, source_instr, type_entry);
+ ConstExprValue *out_val = &result_instruction->value;
+ if (type_entry->id == ZigTypeIdVector) {
+ expand_undef_array(ira->codegen, op1_val);
+ expand_undef_array(ira->codegen, op2_val);
+ out_val->special = ConstValSpecialUndef;
+ expand_undef_array(ira->codegen, out_val);
+ size_t len = type_entry->data.vector.len;
+ ZigType *scalar_type = type_entry->data.vector.elem_type;
+ for (size_t i = 0; i < len; i += 1) {
+ ConstExprValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i];
+ ConstExprValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i];
+ ConstExprValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i];
+ assert(scalar_op1_val->type == scalar_type);
+ assert(scalar_op2_val->type == scalar_type);
+ assert(scalar_out_val->type == scalar_type);
+ ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type,
+ scalar_op1_val, op_id, scalar_op2_val, scalar_out_val);
+ if (msg != nullptr) {
+ add_error_note(ira->codegen, msg, source_instr->source_node,
+ buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i));
+ return ira->codegen->invalid_instruction;
+ }
+ }
+ out_val->type = type_entry;
+ out_val->special = ConstValSpecialStatic;
+ } else {
+ if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) {
+ return ira->codegen->invalid_instruction;
+ }
+ }
+ return ir_implicit_cast(ira, result_instruction, type_entry);
}
static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) {
@@ -12029,24 +12148,7 @@ static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *b
if (op2_val == nullptr)
return ira->codegen->invalid_instruction;
- IrInstruction *result_instruction = ir_const(ira, &bin_op_instruction->base, op1->value.type);
-
- int err;
- if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, &result_instruction->value))) {
- if (err == ErrorOverflow) {
- ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow"));
- return ira->codegen->invalid_instruction;
- } else if (err == ErrorShiftedOutOneBits) {
- ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("exact shift shifted out 1 bits"));
- return ira->codegen->invalid_instruction;
- } else {
- zig_unreachable();
- }
- return ira->codegen->invalid_instruction;
- }
-
- ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);
- return result_instruction;
+ return ir_analyze_math_op(ira, &bin_op_instruction->base, op1->value.type, op1_val, op_id, op2_val);
} else if (op1->value.type->id == ZigTypeIdComptimeInt) {
ir_add_error(ira, &bin_op_instruction->base,
buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known"));
@@ -12292,30 +12394,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
if (op2_val == nullptr)
return ira->codegen->invalid_instruction;
- IrInstruction *result_instruction = ir_const(ira, &instruction->base, resolved_type);
-
- int err;
- if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, &result_instruction->value))) {
- if (err == ErrorDivByZero) {
- ir_add_error(ira, &instruction->base, buf_sprintf("division by zero"));
- return ira->codegen->invalid_instruction;
- } else if (err == ErrorOverflow) {
- ir_add_error(ira, &instruction->base, buf_sprintf("operation caused overflow"));
- return ira->codegen->invalid_instruction;
- } else if (err == ErrorExactDivRemainder) {
- ir_add_error(ira, &instruction->base, buf_sprintf("exact division had a remainder"));
- return ira->codegen->invalid_instruction;
- } else if (err == ErrorNegativeDenominator) {
- ir_add_error(ira, &instruction->base, buf_sprintf("negative denominator"));
- return ira->codegen->invalid_instruction;
- } else {
- zig_unreachable();
- }
- return ira->codegen->invalid_instruction;
- }
-
- ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false);
- return result_instruction;
+ return ir_analyze_math_op(ira, &instruction->base, resolved_type, op1_val, op_id, op2_val);
}
IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope,
@@ -18745,10 +18824,7 @@ static IrInstruction *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstr
if (type_is_invalid(elem_type))
return ira->codegen->invalid_instruction;
- if (elem_type->id != ZigTypeIdInt &&
- elem_type->id != ZigTypeIdFloat &&
- get_codegen_ptr_type(elem_type) == nullptr)
- {
+ if (!is_valid_vector_elem_type(elem_type)) {
ir_add_error(ira, instruction->elem_type,
buf_sprintf("vector element type must be integer, float, or pointer; '%s' is invalid",
buf_ptr(&elem_type->name)));
@@ -20345,6 +20421,17 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value);
}
+static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExprValue *val, size_t len) {
+ size_t buf_i = 0;
+ // TODO optimize the buf case
+ expand_undef_array(codegen, val);
+ for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
+ ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
+ buf_write_value_bytes(codegen, &buf[buf_i], elem);
+ buf_i += type_size(codegen, elem->type);
+ }
+}
+
static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) {
if (val->special == ConstValSpecialUndef)
val->special = ConstValSpecialStatic;
@@ -20390,26 +20477,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
zig_unreachable();
}
case ZigTypeIdArray:
- {
- size_t buf_i = 0;
- // TODO optimize the buf case
- expand_undef_array(codegen, val);
- for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) {
- ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i];
- buf_write_value_bytes(codegen, &buf[buf_i], elem);
- buf_i += type_size(codegen, elem->type);
- }
- }
- return;
- case ZigTypeIdVector: {
- size_t buf_i = 0;
- for (uint32_t elem_i = 0; elem_i < val->type->data.vector.len; elem_i += 1) {
- ConstExprValue *elem = &val->data.x_vector.elements[elem_i];
- buf_write_value_bytes(codegen, &buf[buf_i], elem);
- buf_i += type_size(codegen, elem->type);
- }
- return;
- }
+ return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len);
+ case ZigTypeIdVector:
+ return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len);
case ZigTypeIdStruct:
zig_panic("TODO buf_write_value_bytes struct type");
case ZigTypeIdOptional:
@@ -20426,6 +20496,31 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
zig_unreachable();
}
+static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf,
+ ConstExprValue *val, ZigType *elem_type, size_t len)
+{
+ Error err;
+ uint64_t elem_size = type_size(codegen, elem_type);
+
+ switch (val->data.x_array.special) {
+ case ConstArraySpecialNone:
+ val->data.x_array.data.s_none.elements = create_const_vals(len);
+ for (size_t i = 0; i < len; i++) {
+ ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i];
+ elem->special = ConstValSpecialStatic;
+ elem->type = elem_type;
+ if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
+ return err;
+ }
+ return ErrorNone;
+ case ConstArraySpecialUndef:
+ zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type");
+ case ConstArraySpecialBuf:
+ zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type");
+ }
+ zig_unreachable();
+}
+
static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
Error err;
assert(val->special == ConstValSpecialStatic);
@@ -20464,42 +20559,12 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
return ErrorNone;
}
- case ZigTypeIdArray: {
- uint64_t elem_size = type_size(codegen, val->type->data.array.child_type);
- size_t len = val->type->data.array.len;
-
- switch (val->data.x_array.special) {
- case ConstArraySpecialNone:
- val->data.x_array.data.s_none.elements = create_const_vals(len);
- for (size_t i = 0; i < len; i++) {
- ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i];
- elem->special = ConstValSpecialStatic;
- elem->type = val->type->data.array.child_type;
- if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
- return err;
- }
- return ErrorNone;
- case ConstArraySpecialUndef:
- zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type");
- case ConstArraySpecialBuf:
- zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type");
- }
- zig_unreachable();
- }
- case ZigTypeIdVector: {
- uint64_t elem_size = type_size(codegen, val->type->data.vector.elem_type);
- uint32_t len = val->type->data.vector.len;
-
- val->data.x_vector.elements = create_const_vals(len);
- for (uint32_t i = 0; i < len; i += 1) {
- ConstExprValue *elem = &val->data.x_vector.elements[i];
- elem->special = ConstValSpecialStatic;
- elem->type = val->type->data.vector.elem_type;
- if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem)))
- return err;
- }
- return ErrorNone;
- }
+ case ZigTypeIdArray:
+ return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type,
+ val->type->data.array.len);
+ case ZigTypeIdVector:
+ return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type,
+ val->type->data.vector.len);
case ZigTypeIdEnum:
switch (val->type->data.enumeration.layout) {
case ContainerLayoutAuto:
@@ -21634,6 +21699,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
case IrInstructionIdDeclVarGen:
case IrInstructionIdPtrCastGen:
case IrInstructionIdCmpxchgGen:
+ case IrInstructionIdArrayToVector:
+ case IrInstructionIdVectorToArray:
zig_unreachable();
case IrInstructionIdReturn:
@@ -22129,6 +22196,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdFromBytes:
case IrInstructionIdToBytes:
case IrInstructionIdEnumToInt:
+ case IrInstructionIdVectorToArray:
+ case IrInstructionIdArrayToVector:
return false;
case IrInstructionIdAsm:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index a1fd450b65..e19aa6dda8 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -972,6 +972,18 @@ static void ir_print_check_runtime_scope(IrPrint *irp, IrInstructionCheckRuntime
fprintf(irp->f, ")");
}
+static void ir_print_array_to_vector(IrPrint *irp, IrInstructionArrayToVector *instruction) {
+ fprintf(irp->f, "ArrayToVector(");
+ ir_print_other_instruction(irp, instruction->array);
+ fprintf(irp->f, ")");
+}
+
+static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *instruction) {
+ fprintf(irp->f, "VectorToArray(");
+ ir_print_other_instruction(irp, instruction->vector);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
fprintf(irp->f, "inttoerr ");
ir_print_other_instruction(irp, instruction->target);
@@ -1825,6 +1837,12 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdDeclVarGen:
ir_print_decl_var_gen(irp, (IrInstructionDeclVarGen *)instruction);
break;
+ case IrInstructionIdArrayToVector:
+ ir_print_array_to_vector(irp, (IrInstructionArrayToVector *)instruction);
+ break;
+ case IrInstructionIdVectorToArray:
+ ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index e545a4c418..1fa00b34fd 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -74,6 +74,7 @@ comptime {
_ = @import("behavior/underscore.zig");
_ = @import("behavior/union.zig");
_ = @import("behavior/var_args.zig");
+ _ = @import("behavior/vector.zig");
_ = @import("behavior/void.zig");
_ = @import("behavior/while.zig");
_ = @import("behavior/widening.zig");
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
new file mode 100644
index 0000000000..53c5d01381
--- /dev/null
+++ b/test/stage1/behavior/vector.zig
@@ -0,0 +1,20 @@
+const std = @import("std");
+const assertOrPanic = std.debug.assertOrPanic;
+
+test "implicit array to vector and vector to array" {
+ const S = struct {
+ fn doTheTest() void {
+ var v: @Vector(4, i32) = [4]i32{10, 20, 30, 40};
+ const x: @Vector(4, i32) = [4]i32{1, 2, 3, 4};
+ v +%= x;
+ const result: [4]i32 = v;
+ assertOrPanic(result[0] == 11);
+ assertOrPanic(result[1] == 22);
+ assertOrPanic(result[2] == 33);
+ assertOrPanic(result[3] == 44);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
+
From 06be65a602c2cd83bfdb9a1fa31e0ce038b0262d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 4 Feb 2019 22:14:35 -0500
Subject: [PATCH 136/218] fix vector debug info tripping LLVM assertion
---
src/analyze.cpp | 5 +++--
src/zig_llvm.cpp | 6 +++---
src/zig_llvm.h | 2 +-
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ff961a7044..d92d337c69 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -4486,8 +4486,9 @@ ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type) {
buf_resize(&entry->name, 0);
buf_appendf(&entry->name, "@Vector(%u, %s)", len, buf_ptr(&elem_type->name));
- entry->di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder, len,
- LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref), elem_type->di_type);
+ entry->di_type = ZigLLVMDIBuilderCreateVectorType(g->dbuilder,
+ len * type_size_bits(g, elem_type),
+ LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref), elem_type->di_type, len);
g->type_table.put(type_id, entry);
return entry;
diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp
index 65f6b5abb7..e5a4890914 100644
--- a/src/zig_llvm.cpp
+++ b/src/zig_llvm.cpp
@@ -264,12 +264,12 @@ ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const ch
}
struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
- uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty)
+ uint64_t SizeInBits, uint32_t AlignInBits, struct ZigLLVMDIType *Ty, uint32_t elem_count)
{
SmallVector subrange;
- subrange.push_back(reinterpret_cast(dibuilder)->getOrCreateSubrange(0, Size));
+ subrange.push_back(reinterpret_cast(dibuilder)->getOrCreateSubrange(0, elem_count));
DIType *di_type = reinterpret_cast(dibuilder)->createVectorType(
- Size,
+ SizeInBits,
AlignInBits,
reinterpret_cast(Ty),
reinterpret_cast(dibuilder)->getOrCreateArray(subrange));
diff --git a/src/zig_llvm.h b/src/zig_llvm.h
index 26dca1198b..b5b0e97b53 100644
--- a/src/zig_llvm.h
+++ b/src/zig_llvm.h
@@ -192,7 +192,7 @@ ZIG_EXTERN_C struct ZigLLVMDISubprogram *ZigLLVMCreateFunction(struct ZigLLVMDIB
unsigned scope_line, unsigned flags, bool is_optimized, struct ZigLLVMDISubprogram *decl_subprogram);
ZIG_EXTERN_C struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder,
- uint64_t Size, uint32_t AlignInBits, struct ZigLLVMDIType *Ty);
+ uint64_t SizeInBits, uint32_t AlignInBits, struct ZigLLVMDIType *Ty, uint32_t elem_count);
ZIG_EXTERN_C void ZigLLVMFnSetSubprogram(LLVMValueRef fn, struct ZigLLVMDISubprogram *subprogram);
From 4010f6a11dafa1d047d66a637a0efe58d80a52c6 Mon Sep 17 00:00:00 2001
From: Jimmi Holst Christensen
Date: Tue, 5 Feb 2019 11:00:32 +0100
Subject: [PATCH 137/218] Added support for vector wrapping mult and sub * I
also merged the code that generates ir for add, sub, and mult
---
src/codegen.cpp | 122 +++++++++++++-------------------
test/stage1/behavior/vector.zig | 17 ++---
2 files changed, 58 insertions(+), 81 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index de2222afb7..226a137796 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2582,6 +2582,8 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast
}
+typedef LLVMValueRef (*BuildBinOpFunc)(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, const char *);
+
static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
IrInstructionBinOp *bin_op_instruction)
{
@@ -2640,50 +2642,71 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
} else {
zig_unreachable();
}
+ case IrBinOpMult:
+ case IrBinOpMultWrap:
case IrBinOpAdd:
case IrBinOpAddWrap:
+ case IrBinOpSub:
+ case IrBinOpSubWrap: {
+ // These are lookup table using the AddSubMul enum as the lookup.
+ // If AddSubMul ever changes, then these tables will be out of
+ // date.
+ static const BuildBinOpFunc float_op[3] = { LLVMBuildFAdd, LLVMBuildFSub, LLVMBuildFMul };
+ static const BuildBinOpFunc wrap_op[3] = { LLVMBuildAdd, LLVMBuildSub, LLVMBuildMul };
+ static const BuildBinOpFunc signed_op[3] = { LLVMBuildNSWAdd, LLVMBuildNSWSub, LLVMBuildNSWMul };
+ static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, LLVMBuildNUWMul };
+
+ bool is_vector = type_entry->id == ZigTypeIdVector;
+ bool is_wrapping = (op_id == IrBinOpSubWrap || op_id == IrBinOpAddWrap || op_id == IrBinOpMultWrap);
+ AddSubMul add_sub_mul =
+ op_id == IrBinOpAdd || op_id == IrBinOpAddWrap ? AddSubMulAdd :
+ op_id == IrBinOpSub || op_id == IrBinOpSubWrap ? AddSubMulSub :
+ AddSubMulMul;
+
+ // The code that is generated for vectors and scalars are the same,
+ // so we can just set type_entry to the vectors elem_type an avoid
+ // a lot of repeated code.
+ if (is_vector)
+ type_entry = type_entry->data.vector.elem_type;
+
if (type_entry->id == ZigTypeIdPointer) {
assert(type_entry->data.pointer.ptr_len == PtrLenUnknown);
+ LLVMValueRef subscript_value;
+ if (is_vector)
+ zig_panic("TODO: Implement vector operations on pointers.");
+
+ switch (add_sub_mul) {
+ case AddSubMulAdd:
+ subscript_value = op2_value;
+ break;
+ case AddSubMulSub:
+ subscript_value = LLVMBuildNeg(g->builder, op2_value, "");
+ break;
+ case AddSubMulMul:
+ zig_unreachable();
+ }
+
// TODO runtime safety
- return LLVMBuildInBoundsGEP(g->builder, op1_value, &op2_value, 1, "");
+ return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
} else if (type_entry->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
- return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");
+ return float_op[add_sub_mul](g->builder, op1_value, op2_value, "");
} else if (type_entry->id == ZigTypeIdInt) {
- bool is_wrapping = (op_id == IrBinOpAddWrap);
if (is_wrapping) {
- return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
+ return wrap_op[add_sub_mul](g->builder, op1_value, op2_value, "");
} else if (want_runtime_safety) {
- return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);
+ if (is_vector)
+ zig_panic("TODO: Implement runtime safety vector operations.");
+ return gen_overflow_op(g, type_entry, add_sub_mul, op1_value, op2_value);
} else if (type_entry->data.integral.is_signed) {
- return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
+ return signed_op[add_sub_mul](g->builder, op1_value, op2_value, "");
} else {
- return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
- }
- } else if (type_entry->id == ZigTypeIdVector) {
- ZigType *elem_type = type_entry->data.vector.elem_type;
- if (elem_type->id == ZigTypeIdFloat) {
- ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
- return LLVMBuildFAdd(g->builder, op1_value, op2_value, "");
- } else if (elem_type->id == ZigTypeIdPointer) {
- zig_panic("TODO codegen for pointers in vectors");
- } else if (elem_type->id == ZigTypeIdInt) {
- bool is_wrapping = (op_id == IrBinOpAddWrap);
- if (is_wrapping) {
- return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
- } else if (want_runtime_safety) {
- zig_panic("TODO runtime safety for vector integer addition");
- } else if (elem_type->data.integral.is_signed) {
- return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
- } else {
- return LLVMBuildNUWAdd(g->builder, op1_value, op2_value, "");
- }
- } else {
- zig_unreachable();
+ return unsigned_op[add_sub_mul](g->builder, op1_value, op2_value, "");
}
} else {
zig_unreachable();
}
+ }
case IrBinOpBinOr:
return LLVMBuildOr(g->builder, op1_value, op2_value, "");
case IrBinOpBinXor:
@@ -2728,49 +2751,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
return ZigLLVMBuildLShrExact(g->builder, op1_value, op2_casted, "");
}
}
- case IrBinOpSub:
- case IrBinOpSubWrap:
- if (type_entry->id == ZigTypeIdPointer) {
- assert(type_entry->data.pointer.ptr_len == PtrLenUnknown);
- // TODO runtime safety
- LLVMValueRef subscript_value = LLVMBuildNeg(g->builder, op2_value, "");
- return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
- } else if (type_entry->id == ZigTypeIdFloat) {
- ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
- return LLVMBuildFSub(g->builder, op1_value, op2_value, "");
- } else if (type_entry->id == ZigTypeIdInt) {
- bool is_wrapping = (op_id == IrBinOpSubWrap);
- if (is_wrapping) {
- return LLVMBuildSub(g->builder, op1_value, op2_value, "");
- } else if (want_runtime_safety) {
- return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);
- } else if (type_entry->data.integral.is_signed) {
- return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
- } else {
- return LLVMBuildNUWSub(g->builder, op1_value, op2_value, "");
- }
- } else {
- zig_unreachable();
- }
- case IrBinOpMult:
- case IrBinOpMultWrap:
- if (type_entry->id == ZigTypeIdFloat) {
- ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
- return LLVMBuildFMul(g->builder, op1_value, op2_value, "");
- } else if (type_entry->id == ZigTypeIdInt) {
- bool is_wrapping = (op_id == IrBinOpMultWrap);
- if (is_wrapping) {
- return LLVMBuildMul(g->builder, op1_value, op2_value, "");
- } else if (want_runtime_safety) {
- return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);
- } else if (type_entry->data.integral.is_signed) {
- return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
- } else {
- return LLVMBuildNUWMul(g->builder, op1_value, op2_value, "");
- }
- } else {
- zig_unreachable();
- }
case IrBinOpDivUnspecified:
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
op1_value, op2_value, type_entry, DivKindFloat);
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index 53c5d01381..c97ee0e3d6 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -1,20 +1,17 @@
const std = @import("std");
+const mem = std.mem;
const assertOrPanic = std.debug.assertOrPanic;
-test "implicit array to vector and vector to array" {
+test "vector wrap operators" {
const S = struct {
fn doTheTest() void {
- var v: @Vector(4, i32) = [4]i32{10, 20, 30, 40};
- const x: @Vector(4, i32) = [4]i32{1, 2, 3, 4};
- v +%= x;
- const result: [4]i32 = v;
- assertOrPanic(result[0] == 11);
- assertOrPanic(result[1] == 22);
- assertOrPanic(result[2] == 33);
- assertOrPanic(result[3] == 44);
+ const v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
+ const x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
+ assertOrPanic(mem.eql(i32, ([4]i32)(v +% x), [4]i32{ 11, 22, 33, 44 }));
+ assertOrPanic(mem.eql(i32, ([4]i32)(v -% x), [4]i32{ 9, 18, 27, 36 }));
+ assertOrPanic(mem.eql(i32, ([4]i32)(v *% x), [4]i32{ 10, 40, 90, 160 }));
}
};
S.doTheTest();
comptime S.doTheTest();
}
-
From ac4e38226b45081dfb66f006bba38b11c121ad45 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 5 Feb 2019 10:28:05 -0500
Subject: [PATCH 138/218] docs: clarify passing aggregate types as parameters
---
doc/langref.html.in | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 144c8571c4..e3ba0e3956 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -3192,7 +3192,16 @@ fn foo() void { }
{#code_end#}
{#header_open|Pass-by-value Parameters#}
- In Zig, structs, unions, and enums with payloads can be passed directly to a function:
+ Primitive types such as {#link|Integers#} and {#link|Floats#} passed as parameters
+ are copied, and then the copy is available in the function body. This is called "passing by value".
+ Copying a primitive type is essentially free and typically involves nothing more than
+ setting a register.
+
+
+ Structs, unions, and arrays can sometimes be more efficiently passed as a reference, since a copy
+ could be arbitrarily expensive depending on the size. When these types are passed
+ as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way
+ Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.
{#code_begin|test#}
const Point = struct {
@@ -3201,20 +3210,20 @@ const Point = struct {
};
fn foo(point: Point) i32 {
+ // Here, `point` could be a reference, or a copy. The function body
+ // can ignore the difference and treat it as a value. Be very careful
+ // taking the address of the parameter - it should be treated as if
+ // the address will become invalid when the function returns.
return point.x + point.y;
}
const assert = @import("std").debug.assert;
-test "pass aggregate type by non-copy value to function" {
+test "pass struct to function" {
assert(foo(Point{ .x = 1, .y = 2 }) == 3);
}
{#code_end#}
- In this case, the value may be passed by reference, or by value, whichever way
- Zig decides will be faster.
-
-
For extern functions, Zig follows the C ABI for passing structs and unions by value.
{#header_close#}
From 075fda3c732dc0e34d9917cc9c441b4dff75aa0e Mon Sep 17 00:00:00 2001
From: Sahnvour
Date: Tue, 5 Feb 2019 20:36:57 +0100
Subject: [PATCH 139/218] translate-c: add tests. Commented for now as the
output is currently empty until #646 is fixed.
---
test/translate_c.zig | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 13f2a964d0..02020ddd73 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -1416,4 +1416,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ }
\\}
);
+
+ // cases.add("empty array with initializer",
+ // "int a[4] = {};"
+ // ,
+ // "pub var a: [4]c_int = [1]c_int{0} ** 4;"
+ // );
+
+ // cases.add("array with initialization",
+ // "int a[4] = {1, 2, 3, 4};"
+ // ,
+ // "pub var a: [4]c_int = [4]c_int{1, 2, 3, 4};"
+ // );
+
+ // cases.add("array with incomplete initialization",
+ // "int a[4] = {3, 4};"
+ // ,
+ // "pub var a: [4]c_int = [2]c_int{3, 4} ++ ([1]c_int{0} ** 2);"
+ // );
+
+ // cases.add("2D array with initialization",
+ // "int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };"
+ // ,
+ // "pub var a: [3][3]c_int = [3][3]c_int{[3]c_int{1, 2, 3}, [3]c_int{4, 5, 6}, [3]c_int{7, 8, 9}};"
+ // );
+
+ // cases.add("2D array with incomplete initialization",
+ // "int a[3][3] = { {1, 2}, {4, 5, 6} };"
+ // ,
+ // "pub var a: [3][3]c_int = [2][3]c_int{[2]c_int{1, 2} ++ [1]c_int{0}, [3]c_int{4, 5, 6}} ++ [1][3]c_int{[1]c_int{0} ** 3};"
+ // );
}
From a9faace8b4c9b2bef9425c4cdb136ff8fec056b8 Mon Sep 17 00:00:00 2001
From: Sahnvour
Date: Tue, 5 Feb 2019 22:44:14 +0100
Subject: [PATCH 140/218] Notify failure to create a process when the
executable is not found even in PATH.
---
std/os/child_process.zig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 7aa8582369..37f75483a6 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -610,6 +610,9 @@ pub const ChildProcess = struct {
} else {
return err;
}
+ } else {
+ // Every other error would have been returned earlier.
+ return error.FileNotFound;
}
};
From 6860db66fed86de6cea57134c12374905abac8d8 Mon Sep 17 00:00:00 2001
From: Sahnvour
Date: Tue, 5 Feb 2019 23:13:17 +0100
Subject: [PATCH 141/218] Typo: use the joined path to try executables
available from PATH.
---
std/os/child_process.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 37f75483a6..871f9dd701 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -600,7 +600,7 @@ pub const ChildProcess = struct {
const joined_path = try os.path.join(self.allocator, search_path, app_name);
defer self.allocator.free(joined_path);
- const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, app_name);
+ const joined_path_w = try unicode.utf8ToUtf16LeWithNull(self.allocator, joined_path);
defer self.allocator.free(joined_path_w);
if (windowsCreateProcess(joined_path_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo)) |_| {
From 20e2d8da616aa6406572e64274fec0740cb626c6 Mon Sep 17 00:00:00 2001
From: tgschultz
Date: Wed, 6 Feb 2019 04:04:38 +0000
Subject: [PATCH 142/218] Fixed Serializer and BitOutStream when used with
streams that have empty error sets.
---
std/io.zig | 10 +++++-----
std/io_test.zig | 11 ++++++++++-
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/std/io.zig b/std/io.zig
index c8701aeda6..81d90def6e 100644
--- a/std/io.zig
+++ b/std/io.zig
@@ -912,7 +912,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {
}
/// Flush any remaining bits to the stream.
- pub fn flushBits(self: *Self) !void {
+ pub fn flushBits(self: *Self) Error!void {
if (self.bit_count == 0) return;
try self.out_stream.writeByte(self.bit_buffer);
self.bit_buffer = 0;
@@ -1079,7 +1079,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, is_packed: bool, comptime E
}
//@BUG: inferred error issue. See: #1386
- fn deserializeInt(self: *Self, comptime T: type) (Stream.Error || error{EndOfStream})!T {
+ fn deserializeInt(self: *Self, comptime T: type) (Error || error{EndOfStream})!T {
comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));
const u8_bit_count = 8;
@@ -1287,11 +1287,11 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime is_packed: bool, com
}
/// Flushes any unwritten bits to the stream
- pub fn flush(self: *Self) Stream.Error!void {
+ pub fn flush(self: *Self) Error!void {
if (is_packed) return self.out_stream.flushBits();
}
- fn serializeInt(self: *Self, value: var) !void {
+ fn serializeInt(self: *Self, value: var) Error!void {
const T = @typeOf(value);
comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));
@@ -1323,7 +1323,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime is_packed: bool, com
}
/// Serializes the passed value into the stream
- pub fn serialize(self: *Self, value: var) !void {
+ pub fn serialize(self: *Self, value: var) Error!void {
const T = comptime @typeOf(value);
if (comptime trait.isIndexable(T)) {
diff --git a/std/io_test.zig b/std/io_test.zig
index 0bee0ddaf0..9a0687ec69 100644
--- a/std/io_test.zig
+++ b/std/io_test.zig
@@ -357,6 +357,15 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime is_pa
const total_packed_bytes = (total_bits / u8_bit_count) + extra_packed_byte;
assert(in.pos == if (is_packed) total_packed_bytes else total_bytes);
+
+ //Verify that empty error set works with serializer.
+ //deserializer is covered by SliceInStream
+ const NullError = io.NullOutStream.Error;
+ var null_out = io.NullOutStream.init();
+ var null_out_stream = &null_out.stream;
+ var null_serializer = io.Serializer(endian, is_packed, NullError).init(null_out_stream);
+ try null_serializer.serialize(data_mem[0..]);
+ try null_serializer.flush();
}
test "Serializer/Deserializer Int" {
@@ -568,4 +577,4 @@ test "Deserializer bad data" {
try testBadData(builtin.Endian.Little, false);
try testBadData(builtin.Endian.Big, true);
try testBadData(builtin.Endian.Little, true);
-}
\ No newline at end of file
+}
From 3abf293a84b4dc052c0d735018db520eade6274b Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Feb 2019 11:52:36 -0500
Subject: [PATCH 143/218] doc/targets.md has moved to the github wiki
https://github.com/ziglang/zig/wiki/How-to-Add-Support-For-More-Targets
---
doc/targets.md | 15 ---------------
1 file changed, 15 deletions(-)
delete mode 100644 doc/targets.md
diff --git a/doc/targets.md b/doc/targets.md
deleted file mode 100644
index e5c6ab5534..0000000000
--- a/doc/targets.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# How to Add Support For More Targets
-
-Create bootstrap code in std/bootstrap.zig and add conditional compilation
-logic. This code is responsible for the real executable entry point, calling
-main() and making the exit syscall when main returns.
-
-How to pass a byvalue struct parameter in the C calling convention is
-target-specific. Add logic for how to do function prototypes and function calls
-for the target when an exported or external function has a byvalue struct.
-
-Write the target-specific code in the standard library.
-
-Update the C integer types to be the correct size for the target.
-
-Make sure that `c_longdouble` codegens the correct floating point value.
From b1775ca168e0bcfba6753346c5226881da49c6c4 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Feb 2019 13:48:04 -0500
Subject: [PATCH 144/218] thread local storage working for linux x86_64
---
CMakeLists.txt | 1 +
src/all_types.hpp | 13 ++--
src/analyze.cpp | 69 +++++++++++++-------
src/analyze.hpp | 1 +
src/ast_render.cpp | 7 +-
src/codegen.cpp | 7 ++
src/ir.cpp | 4 ++
src/parser.cpp | 22 ++++---
src/tokenizer.cpp | 2 +
src/tokenizer.hpp | 1 +
std/debug/index.zig | 1 -
std/heap.zig | 7 +-
std/index.zig | 3 +-
std/mem.zig | 20 ++++++
std/os/index.zig | 119 +++++++++++++++++++---------------
std/os/startup.zig | 26 ++++++++
std/os/test.zig | 16 +++++
std/special/bootstrap.zig | 63 ++++++++++++++++--
test/compile_errors.zig | 19 ++++++
test/stage1/behavior/misc.zig | 8 +++
20 files changed, 306 insertions(+), 103 deletions(-)
create mode 100644 std/os/startup.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4dd6a1dcfa..a093bfbfd9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -587,6 +587,7 @@ set(ZIG_STD_FILES
"os/linux/vdso.zig"
"os/linux/x86_64.zig"
"os/path.zig"
+ "os/startup.zig"
"os/time.zig"
"os/uefi.zig"
"os/windows/advapi32.zig"
diff --git a/src/all_types.hpp b/src/all_types.hpp
index c4c9e13cfb..5af4e71157 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -544,12 +544,7 @@ struct AstNodeDefer {
};
struct AstNodeVariableDeclaration {
- VisibMod visib_mod;
Buf *symbol;
- bool is_const;
- bool is_comptime;
- bool is_export;
- bool is_extern;
// one or both of type and expr will be non null
AstNode *type;
AstNode *expr;
@@ -559,6 +554,13 @@ struct AstNodeVariableDeclaration {
AstNode *align_expr;
// populated if the "section(S)" is present
AstNode *section_expr;
+ Token *threadlocal_tok;
+
+ VisibMod visib_mod;
+ bool is_const;
+ bool is_comptime;
+ bool is_export;
+ bool is_extern;
};
struct AstNodeTestDecl {
@@ -1873,6 +1875,7 @@ struct ZigVar {
bool shadowable;
bool src_is_const;
bool gen_is_const;
+ bool is_thread_local;
};
struct ErrorTableEntry {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ff961a7044..96f1faaaa9 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -28,28 +28,10 @@ static Error ATTRIBUTE_MUST_USE resolve_enum_zero_bits(CodeGen *g, ZigType *enum
static Error ATTRIBUTE_MUST_USE resolve_union_zero_bits(CodeGen *g, ZigType *union_type);
static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry);
-ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
- if (node->owner->c_import_node != nullptr) {
- // if this happens, then translate_c generated code that
- // failed semantic analysis, which isn't supposed to happen
- ErrorMsg *err = add_node_error(g, node->owner->c_import_node,
- buf_sprintf("compiler bug: @cImport generated invalid zig code"));
-
- add_error_note(g, err, node, msg);
-
- g->errors.append(err);
- return err;
- }
-
- ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
- node->owner->source_code, node->owner->line_offsets, msg);
-
- g->errors.append(err);
- return err;
-}
-
-ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {
- if (node->owner->c_import_node != nullptr) {
+static ErrorMsg *add_error_note_token(CodeGen *g, ErrorMsg *parent_msg, ImportTableEntry *owner, Token *token,
+ Buf *msg)
+{
+ if (owner->c_import_node != nullptr) {
// if this happens, then translate_c generated code that
// failed semantic analysis, which isn't supposed to happen
@@ -64,13 +46,46 @@ ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *m
return note;
}
- ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column,
- node->owner->source_code, node->owner->line_offsets, msg);
+ ErrorMsg *err = err_msg_create_with_line(owner->path, token->start_line, token->start_column,
+ owner->source_code, owner->line_offsets, msg);
err_msg_add_note(parent_msg, err);
return err;
}
+ErrorMsg *add_token_error(CodeGen *g, ImportTableEntry *owner, Token *token, Buf *msg) {
+ if (owner->c_import_node != nullptr) {
+ // if this happens, then translate_c generated code that
+ // failed semantic analysis, which isn't supposed to happen
+ ErrorMsg *err = add_node_error(g, owner->c_import_node,
+ buf_sprintf("compiler bug: @cImport generated invalid zig code"));
+
+ add_error_note_token(g, err, owner, token, msg);
+
+ g->errors.append(err);
+ return err;
+ }
+ ErrorMsg *err = err_msg_create_with_line(owner->path, token->start_line, token->start_column,
+ owner->source_code, owner->line_offsets, msg);
+
+ g->errors.append(err);
+ return err;
+}
+
+ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
+ Token fake_token;
+ fake_token.start_line = node->line;
+ fake_token.start_column = node->column;
+ return add_token_error(g, node->owner, &fake_token, msg);
+}
+
+ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) {
+ Token fake_token;
+ fake_token.start_line = node->line;
+ fake_token.start_column = node->column;
+ return add_error_note_token(g, parent_msg, node->owner, &fake_token, msg);
+}
+
ZigType *new_type_table_entry(ZigTypeId id) {
ZigType *entry = allocate(1);
entry->id = id;
@@ -3668,6 +3683,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
bool is_const = var_decl->is_const;
bool is_extern = var_decl->is_extern;
bool is_export = var_decl->is_export;
+ bool is_thread_local = var_decl->threadlocal_tok != nullptr;
ZigType *explicit_type = nullptr;
if (var_decl->type) {
@@ -3727,6 +3743,7 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol,
is_const, init_val, &tld_var->base, type);
tld_var->var->linkage = linkage;
+ tld_var->var->is_thread_local = is_thread_local;
if (implicit_type != nullptr && type_is_invalid(implicit_type)) {
tld_var->var->var_type = g->builtin_types.entry_invalid;
@@ -3747,6 +3764,10 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
}
}
+ if (is_thread_local && is_const) {
+ add_node_error(g, source_node, buf_sprintf("threadlocal variable cannot be constant"));
+ }
+
g->global_vars.append(tld_var);
}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index f558fa44b0..9773782510 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -12,6 +12,7 @@
void semantic_analyze(CodeGen *g);
ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg);
+ErrorMsg *add_token_error(CodeGen *g, ImportTableEntry *owner, Token *token, Buf *msg);
ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg);
ZigType *new_type_table_entry(ZigTypeId id);
ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 994ba5f5b1..34a7faa2a5 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -132,6 +132,10 @@ static const char *const_or_var_string(bool is_const) {
return is_const ? "const" : "var";
}
+static const char *thread_local_string(Token *tok) {
+ return (tok == nullptr) ? "" : "threadlocal ";
+}
+
const char *container_string(ContainerKind kind) {
switch (kind) {
case ContainerKindEnum: return "enum";
@@ -554,8 +558,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
{
const char *pub_str = visib_mod_string(node->data.variable_declaration.visib_mod);
const char *extern_str = extern_string(node->data.variable_declaration.is_extern);
+ const char *thread_local_str = thread_local_string(node->data.variable_declaration.threadlocal_tok);
const char *const_or_var = const_or_var_string(node->data.variable_declaration.is_const);
- fprintf(ar->f, "%s%s%s ", pub_str, extern_str, const_or_var);
+ fprintf(ar->f, "%s%s%s%s ", pub_str, extern_str, thread_local_str, const_or_var);
print_symbol(ar, node->data.variable_declaration.symbol);
if (node->data.variable_declaration.type) {
diff --git a/src/codegen.cpp b/src/codegen.cpp
index de2222afb7..d8fc077efc 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -6445,6 +6445,9 @@ static void do_code_gen(CodeGen *g) {
maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
LLVMSetAlignment(global_value, var->align_bytes);
LLVMSetGlobalConstant(global_value, var->gen_is_const);
+ if (var->is_thread_local && !g->is_single_threaded) {
+ LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
+ }
}
} else {
bool exported = (var->linkage == VarLinkageExport);
@@ -6470,6 +6473,9 @@ static void do_code_gen(CodeGen *g) {
}
LLVMSetGlobalConstant(global_value, var->gen_is_const);
+ if (var->is_thread_local && !g->is_single_threaded) {
+ LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
+ }
}
var->value_ref = global_value;
@@ -7520,6 +7526,7 @@ static Error define_builtin_compile_vars(CodeGen *g) {
g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename);
g->root_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package);
+ g->std_package->package_table.put(buf_create_from_str("std"), g->std_package);
g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents);
scan_import(g, g->compile_var_import);
diff --git a/src/ir.cpp b/src/ir.cpp
index 3cbbdc8103..02b2b12230 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5204,6 +5204,10 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
add_node_error(irb->codegen, variable_declaration->section_expr,
buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
}
+ if (variable_declaration->threadlocal_tok != nullptr) {
+ add_token_error(irb->codegen, node->owner, variable_declaration->threadlocal_tok,
+ buf_sprintf("function-local variable '%s' cannot be threadlocal", buf_ptr(variable_declaration->symbol)));
+ }
// Temporarily set the name of the IrExecutable to the VariableDeclaration
// so that the struct or enum from the init expression inherits the name.
diff --git a/src/parser.cpp b/src/parser.cpp
index 81bd469d1c..1c1af87c51 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -844,12 +844,17 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
static AstNode *ast_parse_var_decl(ParseContext *pc) {
- Token *first = eat_token_if(pc, TokenIdKeywordConst);
- if (first == nullptr)
- first = eat_token_if(pc, TokenIdKeywordVar);
- if (first == nullptr)
- return nullptr;
-
+ Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
+ Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
+ if (mut_kw == nullptr)
+ mut_kw = eat_token_if(pc, TokenIdKeywordVar);
+ if (mut_kw == nullptr) {
+ if (thread_local_kw == nullptr) {
+ return nullptr;
+ } else {
+ ast_invalid_token_error(pc, peek_token(pc));
+ }
+ }
Token *identifier = expect_token(pc, TokenIdSymbol);
AstNode *type_expr = nullptr;
if (eat_token_if(pc, TokenIdColon) != nullptr)
@@ -863,8 +868,9 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
expect_token(pc, TokenIdSemicolon);
- AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, first);
- res->data.variable_declaration.is_const = first->id == TokenIdKeywordConst;
+ AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
+ res->data.variable_declaration.threadlocal_tok = thread_local_kw;
+ res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
res->data.variable_declaration.symbol = token_buf(identifier);
res->data.variable_declaration.type = type_expr;
res->data.variable_declaration.align_expr = align_expr;
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index d43bfabf6d..3acd605748 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -146,6 +146,7 @@ static const struct ZigKeyword zig_keywords[] = {
{"suspend", TokenIdKeywordSuspend},
{"switch", TokenIdKeywordSwitch},
{"test", TokenIdKeywordTest},
+ {"threadlocal", TokenIdKeywordThreadLocal},
{"true", TokenIdKeywordTrue},
{"try", TokenIdKeywordTry},
{"undefined", TokenIdKeywordUndefined},
@@ -1586,6 +1587,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordStruct: return "struct";
case TokenIdKeywordSwitch: return "switch";
case TokenIdKeywordTest: return "test";
+ case TokenIdKeywordThreadLocal: return "threadlocal";
case TokenIdKeywordTrue: return "true";
case TokenIdKeywordTry: return "try";
case TokenIdKeywordUndefined: return "undefined";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 1574e95571..17f36699b3 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -88,6 +88,7 @@ enum TokenId {
TokenIdKeywordSuspend,
TokenIdKeywordSwitch,
TokenIdKeywordTest,
+ TokenIdKeywordThreadLocal,
TokenIdKeywordTrue,
TokenIdKeywordTry,
TokenIdKeywordUndefined,
diff --git a/std/debug/index.zig b/std/debug/index.zig
index 838bd0c166..b4ef849509 100644
--- a/std/debug/index.zig
+++ b/std/debug/index.zig
@@ -37,7 +37,6 @@ const Module = struct {
var stderr_file: os.File = undefined;
var stderr_file_out_stream: os.File.OutStream = undefined;
-/// TODO multithreaded awareness
var stderr_stream: ?*io.OutStream(os.File.WriteError) = null;
var stderr_mutex = std.Mutex.init();
pub fn warn(comptime fmt: []const u8, args: ...) void {
diff --git a/std/heap.zig b/std/heap.zig
index fd2ce1e965..1403f8e831 100644
--- a/std/heap.zig
+++ b/std/heap.zig
@@ -106,9 +106,7 @@ pub const DirectAllocator = struct {
};
const ptr = os.windows.HeapAlloc(heap_handle, 0, amt) orelse return error.OutOfMemory;
const root_addr = @ptrToInt(ptr);
- const rem = @rem(root_addr, alignment);
- const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
- const adjusted_addr = root_addr + march_forward_bytes;
+ const adjusted_addr = mem.alignForward(root_addr, alignment);
const record_addr = adjusted_addr + n;
@intToPtr(*align(1) usize, record_addr).* = root_addr;
return @intToPtr([*]u8, adjusted_addr)[0..n];
@@ -126,8 +124,7 @@ pub const DirectAllocator = struct {
const base_addr = @ptrToInt(old_mem.ptr);
const old_addr_end = base_addr + old_mem.len;
const new_addr_end = base_addr + new_size;
- const rem = @rem(new_addr_end, os.page_size);
- const new_addr_end_rounded = new_addr_end + if (rem == 0) 0 else (os.page_size - rem);
+ const new_addr_end_rounded = mem.alignForward(new_addr_end, os.page_size);
if (old_addr_end > new_addr_end_rounded) {
_ = os.posix.munmap(new_addr_end_rounded, old_addr_end - new_addr_end_rounded);
}
diff --git a/std/index.zig b/std/index.zig
index 80d1e46bb6..ef3988460f 100644
--- a/std/index.zig
+++ b/std/index.zig
@@ -33,8 +33,8 @@ pub const io = @import("io.zig");
pub const json = @import("json.zig");
pub const macho = @import("macho.zig");
pub const math = @import("math/index.zig");
-pub const meta = @import("meta/index.zig");
pub const mem = @import("mem.zig");
+pub const meta = @import("meta/index.zig");
pub const net = @import("net.zig");
pub const os = @import("os/index.zig");
pub const pdb = @import("pdb.zig");
@@ -45,6 +45,7 @@ pub const unicode = @import("unicode.zig");
pub const zig = @import("zig/index.zig");
pub const lazyInit = @import("lazy_init.zig").lazyInit;
+pub const startup = @import("os/startup.zig");
test "std" {
// run tests from these
diff --git a/std/mem.zig b/std/mem.zig
index 26ae4ef089..178a5f6c6f 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -1366,3 +1366,23 @@ test "std.mem.subArrayPtr" {
sub2[1] = 'X';
debug.assert(std.mem.eql(u8, a2, "abcXef"));
}
+
+/// Round an address up to the nearest aligned address
+pub fn alignForward(addr: usize, alignment: usize) usize {
+ return (addr + alignment - 1) & ~(alignment - 1);
+}
+
+test "std.mem.alignForward" {
+ debug.assertOrPanic(alignForward(1, 1) == 1);
+ debug.assertOrPanic(alignForward(2, 1) == 2);
+ debug.assertOrPanic(alignForward(1, 2) == 2);
+ debug.assertOrPanic(alignForward(2, 2) == 2);
+ debug.assertOrPanic(alignForward(3, 2) == 4);
+ debug.assertOrPanic(alignForward(4, 2) == 4);
+ debug.assertOrPanic(alignForward(7, 8) == 8);
+ debug.assertOrPanic(alignForward(8, 8) == 8);
+ debug.assertOrPanic(alignForward(9, 8) == 16);
+ debug.assertOrPanic(alignForward(15, 8) == 16);
+ debug.assertOrPanic(alignForward(16, 8) == 16);
+ debug.assertOrPanic(alignForward(17, 8) == 24);
+}
diff --git a/std/os/index.zig b/std/os/index.zig
index 451c0a3436..68b3409757 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -8,6 +8,9 @@ const is_posix = switch (builtin.os) {
};
const os = @This();
+// See the comment in startup.zig for why this does not use the `std` global above.
+const startup = @import("std").startup;
+
test "std.os" {
_ = @import("child_process.zig");
_ = @import("darwin.zig");
@@ -667,14 +670,11 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
}
}
-pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
-pub var posix_environ_raw: [][*]u8 = undefined;
-
/// See std.elf for the constants.
pub fn linuxGetAuxVal(index: usize) usize {
if (builtin.link_libc) {
return usize(std.c.getauxval(index));
- } else if (linux_elf_aux_maybe) |auxv| {
+ } else if (startup.linux_elf_aux_maybe) |auxv| {
var i: usize = 0;
while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
if (auxv[i].a_type == index)
@@ -692,12 +692,7 @@ pub fn getBaseAddress() usize {
return base;
}
const phdr = linuxGetAuxVal(std.elf.AT_PHDR);
- const ElfHeader = switch (@sizeOf(usize)) {
- 4 => std.elf.Elf32_Ehdr,
- 8 => std.elf.Elf64_Ehdr,
- else => @compileError("Unsupported architecture"),
- };
- return phdr - @sizeOf(ElfHeader);
+ return phdr - @sizeOf(std.elf.Ehdr);
},
builtin.Os.macosx, builtin.Os.freebsd => return @ptrToInt(&std.c._mh_execute_header),
builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
@@ -739,7 +734,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
try result.setMove(key, value);
}
} else {
- for (posix_environ_raw) |ptr| {
+ for (startup.posix_environ_raw) |ptr| {
var line_i: usize = 0;
while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
const key = ptr[0..line_i];
@@ -761,7 +756,7 @@ test "os.getEnvMap" {
/// TODO make this go through libc when we have it
pub fn getEnvPosix(key: []const u8) ?[]const u8 {
- for (posix_environ_raw) |ptr| {
+ for (startup.posix_environ_raw) |ptr| {
var line_i: usize = 0;
while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
const this_key = ptr[0..line_i];
@@ -1942,14 +1937,14 @@ pub const ArgIteratorPosix = struct {
pub fn init() ArgIteratorPosix {
return ArgIteratorPosix{
.index = 0,
- .count = raw.len,
+ .count = startup.posix_argv_raw.len,
};
}
pub fn next(self: *ArgIteratorPosix) ?[]const u8 {
if (self.index == self.count) return null;
- const s = raw[self.index];
+ const s = startup.posix_argv_raw[self.index];
self.index += 1;
return cstr.toSlice(s);
}
@@ -1960,10 +1955,6 @@ pub const ArgIteratorPosix = struct {
self.index += 1;
return true;
}
-
- /// This is marked as public but actually it's only meant to be used
- /// internally by zig's startup code.
- pub var raw: [][*]u8 = undefined;
};
pub const ArgIteratorWindows = struct {
@@ -2908,14 +2899,15 @@ pub const Thread = struct {
pub const Data = if (use_pthreads)
struct {
handle: Thread.Handle,
- stack_addr: usize,
- stack_len: usize,
+ mmap_addr: usize,
+ mmap_len: usize,
}
else switch (builtin.os) {
builtin.Os.linux => struct {
handle: Thread.Handle,
- stack_addr: usize,
- stack_len: usize,
+ mmap_addr: usize,
+ mmap_len: usize,
+ tls_end_addr: usize,
},
builtin.Os.windows => struct {
handle: Thread.Handle,
@@ -2955,7 +2947,7 @@ pub const Thread = struct {
posix.EDEADLK => unreachable,
else => unreachable,
}
- assert(posix.munmap(self.data.stack_addr, self.data.stack_len) == 0);
+ assert(posix.munmap(self.data.mmap_addr, self.data.mmap_len) == 0);
} else switch (builtin.os) {
builtin.Os.linux => {
while (true) {
@@ -2969,7 +2961,7 @@ pub const Thread = struct {
else => unreachable,
}
}
- assert(posix.munmap(self.data.stack_addr, self.data.stack_len) == 0);
+ assert(posix.munmap(self.data.mmap_addr, self.data.mmap_len) == 0);
},
builtin.Os.windows => {
assert(windows.WaitForSingleObject(self.data.handle, windows.INFINITE) == windows.WAIT_OBJECT_0);
@@ -3097,42 +3089,56 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
const MAP_GROWSDOWN = if (builtin.os == builtin.Os.linux) linux.MAP_GROWSDOWN else 0;
- const mmap_len = default_stack_size;
- const stack_addr = posix.mmap(null, mmap_len, posix.PROT_READ | posix.PROT_WRITE, posix.MAP_PRIVATE | posix.MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
- if (stack_addr == posix.MAP_FAILED) return error.OutOfMemory;
- errdefer assert(posix.munmap(stack_addr, mmap_len) == 0);
+ var stack_end_offset: usize = undefined;
+ var thread_start_offset: usize = undefined;
+ var context_start_offset: usize = undefined;
+ var tls_start_offset: usize = undefined;
+ const mmap_len = blk: {
+ // First in memory will be the stack, which grows downwards.
+ var l: usize = mem.alignForward(default_stack_size, os.page_size);
+ stack_end_offset = l;
+ // Above the stack, so that it can be in the same mmap call, put the Thread object.
+ l = mem.alignForward(l, @alignOf(Thread));
+ thread_start_offset = l;
+ l += @sizeOf(Thread);
+ // Next, the Context object.
+ if (@sizeOf(Context) != 0) {
+ l = mem.alignForward(l, @alignOf(Context));
+ context_start_offset = l;
+ l += @sizeOf(Context);
+ }
+ // Finally, the Thread Local Storage, if any.
+ if (!Thread.use_pthreads) {
+ if (startup.linux_tls_phdr) |tls_phdr| {
+ l = mem.alignForward(l, tls_phdr.p_align);
+ tls_start_offset = l;
+ l += tls_phdr.p_memsz;
+ }
+ }
+ break :blk l;
+ };
+ const mmap_addr = posix.mmap(null, mmap_len, posix.PROT_READ | posix.PROT_WRITE, posix.MAP_PRIVATE | posix.MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
+ if (mmap_addr == posix.MAP_FAILED) return error.OutOfMemory;
+ errdefer assert(posix.munmap(mmap_addr, mmap_len) == 0);
+
+ const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));
+ thread_ptr.data.mmap_addr = mmap_addr;
+ thread_ptr.data.mmap_len = mmap_len;
- var stack_end: usize = stack_addr + mmap_len;
var arg: usize = undefined;
if (@sizeOf(Context) != 0) {
- stack_end -= @sizeOf(Context);
- stack_end -= stack_end % @alignOf(Context);
- assert(stack_end >= stack_addr);
- const context_ptr = @alignCast(@alignOf(Context), @intToPtr(*Context, stack_end));
+ arg = mmap_addr + context_start_offset;
+ const context_ptr = @alignCast(@alignOf(Context), @intToPtr(*Context, arg));
context_ptr.* = context;
- arg = stack_end;
}
- stack_end -= @sizeOf(Thread);
- stack_end -= stack_end % @alignOf(Thread);
- assert(stack_end >= stack_addr);
- const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, stack_end));
-
- thread_ptr.data.stack_addr = stack_addr;
- thread_ptr.data.stack_len = mmap_len;
-
- if (builtin.os == builtin.Os.windows) {
- // use windows API directly
- @compileError("TODO support spawnThread for Windows");
- } else if (Thread.use_pthreads) {
+ if (Thread.use_pthreads) {
// use pthreads
var attr: c.pthread_attr_t = undefined;
if (c.pthread_attr_init(&attr) != 0) return SpawnThreadError.SystemResources;
defer assert(c.pthread_attr_destroy(&attr) == 0);
- // align to page
- stack_end -= stack_end % os.page_size;
- assert(c.pthread_attr_setstack(&attr, @intToPtr(*c_void, stack_addr), stack_end - stack_addr) == 0);
+ assert(c.pthread_attr_setstack(&attr, @intToPtr(*c_void, mmap_addr), stack_end_offset) == 0);
const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
switch (err) {
@@ -3143,10 +3149,17 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
else => return unexpectedErrorPosix(@intCast(usize, err)),
}
} else if (builtin.os == builtin.Os.linux) {
- // use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly
- const flags = posix.CLONE_VM | posix.CLONE_FS | posix.CLONE_FILES | posix.CLONE_SIGHAND | posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID | posix.CLONE_DETACHED;
- const newtls: usize = 0;
- const rc = posix.clone(MainFuncs.linuxThreadMain, stack_end, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);
+ var flags: u32 = posix.CLONE_VM | posix.CLONE_FS | posix.CLONE_FILES | posix.CLONE_SIGHAND |
+ posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID |
+ posix.CLONE_DETACHED;
+ var newtls: usize = undefined;
+ if (startup.linux_tls_phdr) |tls_phdr| {
+ @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), startup.linux_tls_img_src, tls_phdr.p_filesz);
+ thread_ptr.data.tls_end_addr = mmap_addr + mmap_len;
+ newtls = @ptrToInt(&thread_ptr.data.tls_end_addr);
+ flags |= posix.CLONE_SETTLS;
+ }
+ const rc = posix.clone(MainFuncs.linuxThreadMain, mmap_addr + stack_end_offset, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);
const err = posix.getErrno(rc);
switch (err) {
0 => return thread_ptr,
diff --git a/std/os/startup.zig b/std/os/startup.zig
new file mode 100644
index 0000000000..c54d274c5d
--- /dev/null
+++ b/std/os/startup.zig
@@ -0,0 +1,26 @@
+// This file contains global variables that are initialized on startup from
+// std/special/bootstrap.zig. There are a few things to be aware of here.
+//
+// First, when building an object or library, and no entry point is defined
+// (such as pub fn main), std/special/bootstrap.zig is not included in the
+// compilation. And so these global variables will remain set to the values
+// you see here.
+//
+// Second, when using `zig test` to test the standard library, note that
+// `zig test` is self-hosted. This means that it uses std/special/bootstrap.zig
+// and an @import("std") from the install directory, which is distinct from
+// the standard library files that we are directly testing with `zig test`.
+// This means that these global variables would not get set. So the workaround
+// here is that references to these globals from the standard library must
+// use `@import("std").startup` rather than
+// `@import("path/to/std/index.zig").startup` (and rather than the file path of
+// this file directly). We also put "std" as a reference to itself in the
+// standard library package so that this can work.
+
+const std = @import("../index.zig");
+
+pub var linux_tls_phdr: ?*std.elf.Phdr = null;
+pub var linux_tls_img_src: [*]const u8 = undefined; // defined when linux_tls_phdr is non-null
+pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
+pub var posix_environ_raw: [][*]u8 = undefined;
+pub var posix_argv_raw: [][*]u8 = undefined;
diff --git a/std/os/test.zig b/std/os/test.zig
index f14cf47786..bd9148d1b1 100644
--- a/std/os/test.zig
+++ b/std/os/test.zig
@@ -105,3 +105,19 @@ test "AtomicFile" {
try os.deleteFile(test_out_file);
}
+
+test "thread local storage" {
+ if (builtin.single_threaded) return error.SkipZigTest;
+ const thread1 = try std.os.spawnThread({}, testTls);
+ const thread2 = try std.os.spawnThread({}, testTls);
+ testTls({});
+ thread1.wait();
+ thread2.wait();
+}
+
+threadlocal var x: i32 = 1234;
+fn testTls(context: void) void {
+ if (x != 1234) @panic("bad start value");
+ x += 1;
+ if (x != 1235) @panic("bad end value");
+}
diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig
index 129bde913f..0e84f67481 100644
--- a/std/special/bootstrap.zig
+++ b/std/special/bootstrap.zig
@@ -4,6 +4,7 @@
const root = @import("@root");
const std = @import("std");
const builtin = @import("builtin");
+const assert = std.debug.assert;
var argc_ptr: [*]usize = undefined;
@@ -61,9 +62,23 @@ fn posixCallMainAndExit() noreturn {
while (envp_optional[envp_count]) |_| : (envp_count += 1) {}
const envp = @ptrCast([*][*]u8, envp_optional)[0..envp_count];
if (builtin.os == builtin.Os.linux) {
- const auxv = @ptrCast([*]usize, envp.ptr + envp_count + 1);
- std.os.linux_elf_aux_maybe = @ptrCast([*]std.elf.Auxv, auxv);
- std.debug.assert(std.os.linuxGetAuxVal(std.elf.AT_PAGESZ) == std.os.page_size);
+ // Scan auxiliary vector.
+ const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
+ std.startup.linux_elf_aux_maybe = auxv;
+ var i: usize = 0;
+ var at_phdr: usize = 0;
+ var at_phnum: usize = 0;
+ var at_phent: usize = 0;
+ while (auxv[i].a_un.a_val != 0) : (i += 1) {
+ switch (auxv[i].a_type) {
+ std.elf.AT_PAGESZ => assert(auxv[i].a_un.a_val == std.os.page_size),
+ std.elf.AT_PHDR => at_phdr = auxv[i].a_un.a_val,
+ std.elf.AT_PHNUM => at_phnum = auxv[i].a_un.a_val,
+ std.elf.AT_PHENT => at_phent = auxv[i].a_un.a_val,
+ else => {},
+ }
+ }
+ if (!builtin.single_threaded) linuxInitializeThreadLocalStorage(at_phdr, at_phnum, at_phent);
}
std.os.posix.exit(callMainWithArgs(argc, argv, envp));
@@ -72,8 +87,8 @@ fn posixCallMainAndExit() noreturn {
// This is marked inline because for some reason LLVM in release mode fails to inline it,
// and we want fewer call frames in stack traces.
inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
- std.os.ArgIteratorPosix.raw = argv[0..argc];
- std.os.posix_environ_raw = envp;
+ std.startup.posix_argv_raw = argv[0..argc];
+ std.startup.posix_environ_raw = envp;
return callMain();
}
@@ -116,3 +131,41 @@ inline fn callMain() u8 {
else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"),
}
}
+
+var tls_end_addr: usize = undefined;
+const main_thread_tls_align = 32;
+var main_thread_tls_bytes: [64]u8 align(main_thread_tls_align) = [1]u8{0} ** 64;
+
+fn linuxInitializeThreadLocalStorage(at_phdr: usize, at_phnum: usize, at_phent: usize) void {
+ var phdr_addr = at_phdr;
+ var n = at_phnum;
+ var base: usize = 0;
+ while (n != 0) : ({n -= 1; phdr_addr += at_phent;}) {
+ const phdr = @intToPtr(*std.elf.Phdr, phdr_addr);
+ // TODO look for PT_DYNAMIC when we have https://github.com/ziglang/zig/issues/1917
+ switch (phdr.p_type) {
+ std.elf.PT_PHDR => base = at_phdr - phdr.p_vaddr,
+ std.elf.PT_TLS => std.startup.linux_tls_phdr = phdr,
+ else => continue,
+ }
+ }
+ const tls_phdr = std.startup.linux_tls_phdr orelse return;
+ std.startup.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
+ assert(main_thread_tls_bytes.len >= tls_phdr.p_memsz); // not enough preallocated Thread Local Storage
+ assert(main_thread_tls_align >= tls_phdr.p_align); // preallocated Thread Local Storage not aligned enough
+ @memcpy(&main_thread_tls_bytes, std.startup.linux_tls_img_src, tls_phdr.p_filesz);
+ tls_end_addr = @ptrToInt(&main_thread_tls_bytes) + tls_phdr.p_memsz;
+ linuxSetThreadArea(@ptrToInt(&tls_end_addr));
+}
+
+fn linuxSetThreadArea(addr: usize) void {
+ switch (builtin.arch) {
+ builtin.Arch.x86_64 => {
+ const ARCH_SET_FS = 0x1002;
+ const rc = std.os.linux.syscall2(std.os.linux.SYS_arch_prctl, ARCH_SET_FS, addr);
+ // acrh_prctl is documented to never fail
+ assert(rc == 0);
+ },
+ else => @compileError("Unsupported architecture"),
+ }
+}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 30d9ca5d70..acd1eada06 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,25 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "threadlocal qualifier on const",
+ \\threadlocal const x: i32 = 1234;
+ \\export fn entry() i32 {
+ \\ return x;
+ \\}
+ ,
+ ".tmp_source.zig:1:13: error: threadlocal variable cannot be constant",
+ );
+
+ cases.add(
+ "threadlocal qualifier on local variable",
+ \\export fn entry() void {
+ \\ threadlocal var x: i32 = 1234;
+ \\}
+ ,
+ ".tmp_source.zig:2:5: error: function-local variable 'x' cannot be threadlocal",
+ );
+
cases.add(
"@bitCast same size but bit count mismatch",
\\export fn entry(byte: u8) void {
diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig
index 8d2555dddd..3cc8e5f31e 100644
--- a/test/stage1/behavior/misc.zig
+++ b/test/stage1/behavior/misc.zig
@@ -685,3 +685,11 @@ test "fn call returning scalar optional in equality expression" {
fn getNull() ?*i32 {
return null;
}
+
+test "thread local variable" {
+ const S = struct {
+ threadlocal var t: i32 = 1234;
+ };
+ S.t += 1;
+ assertOrPanic(S.t == 1235);
+}
From d2602b442e7cdea2e74584f9529917d7a53625fd Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Feb 2019 14:32:20 -0500
Subject: [PATCH 145/218] require running std lib tests coherently
this should actually improve CI times a bit too
See the description at the top of std/os/startup.zig (deleted in this
commit) for a more detailed understanding of what this commit does.
---
CMakeLists.txt | 1 -
src/codegen.cpp | 18 +++++++++++++-----
src/codegen.hpp | 2 +-
src/link.cpp | 2 +-
src/main.cpp | 12 +++++++++---
std/build.zig | 10 ++++++++++
std/index.zig | 1 -
std/os/index.zig | 31 +++++++++++++++++++++----------
std/os/startup.zig | 26 --------------------------
std/special/bootstrap.zig | 14 +++++++-------
test/tests.zig | 3 +++
11 files changed, 65 insertions(+), 55 deletions(-)
delete mode 100644 std/os/startup.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a093bfbfd9..4dd6a1dcfa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -587,7 +587,6 @@ set(ZIG_STD_FILES
"os/linux/vdso.zig"
"os/linux/x86_64.zig"
"os/path.zig"
- "os/startup.zig"
"os/time.zig"
"os/uefi.zig"
"os/windows/advapi32.zig"
diff --git a/src/codegen.cpp b/src/codegen.cpp
index d8fc077efc..5e282160d6 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -88,7 +88,7 @@ static const char *symbols_that_llvm_depends_on[] = {
};
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
- Buf *zig_lib_dir)
+ Buf *zig_lib_dir, Buf *override_std_dir)
{
CodeGen *g = allocate(1);
@@ -96,8 +96,12 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
g->zig_lib_dir = zig_lib_dir;
- g->zig_std_dir = buf_alloc();
- os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
+ if (override_std_dir == nullptr) {
+ g->zig_std_dir = buf_alloc();
+ os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
+ } else {
+ g->zig_std_dir = override_std_dir;
+ }
g->zig_c_headers_dir = buf_alloc();
os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
@@ -8356,8 +8360,12 @@ static void add_cache_pkg(CodeGen *g, CacheHash *ch, PackageTableEntry *pkg) {
if (!entry)
break;
- cache_buf(ch, entry->key);
- add_cache_pkg(g, ch, entry->value);
+ // TODO: I think we need a more sophisticated detection of
+ // packages we have already seen
+ if (entry->value != pkg) {
+ cache_buf(ch, entry->key);
+ add_cache_pkg(g, ch, entry->value);
+ }
}
}
diff --git a/src/codegen.hpp b/src/codegen.hpp
index 6f1cdfb677..4bd8f2dcca 100644
--- a/src/codegen.hpp
+++ b/src/codegen.hpp
@@ -15,7 +15,7 @@
#include
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
- Buf *zig_lib_dir);
+ Buf *zig_lib_dir, Buf *override_std_dir);
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
diff --git a/src/link.cpp b/src/link.cpp
index 593f7f309f..58221a99ea 100644
--- a/src/link.cpp
+++ b/src/link.cpp
@@ -42,7 +42,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path)
}
CodeGen *child_gen = codegen_create(full_path, child_target, child_out_type,
- parent_gen->build_mode, parent_gen->zig_lib_dir);
+ parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir);
child_gen->out_h_path = nullptr;
child_gen->verbose_tokenize = parent_gen->verbose_tokenize;
diff --git a/src/main.cpp b/src/main.cpp
index 81f49089be..73a1d75d42 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -74,6 +74,7 @@ static int print_full_usage(const char *arg0) {
" -dirafter [dir] same as -isystem but do it last\n"
" -isystem [dir] add additional search path for other .h files\n"
" -mllvm [arg] forward an arg to LLVM's option processing\n"
+ " --override-std-dir [arg] use an alternate Zig standard library\n"
"\n"
"Link Options:\n"
" --dynamic-linker [path] set the path to ld.so\n"
@@ -395,6 +396,7 @@ int main(int argc, char **argv) {
bool system_linker_hack = false;
TargetSubsystem subsystem = TargetSubsystemAuto;
bool is_single_threaded = false;
+ Buf *override_std_dir = nullptr;
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
Buf zig_exe_path_buf = BUF_INIT;
@@ -430,7 +432,8 @@ int main(int argc, char **argv) {
Buf *build_runner_path = buf_alloc();
os_path_join(get_zig_special_dir(), buf_create_from_str("build_runner.zig"), build_runner_path);
- CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir());
+ CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
+ override_std_dir);
g->enable_time_report = timing_info;
buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);
codegen_set_out_name(g, buf_create_from_str("build"));
@@ -645,6 +648,8 @@ int main(int argc, char **argv) {
clang_argv.append(argv[i]);
llvm_argv.append(argv[i]);
+ } else if (strcmp(arg, "--override-std-dir") == 0) {
+ override_std_dir = buf_create_from_str(argv[i]);
} else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
lib_dirs.append(argv[i]);
} else if (strcmp(arg, "--library") == 0) {
@@ -819,7 +824,7 @@ int main(int argc, char **argv) {
switch (cmd) {
case CmdBuiltin: {
- CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir());
+ CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, get_zig_lib_dir(), override_std_dir);
g->is_single_threaded = is_single_threaded;
Buf *builtin_source = codegen_generate_builtin_source(g);
if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
@@ -878,7 +883,8 @@ int main(int argc, char **argv) {
if (cmd == CmdRun && buf_out_name == nullptr) {
buf_out_name = buf_create_from_str("run");
}
- CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir());
+ CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, get_zig_lib_dir(),
+ override_std_dir);
g->subsystem = subsystem;
if (disable_pic) {
diff --git a/std/build.zig b/std/build.zig
index 5246d97339..07efcec30d 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -1686,6 +1686,7 @@ pub const TestStep = struct {
no_rosegment: bool,
output_path: ?[]const u8,
system_linker_hack: bool,
+ override_std_dir: ?[]const u8,
pub fn init(builder: *Builder, root_src: []const u8) TestStep {
const step_name = builder.fmt("test {}", root_src);
@@ -1707,6 +1708,7 @@ pub const TestStep = struct {
.no_rosegment = false,
.output_path = null,
.system_linker_hack = false,
+ .override_std_dir = null,
};
}
@@ -1737,6 +1739,10 @@ pub const TestStep = struct {
self.build_mode = mode;
}
+ pub fn overrideStdDir(self: *TestStep, dir_path: []const u8) void {
+ self.override_std_dir = dir_path;
+ }
+
pub fn setOutputPath(self: *TestStep, file_path: []const u8) void {
self.output_path = file_path;
@@ -1914,6 +1920,10 @@ pub const TestStep = struct {
if (self.system_linker_hack) {
try zig_args.append("--system-linker-hack");
}
+ if (self.override_std_dir) |dir| {
+ try zig_args.append("--override-std-dir");
+ try zig_args.append(builder.pathFromRoot(dir));
+ }
try builder.spawnChild(zig_args.toSliceConst());
}
diff --git a/std/index.zig b/std/index.zig
index ef3988460f..2a63244004 100644
--- a/std/index.zig
+++ b/std/index.zig
@@ -45,7 +45,6 @@ pub const unicode = @import("unicode.zig");
pub const zig = @import("zig/index.zig");
pub const lazyInit = @import("lazy_init.zig").lazyInit;
-pub const startup = @import("os/startup.zig");
test "std" {
// run tests from these
diff --git a/std/os/index.zig b/std/os/index.zig
index 68b3409757..d17b6f4f40 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -8,8 +8,9 @@ const is_posix = switch (builtin.os) {
};
const os = @This();
-// See the comment in startup.zig for why this does not use the `std` global above.
-const startup = @import("std").startup;
+comptime {
+ assert(@import("std") == std); // You have to run the std lib tests with --override-std-dir
+}
test "std.os" {
_ = @import("child_process.zig");
@@ -670,11 +671,14 @@ fn posixExecveErrnoToErr(err: usize) PosixExecveError {
}
}
+pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
+pub var posix_environ_raw: [][*]u8 = undefined;
+
/// See std.elf for the constants.
pub fn linuxGetAuxVal(index: usize) usize {
if (builtin.link_libc) {
return usize(std.c.getauxval(index));
- } else if (startup.linux_elf_aux_maybe) |auxv| {
+ } else if (linux_elf_aux_maybe) |auxv| {
var i: usize = 0;
while (auxv[i].a_type != std.elf.AT_NULL) : (i += 1) {
if (auxv[i].a_type == index)
@@ -734,7 +738,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
try result.setMove(key, value);
}
} else {
- for (startup.posix_environ_raw) |ptr| {
+ for (posix_environ_raw) |ptr| {
var line_i: usize = 0;
while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
const key = ptr[0..line_i];
@@ -756,7 +760,7 @@ test "os.getEnvMap" {
/// TODO make this go through libc when we have it
pub fn getEnvPosix(key: []const u8) ?[]const u8 {
- for (startup.posix_environ_raw) |ptr| {
+ for (posix_environ_raw) |ptr| {
var line_i: usize = 0;
while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
const this_key = ptr[0..line_i];
@@ -1937,14 +1941,14 @@ pub const ArgIteratorPosix = struct {
pub fn init() ArgIteratorPosix {
return ArgIteratorPosix{
.index = 0,
- .count = startup.posix_argv_raw.len,
+ .count = raw.len,
};
}
pub fn next(self: *ArgIteratorPosix) ?[]const u8 {
if (self.index == self.count) return null;
- const s = startup.posix_argv_raw[self.index];
+ const s = raw[self.index];
self.index += 1;
return cstr.toSlice(s);
}
@@ -1955,6 +1959,10 @@ pub const ArgIteratorPosix = struct {
self.index += 1;
return true;
}
+
+ /// This is marked as public but actually it's only meant to be used
+ /// internally by zig's startup code.
+ pub var raw: [][*]u8 = undefined;
};
pub const ArgIteratorWindows = struct {
@@ -3000,6 +3008,9 @@ pub const SpawnThreadError = error{
Unexpected,
};
+pub var linux_tls_phdr: ?*std.elf.Phdr = null;
+pub var linux_tls_img_src: [*]const u8 = undefined; // defined if linux_tls_phdr is
+
/// caller must call wait on the returned thread
/// fn startFn(@typeOf(context)) T
/// where T is u8, noreturn, void, or !void
@@ -3109,7 +3120,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
}
// Finally, the Thread Local Storage, if any.
if (!Thread.use_pthreads) {
- if (startup.linux_tls_phdr) |tls_phdr| {
+ if (linux_tls_phdr) |tls_phdr| {
l = mem.alignForward(l, tls_phdr.p_align);
tls_start_offset = l;
l += tls_phdr.p_memsz;
@@ -3153,8 +3164,8 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
posix.CLONE_THREAD | posix.CLONE_SYSVSEM | posix.CLONE_PARENT_SETTID | posix.CLONE_CHILD_CLEARTID |
posix.CLONE_DETACHED;
var newtls: usize = undefined;
- if (startup.linux_tls_phdr) |tls_phdr| {
- @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), startup.linux_tls_img_src, tls_phdr.p_filesz);
+ if (linux_tls_phdr) |tls_phdr| {
+ @memcpy(@intToPtr([*]u8, mmap_addr + tls_start_offset), linux_tls_img_src, tls_phdr.p_filesz);
thread_ptr.data.tls_end_addr = mmap_addr + mmap_len;
newtls = @ptrToInt(&thread_ptr.data.tls_end_addr);
flags |= posix.CLONE_SETTLS;
diff --git a/std/os/startup.zig b/std/os/startup.zig
deleted file mode 100644
index c54d274c5d..0000000000
--- a/std/os/startup.zig
+++ /dev/null
@@ -1,26 +0,0 @@
-// This file contains global variables that are initialized on startup from
-// std/special/bootstrap.zig. There are a few things to be aware of here.
-//
-// First, when building an object or library, and no entry point is defined
-// (such as pub fn main), std/special/bootstrap.zig is not included in the
-// compilation. And so these global variables will remain set to the values
-// you see here.
-//
-// Second, when using `zig test` to test the standard library, note that
-// `zig test` is self-hosted. This means that it uses std/special/bootstrap.zig
-// and an @import("std") from the install directory, which is distinct from
-// the standard library files that we are directly testing with `zig test`.
-// This means that these global variables would not get set. So the workaround
-// here is that references to these globals from the standard library must
-// use `@import("std").startup` rather than
-// `@import("path/to/std/index.zig").startup` (and rather than the file path of
-// this file directly). We also put "std" as a reference to itself in the
-// standard library package so that this can work.
-
-const std = @import("../index.zig");
-
-pub var linux_tls_phdr: ?*std.elf.Phdr = null;
-pub var linux_tls_img_src: [*]const u8 = undefined; // defined when linux_tls_phdr is non-null
-pub var linux_elf_aux_maybe: ?[*]std.elf.Auxv = null;
-pub var posix_environ_raw: [][*]u8 = undefined;
-pub var posix_argv_raw: [][*]u8 = undefined;
diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig
index 0e84f67481..97699e0cc5 100644
--- a/std/special/bootstrap.zig
+++ b/std/special/bootstrap.zig
@@ -64,7 +64,7 @@ fn posixCallMainAndExit() noreturn {
if (builtin.os == builtin.Os.linux) {
// Scan auxiliary vector.
const auxv = @ptrCast([*]std.elf.Auxv, envp.ptr + envp_count + 1);
- std.startup.linux_elf_aux_maybe = auxv;
+ std.os.linux_elf_aux_maybe = auxv;
var i: usize = 0;
var at_phdr: usize = 0;
var at_phnum: usize = 0;
@@ -87,8 +87,8 @@ fn posixCallMainAndExit() noreturn {
// This is marked inline because for some reason LLVM in release mode fails to inline it,
// and we want fewer call frames in stack traces.
inline fn callMainWithArgs(argc: usize, argv: [*][*]u8, envp: [][*]u8) u8 {
- std.startup.posix_argv_raw = argv[0..argc];
- std.startup.posix_environ_raw = envp;
+ std.os.ArgIteratorPosix.raw = argv[0..argc];
+ std.os.posix_environ_raw = envp;
return callMain();
}
@@ -145,15 +145,15 @@ fn linuxInitializeThreadLocalStorage(at_phdr: usize, at_phnum: usize, at_phent:
// TODO look for PT_DYNAMIC when we have https://github.com/ziglang/zig/issues/1917
switch (phdr.p_type) {
std.elf.PT_PHDR => base = at_phdr - phdr.p_vaddr,
- std.elf.PT_TLS => std.startup.linux_tls_phdr = phdr,
+ std.elf.PT_TLS => std.os.linux_tls_phdr = phdr,
else => continue,
}
}
- const tls_phdr = std.startup.linux_tls_phdr orelse return;
- std.startup.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
+ const tls_phdr = std.os.linux_tls_phdr orelse return;
+ std.os.linux_tls_img_src = @intToPtr([*]const u8, base + tls_phdr.p_vaddr);
assert(main_thread_tls_bytes.len >= tls_phdr.p_memsz); // not enough preallocated Thread Local Storage
assert(main_thread_tls_align >= tls_phdr.p_align); // preallocated Thread Local Storage not aligned enough
- @memcpy(&main_thread_tls_bytes, std.startup.linux_tls_img_src, tls_phdr.p_filesz);
+ @memcpy(&main_thread_tls_bytes, std.os.linux_tls_img_src, tls_phdr.p_filesz);
tls_end_addr = @ptrToInt(&main_thread_tls_bytes) + tls_phdr.p_memsz;
linuxSetThreadArea(@ptrToInt(&tls_end_addr));
}
diff --git a/test/tests.zig b/test/tests.zig
index 548496fa2f..fc188f5550 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -194,6 +194,9 @@ pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []cons
if (link_libc) {
these_tests.linkSystemLibrary("c");
}
+ if (mem.eql(u8, name, "std")) {
+ these_tests.overrideStdDir("std");
+ }
step.dependOn(&these_tests.step);
}
}
From 89ffb5819703c81514e4f29d2cadb5b74ea1f840 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 6 Feb 2019 18:32:41 -0500
Subject: [PATCH 146/218] implement Thread Local Storage on Windows
---
CMakeLists.txt | 1 +
src/codegen.cpp | 14 ++++++++------
std/os/windows/index.zig | 19 ++++++++++++++++++-
std/os/windows/kernel32.zig | 4 ++++
std/os/windows/tls.zig | 36 ++++++++++++++++++++++++++++++++++++
std/special/bootstrap.zig | 4 +++-
6 files changed, 70 insertions(+), 8 deletions(-)
create mode 100644 std/os/windows/tls.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4dd6a1dcfa..d6bd8a6c2e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -596,6 +596,7 @@ set(ZIG_STD_FILES
"os/windows/ntdll.zig"
"os/windows/ole32.zig"
"os/windows/shell32.zig"
+ "os/windows/tls.zig"
"os/windows/util.zig"
"os/zen.zig"
"pdb.zig"
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 5e282160d6..7169669426 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -6365,6 +6365,12 @@ static void validate_inline_fns(CodeGen *g) {
report_errors_and_maybe_exit(g);
}
+static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) {
+ if (var->is_thread_local && !g->is_single_threaded) {
+ LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
+ }
+}
+
static void do_code_gen(CodeGen *g) {
assert(!g->errors.length);
@@ -6449,9 +6455,7 @@ static void do_code_gen(CodeGen *g) {
maybe_import_dll(g, global_value, GlobalLinkageIdStrong);
LLVMSetAlignment(global_value, var->align_bytes);
LLVMSetGlobalConstant(global_value, var->gen_is_const);
- if (var->is_thread_local && !g->is_single_threaded) {
- LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
- }
+ set_global_tls(g, var, global_value);
}
} else {
bool exported = (var->linkage == VarLinkageExport);
@@ -6477,9 +6481,7 @@ static void do_code_gen(CodeGen *g) {
}
LLVMSetGlobalConstant(global_value, var->gen_is_const);
- if (var->is_thread_local && !g->is_single_threaded) {
- LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel);
- }
+ set_global_tls(g, var, global_value);
}
var->value_ref = global_value;
diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig
index 3f19905835..8e9ed8b8db 100644
--- a/std/os/windows/index.zig
+++ b/std/os/windows/index.zig
@@ -49,7 +49,10 @@ pub const UNICODE = false;
pub const WCHAR = u16;
pub const WORD = u16;
pub const LARGE_INTEGER = i64;
-pub const LONG = c_long;
+pub const ULONG = u32;
+pub const LONG = i32;
+pub const ULONGLONG = u64;
+pub const LONGLONG = i64;
pub const TRUE = 1;
pub const FALSE = 0;
@@ -380,3 +383,17 @@ pub const COORD = extern struct {
};
pub const CREATE_UNICODE_ENVIRONMENT = 1024;
+
+pub const TLS_OUT_OF_INDEXES = 4294967295;
+pub const IMAGE_TLS_DIRECTORY = extern struct {
+ StartAddressOfRawData: usize,
+ EndAddressOfRawData: usize,
+ AddressOfIndex: usize,
+ AddressOfCallBacks: usize,
+ SizeOfZeroFill: u32,
+ Characteristics: u32,
+};
+pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
+pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
+
+pub const PIMAGE_TLS_CALLBACK = ?extern fn(PVOID, DWORD, PVOID) void;
diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig
index 66b9552c5f..ce8443de02 100644
--- a/std/os/windows/kernel32.zig
+++ b/std/os/windows/kernel32.zig
@@ -164,6 +164,10 @@ pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
+pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD;
+
+pub extern "kernel32" stdcallcc fn TlsFree(dwTlsIndex: DWORD) BOOL;
+
pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
pub extern "kernel32" stdcallcc fn WriteFile(
diff --git a/std/os/windows/tls.zig b/std/os/windows/tls.zig
new file mode 100644
index 0000000000..9e62a7c5c6
--- /dev/null
+++ b/std/os/windows/tls.zig
@@ -0,0 +1,36 @@
+const std = @import("../../index.zig");
+
+export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES;
+export var _tls_start: u8 linksection(".tls") = 0;
+export var _tls_end: u8 linksection(".tls$ZZZ") = 0;
+export var __xl_a: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLA") = null;
+export var __xl_z: std.os.windows.PIMAGE_TLS_CALLBACK linksection(".CRT$XLZ") = null;
+
+// TODO this is how I would like it to be expressed
+// TODO also note, ReactOS has a +1 on StartAddressOfRawData and AddressOfCallBacks. Investigate
+// why they do that.
+//export const _tls_used linksection(".rdata$T") = std.os.windows.IMAGE_TLS_DIRECTORY {
+// .StartAddressOfRawData = @ptrToInt(&_tls_start),
+// .EndAddressOfRawData = @ptrToInt(&_tls_end),
+// .AddressOfIndex = @ptrToInt(&_tls_index),
+// .AddressOfCallBacks = @ptrToInt(__xl_a),
+// .SizeOfZeroFill = 0,
+// .Characteristics = 0,
+//};
+// This is the workaround because we can't do @ptrToInt at comptime like that.
+pub const IMAGE_TLS_DIRECTORY = extern struct {
+ StartAddressOfRawData: *c_void,
+ EndAddressOfRawData: *c_void,
+ AddressOfIndex: *c_void,
+ AddressOfCallBacks: *c_void,
+ SizeOfZeroFill: u32,
+ Characteristics: u32,
+};
+export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY {
+ .StartAddressOfRawData = &_tls_start,
+ .EndAddressOfRawData = &_tls_end,
+ .AddressOfIndex = &_tls_index,
+ .AddressOfCallBacks = &__xl_a,
+ .SizeOfZeroFill = 0,
+ .Characteristics = 0,
+};
diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig
index 97699e0cc5..6dcc90b372 100644
--- a/std/special/bootstrap.zig
+++ b/std/special/bootstrap.zig
@@ -45,7 +45,9 @@ nakedcc fn _start() noreturn {
extern fn WinMainCRTStartup() noreturn {
@setAlignStack(16);
-
+ if (!builtin.single_threaded) {
+ _ = @import("../os/windows/tls.zig");
+ }
std.os.windows.ExitProcess(callMain());
}
From 36bade5c562bf0b2479b6dfdd465a1a312890835 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Feb 2019 00:42:41 -0500
Subject: [PATCH 147/218] fixups, and modify std.mem.join and
std.os.path.resolve API
* zig fmt
* std.mem.join takes a slice of slices instead of var args
* std.mem.join takes a separator slice rather than byte,
and always inserts it. Previously it would not insert the separator
if there already was one, violating the documented behavior.
* std.mem.join calculates exactly the correct amount to allocate
and has no call to allocator.shrink()
* bring back joinWindows and joinPosix and the corresponding tests.
it is intended to be able to call these functions from any OS.
* rename std.os.path.resolveSlice to resolve (now resolve takes
a slice of slices instead of var args)
---
build.zig | 35 ++++--
doc/docgen.zig | 25 ++++-
src-self-hosted/libc_installation.zig | 15 ++-
std/build.zig | 79 +++++++++----
std/debug/index.zig | 4 +-
std/event/fs.zig | 4 +-
std/mem.zig | 49 ++++-----
std/os/child_process.zig | 2 +-
std/os/get_app_data_dir.zig | 7 +-
std/os/index.zig | 7 +-
std/os/path.zig | 152 ++++++++++++++++----------
test/cli.zig | 2 +-
test/tests.zig | 55 ++++++++--
13 files changed, 290 insertions(+), 146 deletions(-)
diff --git a/build.zig b/build.zig
index b90f58ff51..5c7c5b8a18 100644
--- a/build.zig
+++ b/build.zig
@@ -16,7 +16,10 @@ pub fn build(b: *Builder) !void {
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
const rel_zig_exe = try os.path.relative(b.allocator, b.build_root, b.zig_exe);
- const langref_out_path = os.path.join(b.allocator, [][]const u8{ b.cache_root, "langref.html" }) catch unreachable;
+ const langref_out_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, "langref.html" },
+ ) catch unreachable;
var docgen_cmd = b.addCommand(null, b.env_map, [][]const u8{
docgen_exe.getOutputPath(),
rel_zig_exe,
@@ -125,13 +128,19 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
for (dep.libdirs.toSliceConst()) |lib_dir| {
lib_exe_obj.addLibPath(lib_dir);
}
- const lib_dir = os.path.join(b.allocator, [][]const u8{dep.prefix, "lib"}) catch unreachable;
+ const lib_dir = os.path.join(
+ b.allocator,
+ [][]const u8{ dep.prefix, "lib" },
+ ) catch unreachable;
for (dep.system_libs.toSliceConst()) |lib| {
const static_bare_name = if (mem.eql(u8, lib, "curses"))
([]const u8)("libncurses.a")
else
b.fmt("lib{}.a", lib);
- const static_lib_name = os.path.join(b.allocator, [][]const u8{lib_dir, static_bare_name}) catch unreachable;
+ const static_lib_name = os.path.join(
+ b.allocator,
+ [][]const u8{ lib_dir, static_bare_name },
+ ) catch unreachable;
const have_static = fileExists(static_lib_name) catch unreachable;
if (have_static) {
lib_exe_obj.addObjectFile(static_lib_name);
@@ -159,7 +168,11 @@ fn fileExists(filename: []const u8) !bool {
fn addCppLib(b: *Builder, lib_exe_obj: var, cmake_binary_dir: []const u8, lib_name: []const u8) void {
const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
- lib_exe_obj.addObjectFile(os.path.join(b.allocator, [][]const u8{ cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt()) }) catch unreachable);
+ lib_exe_obj.addObjectFile(os.path.join(b.allocator, [][]const u8{
+ cmake_binary_dir,
+ "zig_cpp",
+ b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt()),
+ }) catch unreachable);
}
const LibraryDep = struct {
@@ -235,8 +248,11 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
var it = mem.tokenize(stdlib_files, ";");
while (it.next()) |stdlib_file| {
- const src_path = os.path.join(b.allocator, [][]const u8{"std", stdlib_file}) catch unreachable;
- const dest_path = os.path.join(b.allocator, [][]const u8{"lib", "zig", "std", stdlib_file}) catch unreachable;
+ const src_path = os.path.join(b.allocator, [][]const u8{ "std", stdlib_file }) catch unreachable;
+ const dest_path = os.path.join(
+ b.allocator,
+ [][]const u8{ "lib", "zig", "std", stdlib_file },
+ ) catch unreachable;
b.installFile(src_path, dest_path);
}
}
@@ -244,8 +260,11 @@ pub fn installStdLib(b: *Builder, stdlib_files: []const u8) void {
pub fn installCHeaders(b: *Builder, c_header_files: []const u8) void {
var it = mem.tokenize(c_header_files, ";");
while (it.next()) |c_header_file| {
- const src_path = os.path.join(b.allocator, [][]const u8{"c_headers", c_header_file}) catch unreachable;
- const dest_path = os.path.join(b.allocator, [][]const u8{"lib", "zig", "include", c_header_file}) catch unreachable;
+ const src_path = os.path.join(b.allocator, [][]const u8{ "c_headers", c_header_file }) catch unreachable;
+ const dest_path = os.path.join(
+ b.allocator,
+ [][]const u8{ "lib", "zig", "include", c_header_file },
+ ) catch unreachable;
b.installFile(src_path, dest_path);
}
}
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 8b2a7e4c10..14e4700553 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -990,13 +990,19 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
try tokenizeAndPrint(tokenizer, out, code.source_token);
try out.write("");
const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
- const tmp_source_file_name = try os.path.join(allocator, [][]const u8{ tmp_dir_name, name_plus_ext });
+ const tmp_source_file_name = try os.path.join(
+ allocator,
+ [][]const u8{ tmp_dir_name, name_plus_ext },
+ );
try io.writeFile(tmp_source_file_name, trimmed_raw_source);
switch (code.id) {
Code.Id.Exe => |expected_outcome| {
const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
- const tmp_bin_file_name = try os.path.join(allocator, [][]const u8{ tmp_dir_name, name_plus_bin_ext });
+ const tmp_bin_file_name = try os.path.join(
+ allocator,
+ [][]const u8{ tmp_dir_name, name_plus_bin_ext },
+ );
var build_args = std.ArrayList([]const u8).init(allocator);
defer build_args.deinit();
try build_args.appendSlice([][]const u8{
@@ -1024,7 +1030,10 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
}
for (code.link_objects) |link_object| {
const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext);
- const full_path_object = try os.path.join(allocator, [][]const u8{ tmp_dir_name, name_with_ext });
+ const full_path_object = try os.path.join(
+ allocator,
+ [][]const u8{ tmp_dir_name, name_with_ext },
+ );
try build_args.append("--object");
try build_args.append(full_path_object);
try out.print(" --object {}", name_with_ext);
@@ -1216,12 +1225,18 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
},
Code.Id.Obj => |maybe_error_match| {
const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext);
- const tmp_obj_file_name = try os.path.join(allocator, [][]const u8{ tmp_dir_name, name_plus_obj_ext });
+ const tmp_obj_file_name = try os.path.join(
+ allocator,
+ [][]const u8{ tmp_dir_name, name_plus_obj_ext },
+ );
var build_args = std.ArrayList([]const u8).init(allocator);
defer build_args.deinit();
const name_plus_h_ext = try std.fmt.allocPrint(allocator, "{}.h", code.name);
- const output_h_file_name = try os.path.join(allocator, [][]const u8{ tmp_dir_name, name_plus_h_ext });
+ const output_h_file_name = try os.path.join(
+ allocator,
+ [][]const u8{ tmp_dir_name, name_plus_h_ext },
+ );
try build_args.appendSlice([][]const u8{
zig_exe,
diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig
index 682e10c361..edcb9dc579 100644
--- a/src-self-hosted/libc_installation.zig
+++ b/src-self-hosted/libc_installation.zig
@@ -254,7 +254,10 @@ pub const LibCInstallation = struct {
const stream = &std.io.BufferOutStream.init(&result_buf).stream;
try stream.print("{}\\Include\\{}\\ucrt", search.path, search.version);
- const stdlib_path = try std.os.path.join(loop.allocator, [][]const u8{ result_buf.toSliceConst(), "stdlib.h" });
+ const stdlib_path = try std.os.path.join(
+ loop.allocator,
+ [][]const u8{ result_buf.toSliceConst(), "stdlib.h" },
+ );
defer loop.allocator.free(stdlib_path);
if (try fileExists(stdlib_path)) {
@@ -283,7 +286,10 @@ pub const LibCInstallation = struct {
builtin.Arch.aarch64v8 => try stream.write("arm"),
else => return error.UnsupportedArchitecture,
}
- const ucrt_lib_path = try std.os.path.join(loop.allocator, [][]const u8{ result_buf.toSliceConst(), "ucrt.lib" });
+ const ucrt_lib_path = try std.os.path.join(
+ loop.allocator,
+ [][]const u8{ result_buf.toSliceConst(), "ucrt.lib" },
+ );
defer loop.allocator.free(ucrt_lib_path);
if (try fileExists(ucrt_lib_path)) {
self.lib_dir = result_buf.toOwnedSlice();
@@ -358,7 +364,10 @@ pub const LibCInstallation = struct {
builtin.Arch.aarch64v8 => try stream.write("arm\\"),
else => return error.UnsupportedArchitecture,
}
- const kernel32_path = try std.os.path.join(loop.allocator, [][]const u8{ result_buf.toSliceConst(), "kernel32.lib" });
+ const kernel32_path = try std.os.path.join(
+ loop.allocator,
+ [][]const u8{ result_buf.toSliceConst(), "kernel32.lib" },
+ );
defer loop.allocator.free(kernel32_path);
if (try fileExists(kernel32_path)) {
self.kernel32_lib_dir = result_buf.toOwnedSlice();
diff --git a/std/build.zig b/std/build.zig
index 1348396f59..0dbbded802 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -145,8 +145,8 @@ pub const Builder = struct {
pub fn setInstallPrefix(self: *Builder, maybe_prefix: ?[]const u8) void {
self.prefix = maybe_prefix orelse "/usr/local"; // TODO better default
- self.lib_dir = os.path.join(self.allocator, [][]const u8{self.prefix, "lib"}) catch unreachable;
- self.exe_dir = os.path.join(self.allocator, [][]const u8{self.prefix, "bin"}) catch unreachable;
+ self.lib_dir = os.path.join(self.allocator, [][]const u8{ self.prefix, "lib" }) catch unreachable;
+ self.exe_dir = os.path.join(self.allocator, [][]const u8{ self.prefix, "bin" }) catch unreachable;
}
pub fn addExecutable(self: *Builder, name: []const u8, root_src: ?[]const u8) *LibExeObjStep {
@@ -618,7 +618,10 @@ pub const Builder = struct {
///::dest_rel_path is relative to prefix path or it can be an absolute path
pub fn addInstallFile(self: *Builder, src_path: []const u8, dest_rel_path: []const u8) *InstallFileStep {
- const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
+ const full_dest_path = os.path.resolve(
+ self.allocator,
+ [][]const u8{ self.prefix, dest_rel_path },
+ ) catch unreachable;
self.pushInstalledFile(full_dest_path);
const install_step = self.allocator.create(InstallFileStep) catch unreachable;
@@ -653,7 +656,7 @@ pub const Builder = struct {
}
fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
- return os.path.resolve(self.allocator, self.build_root, rel_path) catch unreachable;
+ return os.path.resolve(self.allocator, [][]const u8{ self.build_root, rel_path }) catch unreachable;
}
pub fn fmt(self: *Builder, comptime format: []const u8, args: ...) []u8 {
@@ -676,7 +679,7 @@ pub const Builder = struct {
if (os.path.isAbsolute(name)) {
return name;
}
- const full_path = try os.path.join(self.allocator, [][]const u8{search_prefix, "bin", self.fmt("{}{}", name, exe_extension)});
+ const full_path = try os.path.join(self.allocator, [][]const u8{ search_prefix, "bin", self.fmt("{}{}", name, exe_extension) });
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
@@ -691,7 +694,7 @@ pub const Builder = struct {
}
var it = mem.tokenize(PATH, []u8{os.path.delimiter});
while (it.next()) |path| {
- const full_path = try os.path.join(self.allocator, [][]const u8{path, self.fmt("{}{}", name, exe_extension)});
+ const full_path = try os.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
@@ -705,7 +708,7 @@ pub const Builder = struct {
return name;
}
for (paths) |path| {
- const full_path = try os.path.join(self.allocator, [][]const u8{path, self.fmt("{}{}", name, exe_extension)});
+ const full_path = try os.path.join(self.allocator, [][]const u8{ path, self.fmt("{}{}", name, exe_extension) });
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
@@ -1113,7 +1116,10 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputPath(self: *LibExeObjStep) []const u8 {
- return if (self.output_path) |output_path| output_path else os.path.join(self.builder.allocator, [][]const u8{self.builder.cache_root, self.out_filename}) catch unreachable;
+ return if (self.output_path) |output_path| output_path else os.path.join(
+ self.builder.allocator,
+ [][]const u8{ self.builder.cache_root, self.out_filename },
+ ) catch unreachable;
}
pub fn setOutputHPath(self: *LibExeObjStep, file_path: []const u8) void {
@@ -1126,7 +1132,10 @@ pub const LibExeObjStep = struct {
}
pub fn getOutputHPath(self: *LibExeObjStep) []const u8 {
- return if (self.output_h_path) |output_h_path| output_h_path else os.path.join(self.builder.allocator, [][]const u8{self.builder.cache_root, self.out_h_filename}) catch unreachable;
+ return if (self.output_h_path) |output_h_path| output_h_path else os.path.join(
+ self.builder.allocator,
+ [][]const u8{ self.builder.cache_root, self.out_h_filename },
+ ) catch unreachable;
}
pub fn addAssemblyFile(self: *LibExeObjStep, path: []const u8) void {
@@ -1226,7 +1235,10 @@ pub const LibExeObjStep = struct {
}
if (self.build_options_contents.len() > 0) {
- const build_options_file = try os.path.join(builder.allocator, [][]const u8{builder.cache_root, builder.fmt("{}_build_options.zig", self.name)});
+ const build_options_file = try os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", self.name) },
+ );
try std.io.writeFile(build_options_file, self.build_options_contents.toSliceConst());
try zig_args.append("--pkg-begin");
try zig_args.append("build_options");
@@ -1476,7 +1488,10 @@ pub const LibExeObjStep = struct {
cc_args.append("-c") catch unreachable;
cc_args.append(abs_source_file) catch unreachable;
- const cache_o_src = os.path.join(builder.allocator, [][]const u8{builder.cache_root, source_file}) catch unreachable;
+ const cache_o_src = os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.cache_root, source_file },
+ ) catch unreachable;
if (os.path.dirname(cache_o_src)) |cache_o_dir| {
try builder.makePath(cache_o_dir);
}
@@ -1528,7 +1543,10 @@ pub const LibExeObjStep = struct {
cc_args.append("-current_version") catch unreachable;
cc_args.append(builder.fmt("{}.{}.{}", self.version.major, self.version.minor, self.version.patch)) catch unreachable;
- const install_name = builder.pathFromRoot(os.path.join(builder.allocator, [][]const u8{builder.cache_root, self.major_only_filename}) catch unreachable);
+ const install_name = builder.pathFromRoot(os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.cache_root, self.major_only_filename },
+ ) catch unreachable);
cc_args.append("-install_name") catch unreachable;
cc_args.append(install_name) catch unreachable;
} else {
@@ -1594,7 +1612,10 @@ pub const LibExeObjStep = struct {
cc_args.append("-c") catch unreachable;
cc_args.append(abs_source_file) catch unreachable;
- const cache_o_src = os.path.join(builder.allocator, [][]const u8{builder.cache_root, source_file}) catch unreachable;
+ const cache_o_src = os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.cache_root, source_file },
+ ) catch unreachable;
if (os.path.dirname(cache_o_src)) |cache_o_dir| {
try builder.makePath(cache_o_dir);
}
@@ -1757,7 +1778,10 @@ pub const TestStep = struct {
return output_path;
} else {
const basename = self.builder.fmt("test{}", self.target.exeFileExt());
- return os.path.join(self.builder.allocator, [][]const u8{self.builder.cache_root, basename}) catch unreachable;
+ return os.path.join(
+ self.builder.allocator,
+ [][]const u8{ self.builder.cache_root, basename },
+ ) catch unreachable;
}
}
@@ -1979,13 +2003,22 @@ const InstallArtifactStep = struct {
.builder = builder,
.step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
.artifact = artifact,
- .dest_file = os.path.join(builder.allocator, dest_dir, artifact.out_filename) catch unreachable,
- }) catch unreachable;
+ .dest_file = os.path.join(
+ builder.allocator,
+ [][]const u8{ dest_dir, artifact.out_filename },
+ ) catch unreachable,
+ };
self.step.dependOn(&artifact.step);
builder.pushInstalledFile(self.dest_file);
if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
- builder.pushInstalledFile(os.path.join(builder.allocator, [][]const u8{builder.lib_dir, artifact.major_only_filename}) catch unreachable);
- builder.pushInstalledFile(os.path.join(builder.allocator, [][]const u8{builder.lib_dir, artifact.name_only_filename}) catch unreachable);
+ builder.pushInstalledFile(os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.lib_dir, artifact.major_only_filename },
+ ) catch unreachable);
+ builder.pushInstalledFile(os.path.join(
+ builder.allocator,
+ [][]const u8{ builder.lib_dir, artifact.name_only_filename },
+ ) catch unreachable);
}
return self;
}
@@ -2141,13 +2174,19 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
const out_dir = os.path.dirname(output_path) orelse ".";
const out_basename = os.path.basename(output_path);
// sym link for libfoo.so.1 to libfoo.so.1.2.3
- const major_only_path = os.path.join(allocator, [][]const u8{out_dir, filename_major_only}) catch unreachable;
+ const major_only_path = os.path.join(
+ allocator,
+ [][]const u8{ out_dir, filename_major_only },
+ ) catch unreachable;
os.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", major_only_path, out_basename);
return err;
};
// sym link for libfoo.so to libfoo.so.1
- const name_only_path = os.path.join(allocator, [][]const u8{out_dir, filename_name_only}) catch unreachable;
+ const name_only_path = os.path.join(
+ allocator,
+ [][]const u8{ out_dir, filename_name_only },
+ ) catch unreachable;
os.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only);
return err;
diff --git a/std/debug/index.zig b/std/debug/index.zig
index 0253912d37..a1e2747df5 100644
--- a/std/debug/index.zig
+++ b/std/debug/index.zig
@@ -774,7 +774,7 @@ fn openSelfDebugInfoWindows(allocator: *mem.Allocator) !DebugInfo {
const len = try di.coff.getPdbPath(path_buf[0..]);
const raw_path = path_buf[0..len];
- const path = try os.path.resolve(allocator, raw_path);
+ const path = try os.path.resolve(allocator, [][]const u8{raw_path});
try di.pdb.openFile(di.coff, path);
@@ -1352,7 +1352,7 @@ const LineNumberProgram = struct {
return error.InvalidDebugInfo;
} else
self.include_dirs[file_entry.dir_index];
- const file_name = try os.path.join(self.file_entries.allocator, [][]const u8{dir_name, file_entry.file_name});
+ const file_name = try os.path.join(self.file_entries.allocator, [][]const u8{ dir_name, file_entry.file_name });
errdefer self.file_entries.allocator.free(file_name);
return LineInfo{
.line = if (self.prev_line >= 0) @intCast(usize, self.prev_line) else 0,
diff --git a/std/event/fs.zig b/std/event/fs.zig
index 97a79bed39..fd0fe434cb 100644
--- a/std/event/fs.zig
+++ b/std/event/fs.zig
@@ -871,7 +871,7 @@ pub fn Watch(comptime V: type) type {
}
async fn addFileKEvent(self: *Self, file_path: []const u8, value: V) !?V {
- const resolved_path = try os.path.resolve(self.channel.loop.allocator, file_path);
+ const resolved_path = try os.path.resolve(self.channel.loop.allocator, [][]const u8{file_path});
var resolved_path_consumed = false;
defer if (!resolved_path_consumed) self.channel.loop.allocator.free(resolved_path);
@@ -1336,7 +1336,7 @@ async fn testFsWatchCantFail(loop: *Loop, result: *(anyerror!void)) void {
}
async fn testFsWatch(loop: *Loop) !void {
- const file_path = try os.path.join(loop.allocator, [][]const u8{test_tmp_dir, "file.txt"});
+ const file_path = try os.path.join(loop.allocator, [][]const u8{ test_tmp_dir, "file.txt" });
defer loop.allocator.free(file_path);
const contents =
diff --git a/std/mem.zig b/std/mem.zig
index 178a5f6c6f..48d1cb930c 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -882,42 +882,37 @@ pub const SplitIterator = struct {
}
};
-/// Naively combines a series of strings with a separator.
+/// Naively combines a series of slices with a separator.
/// Allocates memory for the result, which must be freed by the caller.
-pub fn join(allocator: *Allocator, sep: u8, strings: ...) ![]u8 {
- comptime assert(strings.len >= 1);
- var total_strings_len: usize = strings.len; // 1 sep per string
- {
- comptime var string_i = 0;
- inline while (string_i < strings.len) : (string_i += 1) {
- const arg = ([]const u8)(strings[string_i]);
- total_strings_len += arg.len;
- }
- }
+pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {
+ if (slices.len == 0) return (([*]u8)(undefined))[0..0];
- const buf = try allocator.alloc(u8, total_strings_len);
+ const total_len = blk: {
+ var sum: usize = separator.len * (slices.len - 1);
+ for (slices) |slice|
+ sum += slice.len;
+ break :blk sum;
+ };
+
+ const buf = try allocator.alloc(u8, total_len);
errdefer allocator.free(buf);
- var buf_index: usize = 0;
- comptime var string_i = 0;
- inline while (true) {
- const arg = ([]const u8)(strings[string_i]);
- string_i += 1;
- copy(u8, buf[buf_index..], arg);
- buf_index += arg.len;
- if (string_i >= strings.len) break;
- if (buf[buf_index - 1] != sep) {
- buf[buf_index] = sep;
- buf_index += 1;
- }
+ copy(u8, buf, slices[0]);
+ var buf_index: usize = slices[0].len;
+ for (slices[1..]) |slice| {
+ copy(u8, buf[buf_index..], separator);
+ buf_index += separator.len;
+ copy(u8, buf[buf_index..], slice);
+ buf_index += slice.len;
}
- return allocator.shrink(u8, buf, buf_index);
+ // No need for shrink since buf is exactly the correct size.
+ return buf;
}
test "mem.join" {
- assert(eql(u8, try join(debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
- assert(eql(u8, try join(debug.global_allocator, ',', "a"), "a"));
+ assert(eql(u8, try join(debug.global_allocator, ",", [][]const u8{ "a", "b", "c" }), "a,b,c"));
+ assert(eql(u8, try join(debug.global_allocator, ",", [][]const u8{"a"}), "a"));
}
test "testStringEquality" {
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 2651310c98..6635b76976 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -574,7 +574,7 @@ pub const ChildProcess = struct {
// to match posix semantics
const app_name = x: {
if (self.cwd) |cwd| {
- const resolved = try os.path.resolve(self.allocator, cwd, self.argv[0]);
+ const resolved = try os.path.resolve(self.allocator, [][]const u8{ cwd, self.argv[0] });
defer self.allocator.free(resolved);
break :x try cstr.addNullByte(self.allocator, resolved);
} else {
diff --git a/std/os/get_app_data_dir.zig b/std/os/get_app_data_dir.zig
index a0315b4511..f5e0b78eec 100644
--- a/std/os/get_app_data_dir.zig
+++ b/std/os/get_app_data_dir.zig
@@ -30,7 +30,7 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
error.OutOfMemory => return error.OutOfMemory,
};
defer allocator.free(global_dir);
- return os.path.join(allocator, [][]const u8{global_dir, appname});
+ return os.path.join(allocator, [][]const u8{ global_dir, appname });
},
os.windows.E_OUTOFMEMORY => return error.OutOfMemory,
else => return error.AppDataDirUnavailable,
@@ -41,14 +41,14 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
// TODO look in /etc/passwd
return error.AppDataDirUnavailable;
};
- return os.path.join(allocator, [][]const u8{home_dir, "Library", "Application Support", appname});
+ return os.path.join(allocator, [][]const u8{ home_dir, "Library", "Application Support", appname });
},
builtin.Os.linux, builtin.Os.freebsd => {
const home_dir = os.getEnvPosix("HOME") orelse {
// TODO look in /etc/passwd
return error.AppDataDirUnavailable;
};
- return os.path.join(allocator, [][]const u8{home_dir, ".local", "share", appname});
+ return os.path.join(allocator, [][]const u8{ home_dir, ".local", "share", appname });
},
else => @compileError("Unsupported OS"),
}
@@ -67,4 +67,3 @@ test "std.os.getAppDataDir" {
// We can't actually validate the result
_ = getAppDataDir(allocator, "zig") catch return;
}
-
diff --git a/std/os/index.zig b/std/os/index.zig
index d17b6f4f40..8e9876c36b 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -1284,7 +1284,7 @@ pub fn makeDirPosix(dir_path: []const u8) !void {
/// already exists and is a directory.
/// TODO determine if we can remove the allocator requirement from this function
pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {
- const resolved_path = try path.resolve(allocator, full_path);
+ const resolved_path = try path.resolve(allocator, [][]const u8{full_path});
defer allocator.free(resolved_path);
var end_index: usize = resolved_path.len;
@@ -2304,18 +2304,17 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
switch (builtin.os) {
Os.linux => return readLink(out_buffer, "/proc/self/exe"),
Os.freebsd => {
- var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1};
+ var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1 };
var out_len: usize = out_buffer.len;
const err = posix.getErrno(posix.sysctl(&mib, 4, out_buffer, &out_len, null, 0));
- if (err == 0 ) return mem.toSlice(u8, out_buffer);
+ if (err == 0) return mem.toSlice(u8, out_buffer);
return switch (err) {
posix.EFAULT => error.BadAdress,
posix.EPERM => error.PermissionDenied,
else => unexpectedErrorPosix(err),
};
-
},
Os.windows => {
var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined;
diff --git a/std/os/path.zig b/std/os/path.zig
index 5a5b1b7772..266a77b97c 100644
--- a/std/os/path.zig
+++ b/std/os/path.zig
@@ -33,63 +33,103 @@ pub fn isSep(byte: u8) bool {
}
}
-/// Naively combines a series of paths with the native path seperator.
-/// Allocates memory for the result, which must be freed by the caller.
+/// This is different from mem.join in that the separator will not be repeated if
+/// it is found at the end or beginning of a pair of consecutive paths.
+fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u8 {
+ if (paths.len == 0) return (([*]u8)(undefined))[0..0];
-pub fn join(allocator: *Allocator, paths: []const []const u8) ![]u8 {
- assert(paths.len >= 1);
- var total_paths_len: usize = paths.len; // 1 sep per path
- {
- var path_i: usize = 0;
- while (path_i < paths.len) : (path_i += 1) {
- const arg = ([]const u8)(paths[path_i]);
- total_paths_len += arg.len;
+ const total_len = blk: {
+ var sum: usize = paths[0].len;
+ var i: usize = 1;
+ while (i < paths.len) : (i += 1) {
+ const prev_path = paths[i - 1];
+ const this_path = paths[i];
+ const prev_sep = (prev_path.len != 0 and prev_path[prev_path.len - 1] == separator);
+ const this_sep = (this_path.len != 0 and this_path[0] == separator);
+ sum += @boolToInt(!prev_sep and !this_sep);
+ sum += if (prev_sep and this_sep) this_path.len - 1 else this_path.len;
}
- }
+ break :blk sum;
+ };
- const buf = try allocator.alloc(u8, total_paths_len);
+ const buf = try allocator.alloc(u8, total_len);
errdefer allocator.free(buf);
- var buf_index: usize = 0;
- var path_i: usize = 0;
- while (true) {
- const arg = ([]const u8)(paths[path_i]);
- path_i += 1;
- mem.copy(u8, buf[buf_index..], arg);
- buf_index += arg.len;
- if (path_i >= paths.len) break;
- if (buf_index > 0 and buf[buf_index - 1] != sep) {
- buf[buf_index] = sep;
+ mem.copy(u8, buf, paths[0]);
+ var buf_index: usize = paths[0].len;
+ var i: usize = 1;
+ while (i < paths.len) : (i += 1) {
+ const prev_path = paths[i - 1];
+ const this_path = paths[i];
+ const prev_sep = (prev_path.len != 0 and prev_path[prev_path.len - 1] == separator);
+ const this_sep = (this_path.len != 0 and this_path[0] == separator);
+ if (!prev_sep and !this_sep) {
+ buf[buf_index] = separator;
buf_index += 1;
}
+ const adjusted_path = if (prev_sep and this_sep) this_path[1..] else this_path;
+ mem.copy(u8, buf[buf_index..], adjusted_path);
+ buf_index += adjusted_path.len;
}
- return allocator.shrink(u8, buf, buf_index);
+ // No need for shrink since buf is exactly the correct size.
+ return buf;
+}
+
+pub const join = if (is_windows) joinWindows else joinPosix;
+
+/// Naively combines a series of paths with the native path seperator.
+/// Allocates memory for the result, which must be freed by the caller.
+pub fn joinWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
+ return joinSep(allocator, sep_windows, paths);
+}
+
+/// Naively combines a series of paths with the native path seperator.
+/// Allocates memory for the result, which must be freed by the caller.
+pub fn joinPosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
+ return joinSep(allocator, sep_posix, paths);
+}
+
+fn testJoinWindows(paths: []const []const u8, expected: []const u8) void {
+ var buf: [1024]u8 = undefined;
+ const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
+ const actual = joinWindows(a, paths) catch @panic("fail");
+ debug.assertOrPanic(mem.eql(u8, actual, expected));
+}
+
+fn testJoinPosix(paths: []const []const u8, expected: []const u8) void {
+ var buf: [1024]u8 = undefined;
+ const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
+ const actual = joinPosix(a, paths) catch @panic("fail");
+ debug.assertOrPanic(mem.eql(u8, actual, expected));
}
test "os.path.join" {
- switch (builtin.os) {
- Os.windows => {
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"c:\\a\\b", "c"}), "c:\\a\\b\\c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"c:\\a\\b\\", "c"}), "c:\\a\\b\\c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"c:\\", "a", "b\\", "c"}), "c:\\a\\b\\c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"c:\\a\\", "b\\", "c"}), "c:\\a\\b\\c"));
- assert(mem.eql(u8, try join( debug.global_allocator
- , [][]const u8{ "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std"
- , "io.zig"})
- , "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig"));
- },
- else => {
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"/a/b", "c"}), "/a/b/c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"/a/b/", "c"}), "/a/b/c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"/", "a", "b/", "c"}), "/a/b/c"));
- assert(mem.eql(u8, try join(debug.global_allocator, [][]const u8{"/a/", "b/", "c"}), "/a/b/c"));
- assert(mem.eql(u8, try join( debug.global_allocator
- , [][]const u8{ "/home/andy/dev/zig/build/lib/zig/std"
- , "io.zig"})
- , "/home/andy/dev/zig/build/lib/zig/std/io.zig"));
- }
- }
+ testJoinWindows([][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c");
+ testJoinWindows([][]const u8{ "c:\\a\\b", "c" }, "c:\\a\\b\\c");
+ testJoinWindows([][]const u8{ "c:\\a\\b\\", "c" }, "c:\\a\\b\\c");
+
+ testJoinWindows([][]const u8{ "c:\\", "a", "b\\", "c" }, "c:\\a\\b\\c");
+ testJoinWindows([][]const u8{ "c:\\a\\", "b\\", "c" }, "c:\\a\\b\\c");
+
+ testJoinWindows(
+ [][]const u8{ "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig" },
+ "c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig",
+ );
+
+ testJoinPosix([][]const u8{ "/a/b", "c" }, "/a/b/c");
+ testJoinPosix([][]const u8{ "/a/b/", "c" }, "/a/b/c");
+
+ testJoinPosix([][]const u8{ "/", "a", "b/", "c" }, "/a/b/c");
+ testJoinPosix([][]const u8{ "/a/", "b/", "c" }, "/a/b/c");
+
+ testJoinPosix(
+ [][]const u8{ "/home/andy/dev/zig/build/lib/zig/std", "io.zig" },
+ "/home/andy/dev/zig/build/lib/zig/std/io.zig",
+ );
+
+ testJoinPosix([][]const u8{ "a", "/c" }, "a/c");
+ testJoinPosix([][]const u8{ "a/", "/c" }, "a/c");
}
pub fn isAbsolute(path: []const u8) bool {
@@ -335,18 +375,8 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
return true;
}
-/// Converts the command line arguments into a slice and calls `resolveSlice`.
-pub fn resolve(allocator: *Allocator, args: ...) ![]u8 {
- var paths: [args.len][]const u8 = undefined;
- comptime var arg_i = 0;
- inline while (arg_i < args.len) : (arg_i += 1) {
- paths[arg_i] = args[arg_i];
- }
- return resolveSlice(allocator, paths);
-}
-
/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
-pub fn resolveSlice(allocator: *Allocator, paths: []const []const u8) ![]u8 {
+pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (is_windows) {
return resolveWindows(allocator, paths);
} else {
@@ -625,7 +655,10 @@ test "os.path.resolveWindows" {
const parsed_cwd = windowsParsePath(cwd);
{
const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
- const expected = try join(debug.global_allocator, [][]const u8{ parsed_cwd.disk_designator, "usr\\local\\lib\\zig\\std\\array_list.zig"});
+ const expected = try join(debug.global_allocator, [][]const u8{
+ parsed_cwd.disk_designator,
+ "usr\\local\\lib\\zig\\std\\array_list.zig",
+ });
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
@@ -633,7 +666,10 @@ test "os.path.resolveWindows" {
}
{
const result = testResolveWindows([][]const u8{ "usr/local", "lib\\zig" });
- const expected = try join(debug.global_allocator, [][]const u8{ cwd, "usr\\local\\lib\\zig" });
+ const expected = try join(debug.global_allocator, [][]const u8{
+ cwd,
+ "usr\\local\\lib\\zig",
+ });
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
diff --git a/test/cli.zig b/test/cli.zig
index 0980e8c2d8..745da4dd80 100644
--- a/test/cli.zig
+++ b/test/cli.zig
@@ -27,7 +27,7 @@ pub fn main() !void {
std.debug.warn("Expected second argument to be cache root directory path\n");
return error.InvalidArgs;
});
- const zig_exe = try os.path.resolve(a, zig_exe_rel);
+ const zig_exe = try os.path.resolve(a, [][]const u8{zig_exe_rel});
const dir_path = try os.path.join(a, [][]const u8{ cache_root, "clitest" });
const TestFn = fn ([]const u8, []const u8) anyerror!void;
diff --git a/test/tests.zig b/test/tests.zig
index fac941cbde..670c410509 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -439,7 +439,10 @@ pub const CompareOutputContext = struct {
pub fn addCase(self: *CompareOutputContext, case: TestCase) void {
const b = self.b;
- const root_src = os.path.join(b.allocator, [][]const u8{b.cache_root, case.sources.items[0].filename}) catch unreachable;
+ const root_src = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, case.sources.items[0].filename },
+ ) catch unreachable;
switch (case.special) {
Special.Asm => {
@@ -452,7 +455,10 @@ pub const CompareOutputContext = struct {
exe.addAssemblyFile(root_src);
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
exe.step.dependOn(&write_src.step);
}
@@ -476,7 +482,10 @@ pub const CompareOutputContext = struct {
}
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
exe.step.dependOn(&write_src.step);
}
@@ -499,7 +508,10 @@ pub const CompareOutputContext = struct {
}
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
exe.step.dependOn(&write_src.step);
}
@@ -572,8 +584,14 @@ pub const CompileErrorContext = struct {
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
const b = self.context.b;
- const root_src = os.path.join(b.allocator, [][]const u8{b.cache_root, self.case.sources.items[0].filename}) catch unreachable;
- const obj_path = os.path.join(b.allocator, [][]const u8{b.cache_root, "test.o"}) catch unreachable;
+ const root_src = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, self.case.sources.items[0].filename },
+ ) catch unreachable;
+ const obj_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, "test.o" },
+ ) catch unreachable;
var zig_args = ArrayList([]const u8).init(b.allocator);
zig_args.append(b.zig_exe) catch unreachable;
@@ -721,7 +739,10 @@ pub const CompileErrorContext = struct {
self.step.dependOn(&compile_and_cmp_errors.step);
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
compile_and_cmp_errors.step.dependOn(&write_src.step);
}
@@ -852,7 +873,10 @@ pub const TranslateCContext = struct {
const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
const b = self.context.b;
- const root_src = os.path.join(b.allocator, [][]const u8{b.cache_root, self.case.sources.items[0].filename}) catch unreachable;
+ const root_src = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, self.case.sources.items[0].filename },
+ ) catch unreachable;
var zig_args = ArrayList([]const u8).init(b.allocator);
zig_args.append(b.zig_exe) catch unreachable;
@@ -986,7 +1010,10 @@ pub const TranslateCContext = struct {
self.step.dependOn(&translate_c_and_cmp.step);
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
translate_c_and_cmp.step.dependOn(&write_src.step);
}
@@ -1101,7 +1128,10 @@ pub const GenHContext = struct {
pub fn addCase(self: *GenHContext, case: *const TestCase) void {
const b = self.b;
- const root_src = os.path.join(b.allocator, [][]const u8{b.cache_root, case.sources.items[0].filename}) catch unreachable;
+ const root_src = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, case.sources.items[0].filename },
+ ) catch unreachable;
const mode = builtin.Mode.Debug;
const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;
@@ -1113,7 +1143,10 @@ pub const GenHContext = struct {
obj.setBuildMode(mode);
for (case.sources.toSliceConst()) |src_file| {
- const expanded_src_path = os.path.join(b.allocator, [][]const u8{b.cache_root, src_file.filename}) catch unreachable;
+ const expanded_src_path = os.path.join(
+ b.allocator,
+ [][]const u8{ b.cache_root, src_file.filename },
+ ) catch unreachable;
const write_src = b.addWriteFile(expanded_src_path, src_file.source);
obj.step.dependOn(&write_src.step);
}
From 38a77161949dbae036d4172ceba2f698de9f18a1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Feb 2019 10:55:23 -0500
Subject: [PATCH 148/218] fixups
---
std/mem.zig | 105 ++++++++++++++++++----------------------------------
1 file changed, 35 insertions(+), 70 deletions(-)
diff --git a/std/mem.zig b/std/mem.zig
index aac07ece7d..a6cbae744f 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -856,65 +856,31 @@ pub const TokenIterator = struct {
}
};
-/// Naively combines a series of strings with a separator.
-/// Allocates memory for the result, which must be freed by the caller.
-pub fn join(allocator: *Allocator, sep: u8, strings: []const []const u8) ![]u8 {
- assert(strings.len >= 1);
- var total_strings_len: usize = strings.len; // 1 sep per string
- {
- var string_i: usize = 0;
- while (string_i < strings.len) : (string_i += 1) {
- const arg = ([]const u8)(strings[string_i]);
- total_strings_len += arg.len;
- }
+pub const SplitIterator = struct {
+ buffer: []const u8,
+ index: ?usize,
+ delimiter: []const u8,
+
+ /// Returns a slice of the next field, or null if splitting is complete.
+ pub fn next(self: *SplitIterator) ?[]const u8 {
+ const start = self.index orelse return null;
+ const end = if (indexOfPos(u8, self.buffer, start, self.delimiter)) |delim_start| blk: {
+ self.index = delim_start + self.delimiter.len;
+ break :blk delim_start;
+ } else blk: {
+ self.index = null;
+ break :blk self.buffer.len;
+ };
+ return self.buffer[start..end];
}
- const buf = try allocator.alloc(u8, total_strings_len);
- errdefer allocator.free(buf);
-
- var buf_index: usize = 0;
- var string_i: usize = 0;
- while (true) {
- const arg = ([]const u8)(strings[string_i]);
- string_i += 1;
- copy(u8, buf[buf_index..], arg);
- buf_index += arg.len;
- if (string_i >= strings.len) break;
- buf[buf_index] = sep;
- buf_index += 1;
+ /// Returns a slice of the remaining bytes. Does not affect iterator state.
+ pub fn rest(self: SplitIterator) []const u8 {
+ const end = self.buffer.len;
+ const start = self.index orelse end;
+ return self.buffer[start..end];
}
-
- return allocator.shrink(u8, buf, buf_index);
-}
-
-test "mem.join" {
- var str: []u8 = try join(debug.global_allocator, ',', [][]const u8{ "a", "b", "c" });
- errdefer debug.global_allocator.free(str);
- assert(eql(u8, str, "a,b,c"));
- debug.global_allocator.free(str);
-
- str = try join(debug.global_allocator, ',', [][]const u8{"a"});
- assert(eql(u8, str, "a"));
- debug.global_allocator.free(str);
-
- str = try join(debug.global_allocator, ',', [][]const u8{ "a", ([]const u8)(""), "b", ([]const u8)(""), "c" });
- assert(eql(u8, str, "a,,b,,c"));
- debug.global_allocator.free(str);
-}
-
-/// Naively combines a series of strings with a separator inline.
-/// Allocates memory for the result, which must be freed by the caller.
-pub fn joinInline(allocator: *Allocator, sep: u8, strings: ...) ![]u8 {
- comptime assert(strings.len >= 1);
- var total_strings_len: usize = strings.len; // 1 sep per string
- {
- comptime var string_i = 0;
- inline while (string_i < strings.len) : (string_i += 1) {
- const arg = ([]const u8)(strings[string_i]);
- total_strings_len += arg.len;
- }
- }
-}
+};
/// Naively combines a series of slices with a separator.
/// Allocates memory for the result, which must be freed by the caller.
@@ -931,26 +897,25 @@ pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []cons
const buf = try allocator.alloc(u8, total_len);
errdefer allocator.free(buf);
- var buf_index: usize = 0;
- comptime var string_i = 0;
- inline while (true) {
- const arg = ([]const u8)(strings[string_i]);
- string_i += 1;
- copy(u8, buf[buf_index..], arg);
- buf_index += arg.len;
- if (string_i >= strings.len) break;
- buf[buf_index] = sep;
- buf_index += 1;
+ copy(u8, buf, slices[0]);
+ var buf_index: usize = slices[0].len;
+ for (slices[1..]) |slice| {
+ copy(u8, buf[buf_index..], separator);
+ buf_index += separator.len;
+ copy(u8, buf[buf_index..], slice);
+ buf_index += slice.len;
}
// No need for shrink since buf is exactly the correct size.
return buf;
}
-test "mem.joinInline" {
- assert(eql(u8, try joinInline(debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
- assert(eql(u8, try joinInline(debug.global_allocator, ',', "a", "b", ([]const u8)(""), "c"), "a,b,,c"));
- assert(eql(u8, try joinInline(debug.global_allocator, ',', "a"), "a"));
+test "mem.join" {
+ var buf: [1024]u8 = undefined;
+ const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
+ assert(eql(u8, try join(a, ",", [][]const u8{ "a", "b", "c" }), "a,b,c"));
+ assert(eql(u8, try join(a, ",", [][]const u8{"a"}), "a"));
+ assert(eql(u8, try join(a, ",", [][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c"));
}
test "testStringEquality" {
From 2b2bf53a49616192e2b2bdf40b88400964ff1500 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Feb 2019 11:40:56 -0500
Subject: [PATCH 149/218] better error message when LLVM does not understand a
triple
---
src/codegen.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index c5de05e372..f010430e14 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -7553,7 +7553,13 @@ static void init(CodeGen *g) {
LLVMTargetRef target_ref;
char *err_msg = nullptr;
if (LLVMGetTargetFromTriple(buf_ptr(&g->triple_str), &target_ref, &err_msg)) {
- zig_panic("unable to create target based on: %s", buf_ptr(&g->triple_str));
+ fprintf(stderr,
+ "Zig is expecting LLVM to understand this target: '%s'\n"
+ "However LLVM responded with: \"%s\"\n"
+ "Zig is unable to continue. This is a bug in Zig:\n"
+ "https://github.com/ziglang/zig/issues/438\n"
+ , buf_ptr(&g->triple_str), err_msg);
+ exit(1);
}
bool is_optimized = g->build_mode != BuildModeDebug;
From 7843c96df87007561c107d11afa2fa74b46667fd Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Feb 2019 12:18:01 -0500
Subject: [PATCH 150/218] build: make sure LLVM is exactly correct
* check the version to be the correct major version
* ensure that it has all the default targets enabled
---
cmake/Findllvm.cmake | 40 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/cmake/Findllvm.cmake b/cmake/Findllvm.cmake
index 70d50f9843..2f0afa09b7 100644
--- a/cmake/Findllvm.cmake
+++ b/cmake/Findllvm.cmake
@@ -15,14 +15,50 @@ find_program(LLVM_CONFIG_EXE
"c:/msys64/mingw64/bin"
"C:/Libraries/llvm-7.0.0/bin")
+if ("${LLVM_CONFIG_EXE}" STREQUAL "LLVM_CONFIG_EXE-NOTFOUND")
+ message(FATAL_ERROR "unable to find llvm-config")
+endif()
+
execute_process(
COMMAND ${LLVM_CONFIG_EXE} --version
OUTPUT_VARIABLE LLVM_CONFIG_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
-if(LLVM_CONFIG_VERSION VERSION_LESS 7)
- message(FATAL_ERROR "expected LLVM version >=7 but found ${LLVM_CONFIG_VERSION}")
+if("${LLVM_CONFIG_VERSION}" VERSION_LESS 7)
+ message(FATAL_ERROR "expected LLVM 7.x but found ${LLVM_CONFIG_VERSION}")
endif()
+if("${LLVM_CONFIG_VERSION}" VERSION_EQUAL 8)
+ message(FATAL_ERROR "expected LLVM 7.x but found ${LLVM_CONFIG_VERSION}")
+endif()
+if("${LLVM_CONFIG_VERSION}" VERSION_GREATER 8)
+ message(FATAL_ERROR "expected LLVM 7.x but found ${LLVM_CONFIG_VERSION}")
+endif()
+
+execute_process(
+ COMMAND ${LLVM_CONFIG_EXE} --targets-built
+ OUTPUT_VARIABLE LLVM_TARGETS_BUILT_SPACES
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+string(REPLACE " " ";" LLVM_TARGETS_BUILT "${LLVM_TARGETS_BUILT_SPACES}")
+function(NEED_TARGET TARGET_NAME)
+ list (FIND LLVM_TARGETS_BUILT "${TARGET_NAME}" _index)
+ if (${_index} EQUAL -1)
+ message(FATAL_ERROR "LLVM is missing target ${TARGET_NAME}. Zig requires LLVM to be built with all default targets enabled.")
+ endif()
+endfunction(NEED_TARGET)
+NEED_TARGET("AArch64")
+NEED_TARGET("AMDGPU")
+NEED_TARGET("ARM")
+NEED_TARGET("BPF")
+NEED_TARGET("Hexagon")
+NEED_TARGET("Lanai")
+NEED_TARGET("Mips")
+NEED_TARGET("MSP430")
+NEED_TARGET("NVPTX")
+NEED_TARGET("PowerPC")
+NEED_TARGET("Sparc")
+NEED_TARGET("SystemZ")
+NEED_TARGET("X86")
+NEED_TARGET("XCore")
if(NOT(CMAKE_BUILD_TYPE STREQUAL "Debug") OR ZIG_STATIC)
execute_process(
From f330eebe4bc6a036846cf05706f72855627c705a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 7 Feb 2019 16:02:45 -0500
Subject: [PATCH 151/218] fix using the result of @intCast to u0
closes #1817
---
src/all_types.hpp | 7 ++++++
src/codegen.cpp | 40 +++++++++++++++++++++++++----------
src/ir.cpp | 31 +++++++++++++++++++++++++++
src/ir_print.cpp | 9 ++++++++
test/runtime_safety.zig | 17 +++++++++++++++
test/stage1/behavior/cast.zig | 11 ++++++++++
test/stage1/behavior/eval.zig | 6 ------
7 files changed, 104 insertions(+), 17 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 5af4e71157..842c9ae904 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -2239,6 +2239,7 @@ enum IrInstructionId {
IrInstructionIdCheckRuntimeScope,
IrInstructionIdVectorToArray,
IrInstructionIdArrayToVector,
+ IrInstructionIdAssertZero,
};
struct IrInstruction {
@@ -3381,6 +3382,12 @@ struct IrInstructionVectorToArray {
LLVMValueRef tmp_ptr;
};
+struct IrInstructionAssertZero {
+ IrInstruction base;
+
+ IrInstruction *target;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index f010430e14..3bfd7cdfc5 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1651,10 +1651,25 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
+static LLVMValueRef gen_assert_zero(CodeGen *g, LLVMValueRef expr_val, ZigType *int_type) {
+ LLVMValueRef zero = LLVMConstNull(int_type->type_ref);
+ LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, zero, "");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk");
+ LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail");
+ LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, fail_block);
+ gen_safety_crash(g, PanicMsgIdCastTruncatedData);
+
+ LLVMPositionBuilderAtEnd(g->builder, ok_block);
+ return nullptr;
+}
+
static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, ZigType *actual_type,
ZigType *wanted_type, LLVMValueRef expr_val)
{
assert(actual_type->id == wanted_type->id);
+ assert(expr_val != nullptr);
uint64_t actual_bits;
uint64_t wanted_bits;
@@ -1707,17 +1722,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
if (!want_runtime_safety)
return nullptr;
- LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
- LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, zero, "");
- LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk");
- LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail");
- LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
-
- LLVMPositionBuilderAtEnd(g->builder, fail_block);
- gen_safety_crash(g, PanicMsgIdCastTruncatedData);
-
- LLVMPositionBuilderAtEnd(g->builder, ok_block);
- return nullptr;
+ return gen_assert_zero(g, expr_val, actual_type);
}
LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
if (!want_runtime_safety) {
@@ -5209,6 +5214,17 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executab
return gen_load_untyped(g, casted_ptr, 0, false, "");
}
+static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable,
+ IrInstructionAssertZero *instruction)
+{
+ LLVMValueRef target = ir_llvm_value(g, instruction->target);
+ ZigType *int_type = instruction->target->value.type;
+ if (ir_want_runtime_safety(g, &instruction->base)) {
+ return gen_assert_zero(g, target, int_type);
+ }
+ return nullptr;
+}
+
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
@@ -5458,6 +5474,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
case IrInstructionIdVectorToArray:
return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
+ case IrInstructionIdAssertZero:
+ return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);
}
zig_unreachable();
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 02b2b12230..00d358552a 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -908,6 +908,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayToVector *)
return IrInstructionIdArrayToVector;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) {
+ return IrInstructionIdAssertZero;
+}
+
template
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate(1);
@@ -2858,6 +2862,19 @@ static IrInstruction *ir_build_array_to_vector(IrAnalyze *ira, IrInstruction *so
return &instruction->base;
}
+static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source_instruction,
+ IrInstruction *target)
+{
+ IrInstructionAssertZero *instruction = ir_build_instruction(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = ira->codegen->builtin_types.entry_void;
+ instruction->target = target;
+
+ ir_ref_instruction(target, ira->new_irb.current_basic_block);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -10395,6 +10412,18 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction
return result;
}
+ // If the destination integer type has no bits, then we can emit a comptime
+ // zero. However, we still want to emit a runtime safety check to make sure
+ // the target is zero.
+ if (!type_has_bits(wanted_type)) {
+ assert(wanted_type->id == ZigTypeIdInt);
+ assert(type_has_bits(target->value.type));
+ ir_build_assert_zero(ira, source_instr, target);
+ IrInstruction *result = ir_const_unsigned(ira, source_instr, 0);
+ result->value.type = wanted_type;
+ return result;
+ }
+
IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope,
source_instr->source_node, target);
result->value.type = wanted_type;
@@ -21705,6 +21734,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
case IrInstructionIdCmpxchgGen:
case IrInstructionIdArrayToVector:
case IrInstructionIdVectorToArray:
+ case IrInstructionIdAssertZero:
zig_unreachable();
case IrInstructionIdReturn:
@@ -22103,6 +22133,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdAtomicRmw:
case IrInstructionIdCmpxchgGen:
case IrInstructionIdCmpxchgSrc:
+ case IrInstructionIdAssertZero:
return true;
case IrInstructionIdPhi:
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index e19aa6dda8..75da24d1a9 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -984,6 +984,12 @@ static void ir_print_vector_to_array(IrPrint *irp, IrInstructionVectorToArray *i
fprintf(irp->f, ")");
}
+static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruction) {
+ fprintf(irp->f, "AssertZero(");
+ ir_print_other_instruction(irp, instruction->target);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_int_to_err(IrPrint *irp, IrInstructionIntToErr *instruction) {
fprintf(irp->f, "inttoerr ");
ir_print_other_instruction(irp, instruction->target);
@@ -1843,6 +1849,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdVectorToArray:
ir_print_vector_to_array(irp, (IrInstructionVectorToArray *)instruction);
break;
+ case IrInstructionIdAssertZero:
+ ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
+ break;
}
fprintf(irp->f, "\n");
}
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 7c13f5b6fa..7de43b45f4 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -362,6 +362,23 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}
);
+ // @intCast a runtime integer to u0 actually results in a comptime-known value,
+ // but we still emit a safety check to ensure the integer was 0 and thus
+ // did not truncate information.
+ cases.addRuntimeSafety("@intCast to u0",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\
+ \\pub fn main() void {
+ \\ bar(1, 1);
+ \\}
+ \\
+ \\fn bar(one: u1, not_zero: i32) void {
+ \\ var x = one << @intCast(u0, not_zero);
+ \\}
+ );
+
// This case makes sure that the code compiles and runs. There is not actually a special
// runtime safety check having to do specifically with error return traces across suspend points.
cases.addRuntimeSafety("error return trace across suspend points",
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 61ddcd8135..27f685a96e 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -471,3 +471,14 @@ test "@intToEnum passed a comptime_int to an enum with one item" {
const x = @intToEnum(E, 0);
assertOrPanic(x == E.A);
}
+
+test "@intCast to u0 and use the result" {
+ const S = struct {
+ fn doTheTest(zero: u1, one: u1, bigzero: i32) void {
+ assertOrPanic((one << @intCast(u0, bigzero)) == 1);
+ assertOrPanic((zero << @intCast(u0, bigzero)) == 0);
+ }
+ };
+ S.doTheTest(0, 1, 0);
+ comptime S.doTheTest(0, 1, 0);
+}
diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig
index 3e8af0524f..0d1ecfab5b 100644
--- a/test/stage1/behavior/eval.zig
+++ b/test/stage1/behavior/eval.zig
@@ -697,12 +697,6 @@ test "bit shift a u1" {
assertOrPanic(y == 1);
}
-test "@intCast to a u0" {
- var x: u8 = 0;
- var y: u0 = @intCast(u0, x);
- assertOrPanic(y == 0);
-}
-
test "@bytesToslice on a packed struct" {
const F = packed struct {
a: u8,
From be6d022257d8d7e99bd080823d4d8f0175f320c5 Mon Sep 17 00:00:00 2001
From: John Schmidt
Date: Thu, 7 Feb 2019 21:28:37 +0100
Subject: [PATCH 152/218] Make ThreadSafeFixedBufferAllocator alias
FixedBufferAllocator when --single-threaded
Fixes #1910
---
std/heap.zig | 90 ++++++++++++++++++++++++++++------------------------
1 file changed, 48 insertions(+), 42 deletions(-)
diff --git a/std/heap.zig b/std/heap.zig
index 1403f8e831..8a5ebf134c 100644
--- a/std/heap.zig
+++ b/std/heap.zig
@@ -321,51 +321,57 @@ pub const FixedBufferAllocator = struct {
fn free(allocator: *Allocator, bytes: []u8) void {}
};
-/// lock free
-pub const ThreadSafeFixedBufferAllocator = struct {
- allocator: Allocator,
- end_index: usize,
- buffer: []u8,
+pub const ThreadSafeFixedBufferAllocator = blk: {
+ if (builtin.single_threaded) {
+ break :blk FixedBufferAllocator;
+ } else {
+ /// lock free
+ break :blk struct {
+ allocator: Allocator,
+ end_index: usize,
+ buffer: []u8,
- pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
- return ThreadSafeFixedBufferAllocator{
- .allocator = Allocator{
- .allocFn = alloc,
- .reallocFn = realloc,
- .freeFn = free,
- },
- .buffer = buffer,
- .end_index = 0,
+ pub fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
+ return ThreadSafeFixedBufferAllocator{
+ .allocator = Allocator{
+ .allocFn = alloc,
+ .reallocFn = realloc,
+ .freeFn = free,
+ },
+ .buffer = buffer,
+ .end_index = 0,
+ };
+ }
+
+ fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 {
+ const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);
+ var end_index = @atomicLoad(usize, &self.end_index, builtin.AtomicOrder.SeqCst);
+ while (true) {
+ const addr = @ptrToInt(self.buffer.ptr) + end_index;
+ const rem = @rem(addr, alignment);
+ const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
+ const adjusted_index = end_index + march_forward_bytes;
+ const new_end_index = adjusted_index + n;
+ if (new_end_index > self.buffer.len) {
+ return error.OutOfMemory;
+ }
+ end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
+ }
+ }
+
+ fn realloc(allocator: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
+ if (new_size <= old_mem.len) {
+ return old_mem[0..new_size];
+ } else {
+ const result = try alloc(allocator, new_size, alignment);
+ mem.copy(u8, result, old_mem);
+ return result;
+ }
+ }
+
+ fn free(allocator: *Allocator, bytes: []u8) void {}
};
}
-
- fn alloc(allocator: *Allocator, n: usize, alignment: u29) ![]u8 {
- const self = @fieldParentPtr(ThreadSafeFixedBufferAllocator, "allocator", allocator);
- var end_index = @atomicLoad(usize, &self.end_index, builtin.AtomicOrder.SeqCst);
- while (true) {
- const addr = @ptrToInt(self.buffer.ptr) + end_index;
- const rem = @rem(addr, alignment);
- const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
- const adjusted_index = end_index + march_forward_bytes;
- const new_end_index = adjusted_index + n;
- if (new_end_index > self.buffer.len) {
- return error.OutOfMemory;
- }
- end_index = @cmpxchgWeak(usize, &self.end_index, end_index, new_end_index, builtin.AtomicOrder.SeqCst, builtin.AtomicOrder.SeqCst) orelse return self.buffer[adjusted_index..new_end_index];
- }
- }
-
- fn realloc(allocator: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
- if (new_size <= old_mem.len) {
- return old_mem[0..new_size];
- } else {
- const result = try alloc(allocator, new_size, alignment);
- mem.copy(u8, result, old_mem);
- return result;
- }
- }
-
- fn free(allocator: *Allocator, bytes: []u8) void {}
};
pub fn stackFallback(comptime size: usize, fallback_allocator: *Allocator) StackFallbackAllocator(size) {
From c2db077574be841da586fa62d67619c901dd535d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Feb 2019 18:18:47 -0500
Subject: [PATCH 153/218] std.debug.assert: remove special case for test builds
Previously, std.debug.assert would `@panic` in test builds,
if the assertion failed. Now, it's always `unreachable`.
This makes release mode test builds more accurately test
the actual code that will be run.
However this requires tests to call `std.testing.expect`
rather than `std.debug.assert` to make sure output is correct.
Here is the explanation of when to use either one, copied from
the assert doc comments:
Inside a test block, it is best to use the `std.testing` module
rather than assert, because assert may not detect a test failure
in ReleaseFast and ReleaseSafe mode. Outside of a test block, assert
is the correct function to use.
closes #1304
---
CMakeLists.txt | 1 +
doc/docgen.zig | 4 +-
src-self-hosted/arg.zig | 23 +-
src-self-hosted/test.zig | 4 +-
src/ir.cpp | 24 +-
std/array_list.zig | 106 ++---
std/atomic/queue.zig | 23 +-
std/atomic/stack.zig | 5 +-
std/base64.zig | 13 +-
std/buf_map.zig | 16 +-
std/buf_set.zig | 6 +-
std/buffer.zig | 15 +-
std/crypto/chacha20.zig | 15 +-
std/crypto/poly1305.zig | 2 +-
std/crypto/test.zig | 9 +-
std/crypto/x25519.zig | 24 +-
std/cstr.zig | 6 +-
std/debug/index.zig | 38 +-
std/dynamic_library.zig | 3 +-
std/event/channel.zig | 9 +-
std/event/fs.zig | 9 +-
std/event/future.zig | 3 +-
std/event/group.zig | 6 +-
std/event/lock.zig | 3 +-
std/event/loop.zig | 5 +-
std/event/net.zig | 4 +-
std/event/rwlock.zig | 7 +-
std/fmt/index.zig | 158 ++++----
std/hash/adler.zig | 12 +-
std/hash/crc.zig | 25 +-
std/hash/fnv.zig | 18 +-
std/hash/siphash.zig | 15 +-
std/hash_map.zig | 59 +--
std/heap.zig | 55 +--
std/index.zig | 15 +-
std/io.zig | 17 +-
std/io_test.zig | 202 +++++-----
std/json.zig | 17 +-
std/json_test.zig | 6 +-
std/lazy_init.zig | 9 +-
std/linked_list.zig | 29 +-
std/math/acos.zig | 38 +-
std/math/acosh.zig | 30 +-
std/math/asin.zig | 46 +--
std/math/asinh.zig | 54 +--
std/math/atan.zig | 42 +-
std/math/atan2.zig | 110 +++---
std/math/atanh.zig | 38 +-
std/math/big/int.zig | 367 +++++++++---------
std/math/cbrt.zig | 50 +--
std/math/ceil.zig | 38 +-
std/math/complex/abs.zig | 4 +-
std/math/complex/acos.zig | 6 +-
std/math/complex/acosh.zig | 6 +-
std/math/complex/arg.zig | 4 +-
std/math/complex/asin.zig | 6 +-
std/math/complex/asinh.zig | 6 +-
std/math/complex/atan.zig | 10 +-
std/math/complex/atanh.zig | 6 +-
std/math/complex/conj.zig | 4 +-
std/math/complex/cos.zig | 6 +-
std/math/complex/cosh.zig | 10 +-
std/math/complex/exp.zig | 10 +-
std/math/complex/index.zig | 16 +-
std/math/complex/log.zig | 6 +-
std/math/complex/pow.zig | 6 +-
std/math/complex/proj.zig | 4 +-
std/math/complex/sin.zig | 6 +-
std/math/complex/sinh.zig | 10 +-
std/math/complex/sqrt.zig | 10 +-
std/math/complex/tan.zig | 6 +-
std/math/complex/tanh.zig | 10 +-
std/math/copysign.zig | 32 +-
std/math/cos.zig | 42 +-
std/math/cosh.zig | 42 +-
std/math/exp2.zig | 32 +-
std/math/expm1.zig | 38 +-
std/math/fabs.zig | 38 +-
std/math/floor.zig | 56 +--
std/math/fma.zig | 34 +-
std/math/frexp.zig | 34 +-
std/math/hypot.zig | 58 +--
std/math/ilogb.zig | 46 +--
std/math/index.zig | 335 ++++++++--------
std/math/isfinite.zig | 26 +-
std/math/isinf.zig | 74 ++--
std/math/isnan.zig | 14 +-
std/math/isnormal.zig | 20 +-
std/math/ln.zig | 46 +--
std/math/log.zig | 26 +-
std/math/log10.zig | 46 +--
std/math/log1p.zig | 58 +--
std/math/log2.zig | 42 +-
std/math/modf.zig | 58 +--
std/math/pow.zig | 94 ++---
std/math/powi.zig | 122 +++---
std/math/round.zig | 42 +-
std/math/scalbn.zig | 10 +-
std/math/signbit.zig | 20 +-
std/math/sin.zig | 52 +--
std/math/sinh.zig | 42 +-
std/math/sqrt.zig | 104 ++---
std/math/tan.zig | 50 +--
std/math/tanh.zig | 46 +--
std/math/trunc.zig | 38 +-
std/mem.zig | 317 +++++++--------
std/meta/index.zig | 151 +++----
std/meta/trait.zig | 133 +++----
std/mutex.zig | 6 +-
std/os/child_process.zig | 1 -
std/os/index.zig | 9 +-
std/os/linux/test.zig | 12 +-
std/os/path.zig | 113 +++---
std/os/test.zig | 16 +-
std/os/time.zig | 9 +-
std/rand/index.zig | 161 ++++----
std/rb.zig | 5 +-
std/segmented_list.zig | 31 +-
std/sort.zig | 17 +-
std/special/compiler_rt/divti3_test.zig | 4 +-
std/special/compiler_rt/extendXfYf2_test.zig | 1 -
std/special/compiler_rt/fixdfdi_test.zig | 4 +-
std/special/compiler_rt/fixdfsi_test.zig | 4 +-
std/special/compiler_rt/fixdfti_test.zig | 4 +-
std/special/compiler_rt/fixint_test.zig | 4 +-
std/special/compiler_rt/fixsfdi_test.zig | 4 +-
std/special/compiler_rt/fixsfsi_test.zig | 4 +-
std/special/compiler_rt/fixsfti_test.zig | 4 +-
std/special/compiler_rt/fixtfdi_test.zig | 4 +-
std/special/compiler_rt/fixtfsi_test.zig | 4 +-
std/special/compiler_rt/fixtfti_test.zig | 4 +-
std/special/compiler_rt/fixunsdfdi_test.zig | 4 +-
std/special/compiler_rt/fixunsdfsi_test.zig | 4 +-
std/special/compiler_rt/fixunsdfti_test.zig | 4 +-
std/special/compiler_rt/fixunssfdi_test.zig | 4 +-
std/special/compiler_rt/fixunssfsi_test.zig | 4 +-
std/special/compiler_rt/fixunssfti_test.zig | 4 +-
std/special/compiler_rt/fixunstfdi_test.zig | 4 +-
std/special/compiler_rt/fixunstfsi_test.zig | 4 +-
std/special/compiler_rt/fixunstfti_test.zig | 4 +-
std/special/compiler_rt/floattidf_test.zig | 4 +-
std/special/compiler_rt/floattisf_test.zig | 4 +-
std/special/compiler_rt/floattitf_test.zig | 4 +-
std/special/compiler_rt/floatunditf_test.zig | 1 -
std/special/compiler_rt/floatunsitf_test.zig | 1 -
std/special/compiler_rt/floatuntidf_test.zig | 4 +-
std/special/compiler_rt/floatuntisf_test.zig | 4 +-
std/special/compiler_rt/floatuntitf_test.zig | 4 +-
std/special/compiler_rt/index.zig | 5 +-
std/special/compiler_rt/muloti4_test.zig | 4 +-
std/special/compiler_rt/multi3_test.zig | 4 +-
std/special/compiler_rt/udivmoddi4_test.zig | 6 +-
std/special/compiler_rt/udivmodti4_test.zig | 6 +-
std/special/init-lib/src/main.zig | 4 +-
std/statically_initialized_mutex.zig | 5 +-
std/testing.zig | 152 ++++++++
std/unicode.zig | 119 +++---
std/zig/ast.zig | 3 +-
std/zig/parser_test.zig | 2 +-
std/zig/tokenizer.zig | 2 +-
test/cli.zig | 10 +-
test/stage1/behavior/align.zig | 72 ++--
test/stage1/behavior/alignof.zig | 6 +-
test/stage1/behavior/array.zig | 110 +++---
test/stage1/behavior/asm.zig | 4 +-
test/stage1/behavior/atomics.zig | 32 +-
test/stage1/behavior/bit_shifting.zig | 10 +-
test/stage1/behavior/bitcast.zig | 8 +-
test/stage1/behavior/bitreverse.zig | 86 ++--
test/stage1/behavior/bool.zig | 20 +-
test/stage1/behavior/bswap.zig | 42 +-
test/stage1/behavior/bugs/1076.zig | 4 +-
test/stage1/behavior/bugs/1277.zig | 2 +-
test/stage1/behavior/bugs/1322.zig | 4 +-
test/stage1/behavior/bugs/1381.zig | 2 +-
test/stage1/behavior/bugs/1421.zig | 4 +-
test/stage1/behavior/bugs/1442.zig | 2 +-
test/stage1/behavior/bugs/1486.zig | 6 +-
test/stage1/behavior/bugs/394.zig | 4 +-
test/stage1/behavior/bugs/655.zig | 4 +-
test/stage1/behavior/bugs/656.zig | 4 +-
test/stage1/behavior/bugs/726.zig | 6 +-
test/stage1/behavior/bugs/920.zig | 2 +-
test/stage1/behavior/byval_arg_var.zig | 2 +-
test/stage1/behavior/cancel.zig | 14 +-
test/stage1/behavior/cast.zig | 158 ++++----
test/stage1/behavior/const_slice_child.zig | 13 +-
.../behavior/coroutine_await_struct.zig | 6 +-
test/stage1/behavior/coroutines.zig | 36 +-
test/stage1/behavior/defer.zig | 24 +-
test/stage1/behavior/enum.zig | 74 ++--
test/stage1/behavior/enum_with_members.zig | 10 +-
test/stage1/behavior/error.zig | 62 +--
test/stage1/behavior/eval.zig | 232 +++++------
test/stage1/behavior/field_parent_ptr.zig | 14 +-
test/stage1/behavior/fn.zig | 38 +-
.../behavior/fn_in_struct_in_comptime.zig | 4 +-
test/stage1/behavior/for.zig | 10 +-
test/stage1/behavior/generics.zig | 46 +--
test/stage1/behavior/if.zig | 4 +-
test/stage1/behavior/import.zig | 6 +-
.../behavior/incomplete_struct_param_tld.zig | 4 +-
test/stage1/behavior/inttoptr.zig | 2 +-
test/stage1/behavior/ir_block_deps.zig | 6 +-
test/stage1/behavior/math.zig | 256 ++++++------
test/stage1/behavior/misc.zig | 268 ++++++-------
.../index.zig | 6 +-
test/stage1/behavior/new_stack_call.zig | 10 +-
test/stage1/behavior/null.zig | 34 +-
test/stage1/behavior/optional.zig | 28 +-
test/stage1/behavior/pointers.zig | 24 +-
test/stage1/behavior/popcount.zig | 10 +-
test/stage1/behavior/ptrcast.zig | 8 +-
test/stage1/behavior/pub_enum/index.zig | 6 +-
...ef_var_in_if_after_if_2nd_switch_prong.zig | 10 +-
test/stage1/behavior/reflection.zig | 78 ++--
test/stage1/behavior/sizeof_and_typeof.zig | 60 +--
test/stage1/behavior/slice.zig | 16 +-
test/stage1/behavior/struct.zig | 184 ++++-----
.../struct_contains_null_ptr_itself.zig | 4 +-
.../struct_contains_slice_of_itself.zig | 26 +-
test/stage1/behavior/switch.zig | 66 ++--
.../stage1/behavior/switch_prong_err_enum.zig | 6 +-
.../behavior/switch_prong_implicit_cast.zig | 4 +-
test/stage1/behavior/this.zig | 8 +-
test/stage1/behavior/truncate.zig | 4 +-
test/stage1/behavior/try.zig | 10 +-
test/stage1/behavior/type_info.zig | 182 ++++-----
test/stage1/behavior/undefined.zig | 28 +-
test/stage1/behavior/underscore.zig | 2 +-
test/stage1/behavior/union.zig | 76 ++--
test/stage1/behavior/var_args.zig | 34 +-
test/stage1/behavior/vector.zig | 8 +-
test/stage1/behavior/void.zig | 8 +-
test/stage1/behavior/while.zig | 44 +--
test/stage1/behavior/widening.zig | 8 +-
test/stage1/c_abi/main.zig | 82 ++--
test/standalone/brace_expansion/main.zig | 9 +-
test/standalone/issue_794/main.zig | 4 +-
239 files changed, 4084 insertions(+), 3938 deletions(-)
create mode 100644 std/testing.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d6bd8a6c2e..ed79f99901 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -658,6 +658,7 @@ set(ZIG_STD_FILES
"special/test_runner.zig"
"spinlock.zig"
"statically_initialized_mutex.zig"
+ "testing.zig"
"unicode.zig"
"zig/ast.zig"
"zig/index.zig"
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 14e4700553..7aaf5ebdc7 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -4,7 +4,7 @@ const io = std.io;
const os = std.os;
const warn = std.debug.warn;
const mem = std.mem;
-const assert = std.debug.assert;
+const testing = std.testing;
const max_doc_file_size = 10 * 1024 * 1024;
@@ -620,7 +620,7 @@ const TermState = enum {
test "term color" {
const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
const result = try termColor(std.debug.global_allocator, input_bytes);
- assert(mem.eql(u8, result, "AgreenB"));
+ testing.expectEqualSlices(u8, "AgreenB", result));
}
fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
diff --git a/src-self-hosted/arg.zig b/src-self-hosted/arg.zig
index 99e6ecc17a..7bbd233a75 100644
--- a/src-self-hosted/arg.zig
+++ b/src-self-hosted/arg.zig
@@ -1,5 +1,6 @@
const std = @import("std");
const debug = std.debug;
+const testing = std.testing;
const mem = std.mem;
const Allocator = mem.Allocator;
@@ -272,21 +273,21 @@ test "parse arguments" {
var args = try Args.parse(std.debug.global_allocator, spec1, cliargs);
- debug.assert(args.present("help"));
- debug.assert(!args.present("help2"));
- debug.assert(!args.present("init"));
+ testing.expect(args.present("help"));
+ testing.expect(!args.present("help2"));
+ testing.expect(!args.present("init"));
- debug.assert(mem.eql(u8, args.single("build-file").?, "build.zig"));
- debug.assert(mem.eql(u8, args.single("color").?, "on"));
+ testing.expect(mem.eql(u8, args.single("build-file").?, "build.zig"));
+ testing.expect(mem.eql(u8, args.single("color").?, "on"));
const objects = args.many("object").?;
- debug.assert(mem.eql(u8, objects[0], "obj1"));
- debug.assert(mem.eql(u8, objects[1], "obj2"));
+ testing.expect(mem.eql(u8, objects[0], "obj1"));
+ testing.expect(mem.eql(u8, objects[1], "obj2"));
- debug.assert(mem.eql(u8, args.single("library").?, "lib2"));
+ testing.expect(mem.eql(u8, args.single("library").?, "lib2"));
const pos = args.positionals.toSliceConst();
- debug.assert(mem.eql(u8, pos[0], "build"));
- debug.assert(mem.eql(u8, pos[1], "pos1"));
- debug.assert(mem.eql(u8, pos[2], "pos2"));
+ testing.expect(mem.eql(u8, pos[0], "build"));
+ testing.expect(mem.eql(u8, pos[1], "pos1"));
+ testing.expect(mem.eql(u8, pos[2], "pos2"));
}
diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig
index de551cf7f7..4be6d53932 100644
--- a/src-self-hosted/test.zig
+++ b/src-self-hosted/test.zig
@@ -4,7 +4,7 @@ const builtin = @import("builtin");
const Target = @import("target.zig").Target;
const Compilation = @import("compilation.zig").Compilation;
const introspect = @import("introspect.zig");
-const assertOrPanic = std.debug.assertOrPanic;
+const testing = std.testing;
const errmsg = @import("errmsg.zig");
const ZigCompiler = @import("compilation.zig").ZigCompiler;
@@ -210,7 +210,7 @@ pub const TestContext = struct {
@panic("build incorrectly failed");
},
Compilation.Event.Fail => |msgs| {
- assertOrPanic(msgs.len != 0);
+ testing.expect(msgs.len != 0);
for (msgs) |msg| {
if (mem.endsWith(u8, msg.realpath, path) and mem.eql(u8, msg.text, text)) {
const span = msg.getSpan();
diff --git a/src/ir.cpp b/src/ir.cpp
index 00d358552a..efda2b321b 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -17543,21 +17543,16 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val,
enum_field_val->data.x_struct.fields = inner_fields;
}
-static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstExprValue **out) {
+static Error ir_make_type_info_value(IrAnalyze *ira, AstNode *source_node, ZigType *type_entry, ConstExprValue **out) {
Error err;
assert(type_entry != nullptr);
assert(!type_is_invalid(type_entry));
- if ((err = ensure_complete_type(ira->codegen, type_entry)))
+ if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown)))
return err;
- if (type_entry == ira->codegen->builtin_types.entry_global_error_set) {
- zig_panic("TODO implement @typeInfo for global error set");
- }
-
ConstExprValue *result = nullptr;
- switch (type_entry->id)
- {
+ switch (type_entry->id) {
case ZigTypeIdInvalid:
zig_unreachable();
case ZigTypeIdMetaType:
@@ -17778,6 +17773,15 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
ensure_field_index(result->type, "errors", 0);
ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr);
+ if (!resolve_inferred_error_set(ira->codegen, type_entry, source_node)) {
+ return ErrorSemanticAnalyzeFail;
+ }
+ if (type_is_global_error_set(type_entry)) {
+ ir_add_error_node(ira, source_node,
+ buf_sprintf("TODO: compiler bug: implement @typeInfo support for anyerror. https://github.com/ziglang/zig/issues/1936"));
+ return ErrorSemanticAnalyzeFail;
+ }
+
uint32_t error_count = type_entry->data.error_set.err_count;
ConstExprValue *error_array = create_const_vals(1);
error_array->special = ConstValSpecialStatic;
@@ -18103,7 +18107,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstE
{
ZigType *fn_type = type_entry->data.bound_fn.fn_type;
assert(fn_type->id == ZigTypeIdFn);
- if ((err = ir_make_type_info_value(ira, fn_type, &result)))
+ if ((err = ir_make_type_info_value(ira, source_node, fn_type, &result)))
return err;
break;
@@ -18128,7 +18132,7 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira,
ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr);
ConstExprValue *payload;
- if ((err = ir_make_type_info_value(ira, type_entry, &payload)))
+ if ((err = ir_make_type_info_value(ira, instruction->base.source_node, type_entry, &payload)))
return ira->codegen->invalid_instruction;
IrInstruction *result = ir_const(ira, &instruction->base, result_type);
diff --git a/std/array_list.zig b/std/array_list.zig
index ddad9c989c..e2535d6393 100644
--- a/std/array_list.zig
+++ b/std/array_list.zig
@@ -1,7 +1,7 @@
const std = @import("index.zig");
const debug = std.debug;
const assert = debug.assert;
-const assertError = debug.assertError;
+const testing = std.testing;
const mem = std.mem;
const Allocator = mem.Allocator;
@@ -212,8 +212,8 @@ test "std.ArrayList.init" {
var list = ArrayList(i32).init(allocator);
defer list.deinit();
- assert(list.count() == 0);
- assert(list.capacity() == 0);
+ testing.expect(list.count() == 0);
+ testing.expect(list.capacity() == 0);
}
test "std.ArrayList.basic" {
@@ -224,7 +224,7 @@ test "std.ArrayList.basic" {
defer list.deinit();
// setting on empty list is out of bounds
- assertError(list.setOrError(0, 1), error.OutOfBounds);
+ testing.expectError(error.OutOfBounds, list.setOrError(0, 1));
{
var i: usize = 0;
@@ -236,44 +236,44 @@ test "std.ArrayList.basic" {
{
var i: usize = 0;
while (i < 10) : (i += 1) {
- assert(list.items[i] == @intCast(i32, i + 1));
+ testing.expect(list.items[i] == @intCast(i32, i + 1));
}
}
for (list.toSlice()) |v, i| {
- assert(v == @intCast(i32, i + 1));
+ testing.expect(v == @intCast(i32, i + 1));
}
for (list.toSliceConst()) |v, i| {
- assert(v == @intCast(i32, i + 1));
+ testing.expect(v == @intCast(i32, i + 1));
}
- assert(list.pop() == 10);
- assert(list.len == 9);
+ testing.expect(list.pop() == 10);
+ testing.expect(list.len == 9);
list.appendSlice([]const i32{
1,
2,
3,
}) catch unreachable;
- assert(list.len == 12);
- assert(list.pop() == 3);
- assert(list.pop() == 2);
- assert(list.pop() == 1);
- assert(list.len == 9);
+ testing.expect(list.len == 12);
+ testing.expect(list.pop() == 3);
+ testing.expect(list.pop() == 2);
+ testing.expect(list.pop() == 1);
+ testing.expect(list.len == 9);
list.appendSlice([]const i32{}) catch unreachable;
- assert(list.len == 9);
+ testing.expect(list.len == 9);
// can only set on indices < self.len
list.set(7, 33);
list.set(8, 42);
- assertError(list.setOrError(9, 99), error.OutOfBounds);
- assertError(list.setOrError(10, 123), error.OutOfBounds);
+ testing.expectError(error.OutOfBounds, list.setOrError(9, 99));
+ testing.expectError(error.OutOfBounds, list.setOrError(10, 123));
- assert(list.pop() == 42);
- assert(list.pop() == 33);
+ testing.expect(list.pop() == 42);
+ testing.expect(list.pop() == 33);
}
test "std.ArrayList.swapRemove" {
@@ -289,18 +289,18 @@ test "std.ArrayList.swapRemove" {
try list.append(7);
//remove from middle
- assert(list.swapRemove(3) == 4);
- assert(list.at(3) == 7);
- assert(list.len == 6);
+ testing.expect(list.swapRemove(3) == 4);
+ testing.expect(list.at(3) == 7);
+ testing.expect(list.len == 6);
//remove from end
- assert(list.swapRemove(5) == 6);
- assert(list.len == 5);
+ testing.expect(list.swapRemove(5) == 6);
+ testing.expect(list.len == 5);
//remove from front
- assert(list.swapRemove(0) == 1);
- assert(list.at(0) == 5);
- assert(list.len == 4);
+ testing.expect(list.swapRemove(0) == 1);
+ testing.expect(list.at(0) == 5);
+ testing.expect(list.len == 4);
}
test "std.ArrayList.swapRemoveOrError" {
@@ -308,27 +308,27 @@ test "std.ArrayList.swapRemoveOrError" {
defer list.deinit();
// Test just after initialization
- assertError(list.swapRemoveOrError(0), error.OutOfBounds);
+ testing.expectError(error.OutOfBounds, list.swapRemoveOrError(0));
// Test after adding one item and remote it
try list.append(1);
- assert((try list.swapRemoveOrError(0)) == 1);
- assertError(list.swapRemoveOrError(0), error.OutOfBounds);
+ testing.expect((try list.swapRemoveOrError(0)) == 1);
+ testing.expectError(error.OutOfBounds, list.swapRemoveOrError(0));
// Test after adding two items and remote both
try list.append(1);
try list.append(2);
- assert((try list.swapRemoveOrError(1)) == 2);
- assert((try list.swapRemoveOrError(0)) == 1);
- assertError(list.swapRemoveOrError(0), error.OutOfBounds);
+ testing.expect((try list.swapRemoveOrError(1)) == 2);
+ testing.expect((try list.swapRemoveOrError(0)) == 1);
+ testing.expectError(error.OutOfBounds, list.swapRemoveOrError(0));
// Test out of bounds with one item
try list.append(1);
- assertError(list.swapRemoveOrError(1), error.OutOfBounds);
+ testing.expectError(error.OutOfBounds, list.swapRemoveOrError(1));
// Test out of bounds with two items
try list.append(2);
- assertError(list.swapRemoveOrError(2), error.OutOfBounds);
+ testing.expectError(error.OutOfBounds, list.swapRemoveOrError(2));
}
test "std.ArrayList.iterator" {
@@ -342,22 +342,22 @@ test "std.ArrayList.iterator" {
var count: i32 = 0;
var it = list.iterator();
while (it.next()) |next| {
- assert(next == count + 1);
+ testing.expect(next == count + 1);
count += 1;
}
- assert(count == 3);
- assert(it.next() == null);
+ testing.expect(count == 3);
+ testing.expect(it.next() == null);
it.reset();
count = 0;
while (it.next()) |next| {
- assert(next == count + 1);
+ testing.expect(next == count + 1);
count += 1;
if (count == 2) break;
}
it.reset();
- assert(it.next().? == 1);
+ testing.expect(it.next().? == 1);
}
test "std.ArrayList.insert" {
@@ -368,10 +368,10 @@ test "std.ArrayList.insert" {
try list.append(2);
try list.append(3);
try list.insert(0, 5);
- assert(list.items[0] == 5);
- assert(list.items[1] == 1);
- assert(list.items[2] == 2);
- assert(list.items[3] == 3);
+ testing.expect(list.items[0] == 5);
+ testing.expect(list.items[1] == 1);
+ testing.expect(list.items[2] == 2);
+ testing.expect(list.items[3] == 3);
}
test "std.ArrayList.insertSlice" {
@@ -386,17 +386,17 @@ test "std.ArrayList.insertSlice" {
9,
8,
});
- assert(list.items[0] == 1);
- assert(list.items[1] == 9);
- assert(list.items[2] == 8);
- assert(list.items[3] == 2);
- assert(list.items[4] == 3);
- assert(list.items[5] == 4);
+ testing.expect(list.items[0] == 1);
+ testing.expect(list.items[1] == 9);
+ testing.expect(list.items[2] == 8);
+ testing.expect(list.items[3] == 2);
+ testing.expect(list.items[4] == 3);
+ testing.expect(list.items[5] == 4);
const items = []const i32{1};
try list.insertSlice(0, items[0..0]);
- assert(list.len == 6);
- assert(list.items[0] == 1);
+ testing.expect(list.len == 6);
+ testing.expect(list.items[0] == 1);
}
const Item = struct {
@@ -407,5 +407,5 @@ const Item = struct {
test "std.ArrayList: ArrayList(T) of struct T" {
var root = Item{ .integer = 1, .sub_items = ArrayList(Item).init(debug.global_allocator) };
try root.sub_items.append( Item{ .integer = 42, .sub_items = ArrayList(Item).init(debug.global_allocator) } );
- assert(root.sub_items.items[0].integer == 42);
+ testing.expect(root.sub_items.items[0].integer == 42);
}
diff --git a/std/atomic/queue.zig b/std/atomic/queue.zig
index 183c434dc5..bdc86c0981 100644
--- a/std/atomic/queue.zig
+++ b/std/atomic/queue.zig
@@ -3,6 +3,7 @@ const builtin = @import("builtin");
const AtomicOrder = builtin.AtomicOrder;
const AtomicRmwOp = builtin.AtomicRmwOp;
const assert = std.debug.assert;
+const expect = std.testing.expect;
/// Many producer, many consumer, non-allocating, thread-safe.
/// Uses a mutex to protect access.
@@ -174,14 +175,14 @@ test "std.atomic.Queue" {
{
var i: usize = 0;
while (i < put_thread_count) : (i += 1) {
- std.debug.assertOrPanic(startPuts(&context) == 0);
+ expect(startPuts(&context) == 0);
}
}
context.puts_done = 1;
{
var i: usize = 0;
while (i < put_thread_count) : (i += 1) {
- std.debug.assertOrPanic(startGets(&context) == 0);
+ expect(startGets(&context) == 0);
}
}
} else {
@@ -264,7 +265,7 @@ test "std.atomic.Queue single-threaded" {
};
queue.put(&node_1);
- assert(queue.get().?.data == 0);
+ expect(queue.get().?.data == 0);
var node_2 = Queue(i32).Node{
.data = 2,
@@ -280,9 +281,9 @@ test "std.atomic.Queue single-threaded" {
};
queue.put(&node_3);
- assert(queue.get().?.data == 1);
+ expect(queue.get().?.data == 1);
- assert(queue.get().?.data == 2);
+ expect(queue.get().?.data == 2);
var node_4 = Queue(i32).Node{
.data = 4,
@@ -291,12 +292,12 @@ test "std.atomic.Queue single-threaded" {
};
queue.put(&node_4);
- assert(queue.get().?.data == 3);
+ expect(queue.get().?.data == 3);
node_3.next = null;
- assert(queue.get().?.data == 4);
+ expect(queue.get().?.data == 4);
- assert(queue.get() == null);
+ expect(queue.get() == null);
}
test "std.atomic.Queue dump" {
@@ -311,7 +312,7 @@ test "std.atomic.Queue dump" {
// Test empty stream
sos.reset();
try queue.dumpToStream(SliceOutStream.Error, &sos.stream);
- assert(mem.eql(u8, buffer[0..sos.pos],
+ expect(mem.eql(u8, buffer[0..sos.pos],
\\head: (null)
\\tail: (null)
\\
@@ -335,7 +336,7 @@ test "std.atomic.Queue dump" {
\\ (null)
\\
, @ptrToInt(queue.head), @ptrToInt(queue.tail));
- assert(mem.eql(u8, buffer[0..sos.pos], expected));
+ expect(mem.eql(u8, buffer[0..sos.pos], expected));
// Test a stream with two elements
var node_1 = Queue(i32).Node{
@@ -356,5 +357,5 @@ test "std.atomic.Queue dump" {
\\ (null)
\\
, @ptrToInt(queue.head), @ptrToInt(queue.head.?.next), @ptrToInt(queue.tail));
- assert(mem.eql(u8, buffer[0..sos.pos], expected));
+ expect(mem.eql(u8, buffer[0..sos.pos], expected));
}
diff --git a/std/atomic/stack.zig b/std/atomic/stack.zig
index 503fa0c0ce..4d0d5075e0 100644
--- a/std/atomic/stack.zig
+++ b/std/atomic/stack.zig
@@ -1,6 +1,7 @@
const assert = std.debug.assert;
const builtin = @import("builtin");
const AtomicOrder = builtin.AtomicOrder;
+const expect = std.testing.expect;
/// Many reader, many writer, non-allocating, thread-safe
/// Uses a spinlock to protect push() and pop()
@@ -108,14 +109,14 @@ test "std.atomic.stack" {
{
var i: usize = 0;
while (i < put_thread_count) : (i += 1) {
- std.debug.assertOrPanic(startPuts(&context) == 0);
+ expect(startPuts(&context) == 0);
}
}
context.puts_done = 1;
{
var i: usize = 0;
while (i < put_thread_count) : (i += 1) {
- std.debug.assertOrPanic(startGets(&context) == 0);
+ expect(startGets(&context) == 0);
}
}
} else {
diff --git a/std/base64.zig b/std/base64.zig
index bc0bdb1bd3..cfe8ea95f8 100644
--- a/std/base64.zig
+++ b/std/base64.zig
@@ -1,5 +1,6 @@
const std = @import("index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
pub const standard_alphabet_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -394,7 +395,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
var buffer: [0x100]u8 = undefined;
var encoded = buffer[0..Base64Encoder.calcSize(expected_decoded.len)];
standard_encoder.encode(encoded, expected_decoded);
- assert(mem.eql(u8, encoded, expected_encoded));
+ testing.expectEqualSlices(u8, expected_encoded, encoded);
}
// Base64Decoder
@@ -402,7 +403,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..try standard_decoder.calcSize(expected_encoded)];
try standard_decoder.decode(decoded, expected_encoded);
- assert(mem.eql(u8, decoded, expected_decoded));
+ testing.expectEqualSlices(u8, expected_decoded, decoded);
}
// Base64DecoderWithIgnore
@@ -411,8 +412,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];
var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded);
- assert(written <= decoded.len);
- assert(mem.eql(u8, decoded[0..written], expected_decoded));
+ testing.expect(written <= decoded.len);
+ testing.expectEqualSlices(u8, expected_decoded, decoded[0..written]);
}
// Base64DecoderUnsafe
@@ -420,7 +421,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..standard_decoder_unsafe.calcSize(expected_encoded)];
standard_decoder_unsafe.decode(decoded, expected_encoded);
- assert(mem.eql(u8, decoded, expected_decoded));
+ testing.expectEqualSlices(u8, expected_decoded, decoded);
}
}
@@ -429,7 +430,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !voi
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];
var written = try standard_decoder_ignore_space.decode(decoded, encoded);
- assert(mem.eql(u8, decoded[0..written], expected_decoded));
+ testing.expectEqualSlices(u8, expected_decoded, decoded[0..written]);
}
fn testError(encoded: []const u8, expected_err: anyerror) !void {
diff --git a/std/buf_map.zig b/std/buf_map.zig
index 6de0d20cdb..f8d3d5e04d 100644
--- a/std/buf_map.zig
+++ b/std/buf_map.zig
@@ -2,7 +2,7 @@ const std = @import("index.zig");
const HashMap = std.HashMap;
const mem = std.mem;
const Allocator = mem.Allocator;
-const assert = std.debug.assert;
+const testing = std.testing;
/// BufMap copies keys and values before they go into the map, and
/// frees them when they get removed.
@@ -90,17 +90,17 @@ test "BufMap" {
defer bufmap.deinit();
try bufmap.set("x", "1");
- assert(mem.eql(u8, bufmap.get("x").?, "1"));
- assert(1 == bufmap.count());
+ testing.expect(mem.eql(u8, bufmap.get("x").?, "1"));
+ testing.expect(1 == bufmap.count());
try bufmap.set("x", "2");
- assert(mem.eql(u8, bufmap.get("x").?, "2"));
- assert(1 == bufmap.count());
+ testing.expect(mem.eql(u8, bufmap.get("x").?, "2"));
+ testing.expect(1 == bufmap.count());
try bufmap.set("x", "3");
- assert(mem.eql(u8, bufmap.get("x").?, "3"));
- assert(1 == bufmap.count());
+ testing.expect(mem.eql(u8, bufmap.get("x").?, "3"));
+ testing.expect(1 == bufmap.count());
bufmap.delete("x");
- assert(0 == bufmap.count());
+ testing.expect(0 == bufmap.count());
}
diff --git a/std/buf_set.zig b/std/buf_set.zig
index ab2d8e7c34..7ccd94c179 100644
--- a/std/buf_set.zig
+++ b/std/buf_set.zig
@@ -2,7 +2,7 @@ const std = @import("index.zig");
const HashMap = @import("hash_map.zig").HashMap;
const mem = @import("mem.zig");
const Allocator = mem.Allocator;
-const assert = std.debug.assert;
+const testing = std.testing;
pub const BufSet = struct {
hash_map: BufSetHashMap,
@@ -68,9 +68,9 @@ test "BufSet" {
defer bufset.deinit();
try bufset.put("x");
- assert(bufset.count() == 1);
+ testing.expect(bufset.count() == 1);
bufset.delete("x");
- assert(bufset.count() == 0);
+ testing.expect(bufset.count() == 0);
try bufset.put("x");
try bufset.put("y");
diff --git a/std/buffer.zig b/std/buffer.zig
index 2b71c26749..371655f1e5 100644
--- a/std/buffer.zig
+++ b/std/buffer.zig
@@ -3,6 +3,7 @@ const debug = std.debug;
const mem = std.mem;
const Allocator = mem.Allocator;
const assert = debug.assert;
+const testing = std.testing;
const ArrayList = std.ArrayList;
/// A buffer that allocates memory and maintains a null byte at the end.
@@ -141,19 +142,19 @@ test "simple Buffer" {
const cstr = @import("cstr.zig");
var buf = try Buffer.init(debug.global_allocator, "");
- assert(buf.len() == 0);
+ testing.expect(buf.len() == 0);
try buf.append("hello");
try buf.append(" ");
try buf.append("world");
- assert(buf.eql("hello world"));
- assert(mem.eql(u8, cstr.toSliceConst(buf.toSliceConst().ptr), buf.toSliceConst()));
+ testing.expect(buf.eql("hello world"));
+ testing.expect(mem.eql(u8, cstr.toSliceConst(buf.toSliceConst().ptr), buf.toSliceConst()));
var buf2 = try Buffer.initFromBuffer(buf);
- assert(buf.eql(buf2.toSliceConst()));
+ testing.expect(buf.eql(buf2.toSliceConst()));
- assert(buf.startsWith("hell"));
- assert(buf.endsWith("orld"));
+ testing.expect(buf.startsWith("hell"));
+ testing.expect(buf.endsWith("orld"));
try buf2.resize(4);
- assert(buf.startsWith(buf2.toSlice()));
+ testing.expect(buf.startsWith(buf2.toSlice()));
}
diff --git a/std/crypto/chacha20.zig b/std/crypto/chacha20.zig
index 5ec1e79756..d964f4c03d 100644
--- a/std/crypto/chacha20.zig
+++ b/std/crypto/chacha20.zig
@@ -4,6 +4,7 @@ const std = @import("../index.zig");
const mem = std.mem;
const endian = std.endian;
const assert = std.debug.assert;
+const testing = std.testing;
const builtin = @import("builtin");
const maxInt = std.math.maxInt;
@@ -216,12 +217,12 @@ test "crypto.chacha20 test vector sunscreen" {
};
chaCha20IETF(result[0..], input[0..], 1, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
// Chacha20 is self-reversing.
var plaintext: [114]u8 = undefined;
chaCha20IETF(plaintext[0..], result[0..], 1, key, nonce);
- assert(mem.compare(u8, input, plaintext) == mem.Compare.Equal);
+ testing.expect(mem.compare(u8, input, plaintext) == mem.Compare.Equal);
}
// https://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-04#section-7
@@ -256,7 +257,7 @@ test "crypto.chacha20 test vector 1" {
const nonce = []u8{ 0, 0, 0, 0, 0, 0, 0, 0 };
chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
}
test "crypto.chacha20 test vector 2" {
@@ -290,7 +291,7 @@ test "crypto.chacha20 test vector 2" {
const nonce = []u8{ 0, 0, 0, 0, 0, 0, 0, 0 };
chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
}
test "crypto.chacha20 test vector 3" {
@@ -324,7 +325,7 @@ test "crypto.chacha20 test vector 3" {
const nonce = []u8{ 0, 0, 0, 0, 0, 0, 0, 1 };
chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
}
test "crypto.chacha20 test vector 4" {
@@ -358,7 +359,7 @@ test "crypto.chacha20 test vector 4" {
const nonce = []u8{ 1, 0, 0, 0, 0, 0, 0, 0 };
chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
}
test "crypto.chacha20 test vector 5" {
@@ -430,5 +431,5 @@ test "crypto.chacha20 test vector 5" {
};
chaCha20With64BitNonce(result[0..], input[0..], 0, key, nonce);
- assert(mem.eql(u8, expected_result, result));
+ testing.expectEqualSlices(u8, expected_result, result);
}
diff --git a/std/crypto/poly1305.zig b/std/crypto/poly1305.zig
index 0d7a4d672d..64adb17c45 100644
--- a/std/crypto/poly1305.zig
+++ b/std/crypto/poly1305.zig
@@ -230,5 +230,5 @@ test "poly1305 rfc7439 vector1" {
var mac: [16]u8 = undefined;
Poly1305.create(mac[0..], msg, key);
- std.debug.assert(std.mem.eql(u8, mac, expected_mac));
+ std.testing.expectEqualSlices(u8, expected_mac, mac);
}
diff --git a/std/crypto/test.zig b/std/crypto/test.zig
index 3fa24272e5..258cdf7320 100644
--- a/std/crypto/test.zig
+++ b/std/crypto/test.zig
@@ -1,6 +1,7 @@
-const debug = @import("../debug/index.zig");
-const mem = @import("../mem.zig");
-const fmt = @import("../fmt/index.zig");
+const std = @import("../index.zig");
+const testing = std.testing;
+const mem = std.mem;
+const fmt = std.fmt;
// Hash using the specified hasher `H` asserting `expected == H(input)`.
pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) void {
@@ -17,5 +18,5 @@ pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {
r.* = fmt.parseInt(u8, expected[2 * i .. 2 * i + 2], 16) catch unreachable;
}
- debug.assert(mem.eql(u8, expected_bytes, input));
+ testing.expectEqualSlices(u8, expected_bytes, input);
}
diff --git a/std/crypto/x25519.zig b/std/crypto/x25519.zig
index daccb56808..9349569f97 100644
--- a/std/crypto/x25519.zig
+++ b/std/crypto/x25519.zig
@@ -581,8 +581,8 @@ test "x25519 public key calculation from secret key" {
var pk_calculated: [32]u8 = undefined;
try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
- std.debug.assert(X25519.createPublicKey(pk_calculated[0..], sk));
- std.debug.assert(std.mem.eql(u8, pk_calculated, pk_expected));
+ std.testing.expect(X25519.createPublicKey(pk_calculated[0..], sk));
+ std.testing.expect(std.mem.eql(u8, pk_calculated, pk_expected));
}
test "x25519 rfc7748 vector1" {
@@ -593,8 +593,8 @@ test "x25519 rfc7748 vector1" {
var output: [32]u8 = undefined;
- std.debug.assert(X25519.create(output[0..], secret_key, public_key));
- std.debug.assert(std.mem.eql(u8, output, expected_output));
+ std.testing.expect(X25519.create(output[0..], secret_key, public_key));
+ std.testing.expect(std.mem.eql(u8, output, expected_output));
}
test "x25519 rfc7748 vector2" {
@@ -605,8 +605,8 @@ test "x25519 rfc7748 vector2" {
var output: [32]u8 = undefined;
- std.debug.assert(X25519.create(output[0..], secret_key, public_key));
- std.debug.assert(std.mem.eql(u8, output, expected_output));
+ std.testing.expect(X25519.create(output[0..], secret_key, public_key));
+ std.testing.expect(std.mem.eql(u8, output, expected_output));
}
test "x25519 rfc7748 one iteration" {
@@ -619,13 +619,13 @@ test "x25519 rfc7748 one iteration" {
var i: usize = 0;
while (i < 1) : (i += 1) {
var output: [32]u8 = undefined;
- std.debug.assert(X25519.create(output[0..], k, u));
+ std.testing.expect(X25519.create(output[0..], k, u));
std.mem.copy(u8, u[0..], k[0..]);
std.mem.copy(u8, k[0..], output[0..]);
}
- std.debug.assert(std.mem.eql(u8, k[0..], expected_output));
+ std.testing.expect(std.mem.eql(u8, k[0..], expected_output));
}
test "x25519 rfc7748 1,000 iterations" {
@@ -643,13 +643,13 @@ test "x25519 rfc7748 1,000 iterations" {
var i: usize = 0;
while (i < 1000) : (i += 1) {
var output: [32]u8 = undefined;
- std.debug.assert(X25519.create(output[0..], k, u));
+ std.testing.expect(X25519.create(output[0..], k, u));
std.mem.copy(u8, u[0..], k[0..]);
std.mem.copy(u8, k[0..], output[0..]);
}
- std.debug.assert(std.mem.eql(u8, k[0..], expected_output));
+ std.testing.expect(std.mem.eql(u8, k[0..], expected_output));
}
test "x25519 rfc7748 1,000,000 iterations" {
@@ -666,11 +666,11 @@ test "x25519 rfc7748 1,000,000 iterations" {
var i: usize = 0;
while (i < 1000000) : (i += 1) {
var output: [32]u8 = undefined;
- std.debug.assert(X25519.create(output[0..], k, u));
+ std.testing.expect(X25519.create(output[0..], k, u));
std.mem.copy(u8, u[0..], k[0..]);
std.mem.copy(u8, k[0..], output[0..]);
}
- std.debug.assert(std.mem.eql(u8, k[0..], expected_output));
+ std.testing.expect(std.mem.eql(u8, k[0..], expected_output));
}
diff --git a/std/cstr.zig b/std/cstr.zig
index a8aaf21279..abd2eac48f 100644
--- a/std/cstr.zig
+++ b/std/cstr.zig
@@ -2,7 +2,7 @@ const std = @import("index.zig");
const builtin = @import("builtin");
const debug = std.debug;
const mem = std.mem;
-const assert = debug.assert;
+const testing = std.testing;
pub const line_sep = switch (builtin.os) {
builtin.Os.windows => "\r\n",
@@ -42,8 +42,8 @@ test "cstr fns" {
}
fn testCStrFnsImpl() void {
- assert(cmp(c"aoeu", c"aoez") == -1);
- assert(len(c"123456789") == 9);
+ testing.expect(cmp(c"aoeu", c"aoez") == -1);
+ testing.expect(len(c"123456789") == 9);
}
/// Returns a mutable slice with 1 more byte of length which is a null byte.
diff --git a/std/debug/index.zig b/std/debug/index.zig
index a1e2747df5..7e5be9acef 100644
--- a/std/debug/index.zig
+++ b/std/debug/index.zig
@@ -107,37 +107,15 @@ pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void {
/// This function invokes undefined behavior when `ok` is `false`.
/// In Debug and ReleaseSafe modes, calls to this function are always
/// generated, and the `unreachable` statement triggers a panic.
-/// In ReleaseFast and ReleaseSmall modes, calls to this function can be
-/// optimized away.
+/// In ReleaseFast and ReleaseSmall modes, calls to this function are
+/// optimized away, and in fact the optimizer is able to use the assertion
+/// in its heuristics.
+/// Inside a test block, it is best to use the `std.testing` module rather
+/// than this function, because this function may not detect a test failure
+/// in ReleaseFast and ReleaseSafe mode. Outside of a test block, this assert
+/// function is the correct function to use.
pub fn assert(ok: bool) void {
- if (!ok) {
- // In ReleaseFast test mode, we still want assert(false) to crash, so
- // we insert an explicit call to @panic instead of unreachable.
- // TODO we should use `assertOrPanic` in tests and remove this logic.
- if (builtin.is_test) {
- @panic("assertion failure");
- } else {
- unreachable; // assertion failure
- }
- }
-}
-
-/// TODO: add `==` operator for `error_union == error_set`, and then
-/// remove this function
-pub fn assertError(value: var, expected_error: anyerror) void {
- if (value) {
- @panic("expected error");
- } else |actual_error| {
- assert(actual_error == expected_error);
- }
-}
-
-/// Call this function when you want to panic if the condition is not true.
-/// If `ok` is `false`, this function will panic in every release mode.
-pub fn assertOrPanic(ok: bool) void {
- if (!ok) {
- @panic("assertion failure");
- }
+ if (!ok) unreachable; // assertion failure
}
pub fn panic(comptime format: []const u8, args: ...) noreturn {
diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig
index 4d19951318..66026b1f29 100644
--- a/std/dynamic_library.zig
+++ b/std/dynamic_library.zig
@@ -6,6 +6,7 @@ const mem = std.mem;
const cstr = std.cstr;
const os = std.os;
const assert = std.debug.assert;
+const testing = std.testing;
const elf = std.elf;
const linux = os.linux;
const windows = os.windows;
@@ -206,7 +207,7 @@ test "dynamic_library" {
};
const dynlib = DynLib.open(std.debug.global_allocator, libname) catch |err| {
- assert(err == error.FileNotFound);
+ testing.expect(err == error.FileNotFound);
return;
};
@panic("Expected error from function");
diff --git a/std/event/channel.zig b/std/event/channel.zig
index f8cdae6208..4af9bf612b 100644
--- a/std/event/channel.zig
+++ b/std/event/channel.zig
@@ -1,6 +1,7 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const testing = std.testing;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
const Loop = std.event.Loop;
@@ -350,19 +351,19 @@ async fn testChannelGetter(loop: *Loop, channel: *Channel(i32)) void {
const value1_promise = try async channel.get();
const value1 = await value1_promise;
- assert(value1 == 1234);
+ testing.expect(value1 == 1234);
const value2_promise = try async channel.get();
const value2 = await value2_promise;
- assert(value2 == 4567);
+ testing.expect(value2 == 4567);
const value3_promise = try async channel.getOrNull();
const value3 = await value3_promise;
- assert(value3 == null);
+ testing.expect(value3 == null);
const last_put = try async testPut(channel, 4444);
const value4 = await try async channel.getOrNull();
- assert(value4.? == 4444);
+ testing.expect(value4.? == 4444);
await last_put;
}
diff --git a/std/event/fs.zig b/std/event/fs.zig
index fd0fe434cb..0e7482ec60 100644
--- a/std/event/fs.zig
+++ b/std/event/fs.zig
@@ -2,6 +2,7 @@ const builtin = @import("builtin");
const std = @import("../index.zig");
const event = std.event;
const assert = std.debug.assert;
+const testing = std.testing;
const os = std.os;
const mem = std.mem;
const posix = os.posix;
@@ -1349,13 +1350,13 @@ async fn testFsWatch(loop: *Loop) !void {
try await try async writeFile(loop, file_path, contents);
const read_contents = try await try async readFile(loop, file_path, 1024 * 1024);
- assert(mem.eql(u8, read_contents, contents));
+ testing.expectEqualSlices(u8, contents, read_contents);
// now watch the file
var watch = try Watch(void).create(loop, 0);
defer watch.destroy();
- assert((try await try async watch.addFile(file_path, {})) == null);
+ testing.expect((try await try async watch.addFile(file_path, {})) == null);
const ev = try async watch.channel.get();
var ev_consumed = false;
@@ -1375,10 +1376,10 @@ async fn testFsWatch(loop: *Loop) !void {
WatchEventId.Delete => @panic("wrong event"),
}
const contents_updated = try await try async readFile(loop, file_path, 1024 * 1024);
- assert(mem.eql(u8, contents_updated,
+ testing.expectEqualSlices(u8,
\\line 1
\\lorem ipsum
- ));
+ , contents_updated);
// TODO test deleting the file and then re-adding it. we should get events for both
}
diff --git a/std/event/future.zig b/std/event/future.zig
index 55ed01046d..66acac5ad7 100644
--- a/std/event/future.zig
+++ b/std/event/future.zig
@@ -1,5 +1,6 @@
const std = @import("../index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const builtin = @import("builtin");
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -114,7 +115,7 @@ async fn testFuture(loop: *Loop) void {
const result = (await a) + (await b);
cancel c;
- assert(result == 12);
+ testing.expect(result == 12);
}
async fn waitOnFuture(future: *Future(i32)) i32 {
diff --git a/std/event/group.zig b/std/event/group.zig
index 7f6b5d953b..25e79640cb 100644
--- a/std/event/group.zig
+++ b/std/event/group.zig
@@ -4,7 +4,7 @@ const Lock = std.event.Lock;
const Loop = std.event.Loop;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
-const assert = std.debug.assert;
+const testing = std.testing;
/// ReturnType must be `void` or `E!void`
pub fn Group(comptime ReturnType: type) type {
@@ -146,12 +146,12 @@ async fn testGroup(loop: *Loop) void {
group.add(async sleepALittle(&count) catch @panic("memory")) catch @panic("memory");
group.call(increaseByTen, &count) catch @panic("memory");
await (async group.wait() catch @panic("memory"));
- assert(count == 11);
+ testing.expect(count == 11);
var another = Group(anyerror!void).init(loop);
another.add(async somethingElse() catch @panic("memory")) catch @panic("memory");
another.call(doSomethingThatFails) catch @panic("memory");
- std.debug.assertError(await (async another.wait() catch @panic("memory")), error.ItBroke);
+ testing.expectError(error.ItBroke, await (async another.wait() catch @panic("memory")));
}
async fn sleepALittle(count: *usize) void {
diff --git a/std/event/lock.zig b/std/event/lock.zig
index 01978e1909..d6a246cee5 100644
--- a/std/event/lock.zig
+++ b/std/event/lock.zig
@@ -1,6 +1,7 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -141,7 +142,7 @@ test "std.event.Lock" {
defer cancel handle;
loop.run();
- assert(mem.eql(i32, shared_test_data, [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len));
+ testing.expectEqualSlices(i32, [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len, shared_test_data);
}
async fn testLock(loop: *Loop, lock: *Lock) void {
diff --git a/std/event/loop.zig b/std/event/loop.zig
index d5228db604..b92bf41982 100644
--- a/std/event/loop.zig
+++ b/std/event/loop.zig
@@ -1,6 +1,7 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -896,7 +897,7 @@ test "std.event.Loop - call" {
loop.run();
- assert(did_it);
+ testing.expect(did_it);
}
async fn testEventLoop() i32 {
@@ -905,6 +906,6 @@ async fn testEventLoop() i32 {
async fn testEventLoop2(h: promise->i32, did_it: *bool) void {
const value = await h;
- assert(value == 1234);
+ testing.expect(value == 1234);
did_it.* = true;
}
diff --git a/std/event/net.zig b/std/event/net.zig
index 9dac6aa566..48461c3d81 100644
--- a/std/event/net.zig
+++ b/std/event/net.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
-const assert = std.debug.assert;
+const testing = std.testing;
const event = std.event;
const mem = std.mem;
const os = std.os;
@@ -326,7 +326,7 @@ async fn doAsyncTest(loop: *Loop, address: *const std.net.Address, server: *Serv
var buf: [512]u8 = undefined;
const amt_read = try socket_file.read(buf[0..]);
const msg = buf[0..amt_read];
- assert(mem.eql(u8, msg, "hello from server\n"));
+ testing.expect(mem.eql(u8, msg, "hello from server\n"));
server.close();
}
diff --git a/std/event/rwlock.zig b/std/event/rwlock.zig
index f272ac71ea..26ccd12b73 100644
--- a/std/event/rwlock.zig
+++ b/std/event/rwlock.zig
@@ -1,6 +1,7 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -231,7 +232,7 @@ test "std.event.RwLock" {
loop.run();
const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
- assert(mem.eql(i32, shared_test_data, expected_result));
+ testing.expectEqualSlices(i32, expected_result, shared_test_data);
}
async fn testLock(loop: *Loop, lock: *RwLock) void {
@@ -293,7 +294,7 @@ async fn readRunner(lock: *RwLock) void {
const handle = await lock_promise;
defer handle.release();
- assert(shared_test_index == 0);
- assert(shared_test_data[i] == @intCast(i32, shared_count));
+ testing.expect(shared_test_index == 0);
+ testing.expect(shared_test_data[i] == @intCast(i32, shared_count));
}
}
diff --git a/std/fmt/index.zig b/std/fmt/index.zig
index 6097a12c23..05b028112f 100644
--- a/std/fmt/index.zig
+++ b/std/fmt/index.zig
@@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const debug = std.debug;
const assert = debug.assert;
-const assertError = debug.assertError;
+const testing = std.testing;
const mem = std.mem;
const builtin = @import("builtin");
const errol = @import("errol/index.zig");
@@ -588,7 +588,7 @@ pub fn formatFloatDecimal(
}
// Remaining fractional portion, zero-padding if insufficient.
- debug.assert(precision >= printed);
+ assert(precision >= printed);
if (num_digits_whole_no_pad + precision - printed < float_decimal.digits.len) {
try output(context, float_decimal.digits[num_digits_whole_no_pad .. num_digits_whole_no_pad + precision - printed]);
return;
@@ -798,13 +798,13 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
}
test "fmt.parseInt" {
- assert((parseInt(i32, "-10", 10) catch unreachable) == -10);
- assert((parseInt(i32, "+10", 10) catch unreachable) == 10);
- assert(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter);
- assert(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter);
- assert(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter);
- assert((parseInt(u8, "255", 10) catch unreachable) == 255);
- assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
+ testing.expect((parseInt(i32, "-10", 10) catch unreachable) == -10);
+ testing.expect((parseInt(i32, "+10", 10) catch unreachable) == 10);
+ testing.expect(if (parseInt(i32, " 10", 10)) |_| false else |err| err == error.InvalidCharacter);
+ testing.expect(if (parseInt(i32, "10 ", 10)) |_| false else |err| err == error.InvalidCharacter);
+ testing.expect(if (parseInt(u32, "-10", 10)) |_| false else |err| err == error.InvalidCharacter);
+ testing.expect((parseInt(u8, "255", 10) catch unreachable) == 255);
+ testing.expect(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
}
const ParseUnsignedError = error{
@@ -829,30 +829,30 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
}
test "parseUnsigned" {
- assert((try parseUnsigned(u16, "050124", 10)) == 50124);
- assert((try parseUnsigned(u16, "65535", 10)) == 65535);
- assertError(parseUnsigned(u16, "65536", 10), error.Overflow);
+ testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);
+ testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);
+ testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
- assert((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
- assertError(parseUnsigned(u64, "10000000000000000", 16), error.Overflow);
+ testing.expect((try parseUnsigned(u64, "0ffffffffffffffff", 16)) == 0xffffffffffffffff);
+ testing.expectError(error.Overflow, parseUnsigned(u64, "10000000000000000", 16));
- assert((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
+ testing.expect((try parseUnsigned(u32, "DeadBeef", 16)) == 0xDEADBEEF);
- assert((try parseUnsigned(u7, "1", 10)) == 1);
- assert((try parseUnsigned(u7, "1000", 2)) == 8);
+ testing.expect((try parseUnsigned(u7, "1", 10)) == 1);
+ testing.expect((try parseUnsigned(u7, "1000", 2)) == 8);
- assertError(parseUnsigned(u32, "f", 10), error.InvalidCharacter);
- assertError(parseUnsigned(u8, "109", 8), error.InvalidCharacter);
+ testing.expectError(error.InvalidCharacter, parseUnsigned(u32, "f", 10));
+ testing.expectError(error.InvalidCharacter, parseUnsigned(u8, "109", 8));
- assert((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
+ testing.expect((try parseUnsigned(u32, "NUMBER", 36)) == 1442151747);
// these numbers should fit even though the radix itself doesn't fit in the destination type
- assert((try parseUnsigned(u1, "0", 10)) == 0);
- assert((try parseUnsigned(u1, "1", 10)) == 1);
- assertError(parseUnsigned(u1, "2", 10), error.Overflow);
- assert((try parseUnsigned(u1, "001", 16)) == 1);
- assert((try parseUnsigned(u2, "3", 16)) == 3);
- assertError(parseUnsigned(u2, "4", 16), error.Overflow);
+ testing.expect((try parseUnsigned(u1, "0", 10)) == 0);
+ testing.expect((try parseUnsigned(u1, "1", 10)) == 1);
+ testing.expectError(error.Overflow, parseUnsigned(u1, "2", 10));
+ testing.expect((try parseUnsigned(u1, "001", 16)) == 1);
+ testing.expect((try parseUnsigned(u2, "3", 16)) == 3);
+ testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
}
pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
@@ -910,19 +910,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
test "buf print int" {
var buffer: [max_int_digits]u8 = undefined;
const buf = buffer[0..];
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, 0), "-101111000110000101001110"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, 0), "-12345678"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, 0), "-bc614e"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, 0), "-BC614E"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, 0), "-101111000110000101001110"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, 0), "-12345678"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, 0), "-bc614e"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, 0), "-BC614E"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, 0), "12345678"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, 0), "12345678"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, 6), "000666"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 6), "001234"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 1), "1234"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, 6), "000666"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 6), "001234"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, 1), "1234"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, 3), "+42"));
- assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, 3), "+42"));
+ testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
}
fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) []u8 {
@@ -939,7 +939,7 @@ test "parse u64 digit too big" {
test "parse unsigned comptime" {
comptime {
- assert((try parseUnsigned(usize, "2", 10)) == 2);
+ testing.expect((try parseUnsigned(usize, "2", 10)) == 2);
}
}
@@ -977,17 +977,17 @@ test "fmt.format" {
var context = BufPrintContext{ .remaining = buf1[0..] };
try formatType(1234, "", &context, error{BufferTooSmall}, bufPrintWrite);
var res = buf1[0 .. buf1.len - context.remaining.len];
- assert(mem.eql(u8, res, "1234"));
+ testing.expect(mem.eql(u8, res, "1234"));
context = BufPrintContext{ .remaining = buf1[0..] };
try formatType('a', "c", &context, error{BufferTooSmall}, bufPrintWrite);
res = buf1[0 .. buf1.len - context.remaining.len];
- assert(mem.eql(u8, res, "a"));
+ testing.expect(mem.eql(u8, res, "a"));
context = BufPrintContext{ .remaining = buf1[0..] };
try formatType(0b1100, "b", &context, error{BufferTooSmall}, bufPrintWrite);
res = buf1[0 .. buf1.len - context.remaining.len];
- assert(mem.eql(u8, res, "1100"));
+ testing.expect(mem.eql(u8, res, "1100"));
}
{
const value: [3]u8 = "abc";
@@ -1053,19 +1053,19 @@ test "fmt.format" {
var buf1: [32]u8 = undefined;
const value: f32 = 1.34;
const result = try bufPrint(buf1[0..], "f32: {e}\n", value);
- assert(mem.eql(u8, result, "f32: 1.34000003e+00\n"));
+ testing.expect(mem.eql(u8, result, "f32: 1.34000003e+00\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f32 = 12.34;
const result = try bufPrint(buf1[0..], "f32: {e}\n", value);
- assert(mem.eql(u8, result, "f32: 1.23400001e+01\n"));
+ testing.expect(mem.eql(u8, result, "f32: 1.23400001e+01\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = -12.34e10;
const result = try bufPrint(buf1[0..], "f64: {e}\n", value);
- assert(mem.eql(u8, result, "f64: -1.234e+11\n"));
+ testing.expect(mem.eql(u8, result, "f64: -1.234e+11\n"));
}
{
// This fails on release due to a minor rounding difference.
@@ -1075,26 +1075,26 @@ test "fmt.format" {
var buf1: [32]u8 = undefined;
const value: f64 = 9.999960e-40;
const result = try bufPrint(buf1[0..], "f64: {e}\n", value);
- assert(mem.eql(u8, result, "f64: 9.99996e-40\n"));
+ testing.expect(mem.eql(u8, result, "f64: 9.99996e-40\n"));
}
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 1.409706e-42;
const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
- assert(mem.eql(u8, result, "f64: 1.40971e-42\n"));
+ testing.expect(mem.eql(u8, result, "f64: 1.40971e-42\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = @bitCast(f32, u32(814313563));
const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
- assert(mem.eql(u8, result, "f64: 1.00000e-09\n"));
+ testing.expect(mem.eql(u8, result, "f64: 1.00000e-09\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = @bitCast(f32, u32(1006632960));
const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
- assert(mem.eql(u8, result, "f64: 7.81250e-03\n"));
+ testing.expect(mem.eql(u8, result, "f64: 7.81250e-03\n"));
}
{
// libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
@@ -1102,47 +1102,47 @@ test "fmt.format" {
var buf1: [32]u8 = undefined;
const value: f64 = @bitCast(f32, u32(1203982400));
const result = try bufPrint(buf1[0..], "f64: {e5}\n", value);
- assert(mem.eql(u8, result, "f64: 1.00001e+05\n"));
+ testing.expect(mem.eql(u8, result, "f64: 1.00001e+05\n"));
}
{
var buf1: [32]u8 = undefined;
const result = try bufPrint(buf1[0..], "f64: {}\n", math.nan_f64);
- assert(mem.eql(u8, result, "f64: nan\n"));
+ testing.expect(mem.eql(u8, result, "f64: nan\n"));
}
if (builtin.arch != builtin.Arch.armv8) {
// negative nan is not defined by IEE 754,
// and ARM thus normalizes it to positive nan
var buf1: [32]u8 = undefined;
const result = try bufPrint(buf1[0..], "f64: {}\n", -math.nan_f64);
- assert(mem.eql(u8, result, "f64: -nan\n"));
+ testing.expect(mem.eql(u8, result, "f64: -nan\n"));
}
{
var buf1: [32]u8 = undefined;
const result = try bufPrint(buf1[0..], "f64: {}\n", math.inf_f64);
- assert(mem.eql(u8, result, "f64: inf\n"));
+ testing.expect(mem.eql(u8, result, "f64: inf\n"));
}
{
var buf1: [32]u8 = undefined;
const result = try bufPrint(buf1[0..], "f64: {}\n", -math.inf_f64);
- assert(mem.eql(u8, result, "f64: -inf\n"));
+ testing.expect(mem.eql(u8, result, "f64: -inf\n"));
}
{
var buf1: [64]u8 = undefined;
const value: f64 = 1.52314e+29;
const result = try bufPrint(buf1[0..], "f64: {.}\n", value);
- assert(mem.eql(u8, result, "f64: 152314000000000000000000000000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 152314000000000000000000000000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f32 = 1.1234;
const result = try bufPrint(buf1[0..], "f32: {.1}\n", value);
- assert(mem.eql(u8, result, "f32: 1.1\n"));
+ testing.expect(mem.eql(u8, result, "f32: 1.1\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f32 = 1234.567;
const result = try bufPrint(buf1[0..], "f32: {.2}\n", value);
- assert(mem.eql(u8, result, "f32: 1234.57\n"));
+ testing.expect(mem.eql(u8, result, "f32: 1234.57\n"));
}
{
var buf1: [32]u8 = undefined;
@@ -1150,92 +1150,92 @@ test "fmt.format" {
const result = try bufPrint(buf1[0..], "f32: {.4}\n", value);
// -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
// -11.12339... is rounded back up to -11.1234
- assert(mem.eql(u8, result, "f32: -11.1234\n"));
+ testing.expect(mem.eql(u8, result, "f32: -11.1234\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f32 = 91.12345;
const result = try bufPrint(buf1[0..], "f32: {.5}\n", value);
- assert(mem.eql(u8, result, "f32: 91.12345\n"));
+ testing.expect(mem.eql(u8, result, "f32: 91.12345\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 91.12345678901235;
const result = try bufPrint(buf1[0..], "f64: {.10}\n", value);
- assert(mem.eql(u8, result, "f64: 91.1234567890\n"));
+ testing.expect(mem.eql(u8, result, "f64: 91.1234567890\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 0.0;
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 5.700;
const result = try bufPrint(buf1[0..], "f64: {.0}\n", value);
- assert(mem.eql(u8, result, "f64: 6\n"));
+ testing.expect(mem.eql(u8, result, "f64: 6\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 9.999;
const result = try bufPrint(buf1[0..], "f64: {.1}\n", value);
- assert(mem.eql(u8, result, "f64: 10.0\n"));
+ testing.expect(mem.eql(u8, result, "f64: 10.0\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 1.0;
const result = try bufPrint(buf1[0..], "f64: {.3}\n", value);
- assert(mem.eql(u8, result, "f64: 1.000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 1.000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 0.0003;
const result = try bufPrint(buf1[0..], "f64: {.8}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00030000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00030000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 1.40130e-45;
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = 9.999960e-40;
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00000\n"));
}
// libc checks
{
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(916964781)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00001\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00001\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(925353389)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.00001\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.00001\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(1036831278)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.10000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.10000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(1065353133)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 1.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 1.00000\n"));
}
{
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(1092616192)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 10.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 10.00000\n"));
}
// libc differences
{
@@ -1245,7 +1245,7 @@ test "fmt.format" {
// floats of the form x.yyyy25 on a precision point.
const value: f64 = f64(@bitCast(f32, u32(1015021568)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 0.01563\n"));
+ testing.expect(mem.eql(u8, result, "f64: 0.01563\n"));
}
// std-windows-x86_64-Debug-bare test case fails
{
@@ -1255,7 +1255,7 @@ test "fmt.format" {
var buf1: [32]u8 = undefined;
const value: f64 = f64(@bitCast(f32, u32(1518338049)));
const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
- assert(mem.eql(u8, result, "f64: 18014400656965630.00000\n"));
+ testing.expect(mem.eql(u8, result, "f64: 18014400656965630.00000\n"));
}
//custom type format
{
@@ -1336,10 +1336,10 @@ test "fmt.format" {
var buf: [100]u8 = undefined;
const uu_result = try bufPrint(buf[0..], "{}", uu_inst);
- debug.assert(mem.eql(u8, uu_result[0..3], "UU@"));
+ testing.expect(mem.eql(u8, uu_result[0..3], "UU@"));
const eu_result = try bufPrint(buf[0..], "{}", eu_inst);
- debug.assert(mem.eql(u8, uu_result[0..3], "EU@"));
+ testing.expect(mem.eql(u8, uu_result[0..3], "EU@"));
}
//enum format
{
@@ -1398,11 +1398,11 @@ pub fn trim(buf: []const u8) []const u8 {
}
test "fmt.trim" {
- assert(mem.eql(u8, "abc", trim("\n abc \t")));
- assert(mem.eql(u8, "", trim(" ")));
- assert(mem.eql(u8, "", trim("")));
- assert(mem.eql(u8, "abc", trim(" abc")));
- assert(mem.eql(u8, "abc", trim("abc ")));
+ testing.expect(mem.eql(u8, "abc", trim("\n abc \t")));
+ testing.expect(mem.eql(u8, "", trim(" ")));
+ testing.expect(mem.eql(u8, "", trim("")));
+ testing.expect(mem.eql(u8, "abc", trim(" abc")));
+ testing.expect(mem.eql(u8, "abc", trim("abc ")));
}
pub fn isWhiteSpace(byte: u8) bool {
diff --git a/std/hash/adler.zig b/std/hash/adler.zig
index 9c5966f89b..78f960367a 100644
--- a/std/hash/adler.zig
+++ b/std/hash/adler.zig
@@ -4,7 +4,7 @@
// https://github.com/madler/zlib/blob/master/adler32.c
const std = @import("../index.zig");
-const debug = std.debug;
+const testing = std.testing;
pub const Adler32 = struct {
const base = 65521;
@@ -89,19 +89,19 @@ pub const Adler32 = struct {
};
test "adler32 sanity" {
- debug.assert(Adler32.hash("a") == 0x620062);
- debug.assert(Adler32.hash("example") == 0xbc002ed);
+ testing.expect(Adler32.hash("a") == 0x620062);
+ testing.expect(Adler32.hash("example") == 0xbc002ed);
}
test "adler32 long" {
const long1 = []u8{1} ** 1024;
- debug.assert(Adler32.hash(long1[0..]) == 0x06780401);
+ testing.expect(Adler32.hash(long1[0..]) == 0x06780401);
const long2 = []u8{1} ** 1025;
- debug.assert(Adler32.hash(long2[0..]) == 0x0a7a0402);
+ testing.expect(Adler32.hash(long2[0..]) == 0x0a7a0402);
}
test "adler32 very long" {
const long = []u8{1} ** 5553;
- debug.assert(Adler32.hash(long[0..]) == 0x707f15b2);
+ testing.expect(Adler32.hash(long[0..]) == 0x707f15b2);
}
diff --git a/std/hash/crc.zig b/std/hash/crc.zig
index c4bd92884a..9bea358bf1 100644
--- a/std/hash/crc.zig
+++ b/std/hash/crc.zig
@@ -7,6 +7,7 @@
const std = @import("../index.zig");
const debug = std.debug;
+const testing = std.testing;
pub const Polynomial = struct {
const IEEE = 0xedb88320;
@@ -101,17 +102,17 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
test "crc32 ieee" {
const Crc32Ieee = Crc32WithPoly(Polynomial.IEEE);
- debug.assert(Crc32Ieee.hash("") == 0x00000000);
- debug.assert(Crc32Ieee.hash("a") == 0xe8b7be43);
- debug.assert(Crc32Ieee.hash("abc") == 0x352441c2);
+ testing.expect(Crc32Ieee.hash("") == 0x00000000);
+ testing.expect(Crc32Ieee.hash("a") == 0xe8b7be43);
+ testing.expect(Crc32Ieee.hash("abc") == 0x352441c2);
}
test "crc32 castagnoli" {
const Crc32Castagnoli = Crc32WithPoly(Polynomial.Castagnoli);
- debug.assert(Crc32Castagnoli.hash("") == 0x00000000);
- debug.assert(Crc32Castagnoli.hash("a") == 0xc1d04330);
- debug.assert(Crc32Castagnoli.hash("abc") == 0x364b3fb7);
+ testing.expect(Crc32Castagnoli.hash("") == 0x00000000);
+ testing.expect(Crc32Castagnoli.hash("a") == 0xc1d04330);
+ testing.expect(Crc32Castagnoli.hash("abc") == 0x364b3fb7);
}
// half-byte lookup table implementation.
@@ -165,15 +166,15 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
test "small crc32 ieee" {
const Crc32Ieee = Crc32SmallWithPoly(Polynomial.IEEE);
- debug.assert(Crc32Ieee.hash("") == 0x00000000);
- debug.assert(Crc32Ieee.hash("a") == 0xe8b7be43);
- debug.assert(Crc32Ieee.hash("abc") == 0x352441c2);
+ testing.expect(Crc32Ieee.hash("") == 0x00000000);
+ testing.expect(Crc32Ieee.hash("a") == 0xe8b7be43);
+ testing.expect(Crc32Ieee.hash("abc") == 0x352441c2);
}
test "small crc32 castagnoli" {
const Crc32Castagnoli = Crc32SmallWithPoly(Polynomial.Castagnoli);
- debug.assert(Crc32Castagnoli.hash("") == 0x00000000);
- debug.assert(Crc32Castagnoli.hash("a") == 0xc1d04330);
- debug.assert(Crc32Castagnoli.hash("abc") == 0x364b3fb7);
+ testing.expect(Crc32Castagnoli.hash("") == 0x00000000);
+ testing.expect(Crc32Castagnoli.hash("a") == 0xc1d04330);
+ testing.expect(Crc32Castagnoli.hash("abc") == 0x364b3fb7);
}
diff --git a/std/hash/fnv.zig b/std/hash/fnv.zig
index 9bb18f14b3..6876b636f6 100644
--- a/std/hash/fnv.zig
+++ b/std/hash/fnv.zig
@@ -5,7 +5,7 @@
// https://tools.ietf.org/html/draft-eastlake-fnv-14
const std = @import("../index.zig");
-const debug = std.debug;
+const testing = std.testing;
pub const Fnv1a_32 = Fnv1a(u32, 0x01000193, 0x811c9dc5);
pub const Fnv1a_64 = Fnv1a(u64, 0x100000001b3, 0xcbf29ce484222325);
@@ -41,18 +41,18 @@ fn Fnv1a(comptime T: type, comptime prime: T, comptime offset: T) type {
}
test "fnv1a-32" {
- debug.assert(Fnv1a_32.hash("") == 0x811c9dc5);
- debug.assert(Fnv1a_32.hash("a") == 0xe40c292c);
- debug.assert(Fnv1a_32.hash("foobar") == 0xbf9cf968);
+ testing.expect(Fnv1a_32.hash("") == 0x811c9dc5);
+ testing.expect(Fnv1a_32.hash("a") == 0xe40c292c);
+ testing.expect(Fnv1a_32.hash("foobar") == 0xbf9cf968);
}
test "fnv1a-64" {
- debug.assert(Fnv1a_64.hash("") == 0xcbf29ce484222325);
- debug.assert(Fnv1a_64.hash("a") == 0xaf63dc4c8601ec8c);
- debug.assert(Fnv1a_64.hash("foobar") == 0x85944171f73967e8);
+ testing.expect(Fnv1a_64.hash("") == 0xcbf29ce484222325);
+ testing.expect(Fnv1a_64.hash("a") == 0xaf63dc4c8601ec8c);
+ testing.expect(Fnv1a_64.hash("foobar") == 0x85944171f73967e8);
}
test "fnv1a-128" {
- debug.assert(Fnv1a_128.hash("") == 0x6c62272e07bb014262b821756295c58d);
- debug.assert(Fnv1a_128.hash("a") == 0xd228cb696f1a8caf78912b704e4a8964);
+ testing.expect(Fnv1a_128.hash("") == 0x6c62272e07bb014262b821756295c58d);
+ testing.expect(Fnv1a_128.hash("a") == 0xd228cb696f1a8caf78912b704e4a8964);
}
diff --git a/std/hash/siphash.zig b/std/hash/siphash.zig
index ee26950272..c9a6128d35 100644
--- a/std/hash/siphash.zig
+++ b/std/hash/siphash.zig
@@ -6,7 +6,8 @@
// https://131002.net/siphash/
const std = @import("../index.zig");
-const debug = std.debug;
+const assert = std.debug.assert;
+const testing = std.testing;
const math = std.math;
const mem = std.mem;
@@ -21,8 +22,8 @@ pub fn SipHash128(comptime c_rounds: usize, comptime d_rounds: usize) type {
}
fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) type {
- debug.assert(T == u64 or T == u128);
- debug.assert(c_rounds > 0 and d_rounds > 0);
+ assert(T == u64 or T == u128);
+ assert(c_rounds > 0 and d_rounds > 0);
return struct {
const Self = @This();
@@ -40,7 +41,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
msg_len: u8,
pub fn init(key: []const u8) Self {
- debug.assert(key.len >= 16);
+ assert(key.len >= 16);
const k0 = mem.readIntSliceLittle(u64, key[0..8]);
const k1 = mem.readIntSliceLittle(u64, key[8..16]);
@@ -119,7 +120,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
}
fn round(d: *Self, b: []const u8) void {
- debug.assert(b.len == 8);
+ assert(b.len == 8);
const m = mem.readIntSliceLittle(u64, b[0..]);
d.v3 ^= m;
@@ -236,7 +237,7 @@ test "siphash64-2-4 sanity" {
buffer[i] = @intCast(u8, i);
const expected = mem.readIntLittle(u64, &vector);
- debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
+ testing.expect(siphash.hash(test_key, buffer[0..i]) == expected);
}
}
@@ -315,6 +316,6 @@ test "siphash128-2-4 sanity" {
buffer[i] = @intCast(u8, i);
const expected = mem.readIntLittle(u128, &vector);
- debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
+ testing.expect(siphash.hash(test_key, buffer[0..i]) == expected);
}
}
diff --git a/std/hash_map.zig b/std/hash_map.zig
index a63a549814..716f04ff34 100644
--- a/std/hash_map.zig
+++ b/std/hash_map.zig
@@ -1,6 +1,7 @@
const std = @import("index.zig");
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const math = std.math;
const mem = std.mem;
const Allocator = mem.Allocator;
@@ -342,37 +343,37 @@ test "basic hash map usage" {
var map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);
defer map.deinit();
- assert((try map.put(1, 11)) == null);
- assert((try map.put(2, 22)) == null);
- assert((try map.put(3, 33)) == null);
- assert((try map.put(4, 44)) == null);
- assert((try map.put(5, 55)) == null);
+ testing.expect((try map.put(1, 11)) == null);
+ testing.expect((try map.put(2, 22)) == null);
+ testing.expect((try map.put(3, 33)) == null);
+ testing.expect((try map.put(4, 44)) == null);
+ testing.expect((try map.put(5, 55)) == null);
- assert((try map.put(5, 66)).?.value == 55);
- assert((try map.put(5, 55)).?.value == 66);
+ testing.expect((try map.put(5, 66)).?.value == 55);
+ testing.expect((try map.put(5, 55)).?.value == 66);
const gop1 = try map.getOrPut(5);
- assert(gop1.found_existing == true);
- assert(gop1.kv.value == 55);
+ testing.expect(gop1.found_existing == true);
+ testing.expect(gop1.kv.value == 55);
gop1.kv.value = 77;
- assert(map.get(5).?.value == 77);
+ testing.expect(map.get(5).?.value == 77);
const gop2 = try map.getOrPut(99);
- assert(gop2.found_existing == false);
+ testing.expect(gop2.found_existing == false);
gop2.kv.value = 42;
- assert(map.get(99).?.value == 42);
+ testing.expect(map.get(99).?.value == 42);
const gop3 = try map.getOrPutValue(5, 5);
- assert(gop3.value == 77);
+ testing.expect(gop3.value == 77);
const gop4 = try map.getOrPutValue(100, 41);
- assert(gop4.value == 41);
+ testing.expect(gop4.value == 41);
- assert(map.contains(2));
- assert(map.get(2).?.value == 22);
+ testing.expect(map.contains(2));
+ testing.expect(map.get(2).?.value == 22);
_ = map.remove(2);
- assert(map.remove(2) == null);
- assert(map.get(2) == null);
+ testing.expect(map.remove(2) == null);
+ testing.expect(map.get(2) == null);
}
test "iterator hash map" {
@@ -382,9 +383,9 @@ test "iterator hash map" {
var reset_map = AutoHashMap(i32, i32).init(&direct_allocator.allocator);
defer reset_map.deinit();
- assert((try reset_map.put(1, 11)) == null);
- assert((try reset_map.put(2, 22)) == null);
- assert((try reset_map.put(3, 33)) == null);
+ testing.expect((try reset_map.put(1, 11)) == null);
+ testing.expect((try reset_map.put(2, 22)) == null);
+ testing.expect((try reset_map.put(3, 33)) == null);
var keys = []i32{
3,
@@ -400,26 +401,26 @@ test "iterator hash map" {
var it = reset_map.iterator();
var count: usize = 0;
while (it.next()) |next| {
- assert(next.key == keys[count]);
- assert(next.value == values[count]);
+ testing.expect(next.key == keys[count]);
+ testing.expect(next.value == values[count]);
count += 1;
}
- assert(count == 3);
- assert(it.next() == null);
+ testing.expect(count == 3);
+ testing.expect(it.next() == null);
it.reset();
count = 0;
while (it.next()) |next| {
- assert(next.key == keys[count]);
- assert(next.value == values[count]);
+ testing.expect(next.key == keys[count]);
+ testing.expect(next.value == values[count]);
count += 1;
if (count == 2) break;
}
it.reset();
var entry = it.next().?;
- assert(entry.key == keys[0]);
- assert(entry.value == values[0]);
+ testing.expect(entry.key == keys[0]);
+ testing.expect(entry.value == values[0]);
}
pub fn getHashPtrAddrFn(comptime K: type) (fn (K) u32) {
diff --git a/std/heap.zig b/std/heap.zig
index 8a5ebf134c..e7088150a8 100644
--- a/std/heap.zig
+++ b/std/heap.zig
@@ -1,6 +1,7 @@
const std = @import("index.zig");
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const mem = std.mem;
const os = std.os;
const builtin = @import("builtin");
@@ -487,11 +488,11 @@ test "FixedBufferAllocator Reuse memory on realloc" {
var fixed_buffer_allocator = FixedBufferAllocator.init(small_fixed_buffer[0..]);
var slice0 = try fixed_buffer_allocator.allocator.alloc(u8, 5);
- assert(slice0.len == 5);
+ testing.expect(slice0.len == 5);
var slice1 = try fixed_buffer_allocator.allocator.realloc(u8, slice0, 10);
- assert(slice1.ptr == slice0.ptr);
- assert(slice1.len == 10);
- debug.assertError(fixed_buffer_allocator.allocator.realloc(u8, slice1, 11), error.OutOfMemory);
+ testing.expect(slice1.ptr == slice0.ptr);
+ testing.expect(slice1.len == 10);
+ testing.expectError(error.OutOfMemory, fixed_buffer_allocator.allocator.realloc(u8, slice1, 11));
}
// check that we don't re-use the memory if it's not the most recent block
{
@@ -502,10 +503,10 @@ test "FixedBufferAllocator Reuse memory on realloc" {
slice0[1] = 2;
var slice1 = try fixed_buffer_allocator.allocator.alloc(u8, 2);
var slice2 = try fixed_buffer_allocator.allocator.realloc(u8, slice0, 4);
- assert(slice0.ptr != slice2.ptr);
- assert(slice1.ptr != slice2.ptr);
- assert(slice2[0] == 1);
- assert(slice2[1] == 2);
+ testing.expect(slice0.ptr != slice2.ptr);
+ testing.expect(slice1.ptr != slice2.ptr);
+ testing.expect(slice2[0] == 1);
+ testing.expect(slice2[1] == 2);
}
}
@@ -519,28 +520,28 @@ test "ThreadSafeFixedBufferAllocator" {
fn testAllocator(allocator: *mem.Allocator) !void {
var slice = try allocator.alloc(*i32, 100);
- assert(slice.len == 100);
+ testing.expect(slice.len == 100);
for (slice) |*item, i| {
item.* = try allocator.create(i32);
item.*.* = @intCast(i32, i);
}
slice = try allocator.realloc(*i32, slice, 20000);
- assert(slice.len == 20000);
+ testing.expect(slice.len == 20000);
for (slice[0..100]) |item, i| {
- assert(item.* == @intCast(i32, i));
+ testing.expect(item.* == @intCast(i32, i));
allocator.destroy(item);
}
slice = try allocator.realloc(*i32, slice, 50);
- assert(slice.len == 50);
+ testing.expect(slice.len == 50);
slice = try allocator.realloc(*i32, slice, 25);
- assert(slice.len == 25);
+ testing.expect(slice.len == 25);
slice = try allocator.realloc(*i32, slice, 0);
- assert(slice.len == 0);
+ testing.expect(slice.len == 0);
slice = try allocator.realloc(*i32, slice, 10);
- assert(slice.len == 10);
+ testing.expect(slice.len == 10);
allocator.free(slice);
}
@@ -548,25 +549,25 @@ fn testAllocator(allocator: *mem.Allocator) !void {
fn testAllocatorAligned(allocator: *mem.Allocator, comptime alignment: u29) !void {
// initial
var slice = try allocator.alignedAlloc(u8, alignment, 10);
- assert(slice.len == 10);
+ testing.expect(slice.len == 10);
// grow
slice = try allocator.alignedRealloc(u8, alignment, slice, 100);
- assert(slice.len == 100);
+ testing.expect(slice.len == 100);
// shrink
slice = try allocator.alignedRealloc(u8, alignment, slice, 10);
- assert(slice.len == 10);
+ testing.expect(slice.len == 10);
// go to zero
slice = try allocator.alignedRealloc(u8, alignment, slice, 0);
- assert(slice.len == 0);
+ testing.expect(slice.len == 0);
// realloc from zero
slice = try allocator.alignedRealloc(u8, alignment, slice, 100);
- assert(slice.len == 100);
+ testing.expect(slice.len == 100);
// shrink with shrink
slice = allocator.alignedShrink(u8, alignment, slice, 10);
- assert(slice.len == 10);
+ testing.expect(slice.len == 10);
// shrink to zero
slice = allocator.alignedShrink(u8, alignment, slice, 0);
- assert(slice.len == 0);
+ testing.expect(slice.len == 0);
}
fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!void {
@@ -581,19 +582,19 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
_ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask);
var slice = try allocator.allocFn(allocator, 500, large_align);
- debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
+ testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
slice = try allocator.reallocFn(allocator, slice, 100, large_align);
- debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
+ testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
slice = try allocator.reallocFn(allocator, slice, 5000, large_align);
- debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
+ testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
slice = try allocator.reallocFn(allocator, slice, 10, large_align);
- debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
+ testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
slice = try allocator.reallocFn(allocator, slice, 20000, large_align);
- debug.assert(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
+ testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
allocator.free(slice);
}
diff --git a/std/index.zig b/std/index.zig
index 2a63244004..9d9b7ee8d6 100644
--- a/std/index.zig
+++ b/std/index.zig
@@ -31,6 +31,7 @@ pub const hash_map = @import("hash_map.zig");
pub const heap = @import("heap.zig");
pub const io = @import("io.zig");
pub const json = @import("json.zig");
+pub const lazyInit = @import("lazy_init.zig").lazyInit;
pub const macho = @import("macho.zig");
pub const math = @import("math/index.zig");
pub const mem = @import("mem.zig");
@@ -41,11 +42,10 @@ pub const pdb = @import("pdb.zig");
pub const rand = @import("rand/index.zig");
pub const rb = @import("rb.zig");
pub const sort = @import("sort.zig");
+pub const testing = @import("testing.zig");
pub const unicode = @import("unicode.zig");
pub const zig = @import("zig/index.zig");
-pub const lazyInit = @import("lazy_init.zig").lazyInit;
-
test "std" {
// run tests from these
_ = @import("array_list.zig");
@@ -60,7 +60,6 @@ test "std" {
_ = @import("segmented_list.zig");
_ = @import("spinlock.zig");
- _ = @import("dynamic_library.zig");
_ = @import("base64.zig");
_ = @import("build.zig");
_ = @import("c/index.zig");
@@ -69,24 +68,26 @@ test "std" {
_ = @import("cstr.zig");
_ = @import("debug/index.zig");
_ = @import("dwarf.zig");
+ _ = @import("dynamic_library.zig");
_ = @import("elf.zig");
_ = @import("empty.zig");
_ = @import("event.zig");
_ = @import("fmt/index.zig");
_ = @import("hash/index.zig");
+ _ = @import("heap.zig");
_ = @import("io.zig");
_ = @import("json.zig");
+ _ = @import("lazy_init.zig");
_ = @import("macho.zig");
_ = @import("math/index.zig");
- _ = @import("meta/index.zig");
_ = @import("mem.zig");
+ _ = @import("meta/index.zig");
_ = @import("net.zig");
- _ = @import("heap.zig");
_ = @import("os/index.zig");
- _ = @import("rand/index.zig");
_ = @import("pdb.zig");
+ _ = @import("rand/index.zig");
_ = @import("sort.zig");
+ _ = @import("testing.zig");
_ = @import("unicode.zig");
_ = @import("zig/index.zig");
- _ = @import("lazy_init.zig");
}
diff --git a/std/io.zig b/std/io.zig
index 81d90def6e..d7e8507f9b 100644
--- a/std/io.zig
+++ b/std/io.zig
@@ -13,6 +13,7 @@ const trait = meta.trait;
const Buffer = std.Buffer;
const fmt = std.fmt;
const File = std.os.File;
+const testing = std.testing;
const is_posix = builtin.os != builtin.Os.windows;
const is_windows = builtin.os == builtin.Os.windows;
@@ -664,7 +665,7 @@ test "io.SliceOutStream" {
const stream = &slice_stream.stream;
try stream.print("{}{}!", "Hello", "World");
- debug.assertOrPanic(mem.eql(u8, "HelloWorld!", slice_stream.getWritten()));
+ testing.expectEqualSlices(u8, "HelloWorld!", slice_stream.getWritten());
}
var null_out_stream_state = NullOutStream.init();
@@ -726,7 +727,7 @@ test "io.CountingOutStream" {
const bytes = "yay" ** 10000;
stream.write(bytes) catch unreachable;
- debug.assertOrPanic(counting_stream.bytes_written == bytes.len);
+ testing.expect(counting_stream.bytes_written == bytes.len);
}
pub fn BufferedOutStream(comptime Error: type) type {
@@ -1014,10 +1015,10 @@ test "io.readLineFrom" {
);
const stream = &mem_stream.stream;
- debug.assertOrPanic(mem.eql(u8, "Line 1", try readLineFrom(stream, &buf)));
- debug.assertOrPanic(mem.eql(u8, "Line 22", try readLineFrom(stream, &buf)));
- debug.assertError(readLineFrom(stream, &buf), error.EndOfStream);
- debug.assertOrPanic(mem.eql(u8, buf.toSlice(), "Line 1Line 22Line 333"));
+ testing.expectEqualSlices(u8, "Line 1", try readLineFrom(stream, &buf));
+ testing.expectEqualSlices(u8, "Line 22", try readLineFrom(stream, &buf));
+ testing.expectError(error.EndOfStream, readLineFrom(stream, &buf));
+ testing.expectEqualSlices(u8, "Line 1Line 22Line 333", buf.toSlice());
}
pub fn readLineSlice(slice: []u8) ![]u8 {
@@ -1045,8 +1046,8 @@ test "io.readLineSliceFrom" {
);
const stream = &mem_stream.stream;
- debug.assertOrPanic(mem.eql(u8, "Line 1", try readLineSliceFrom(stream, buf[0..])));
- debug.assertError(readLineSliceFrom(stream, buf[0..]), error.OutOfMemory);
+ testing.expectEqualSlices(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]));
+ testing.expectError(error.OutOfMemory, readLineSliceFrom(stream, buf[0..]));
}
/// Creates a deserializer that deserializes types from any stream.
diff --git a/std/io_test.zig b/std/io_test.zig
index 9a0687ec69..fb6e0ae7e9 100644
--- a/std/io_test.zig
+++ b/std/io_test.zig
@@ -3,8 +3,8 @@ const io = std.io;
const meta = std.meta;
const trait = std.trait;
const DefaultPrng = std.rand.DefaultPrng;
-const assert = std.debug.assert;
-const assertError = std.debug.assertError;
+const expect = std.testing.expect;
+const expectError = std.testing.expectError;
const mem = std.mem;
const os = std.os;
const builtin = @import("builtin");
@@ -35,7 +35,7 @@ test "write a file, read it, then delete it" {
const file_size = try file.getEndPos();
const expected_file_size = "begin".len + data.len + "end".len;
- assert(file_size == expected_file_size);
+ expect(file_size == expected_file_size);
var file_in_stream = file.inStream();
var buf_stream = io.BufferedInStream(os.File.ReadError).init(&file_in_stream.stream);
@@ -43,9 +43,9 @@ test "write a file, read it, then delete it" {
const contents = try st.readAllAlloc(allocator, 2 * 1024);
defer allocator.free(contents);
- assert(mem.eql(u8, contents[0.."begin".len], "begin"));
- assert(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
- assert(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
+ expect(mem.eql(u8, contents[0.."begin".len], "begin"));
+ expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
+ expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
}
try os.deleteFile(tmp_file_name);
}
@@ -61,7 +61,7 @@ test "BufferOutStream" {
const y: i32 = 1234;
try buf_stream.print("x: {}\ny: {}\n", x, y);
- assert(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
+ expect(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
}
test "SliceInStream" {
@@ -71,15 +71,15 @@ test "SliceInStream" {
var dest: [4]u8 = undefined;
var read = try ss.stream.read(dest[0..4]);
- assert(read == 4);
- assert(mem.eql(u8, dest[0..4], bytes[0..4]));
+ expect(read == 4);
+ expect(mem.eql(u8, dest[0..4], bytes[0..4]));
read = try ss.stream.read(dest[0..4]);
- assert(read == 3);
- assert(mem.eql(u8, dest[0..3], bytes[4..7]));
+ expect(read == 3);
+ expect(mem.eql(u8, dest[0..3], bytes[4..7]));
read = try ss.stream.read(dest[0..4]);
- assert(read == 0);
+ expect(read == 0);
}
test "PeekStream" {
@@ -93,26 +93,26 @@ test "PeekStream" {
ps.putBackByte(10);
var read = try ps.stream.read(dest[0..4]);
- assert(read == 4);
- assert(dest[0] == 10);
- assert(dest[1] == 9);
- assert(mem.eql(u8, dest[2..4], bytes[0..2]));
+ expect(read == 4);
+ expect(dest[0] == 10);
+ expect(dest[1] == 9);
+ expect(mem.eql(u8, dest[2..4], bytes[0..2]));
read = try ps.stream.read(dest[0..4]);
- assert(read == 4);
- assert(mem.eql(u8, dest[0..4], bytes[2..6]));
+ expect(read == 4);
+ expect(mem.eql(u8, dest[0..4], bytes[2..6]));
read = try ps.stream.read(dest[0..4]);
- assert(read == 2);
- assert(mem.eql(u8, dest[0..2], bytes[6..8]));
+ expect(read == 2);
+ expect(mem.eql(u8, dest[0..2], bytes[6..8]));
ps.putBackByte(11);
ps.putBackByte(12);
read = try ps.stream.read(dest[0..4]);
- assert(read == 2);
- assert(dest[0] == 12);
- assert(dest[1] == 11);
+ expect(read == 2);
+ expect(dest[0] == 12);
+ expect(dest[1] == 11);
}
test "SliceOutStream" {
@@ -120,19 +120,19 @@ test "SliceOutStream" {
var ss = io.SliceOutStream.init(buffer[0..]);
try ss.stream.write("Hello");
- assert(mem.eql(u8, ss.getWritten(), "Hello"));
+ expect(mem.eql(u8, ss.getWritten(), "Hello"));
try ss.stream.write("world");
- assert(mem.eql(u8, ss.getWritten(), "Helloworld"));
+ expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
- assertError(ss.stream.write("!"), error.OutOfSpace);
- assert(mem.eql(u8, ss.getWritten(), "Helloworld"));
+ expectError(error.OutOfSpace, ss.stream.write("!"));
+ expect(mem.eql(u8, ss.getWritten(), "Helloworld"));
ss.reset();
- assert(ss.getWritten().len == 0);
+ expect(ss.getWritten().len == 0);
- assertError(ss.stream.write("Hello world!"), error.OutOfSpace);
- assert(mem.eql(u8, ss.getWritten(), "Hello worl"));
+ expectError(error.OutOfSpace, ss.stream.write("Hello world!"));
+ expect(mem.eql(u8, ss.getWritten(), "Hello worl"));
}
test "BitInStream" {
@@ -145,66 +145,66 @@ test "BitInStream" {
var out_bits: usize = undefined;
- assert(1 == try bit_stream_be.readBits(u2, 1, &out_bits));
- assert(out_bits == 1);
- assert(2 == try bit_stream_be.readBits(u5, 2, &out_bits));
- assert(out_bits == 2);
- assert(3 == try bit_stream_be.readBits(u128, 3, &out_bits));
- assert(out_bits == 3);
- assert(4 == try bit_stream_be.readBits(u8, 4, &out_bits));
- assert(out_bits == 4);
- assert(5 == try bit_stream_be.readBits(u9, 5, &out_bits));
- assert(out_bits == 5);
- assert(1 == try bit_stream_be.readBits(u1, 1, &out_bits));
- assert(out_bits == 1);
+ expect(1 == try bit_stream_be.readBits(u2, 1, &out_bits));
+ expect(out_bits == 1);
+ expect(2 == try bit_stream_be.readBits(u5, 2, &out_bits));
+ expect(out_bits == 2);
+ expect(3 == try bit_stream_be.readBits(u128, 3, &out_bits));
+ expect(out_bits == 3);
+ expect(4 == try bit_stream_be.readBits(u8, 4, &out_bits));
+ expect(out_bits == 4);
+ expect(5 == try bit_stream_be.readBits(u9, 5, &out_bits));
+ expect(out_bits == 5);
+ expect(1 == try bit_stream_be.readBits(u1, 1, &out_bits));
+ expect(out_bits == 1);
mem_in_be.pos = 0;
bit_stream_be.bit_count = 0;
- assert(0b110011010000101 == try bit_stream_be.readBits(u15, 15, &out_bits));
- assert(out_bits == 15);
+ expect(0b110011010000101 == try bit_stream_be.readBits(u15, 15, &out_bits));
+ expect(out_bits == 15);
mem_in_be.pos = 0;
bit_stream_be.bit_count = 0;
- assert(0b1100110100001011 == try bit_stream_be.readBits(u16, 16, &out_bits));
- assert(out_bits == 16);
+ expect(0b1100110100001011 == try bit_stream_be.readBits(u16, 16, &out_bits));
+ expect(out_bits == 16);
_ = try bit_stream_be.readBits(u0, 0, &out_bits);
- assert(0 == try bit_stream_be.readBits(u1, 1, &out_bits));
- assert(out_bits == 0);
- assertError(bit_stream_be.readBitsNoEof(u1, 1), error.EndOfStream);
+ expect(0 == try bit_stream_be.readBits(u1, 1, &out_bits));
+ expect(out_bits == 0);
+ expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1));
var mem_in_le = io.SliceInStream.init(mem_le[0..]);
var bit_stream_le = io.BitInStream(builtin.Endian.Little, InError).init(&mem_in_le.stream);
- assert(1 == try bit_stream_le.readBits(u2, 1, &out_bits));
- assert(out_bits == 1);
- assert(2 == try bit_stream_le.readBits(u5, 2, &out_bits));
- assert(out_bits == 2);
- assert(3 == try bit_stream_le.readBits(u128, 3, &out_bits));
- assert(out_bits == 3);
- assert(4 == try bit_stream_le.readBits(u8, 4, &out_bits));
- assert(out_bits == 4);
- assert(5 == try bit_stream_le.readBits(u9, 5, &out_bits));
- assert(out_bits == 5);
- assert(1 == try bit_stream_le.readBits(u1, 1, &out_bits));
- assert(out_bits == 1);
+ expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits));
+ expect(out_bits == 1);
+ expect(2 == try bit_stream_le.readBits(u5, 2, &out_bits));
+ expect(out_bits == 2);
+ expect(3 == try bit_stream_le.readBits(u128, 3, &out_bits));
+ expect(out_bits == 3);
+ expect(4 == try bit_stream_le.readBits(u8, 4, &out_bits));
+ expect(out_bits == 4);
+ expect(5 == try bit_stream_le.readBits(u9, 5, &out_bits));
+ expect(out_bits == 5);
+ expect(1 == try bit_stream_le.readBits(u1, 1, &out_bits));
+ expect(out_bits == 1);
mem_in_le.pos = 0;
bit_stream_le.bit_count = 0;
- assert(0b001010100011101 == try bit_stream_le.readBits(u15, 15, &out_bits));
- assert(out_bits == 15);
+ expect(0b001010100011101 == try bit_stream_le.readBits(u15, 15, &out_bits));
+ expect(out_bits == 15);
mem_in_le.pos = 0;
bit_stream_le.bit_count = 0;
- assert(0b1001010100011101 == try bit_stream_le.readBits(u16, 16, &out_bits));
- assert(out_bits == 16);
+ expect(0b1001010100011101 == try bit_stream_le.readBits(u16, 16, &out_bits));
+ expect(out_bits == 16);
_ = try bit_stream_le.readBits(u0, 0, &out_bits);
- assert(0 == try bit_stream_le.readBits(u1, 1, &out_bits));
- assert(out_bits == 0);
- assertError(bit_stream_le.readBitsNoEof(u1, 1), error.EndOfStream);
+ expect(0 == try bit_stream_le.readBits(u1, 1, &out_bits));
+ expect(out_bits == 0);
+ expectError(error.EndOfStream, bit_stream_le.readBitsNoEof(u1, 1));
}
test "BitOutStream" {
@@ -222,17 +222,17 @@ test "BitOutStream" {
try bit_stream_be.writeBits(u9(5), 5);
try bit_stream_be.writeBits(u1(1), 1);
- assert(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
+ expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
mem_out_be.pos = 0;
try bit_stream_be.writeBits(u15(0b110011010000101), 15);
try bit_stream_be.flushBits();
- assert(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
+ expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
mem_out_be.pos = 0;
try bit_stream_be.writeBits(u32(0b110011010000101), 16);
- assert(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
+ expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
try bit_stream_be.writeBits(u0(0), 0);
@@ -246,16 +246,16 @@ test "BitOutStream" {
try bit_stream_le.writeBits(u9(5), 5);
try bit_stream_le.writeBits(u1(1), 1);
- assert(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
+ expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
mem_out_le.pos = 0;
try bit_stream_le.writeBits(u15(0b110011010000101), 15);
try bit_stream_le.flushBits();
- assert(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
+ expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
mem_out_le.pos = 0;
try bit_stream_le.writeBits(u32(0b1100110100001011), 16);
- assert(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
+ expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
try bit_stream_le.writeBits(u0(0), 0);
}
@@ -290,20 +290,20 @@ test "BitStreams with File Stream" {
var out_bits: usize = undefined;
- assert(1 == try bit_stream.readBits(u2, 1, &out_bits));
- assert(out_bits == 1);
- assert(2 == try bit_stream.readBits(u5, 2, &out_bits));
- assert(out_bits == 2);
- assert(3 == try bit_stream.readBits(u128, 3, &out_bits));
- assert(out_bits == 3);
- assert(4 == try bit_stream.readBits(u8, 4, &out_bits));
- assert(out_bits == 4);
- assert(5 == try bit_stream.readBits(u9, 5, &out_bits));
- assert(out_bits == 5);
- assert(1 == try bit_stream.readBits(u1, 1, &out_bits));
- assert(out_bits == 1);
+ expect(1 == try bit_stream.readBits(u2, 1, &out_bits));
+ expect(out_bits == 1);
+ expect(2 == try bit_stream.readBits(u5, 2, &out_bits));
+ expect(out_bits == 2);
+ expect(3 == try bit_stream.readBits(u128, 3, &out_bits));
+ expect(out_bits == 3);
+ expect(4 == try bit_stream.readBits(u8, 4, &out_bits));
+ expect(out_bits == 4);
+ expect(5 == try bit_stream.readBits(u9, 5, &out_bits));
+ expect(out_bits == 5);
+ expect(1 == try bit_stream.readBits(u1, 1, &out_bits));
+ expect(out_bits == 1);
- assertError(bit_stream.readBitsNoEof(u1, 1), error.EndOfStream);
+ expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
}
try os.deleteFile(tmp_file_name);
}
@@ -345,8 +345,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime is_pa
const S = @IntType(true, i);
const x = try deserializer.deserializeInt(U);
const y = try deserializer.deserializeInt(S);
- assert(x == U(i));
- if (i != 0) assert(y == S(-1)) else assert(y == 0);
+ expect(x == U(i));
+ if (i != 0) expect(y == S(-1)) else expect(y == 0);
}
const u8_bit_count = comptime meta.bitCount(u8);
@@ -356,7 +356,7 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime is_pa
const extra_packed_byte = @boolToInt(total_bits % u8_bit_count > 0);
const total_packed_bytes = (total_bits / u8_bit_count) + extra_packed_byte;
- assert(in.pos == if (is_packed) total_packed_bytes else total_bytes);
+ expect(in.pos == if (is_packed) total_packed_bytes else total_bytes);
//Verify that empty error set works with serializer.
//deserializer is covered by SliceInStream
@@ -408,14 +408,14 @@ fn testIntSerializerDeserializerInfNaN(comptime endian: builtin.Endian,
const inf_check_f64 = try deserializer.deserialize(f64);
//const nan_check_f128 = try deserializer.deserialize(f128);
//const inf_check_f128 = try deserializer.deserialize(f128);
- assert(std.math.isNan(nan_check_f16));
- assert(std.math.isInf(inf_check_f16));
- assert(std.math.isNan(nan_check_f32));
- assert(std.math.isInf(inf_check_f32));
- assert(std.math.isNan(nan_check_f64));
- assert(std.math.isInf(inf_check_f64));
- //assert(std.math.isNan(nan_check_f128));
- //assert(std.math.isInf(inf_check_f128));
+ expect(std.math.isNan(nan_check_f16));
+ expect(std.math.isInf(inf_check_f16));
+ expect(std.math.isNan(nan_check_f32));
+ expect(std.math.isInf(inf_check_f32));
+ expect(std.math.isNan(nan_check_f64));
+ expect(std.math.isInf(inf_check_f64));
+ //expect(std.math.isNan(nan_check_f128));
+ //expect(std.math.isInf(inf_check_f128));
}
test "Serializer/Deserializer Int: Inf/NaN" {
@@ -528,7 +528,7 @@ fn testSerializerDeserializer(comptime endian: builtin.Endian, comptime is_packe
try serializer.serialize(my_inst);
const my_copy = try deserializer.deserialize(MyStruct);
- assert(meta.eql(my_copy, my_inst));
+ expect(meta.eql(my_copy, my_inst));
}
test "Serializer/Deserializer generic" {
@@ -565,11 +565,11 @@ fn testBadData(comptime endian: builtin.Endian, comptime is_packed: bool) !void
var deserializer = io.Deserializer(endian, is_packed, InError).init(in_stream);
try serializer.serialize(u14(3));
- assertError(deserializer.deserialize(A), error.InvalidEnumTag);
+ expectError(error.InvalidEnumTag, deserializer.deserialize(A));
out.pos = 0;
try serializer.serialize(u14(3));
try serializer.serialize(u14(88));
- assertError(deserializer.deserialize(C), error.InvalidEnumTag);
+ expectError(error.InvalidEnumTag, deserializer.deserialize(C));
}
test "Deserializer bad data" {
diff --git a/std/json.zig b/std/json.zig
index 4d07d7b89d..d8f28560e5 100644
--- a/std/json.zig
+++ b/std/json.zig
@@ -4,6 +4,7 @@
const std = @import("index.zig");
const debug = std.debug;
+const testing = std.testing;
const mem = std.mem;
const maxInt = std.math.maxInt;
@@ -960,7 +961,7 @@ test "json.token" {
checkNext(&p, Token.Id.ObjectEnd);
checkNext(&p, Token.Id.ObjectEnd);
- debug.assert((try p.next()) == null);
+ testing.expect((try p.next()) == null);
}
// Validate a JSON string. This does not limit number precision so a decoder may not necessarily
@@ -981,7 +982,7 @@ pub fn validate(s: []const u8) bool {
}
test "json.validate" {
- debug.assert(validate("{}"));
+ testing.expect(validate("{}"));
}
const Allocator = std.mem.Allocator;
@@ -1378,20 +1379,20 @@ test "json.parser.dynamic" {
var image = root.Object.get("Image").?.value;
const width = image.Object.get("Width").?.value;
- debug.assert(width.Integer == 800);
+ testing.expect(width.Integer == 800);
const height = image.Object.get("Height").?.value;
- debug.assert(height.Integer == 600);
+ testing.expect(height.Integer == 600);
const title = image.Object.get("Title").?.value;
- debug.assert(mem.eql(u8, title.String, "View from 15th Floor"));
+ testing.expect(mem.eql(u8, title.String, "View from 15th Floor"));
const animated = image.Object.get("Animated").?.value;
- debug.assert(animated.Bool == false);
+ testing.expect(animated.Bool == false);
const array_of_object = image.Object.get("ArrayOfObject").?.value;
- debug.assert(array_of_object.Array.len == 1);
+ testing.expect(array_of_object.Array.len == 1);
const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;
- debug.assert(mem.eql(u8, obj0.String, "m"));
+ testing.expect(mem.eql(u8, obj0.String, "m"));
}
diff --git a/std/json_test.zig b/std/json_test.zig
index 9e19ec592a..edc50be8cb 100644
--- a/std/json_test.zig
+++ b/std/json_test.zig
@@ -6,15 +6,15 @@
const std = @import("index.zig");
fn ok(comptime s: []const u8) void {
- std.debug.assert(std.json.validate(s));
+ std.testing.expect(std.json.validate(s));
}
fn err(comptime s: []const u8) void {
- std.debug.assert(!std.json.validate(s));
+ std.testing.expect(!std.json.validate(s));
}
fn any(comptime s: []const u8) void {
- std.debug.assert(true);
+ std.testing.expect(true);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/std/lazy_init.zig b/std/lazy_init.zig
index f08c01e874..a09168786b 100644
--- a/std/lazy_init.zig
+++ b/std/lazy_init.zig
@@ -1,6 +1,7 @@
const std = @import("index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const testing = std.testing;
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -63,12 +64,12 @@ test "std.lazyInit" {
global_number.resolve();
}
if (global_number.get()) |x| {
- assert(x.* == 1234);
+ testing.expect(x.* == 1234);
} else {
@panic("bad");
}
if (global_number.get()) |x| {
- assert(x.* == 1234);
+ testing.expect(x.* == 1234);
} else {
@panic("bad");
}
@@ -80,6 +81,6 @@ test "std.lazyInit(void)" {
if (global_void.get()) |_| @panic("bad") else {
global_void.resolve();
}
- assert(global_void.get() != null);
- assert(global_void.get() != null);
+ testing.expect(global_void.get() != null);
+ testing.expect(global_void.get() != null);
}
diff --git a/std/linked_list.zig b/std/linked_list.zig
index 7021cac707..86e5cd056e 100644
--- a/std/linked_list.zig
+++ b/std/linked_list.zig
@@ -1,6 +1,7 @@
const std = @import("index.zig");
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const mem = std.mem;
const Allocator = mem.Allocator;
@@ -246,7 +247,7 @@ test "basic linked list test" {
var it = list.first;
var index: u32 = 1;
while (it) |node| : (it = node.next) {
- assert(node.data == index);
+ testing.expect(node.data == index);
index += 1;
}
}
@@ -256,7 +257,7 @@ test "basic linked list test" {
var it = list.last;
var index: u32 = 1;
while (it) |node| : (it = node.prev) {
- assert(node.data == (6 - index));
+ testing.expect(node.data == (6 - index));
index += 1;
}
}
@@ -265,9 +266,9 @@ test "basic linked list test" {
var last = list.pop(); // {2, 3, 4}
list.remove(three); // {2, 4}
- assert(list.first.?.data == 2);
- assert(list.last.?.data == 4);
- assert(list.len == 2);
+ testing.expect(list.first.?.data == 2);
+ testing.expect(list.last.?.data == 4);
+ testing.expect(list.len == 2);
}
test "linked list concatenation" {
@@ -294,18 +295,18 @@ test "linked list concatenation" {
list1.concatByMoving(&list2);
- assert(list1.last == five);
- assert(list1.len == 5);
- assert(list2.first == null);
- assert(list2.last == null);
- assert(list2.len == 0);
+ testing.expect(list1.last == five);
+ testing.expect(list1.len == 5);
+ testing.expect(list2.first == null);
+ testing.expect(list2.last == null);
+ testing.expect(list2.len == 0);
// Traverse forwards.
{
var it = list1.first;
var index: u32 = 1;
while (it) |node| : (it = node.next) {
- assert(node.data == index);
+ testing.expect(node.data == index);
index += 1;
}
}
@@ -315,7 +316,7 @@ test "linked list concatenation" {
var it = list1.last;
var index: u32 = 1;
while (it) |node| : (it = node.prev) {
- assert(node.data == (6 - index));
+ testing.expect(node.data == (6 - index));
index += 1;
}
}
@@ -328,7 +329,7 @@ test "linked list concatenation" {
var it = list2.first;
var index: u32 = 1;
while (it) |node| : (it = node.next) {
- assert(node.data == index);
+ testing.expect(node.data == index);
index += 1;
}
}
@@ -338,7 +339,7 @@ test "linked list concatenation" {
var it = list2.last;
var index: u32 = 1;
while (it) |node| : (it = node.prev) {
- assert(node.data == (6 - index));
+ testing.expect(node.data == (6 - index));
index += 1;
}
}
diff --git a/std/math/acos.zig b/std/math/acos.zig
index 54844e8f6e..734f7a8651 100644
--- a/std/math/acos.zig
+++ b/std/math/acos.zig
@@ -4,7 +4,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn acos(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -143,38 +143,38 @@ fn acos64(x: f64) f64 {
}
test "math.acos" {
- assert(acos(f32(0.0)) == acos32(0.0));
- assert(acos(f64(0.0)) == acos64(0.0));
+ expect(acos(f32(0.0)) == acos32(0.0));
+ expect(acos(f64(0.0)) == acos64(0.0));
}
test "math.acos32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, acos32(0.0), 1.570796, epsilon));
- assert(math.approxEq(f32, acos32(0.2), 1.369438, epsilon));
- assert(math.approxEq(f32, acos32(0.3434), 1.220262, epsilon));
- assert(math.approxEq(f32, acos32(0.5), 1.047198, epsilon));
- assert(math.approxEq(f32, acos32(0.8923), 0.468382, epsilon));
- assert(math.approxEq(f32, acos32(-0.2), 1.772154, epsilon));
+ expect(math.approxEq(f32, acos32(0.0), 1.570796, epsilon));
+ expect(math.approxEq(f32, acos32(0.2), 1.369438, epsilon));
+ expect(math.approxEq(f32, acos32(0.3434), 1.220262, epsilon));
+ expect(math.approxEq(f32, acos32(0.5), 1.047198, epsilon));
+ expect(math.approxEq(f32, acos32(0.8923), 0.468382, epsilon));
+ expect(math.approxEq(f32, acos32(-0.2), 1.772154, epsilon));
}
test "math.acos64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, acos64(0.0), 1.570796, epsilon));
- assert(math.approxEq(f64, acos64(0.2), 1.369438, epsilon));
- assert(math.approxEq(f64, acos64(0.3434), 1.220262, epsilon));
- assert(math.approxEq(f64, acos64(0.5), 1.047198, epsilon));
- assert(math.approxEq(f64, acos64(0.8923), 0.468382, epsilon));
- assert(math.approxEq(f64, acos64(-0.2), 1.772154, epsilon));
+ expect(math.approxEq(f64, acos64(0.0), 1.570796, epsilon));
+ expect(math.approxEq(f64, acos64(0.2), 1.369438, epsilon));
+ expect(math.approxEq(f64, acos64(0.3434), 1.220262, epsilon));
+ expect(math.approxEq(f64, acos64(0.5), 1.047198, epsilon));
+ expect(math.approxEq(f64, acos64(0.8923), 0.468382, epsilon));
+ expect(math.approxEq(f64, acos64(-0.2), 1.772154, epsilon));
}
test "math.acos32.special" {
- assert(math.isNan(acos32(-2)));
- assert(math.isNan(acos32(1.5)));
+ expect(math.isNan(acos32(-2)));
+ expect(math.isNan(acos32(1.5)));
}
test "math.acos64.special" {
- assert(math.isNan(acos64(-2)));
- assert(math.isNan(acos64(1.5)));
+ expect(math.isNan(acos64(-2)));
+ expect(math.isNan(acos64(1.5)));
}
diff --git a/std/math/acosh.zig b/std/math/acosh.zig
index 9be323e1f6..a9c4a908ef 100644
--- a/std/math/acosh.zig
+++ b/std/math/acosh.zig
@@ -6,7 +6,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn acosh(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -55,34 +55,34 @@ fn acosh64(x: f64) f64 {
}
test "math.acosh" {
- assert(acosh(f32(1.5)) == acosh32(1.5));
- assert(acosh(f64(1.5)) == acosh64(1.5));
+ expect(acosh(f32(1.5)) == acosh32(1.5));
+ expect(acosh(f64(1.5)) == acosh64(1.5));
}
test "math.acosh32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, acosh32(1.5), 0.962424, epsilon));
- assert(math.approxEq(f32, acosh32(37.45), 4.315976, epsilon));
- assert(math.approxEq(f32, acosh32(89.123), 5.183133, epsilon));
- assert(math.approxEq(f32, acosh32(123123.234375), 12.414088, epsilon));
+ expect(math.approxEq(f32, acosh32(1.5), 0.962424, epsilon));
+ expect(math.approxEq(f32, acosh32(37.45), 4.315976, epsilon));
+ expect(math.approxEq(f32, acosh32(89.123), 5.183133, epsilon));
+ expect(math.approxEq(f32, acosh32(123123.234375), 12.414088, epsilon));
}
test "math.acosh64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, acosh64(1.5), 0.962424, epsilon));
- assert(math.approxEq(f64, acosh64(37.45), 4.315976, epsilon));
- assert(math.approxEq(f64, acosh64(89.123), 5.183133, epsilon));
- assert(math.approxEq(f64, acosh64(123123.234375), 12.414088, epsilon));
+ expect(math.approxEq(f64, acosh64(1.5), 0.962424, epsilon));
+ expect(math.approxEq(f64, acosh64(37.45), 4.315976, epsilon));
+ expect(math.approxEq(f64, acosh64(89.123), 5.183133, epsilon));
+ expect(math.approxEq(f64, acosh64(123123.234375), 12.414088, epsilon));
}
test "math.acosh32.special" {
- assert(math.isNan(acosh32(math.nan(f32))));
- assert(math.isSignalNan(acosh32(0.5)));
+ expect(math.isNan(acosh32(math.nan(f32))));
+ expect(math.isSignalNan(acosh32(0.5)));
}
test "math.acosh64.special" {
- assert(math.isNan(acosh64(math.nan(f64))));
- assert(math.isSignalNan(acosh64(0.5)));
+ expect(math.isNan(acosh64(math.nan(f64))));
+ expect(math.isSignalNan(acosh64(0.5)));
}
diff --git a/std/math/asin.zig b/std/math/asin.zig
index 30b3a57e32..c9dbdf704f 100644
--- a/std/math/asin.zig
+++ b/std/math/asin.zig
@@ -5,7 +5,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn asin(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -136,42 +136,42 @@ fn asin64(x: f64) f64 {
}
test "math.asin" {
- assert(asin(f32(0.0)) == asin32(0.0));
- assert(asin(f64(0.0)) == asin64(0.0));
+ expect(asin(f32(0.0)) == asin32(0.0));
+ expect(asin(f64(0.0)) == asin64(0.0));
}
test "math.asin32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, asin32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, asin32(0.2), 0.201358, epsilon));
- assert(math.approxEq(f32, asin32(-0.2), -0.201358, epsilon));
- assert(math.approxEq(f32, asin32(0.3434), 0.350535, epsilon));
- assert(math.approxEq(f32, asin32(0.5), 0.523599, epsilon));
- assert(math.approxEq(f32, asin32(0.8923), 1.102415, epsilon));
+ expect(math.approxEq(f32, asin32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, asin32(0.2), 0.201358, epsilon));
+ expect(math.approxEq(f32, asin32(-0.2), -0.201358, epsilon));
+ expect(math.approxEq(f32, asin32(0.3434), 0.350535, epsilon));
+ expect(math.approxEq(f32, asin32(0.5), 0.523599, epsilon));
+ expect(math.approxEq(f32, asin32(0.8923), 1.102415, epsilon));
}
test "math.asin64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, asin64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, asin64(0.2), 0.201358, epsilon));
- assert(math.approxEq(f64, asin64(-0.2), -0.201358, epsilon));
- assert(math.approxEq(f64, asin64(0.3434), 0.350535, epsilon));
- assert(math.approxEq(f64, asin64(0.5), 0.523599, epsilon));
- assert(math.approxEq(f64, asin64(0.8923), 1.102415, epsilon));
+ expect(math.approxEq(f64, asin64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, asin64(0.2), 0.201358, epsilon));
+ expect(math.approxEq(f64, asin64(-0.2), -0.201358, epsilon));
+ expect(math.approxEq(f64, asin64(0.3434), 0.350535, epsilon));
+ expect(math.approxEq(f64, asin64(0.5), 0.523599, epsilon));
+ expect(math.approxEq(f64, asin64(0.8923), 1.102415, epsilon));
}
test "math.asin32.special" {
- assert(asin32(0.0) == 0.0);
- assert(asin32(-0.0) == -0.0);
- assert(math.isNan(asin32(-2)));
- assert(math.isNan(asin32(1.5)));
+ expect(asin32(0.0) == 0.0);
+ expect(asin32(-0.0) == -0.0);
+ expect(math.isNan(asin32(-2)));
+ expect(math.isNan(asin32(1.5)));
}
test "math.asin64.special" {
- assert(asin64(0.0) == 0.0);
- assert(asin64(-0.0) == -0.0);
- assert(math.isNan(asin64(-2)));
- assert(math.isNan(asin64(1.5)));
+ expect(asin64(0.0) == 0.0);
+ expect(asin64(-0.0) == -0.0);
+ expect(math.isNan(asin64(-2)));
+ expect(math.isNan(asin64(1.5)));
}
diff --git a/std/math/asinh.zig b/std/math/asinh.zig
index 98892bcbcb..05bd8d008e 100644
--- a/std/math/asinh.zig
+++ b/std/math/asinh.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn asinh(x: var) @typeOf(x) {
@@ -83,46 +83,46 @@ fn asinh64(x: f64) f64 {
}
test "math.asinh" {
- assert(asinh(f32(0.0)) == asinh32(0.0));
- assert(asinh(f64(0.0)) == asinh64(0.0));
+ expect(asinh(f32(0.0)) == asinh32(0.0));
+ expect(asinh(f64(0.0)) == asinh64(0.0));
}
test "math.asinh32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, asinh32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, asinh32(0.2), 0.198690, epsilon));
- assert(math.approxEq(f32, asinh32(0.8923), 0.803133, epsilon));
- assert(math.approxEq(f32, asinh32(1.5), 1.194763, epsilon));
- assert(math.approxEq(f32, asinh32(37.45), 4.316332, epsilon));
- assert(math.approxEq(f32, asinh32(89.123), 5.183196, epsilon));
- assert(math.approxEq(f32, asinh32(123123.234375), 12.414088, epsilon));
+ expect(math.approxEq(f32, asinh32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, asinh32(0.2), 0.198690, epsilon));
+ expect(math.approxEq(f32, asinh32(0.8923), 0.803133, epsilon));
+ expect(math.approxEq(f32, asinh32(1.5), 1.194763, epsilon));
+ expect(math.approxEq(f32, asinh32(37.45), 4.316332, epsilon));
+ expect(math.approxEq(f32, asinh32(89.123), 5.183196, epsilon));
+ expect(math.approxEq(f32, asinh32(123123.234375), 12.414088, epsilon));
}
test "math.asinh64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, asinh64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, asinh64(0.2), 0.198690, epsilon));
- assert(math.approxEq(f64, asinh64(0.8923), 0.803133, epsilon));
- assert(math.approxEq(f64, asinh64(1.5), 1.194763, epsilon));
- assert(math.approxEq(f64, asinh64(37.45), 4.316332, epsilon));
- assert(math.approxEq(f64, asinh64(89.123), 5.183196, epsilon));
- assert(math.approxEq(f64, asinh64(123123.234375), 12.414088, epsilon));
+ expect(math.approxEq(f64, asinh64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, asinh64(0.2), 0.198690, epsilon));
+ expect(math.approxEq(f64, asinh64(0.8923), 0.803133, epsilon));
+ expect(math.approxEq(f64, asinh64(1.5), 1.194763, epsilon));
+ expect(math.approxEq(f64, asinh64(37.45), 4.316332, epsilon));
+ expect(math.approxEq(f64, asinh64(89.123), 5.183196, epsilon));
+ expect(math.approxEq(f64, asinh64(123123.234375), 12.414088, epsilon));
}
test "math.asinh32.special" {
- assert(asinh32(0.0) == 0.0);
- assert(asinh32(-0.0) == -0.0);
- assert(math.isPositiveInf(asinh32(math.inf(f32))));
- assert(math.isNegativeInf(asinh32(-math.inf(f32))));
- assert(math.isNan(asinh32(math.nan(f32))));
+ expect(asinh32(0.0) == 0.0);
+ expect(asinh32(-0.0) == -0.0);
+ expect(math.isPositiveInf(asinh32(math.inf(f32))));
+ expect(math.isNegativeInf(asinh32(-math.inf(f32))));
+ expect(math.isNan(asinh32(math.nan(f32))));
}
test "math.asinh64.special" {
- assert(asinh64(0.0) == 0.0);
- assert(asinh64(-0.0) == -0.0);
- assert(math.isPositiveInf(asinh64(math.inf(f64))));
- assert(math.isNegativeInf(asinh64(-math.inf(f64))));
- assert(math.isNan(asinh64(math.nan(f64))));
+ expect(asinh64(0.0) == 0.0);
+ expect(asinh64(-0.0) == -0.0);
+ expect(math.isPositiveInf(asinh64(math.inf(f64))));
+ expect(math.isNegativeInf(asinh64(-math.inf(f64))));
+ expect(math.isNan(asinh64(math.nan(f64))));
}
diff --git a/std/math/atan.zig b/std/math/atan.zig
index 6ca94dd84a..72d17b4db2 100644
--- a/std/math/atan.zig
+++ b/std/math/atan.zig
@@ -5,7 +5,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn atan(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -206,44 +206,44 @@ fn atan64(x_: f64) f64 {
}
test "math.atan" {
- assert(@bitCast(u32, atan(f32(0.2))) == @bitCast(u32, atan32(0.2)));
- assert(atan(f64(0.2)) == atan64(0.2));
+ expect(@bitCast(u32, atan(f32(0.2))) == @bitCast(u32, atan32(0.2)));
+ expect(atan(f64(0.2)) == atan64(0.2));
}
test "math.atan32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, atan32(0.2), 0.197396, epsilon));
- assert(math.approxEq(f32, atan32(-0.2), -0.197396, epsilon));
- assert(math.approxEq(f32, atan32(0.3434), 0.330783, epsilon));
- assert(math.approxEq(f32, atan32(0.8923), 0.728545, epsilon));
- assert(math.approxEq(f32, atan32(1.5), 0.982794, epsilon));
+ expect(math.approxEq(f32, atan32(0.2), 0.197396, epsilon));
+ expect(math.approxEq(f32, atan32(-0.2), -0.197396, epsilon));
+ expect(math.approxEq(f32, atan32(0.3434), 0.330783, epsilon));
+ expect(math.approxEq(f32, atan32(0.8923), 0.728545, epsilon));
+ expect(math.approxEq(f32, atan32(1.5), 0.982794, epsilon));
}
test "math.atan64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, atan64(0.2), 0.197396, epsilon));
- assert(math.approxEq(f64, atan64(-0.2), -0.197396, epsilon));
- assert(math.approxEq(f64, atan64(0.3434), 0.330783, epsilon));
- assert(math.approxEq(f64, atan64(0.8923), 0.728545, epsilon));
- assert(math.approxEq(f64, atan64(1.5), 0.982794, epsilon));
+ expect(math.approxEq(f64, atan64(0.2), 0.197396, epsilon));
+ expect(math.approxEq(f64, atan64(-0.2), -0.197396, epsilon));
+ expect(math.approxEq(f64, atan64(0.3434), 0.330783, epsilon));
+ expect(math.approxEq(f64, atan64(0.8923), 0.728545, epsilon));
+ expect(math.approxEq(f64, atan64(1.5), 0.982794, epsilon));
}
test "math.atan32.special" {
const epsilon = 0.000001;
- assert(atan32(0.0) == 0.0);
- assert(atan32(-0.0) == -0.0);
- assert(math.approxEq(f32, atan32(math.inf(f32)), math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan32(-math.inf(f32)), -math.pi / 2.0, epsilon));
+ expect(atan32(0.0) == 0.0);
+ expect(atan32(-0.0) == -0.0);
+ expect(math.approxEq(f32, atan32(math.inf(f32)), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan32(-math.inf(f32)), -math.pi / 2.0, epsilon));
}
test "math.atan64.special" {
const epsilon = 0.000001;
- assert(atan64(0.0) == 0.0);
- assert(atan64(-0.0) == -0.0);
- assert(math.approxEq(f64, atan64(math.inf(f64)), math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan64(-math.inf(f64)), -math.pi / 2.0, epsilon));
+ expect(atan64(0.0) == 0.0);
+ expect(atan64(-0.0) == -0.0);
+ expect(math.approxEq(f64, atan64(math.inf(f64)), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan64(-math.inf(f64)), -math.pi / 2.0, epsilon));
}
diff --git a/std/math/atan2.zig b/std/math/atan2.zig
index a7757132d7..6e1f67cfbb 100644
--- a/std/math/atan2.zig
+++ b/std/math/atan2.zig
@@ -20,7 +20,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn atan2(comptime T: type, y: T, x: T) T {
return switch (T) {
@@ -206,78 +206,78 @@ fn atan2_64(y: f64, x: f64) f64 {
}
test "math.atan2" {
- assert(atan2(f32, 0.2, 0.21) == atan2_32(0.2, 0.21));
- assert(atan2(f64, 0.2, 0.21) == atan2_64(0.2, 0.21));
+ expect(atan2(f32, 0.2, 0.21) == atan2_32(0.2, 0.21));
+ expect(atan2(f64, 0.2, 0.21) == atan2_64(0.2, 0.21));
}
test "math.atan2_32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, atan2_32(0.0, 0.0), 0.0, epsilon));
- assert(math.approxEq(f32, atan2_32(0.2, 0.2), 0.785398, epsilon));
- assert(math.approxEq(f32, atan2_32(-0.2, 0.2), -0.785398, epsilon));
- assert(math.approxEq(f32, atan2_32(0.2, -0.2), 2.356194, epsilon));
- assert(math.approxEq(f32, atan2_32(-0.2, -0.2), -2.356194, epsilon));
- assert(math.approxEq(f32, atan2_32(0.34, -0.4), 2.437099, epsilon));
- assert(math.approxEq(f32, atan2_32(0.34, 1.243), 0.267001, epsilon));
+ expect(math.approxEq(f32, atan2_32(0.0, 0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(0.2, 0.2), 0.785398, epsilon));
+ expect(math.approxEq(f32, atan2_32(-0.2, 0.2), -0.785398, epsilon));
+ expect(math.approxEq(f32, atan2_32(0.2, -0.2), 2.356194, epsilon));
+ expect(math.approxEq(f32, atan2_32(-0.2, -0.2), -2.356194, epsilon));
+ expect(math.approxEq(f32, atan2_32(0.34, -0.4), 2.437099, epsilon));
+ expect(math.approxEq(f32, atan2_32(0.34, 1.243), 0.267001, epsilon));
}
test "math.atan2_64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, atan2_64(0.0, 0.0), 0.0, epsilon));
- assert(math.approxEq(f64, atan2_64(0.2, 0.2), 0.785398, epsilon));
- assert(math.approxEq(f64, atan2_64(-0.2, 0.2), -0.785398, epsilon));
- assert(math.approxEq(f64, atan2_64(0.2, -0.2), 2.356194, epsilon));
- assert(math.approxEq(f64, atan2_64(-0.2, -0.2), -2.356194, epsilon));
- assert(math.approxEq(f64, atan2_64(0.34, -0.4), 2.437099, epsilon));
- assert(math.approxEq(f64, atan2_64(0.34, 1.243), 0.267001, epsilon));
+ expect(math.approxEq(f64, atan2_64(0.0, 0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(0.2, 0.2), 0.785398, epsilon));
+ expect(math.approxEq(f64, atan2_64(-0.2, 0.2), -0.785398, epsilon));
+ expect(math.approxEq(f64, atan2_64(0.2, -0.2), 2.356194, epsilon));
+ expect(math.approxEq(f64, atan2_64(-0.2, -0.2), -2.356194, epsilon));
+ expect(math.approxEq(f64, atan2_64(0.34, -0.4), 2.437099, epsilon));
+ expect(math.approxEq(f64, atan2_64(0.34, 1.243), 0.267001, epsilon));
}
test "math.atan2_32.special" {
const epsilon = 0.000001;
- assert(math.isNan(atan2_32(1.0, math.nan(f32))));
- assert(math.isNan(atan2_32(math.nan(f32), 1.0)));
- assert(atan2_32(0.0, 5.0) == 0.0);
- assert(atan2_32(-0.0, 5.0) == -0.0);
- assert(math.approxEq(f32, atan2_32(0.0, -5.0), math.pi, epsilon));
- //assert(math.approxEq(f32, atan2_32(-0.0, -5.0), -math.pi, epsilon)); TODO support negative zero?
- assert(math.approxEq(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan2_32(1.0, -0.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan2_32(-1.0, 0.0), -math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan2_32(-1.0, -0.0), -math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan2_32(math.inf(f32), math.inf(f32)), math.pi / 4.0, epsilon));
- assert(math.approxEq(f32, atan2_32(-math.inf(f32), math.inf(f32)), -math.pi / 4.0, epsilon));
- assert(math.approxEq(f32, atan2_32(math.inf(f32), -math.inf(f32)), 3.0 * math.pi / 4.0, epsilon));
- assert(math.approxEq(f32, atan2_32(-math.inf(f32), -math.inf(f32)), -3.0 * math.pi / 4.0, epsilon));
- assert(atan2_32(1.0, math.inf(f32)) == 0.0);
- assert(math.approxEq(f32, atan2_32(1.0, -math.inf(f32)), math.pi, epsilon));
- assert(math.approxEq(f32, atan2_32(-1.0, -math.inf(f32)), -math.pi, epsilon));
- assert(math.approxEq(f32, atan2_32(math.inf(f32), 1.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f32, atan2_32(-math.inf(f32), 1.0), -math.pi / 2.0, epsilon));
+ expect(math.isNan(atan2_32(1.0, math.nan(f32))));
+ expect(math.isNan(atan2_32(math.nan(f32), 1.0)));
+ expect(atan2_32(0.0, 5.0) == 0.0);
+ expect(atan2_32(-0.0, 5.0) == -0.0);
+ expect(math.approxEq(f32, atan2_32(0.0, -5.0), math.pi, epsilon));
+ //expect(math.approxEq(f32, atan2_32(-0.0, -5.0), -math.pi, epsilon)); TODO support negative zero?
+ expect(math.approxEq(f32, atan2_32(1.0, 0.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(1.0, -0.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(-1.0, 0.0), -math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(-1.0, -0.0), -math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(math.inf(f32), math.inf(f32)), math.pi / 4.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(-math.inf(f32), math.inf(f32)), -math.pi / 4.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(math.inf(f32), -math.inf(f32)), 3.0 * math.pi / 4.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(-math.inf(f32), -math.inf(f32)), -3.0 * math.pi / 4.0, epsilon));
+ expect(atan2_32(1.0, math.inf(f32)) == 0.0);
+ expect(math.approxEq(f32, atan2_32(1.0, -math.inf(f32)), math.pi, epsilon));
+ expect(math.approxEq(f32, atan2_32(-1.0, -math.inf(f32)), -math.pi, epsilon));
+ expect(math.approxEq(f32, atan2_32(math.inf(f32), 1.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f32, atan2_32(-math.inf(f32), 1.0), -math.pi / 2.0, epsilon));
}
test "math.atan2_64.special" {
const epsilon = 0.000001;
- assert(math.isNan(atan2_64(1.0, math.nan(f64))));
- assert(math.isNan(atan2_64(math.nan(f64), 1.0)));
- assert(atan2_64(0.0, 5.0) == 0.0);
- assert(atan2_64(-0.0, 5.0) == -0.0);
- assert(math.approxEq(f64, atan2_64(0.0, -5.0), math.pi, epsilon));
- //assert(math.approxEq(f64, atan2_64(-0.0, -5.0), -math.pi, epsilon)); TODO support negative zero?
- assert(math.approxEq(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan2_64(1.0, -0.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan2_64(-1.0, 0.0), -math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan2_64(-1.0, -0.0), -math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan2_64(math.inf(f64), math.inf(f64)), math.pi / 4.0, epsilon));
- assert(math.approxEq(f64, atan2_64(-math.inf(f64), math.inf(f64)), -math.pi / 4.0, epsilon));
- assert(math.approxEq(f64, atan2_64(math.inf(f64), -math.inf(f64)), 3.0 * math.pi / 4.0, epsilon));
- assert(math.approxEq(f64, atan2_64(-math.inf(f64), -math.inf(f64)), -3.0 * math.pi / 4.0, epsilon));
- assert(atan2_64(1.0, math.inf(f64)) == 0.0);
- assert(math.approxEq(f64, atan2_64(1.0, -math.inf(f64)), math.pi, epsilon));
- assert(math.approxEq(f64, atan2_64(-1.0, -math.inf(f64)), -math.pi, epsilon));
- assert(math.approxEq(f64, atan2_64(math.inf(f64), 1.0), math.pi / 2.0, epsilon));
- assert(math.approxEq(f64, atan2_64(-math.inf(f64), 1.0), -math.pi / 2.0, epsilon));
+ expect(math.isNan(atan2_64(1.0, math.nan(f64))));
+ expect(math.isNan(atan2_64(math.nan(f64), 1.0)));
+ expect(atan2_64(0.0, 5.0) == 0.0);
+ expect(atan2_64(-0.0, 5.0) == -0.0);
+ expect(math.approxEq(f64, atan2_64(0.0, -5.0), math.pi, epsilon));
+ //expect(math.approxEq(f64, atan2_64(-0.0, -5.0), -math.pi, epsilon)); TODO support negative zero?
+ expect(math.approxEq(f64, atan2_64(1.0, 0.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(1.0, -0.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(-1.0, 0.0), -math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(-1.0, -0.0), -math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(math.inf(f64), math.inf(f64)), math.pi / 4.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(-math.inf(f64), math.inf(f64)), -math.pi / 4.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(math.inf(f64), -math.inf(f64)), 3.0 * math.pi / 4.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(-math.inf(f64), -math.inf(f64)), -3.0 * math.pi / 4.0, epsilon));
+ expect(atan2_64(1.0, math.inf(f64)) == 0.0);
+ expect(math.approxEq(f64, atan2_64(1.0, -math.inf(f64)), math.pi, epsilon));
+ expect(math.approxEq(f64, atan2_64(-1.0, -math.inf(f64)), -math.pi, epsilon));
+ expect(math.approxEq(f64, atan2_64(math.inf(f64), 1.0), math.pi / 2.0, epsilon));
+ expect(math.approxEq(f64, atan2_64(-math.inf(f64), 1.0), -math.pi / 2.0, epsilon));
}
diff --git a/std/math/atanh.zig b/std/math/atanh.zig
index c97855c234..f2feab0207 100644
--- a/std/math/atanh.zig
+++ b/std/math/atanh.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn atanh(x: var) @typeOf(x) {
@@ -78,38 +78,38 @@ fn atanh_64(x: f64) f64 {
}
test "math.atanh" {
- assert(atanh(f32(0.0)) == atanh_32(0.0));
- assert(atanh(f64(0.0)) == atanh_64(0.0));
+ expect(atanh(f32(0.0)) == atanh_32(0.0));
+ expect(atanh(f64(0.0)) == atanh_64(0.0));
}
test "math.atanh_32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, atanh_32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, atanh_32(0.2), 0.202733, epsilon));
- assert(math.approxEq(f32, atanh_32(0.8923), 1.433099, epsilon));
+ expect(math.approxEq(f32, atanh_32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, atanh_32(0.2), 0.202733, epsilon));
+ expect(math.approxEq(f32, atanh_32(0.8923), 1.433099, epsilon));
}
test "math.atanh_64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, atanh_64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, atanh_64(0.2), 0.202733, epsilon));
- assert(math.approxEq(f64, atanh_64(0.8923), 1.433099, epsilon));
+ expect(math.approxEq(f64, atanh_64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, atanh_64(0.2), 0.202733, epsilon));
+ expect(math.approxEq(f64, atanh_64(0.8923), 1.433099, epsilon));
}
test "math.atanh32.special" {
- assert(math.isPositiveInf(atanh_32(1)));
- assert(math.isNegativeInf(atanh_32(-1)));
- assert(math.isSignalNan(atanh_32(1.5)));
- assert(math.isSignalNan(atanh_32(-1.5)));
- assert(math.isNan(atanh_32(math.nan(f32))));
+ expect(math.isPositiveInf(atanh_32(1)));
+ expect(math.isNegativeInf(atanh_32(-1)));
+ expect(math.isSignalNan(atanh_32(1.5)));
+ expect(math.isSignalNan(atanh_32(-1.5)));
+ expect(math.isNan(atanh_32(math.nan(f32))));
}
test "math.atanh64.special" {
- assert(math.isPositiveInf(atanh_64(1)));
- assert(math.isNegativeInf(atanh_64(-1)));
- assert(math.isSignalNan(atanh_64(1.5)));
- assert(math.isSignalNan(atanh_64(-1.5)));
- assert(math.isNan(atanh_64(math.nan(f64))));
+ expect(math.isPositiveInf(atanh_64(1)));
+ expect(math.isNegativeInf(atanh_64(-1)));
+ expect(math.isSignalNan(atanh_64(1.5)));
+ expect(math.isSignalNan(atanh_64(-1.5)));
+ expect(math.isNan(atanh_64(math.nan(f64))));
}
diff --git a/std/math/big/int.zig b/std/math/big/int.zig
index cda2e1419f..f21e5df8aa 100644
--- a/std/math/big/int.zig
+++ b/std/math/big/int.zig
@@ -1,6 +1,7 @@
const std = @import("../../index.zig");
const builtin = @import("builtin");
const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const mem = std.mem;
const Allocator = mem.Allocator;
@@ -1086,44 +1087,40 @@ test "big.int comptime_int set" {
const result = Limb(s & maxInt(Limb));
s >>= Limb.bit_count / 2;
s >>= Limb.bit_count / 2;
- debug.assert(a.limbs[i] == result);
+ testing.expect(a.limbs[i] == result);
}
}
test "big.int comptime_int set negative" {
var a = try Int.initSet(al, -10);
- debug.assert(a.limbs[0] == 10);
- debug.assert(a.positive == false);
+ testing.expect(a.limbs[0] == 10);
+ testing.expect(a.positive == false);
}
test "big.int int set unaligned small" {
var a = try Int.initSet(al, u7(45));
- debug.assert(a.limbs[0] == 45);
- debug.assert(a.positive == true);
+ testing.expect(a.limbs[0] == 45);
+ testing.expect(a.positive == true);
}
test "big.int comptime_int to" {
const a = try Int.initSet(al, 0xefffffff00000001eeeeeeefaaaaaaab);
- debug.assert((try a.to(u128)) == 0xefffffff00000001eeeeeeefaaaaaaab);
+ testing.expect((try a.to(u128)) == 0xefffffff00000001eeeeeeefaaaaaaab);
}
test "big.int sub-limb to" {
const a = try Int.initSet(al, 10);
- debug.assert((try a.to(u8)) == 10);
+ testing.expect((try a.to(u8)) == 10);
}
test "big.int to target too small error" {
const a = try Int.initSet(al, 0xffffffff);
- if (a.to(u8)) |_| {
- unreachable;
- } else |err| {
- debug.assert(err == error.TargetTooSmall);
- }
+ testing.expectError(error.TargetTooSmall, a.to(u8));
}
test "big.int norm1" {
@@ -1135,22 +1132,22 @@ test "big.int norm1" {
a.limbs[2] = 3;
a.limbs[3] = 0;
a.norm1(4);
- debug.assert(a.len == 3);
+ testing.expect(a.len == 3);
a.limbs[0] = 1;
a.limbs[1] = 2;
a.limbs[2] = 3;
a.norm1(3);
- debug.assert(a.len == 3);
+ testing.expect(a.len == 3);
a.limbs[0] = 0;
a.limbs[1] = 0;
a.norm1(2);
- debug.assert(a.len == 1);
+ testing.expect(a.len == 1);
a.limbs[0] = 0;
a.norm1(1);
- debug.assert(a.len == 1);
+ testing.expect(a.len == 1);
}
test "big.int normN" {
@@ -1162,144 +1159,144 @@ test "big.int normN" {
a.limbs[2] = 0;
a.limbs[3] = 0;
a.normN(4);
- debug.assert(a.len == 2);
+ testing.expect(a.len == 2);
a.limbs[0] = 1;
a.limbs[1] = 2;
a.limbs[2] = 3;
a.normN(3);
- debug.assert(a.len == 3);
+ testing.expect(a.len == 3);
a.limbs[0] = 0;
a.limbs[1] = 0;
a.limbs[2] = 0;
a.limbs[3] = 0;
a.normN(4);
- debug.assert(a.len == 1);
+ testing.expect(a.len == 1);
a.limbs[0] = 0;
a.normN(1);
- debug.assert(a.len == 1);
+ testing.expect(a.len == 1);
}
test "big.int parity" {
var a = try Int.init(al);
try a.set(0);
- debug.assert(a.isEven());
- debug.assert(!a.isOdd());
+ testing.expect(a.isEven());
+ testing.expect(!a.isOdd());
try a.set(7);
- debug.assert(!a.isEven());
- debug.assert(a.isOdd());
+ testing.expect(!a.isEven());
+ testing.expect(a.isOdd());
}
test "big.int bitcount + sizeInBase" {
var a = try Int.init(al);
try a.set(0b100);
- debug.assert(a.bitCountAbs() == 3);
- debug.assert(a.sizeInBase(2) >= 3);
- debug.assert(a.sizeInBase(10) >= 1);
+ testing.expect(a.bitCountAbs() == 3);
+ testing.expect(a.sizeInBase(2) >= 3);
+ testing.expect(a.sizeInBase(10) >= 1);
a.negate();
- debug.assert(a.bitCountAbs() == 3);
- debug.assert(a.sizeInBase(2) >= 4);
- debug.assert(a.sizeInBase(10) >= 2);
+ testing.expect(a.bitCountAbs() == 3);
+ testing.expect(a.sizeInBase(2) >= 4);
+ testing.expect(a.sizeInBase(10) >= 2);
try a.set(0xffffffff);
- debug.assert(a.bitCountAbs() == 32);
- debug.assert(a.sizeInBase(2) >= 32);
- debug.assert(a.sizeInBase(10) >= 10);
+ testing.expect(a.bitCountAbs() == 32);
+ testing.expect(a.sizeInBase(2) >= 32);
+ testing.expect(a.sizeInBase(10) >= 10);
try a.shiftLeft(a, 5000);
- debug.assert(a.bitCountAbs() == 5032);
- debug.assert(a.sizeInBase(2) >= 5032);
+ testing.expect(a.bitCountAbs() == 5032);
+ testing.expect(a.sizeInBase(2) >= 5032);
a.positive = false;
- debug.assert(a.bitCountAbs() == 5032);
- debug.assert(a.sizeInBase(2) >= 5033);
+ testing.expect(a.bitCountAbs() == 5032);
+ testing.expect(a.sizeInBase(2) >= 5033);
}
test "big.int bitcount/to" {
var a = try Int.init(al);
try a.set(0);
- debug.assert(a.bitCountTwosComp() == 0);
+ testing.expect(a.bitCountTwosComp() == 0);
// TODO: stack smashing
- // debug.assert((try a.to(u0)) == 0);
+ // testing.expect((try a.to(u0)) == 0);
// TODO: sigsegv
- // debug.assert((try a.to(i0)) == 0);
+ // testing.expect((try a.to(i0)) == 0);
try a.set(-1);
- debug.assert(a.bitCountTwosComp() == 1);
- debug.assert((try a.to(i1)) == -1);
+ testing.expect(a.bitCountTwosComp() == 1);
+ testing.expect((try a.to(i1)) == -1);
try a.set(-8);
- debug.assert(a.bitCountTwosComp() == 4);
- debug.assert((try a.to(i4)) == -8);
+ testing.expect(a.bitCountTwosComp() == 4);
+ testing.expect((try a.to(i4)) == -8);
try a.set(127);
- debug.assert(a.bitCountTwosComp() == 7);
- debug.assert((try a.to(u7)) == 127);
+ testing.expect(a.bitCountTwosComp() == 7);
+ testing.expect((try a.to(u7)) == 127);
try a.set(-128);
- debug.assert(a.bitCountTwosComp() == 8);
- debug.assert((try a.to(i8)) == -128);
+ testing.expect(a.bitCountTwosComp() == 8);
+ testing.expect((try a.to(i8)) == -128);
try a.set(-129);
- debug.assert(a.bitCountTwosComp() == 9);
- debug.assert((try a.to(i9)) == -129);
+ testing.expect(a.bitCountTwosComp() == 9);
+ testing.expect((try a.to(i9)) == -129);
}
test "big.int fits" {
var a = try Int.init(al);
try a.set(0);
- debug.assert(a.fits(u0));
- debug.assert(a.fits(i0));
+ testing.expect(a.fits(u0));
+ testing.expect(a.fits(i0));
try a.set(255);
- debug.assert(!a.fits(u0));
- debug.assert(!a.fits(u1));
- debug.assert(!a.fits(i8));
- debug.assert(a.fits(u8));
- debug.assert(a.fits(u9));
- debug.assert(a.fits(i9));
+ testing.expect(!a.fits(u0));
+ testing.expect(!a.fits(u1));
+ testing.expect(!a.fits(i8));
+ testing.expect(a.fits(u8));
+ testing.expect(a.fits(u9));
+ testing.expect(a.fits(i9));
try a.set(-128);
- debug.assert(!a.fits(i7));
- debug.assert(a.fits(i8));
- debug.assert(a.fits(i9));
- debug.assert(!a.fits(u9));
+ testing.expect(!a.fits(i7));
+ testing.expect(a.fits(i8));
+ testing.expect(a.fits(i9));
+ testing.expect(!a.fits(u9));
try a.set(0x1ffffffffeeeeeeee);
- debug.assert(!a.fits(u32));
- debug.assert(!a.fits(u64));
- debug.assert(a.fits(u65));
+ testing.expect(!a.fits(u32));
+ testing.expect(!a.fits(u64));
+ testing.expect(a.fits(u65));
}
test "big.int string set" {
var a = try Int.init(al);
try a.setString(10, "120317241209124781241290847124");
- debug.assert((try a.to(u128)) == 120317241209124781241290847124);
+ testing.expect((try a.to(u128)) == 120317241209124781241290847124);
}
test "big.int string negative" {
var a = try Int.init(al);
try a.setString(10, "-1023");
- debug.assert((try a.to(i32)) == -1023);
+ testing.expect((try a.to(i32)) == -1023);
}
test "big.int string set bad char error" {
var a = try Int.init(al);
- a.setString(10, "x") catch |err| debug.assert(err == error.InvalidCharForDigit);
+ testing.expectError(error.InvalidCharForDigit, a.setString(10, "x"));
}
test "big.int string set bad base error" {
var a = try Int.init(al);
- a.setString(45, "10") catch |err| debug.assert(err == error.InvalidBase);
+ testing.expectError(error.InvalidBase, a.setString(45, "10"));
}
test "big.int string to" {
@@ -1308,17 +1305,13 @@ test "big.int string to" {
const as = try a.toString(al, 10);
const es = "120317241209124781241290847124";
- debug.assert(mem.eql(u8, as, es));
+ testing.expect(mem.eql(u8, as, es));
}
test "big.int string to base base error" {
const a = try Int.initSet(al, 0xffffffff);
- if (a.toString(al, 45)) |_| {
- unreachable;
- } else |err| {
- debug.assert(err == error.InvalidBase);
- }
+ testing.expectError(error.InvalidBase, a.toString(al, 45));
}
test "big.int string to base 2" {
@@ -1327,7 +1320,7 @@ test "big.int string to base 2" {
const as = try a.toString(al, 2);
const es = "-1011";
- debug.assert(mem.eql(u8, as, es));
+ testing.expect(mem.eql(u8, as, es));
}
test "big.int string to base 16" {
@@ -1336,7 +1329,7 @@ test "big.int string to base 16" {
const as = try a.toString(al, 16);
const es = "efffffff00000001eeeeeeefaaaaaaab";
- debug.assert(mem.eql(u8, as, es));
+ testing.expect(mem.eql(u8, as, es));
}
test "big.int neg string to" {
@@ -1345,7 +1338,7 @@ test "big.int neg string to" {
const as = try a.toString(al, 10);
const es = "-123907434";
- debug.assert(mem.eql(u8, as, es));
+ testing.expect(mem.eql(u8, as, es));
}
test "big.int zero string to" {
@@ -1354,98 +1347,98 @@ test "big.int zero string to" {
const as = try a.toString(al, 10);
const es = "0";
- debug.assert(mem.eql(u8, as, es));
+ testing.expect(mem.eql(u8, as, es));
}
test "big.int clone" {
var a = try Int.initSet(al, 1234);
const b = try a.clone();
- debug.assert((try a.to(u32)) == 1234);
- debug.assert((try b.to(u32)) == 1234);
+ testing.expect((try a.to(u32)) == 1234);
+ testing.expect((try b.to(u32)) == 1234);
try a.set(77);
- debug.assert((try a.to(u32)) == 77);
- debug.assert((try b.to(u32)) == 1234);
+ testing.expect((try a.to(u32)) == 77);
+ testing.expect((try b.to(u32)) == 1234);
}
test "big.int swap" {
var a = try Int.initSet(al, 1234);
var b = try Int.initSet(al, 5678);
- debug.assert((try a.to(u32)) == 1234);
- debug.assert((try b.to(u32)) == 5678);
+ testing.expect((try a.to(u32)) == 1234);
+ testing.expect((try b.to(u32)) == 5678);
a.swap(&b);
- debug.assert((try a.to(u32)) == 5678);
- debug.assert((try b.to(u32)) == 1234);
+ testing.expect((try a.to(u32)) == 5678);
+ testing.expect((try b.to(u32)) == 1234);
}
test "big.int to negative" {
var a = try Int.initSet(al, -10);
- debug.assert((try a.to(i32)) == -10);
+ testing.expect((try a.to(i32)) == -10);
}
test "big.int compare" {
var a = try Int.initSet(al, -11);
var b = try Int.initSet(al, 10);
- debug.assert(a.cmpAbs(b) == 1);
- debug.assert(a.cmp(b) == -1);
+ testing.expect(a.cmpAbs(b) == 1);
+ testing.expect(a.cmp(b) == -1);
}
test "big.int compare similar" {
var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);
var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);
- debug.assert(a.cmpAbs(b) == -1);
- debug.assert(b.cmpAbs(a) == 1);
+ testing.expect(a.cmpAbs(b) == -1);
+ testing.expect(b.cmpAbs(a) == 1);
}
test "big.int compare different limb size" {
var a = try Int.initSet(al, maxInt(Limb) + 1);
var b = try Int.initSet(al, 1);
- debug.assert(a.cmpAbs(b) == 1);
- debug.assert(b.cmpAbs(a) == -1);
+ testing.expect(a.cmpAbs(b) == 1);
+ testing.expect(b.cmpAbs(a) == -1);
}
test "big.int compare multi-limb" {
var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
- debug.assert(a.cmpAbs(b) == 1);
- debug.assert(a.cmp(b) == -1);
+ testing.expect(a.cmpAbs(b) == 1);
+ testing.expect(a.cmp(b) == -1);
}
test "big.int equality" {
var a = try Int.initSet(al, 0xffffffff1);
var b = try Int.initSet(al, -0xffffffff1);
- debug.assert(a.eqAbs(b));
- debug.assert(!a.eq(b));
+ testing.expect(a.eqAbs(b));
+ testing.expect(!a.eq(b));
}
test "big.int abs" {
var a = try Int.initSet(al, -5);
a.abs();
- debug.assert((try a.to(u32)) == 5);
+ testing.expect((try a.to(u32)) == 5);
a.abs();
- debug.assert((try a.to(u32)) == 5);
+ testing.expect((try a.to(u32)) == 5);
}
test "big.int negate" {
var a = try Int.initSet(al, 5);
a.negate();
- debug.assert((try a.to(i32)) == -5);
+ testing.expect((try a.to(i32)) == -5);
a.negate();
- debug.assert((try a.to(i32)) == 5);
+ testing.expect((try a.to(i32)) == 5);
}
test "big.int add single-single" {
@@ -1455,7 +1448,7 @@ test "big.int add single-single" {
var c = try Int.init(al);
try c.add(a, b);
- debug.assert((try c.to(u32)) == 55);
+ testing.expect((try c.to(u32)) == 55);
}
test "big.int add multi-single" {
@@ -1465,10 +1458,10 @@ test "big.int add multi-single" {
var c = try Int.init(al);
try c.add(a, b);
- debug.assert((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
+ testing.expect((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
try c.add(b, a);
- debug.assert((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
+ testing.expect((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
}
test "big.int add multi-multi" {
@@ -1480,7 +1473,7 @@ test "big.int add multi-multi" {
var c = try Int.init(al);
try c.add(a, b);
- debug.assert((try c.to(u128)) == op1 + op2);
+ testing.expect((try c.to(u128)) == op1 + op2);
}
test "big.int add zero-zero" {
@@ -1490,7 +1483,7 @@ test "big.int add zero-zero" {
var c = try Int.init(al);
try c.add(a, b);
- debug.assert((try c.to(u32)) == 0);
+ testing.expect((try c.to(u32)) == 0);
}
test "big.int add alias multi-limb nonzero-zero" {
@@ -1500,7 +1493,7 @@ test "big.int add alias multi-limb nonzero-zero" {
try a.add(a, b);
- debug.assert((try a.to(u128)) == op1);
+ testing.expect((try a.to(u128)) == op1);
}
test "big.int add sign" {
@@ -1512,16 +1505,16 @@ test "big.int add sign" {
const neg_two = try Int.initSet(al, -2);
try a.add(one, two);
- debug.assert((try a.to(i32)) == 3);
+ testing.expect((try a.to(i32)) == 3);
try a.add(neg_one, two);
- debug.assert((try a.to(i32)) == 1);
+ testing.expect((try a.to(i32)) == 1);
try a.add(one, neg_two);
- debug.assert((try a.to(i32)) == -1);
+ testing.expect((try a.to(i32)) == -1);
try a.add(neg_one, neg_two);
- debug.assert((try a.to(i32)) == -3);
+ testing.expect((try a.to(i32)) == -3);
}
test "big.int sub single-single" {
@@ -1531,7 +1524,7 @@ test "big.int sub single-single" {
var c = try Int.init(al);
try c.sub(a, b);
- debug.assert((try c.to(u32)) == 45);
+ testing.expect((try c.to(u32)) == 45);
}
test "big.int sub multi-single" {
@@ -1541,7 +1534,7 @@ test "big.int sub multi-single" {
var c = try Int.init(al);
try c.sub(a, b);
- debug.assert((try c.to(Limb)) == maxInt(Limb));
+ testing.expect((try c.to(Limb)) == maxInt(Limb));
}
test "big.int sub multi-multi" {
@@ -1554,7 +1547,7 @@ test "big.int sub multi-multi" {
var c = try Int.init(al);
try c.sub(a, b);
- debug.assert((try c.to(u128)) == op1 - op2);
+ testing.expect((try c.to(u128)) == op1 - op2);
}
test "big.int sub equal" {
@@ -1564,7 +1557,7 @@ test "big.int sub equal" {
var c = try Int.init(al);
try c.sub(a, b);
- debug.assert((try c.to(u32)) == 0);
+ testing.expect((try c.to(u32)) == 0);
}
test "big.int sub sign" {
@@ -1576,19 +1569,19 @@ test "big.int sub sign" {
const neg_two = try Int.initSet(al, -2);
try a.sub(one, two);
- debug.assert((try a.to(i32)) == -1);
+ testing.expect((try a.to(i32)) == -1);
try a.sub(neg_one, two);
- debug.assert((try a.to(i32)) == -3);
+ testing.expect((try a.to(i32)) == -3);
try a.sub(one, neg_two);
- debug.assert((try a.to(i32)) == 3);
+ testing.expect((try a.to(i32)) == 3);
try a.sub(neg_one, neg_two);
- debug.assert((try a.to(i32)) == 1);
+ testing.expect((try a.to(i32)) == 1);
try a.sub(neg_two, neg_one);
- debug.assert((try a.to(i32)) == -1);
+ testing.expect((try a.to(i32)) == -1);
}
test "big.int mul single-single" {
@@ -1598,7 +1591,7 @@ test "big.int mul single-single" {
var c = try Int.init(al);
try c.mul(a, b);
- debug.assert((try c.to(u64)) == 250);
+ testing.expect((try c.to(u64)) == 250);
}
test "big.int mul multi-single" {
@@ -1608,7 +1601,7 @@ test "big.int mul multi-single" {
var c = try Int.init(al);
try c.mul(a, b);
- debug.assert((try c.to(DoubleLimb)) == 2 * maxInt(Limb));
+ testing.expect((try c.to(DoubleLimb)) == 2 * maxInt(Limb));
}
test "big.int mul multi-multi" {
@@ -1620,7 +1613,7 @@ test "big.int mul multi-multi" {
var c = try Int.init(al);
try c.mul(a, b);
- debug.assert((try c.to(u256)) == op1 * op2);
+ testing.expect((try c.to(u256)) == op1 * op2);
}
test "big.int mul alias r with a" {
@@ -1629,7 +1622,7 @@ test "big.int mul alias r with a" {
try a.mul(a, b);
- debug.assert((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
+ testing.expect((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
}
test "big.int mul alias r with b" {
@@ -1638,7 +1631,7 @@ test "big.int mul alias r with b" {
try a.mul(b, a);
- debug.assert((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
+ testing.expect((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
}
test "big.int mul alias r with a and b" {
@@ -1646,7 +1639,7 @@ test "big.int mul alias r with a and b" {
try a.mul(a, a);
- debug.assert((try a.to(DoubleLimb)) == maxInt(Limb) * maxInt(Limb));
+ testing.expect((try a.to(DoubleLimb)) == maxInt(Limb) * maxInt(Limb));
}
test "big.int mul a*0" {
@@ -1656,7 +1649,7 @@ test "big.int mul a*0" {
var c = try Int.init(al);
try c.mul(a, b);
- debug.assert((try c.to(u32)) == 0);
+ testing.expect((try c.to(u32)) == 0);
}
test "big.int mul 0*0" {
@@ -1666,7 +1659,7 @@ test "big.int mul 0*0" {
var c = try Int.init(al);
try c.mul(a, b);
- debug.assert((try c.to(u32)) == 0);
+ testing.expect((try c.to(u32)) == 0);
}
test "big.int div single-single no rem" {
@@ -1677,8 +1670,8 @@ test "big.int div single-single no rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u32)) == 10);
- debug.assert((try r.to(u32)) == 0);
+ testing.expect((try q.to(u32)) == 10);
+ testing.expect((try r.to(u32)) == 0);
}
test "big.int div single-single with rem" {
@@ -1689,8 +1682,8 @@ test "big.int div single-single with rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u32)) == 9);
- debug.assert((try r.to(u32)) == 4);
+ testing.expect((try q.to(u32)) == 9);
+ testing.expect((try r.to(u32)) == 4);
}
test "big.int div multi-single no rem" {
@@ -1704,8 +1697,8 @@ test "big.int div multi-single no rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u64)) == op1 / op2);
- debug.assert((try r.to(u64)) == 0);
+ testing.expect((try q.to(u64)) == op1 / op2);
+ testing.expect((try r.to(u64)) == 0);
}
test "big.int div multi-single with rem" {
@@ -1719,8 +1712,8 @@ test "big.int div multi-single with rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u64)) == op1 / op2);
- debug.assert((try r.to(u64)) == 3);
+ testing.expect((try q.to(u64)) == op1 / op2);
+ testing.expect((try r.to(u64)) == 3);
}
test "big.int div multi>2-single" {
@@ -1734,8 +1727,8 @@ test "big.int div multi>2-single" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == op1 / op2);
- debug.assert((try r.to(u32)) == 0x3e4e);
+ testing.expect((try q.to(u128)) == op1 / op2);
+ testing.expect((try r.to(u32)) == 0x3e4e);
}
test "big.int div single-single q < r" {
@@ -1746,8 +1739,8 @@ test "big.int div single-single q < r" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u64)) == 0);
- debug.assert((try r.to(u64)) == 0x0078f432);
+ testing.expect((try q.to(u64)) == 0);
+ testing.expect((try r.to(u64)) == 0x0078f432);
}
test "big.int div single-single q == r" {
@@ -1758,8 +1751,8 @@ test "big.int div single-single q == r" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u64)) == 1);
- debug.assert((try r.to(u64)) == 0);
+ testing.expect((try q.to(u64)) == 1);
+ testing.expect((try r.to(u64)) == 0);
}
test "big.int div q=0 alias" {
@@ -1768,8 +1761,8 @@ test "big.int div q=0 alias" {
try Int.divTrunc(&a, &b, a, b);
- debug.assert((try a.to(u64)) == 0);
- debug.assert((try b.to(u64)) == 3);
+ testing.expect((try a.to(u64)) == 0);
+ testing.expect((try b.to(u64)) == 3);
}
test "big.int div multi-multi q < r" {
@@ -1782,8 +1775,8 @@ test "big.int div multi-multi q < r" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == 0);
- debug.assert((try r.to(u128)) == op1);
+ testing.expect((try q.to(u128)) == 0);
+ testing.expect((try r.to(u128)) == op1);
}
test "big.int div trunc single-single +/+" {
@@ -1802,8 +1795,8 @@ test "big.int div trunc single-single +/+" {
const eq = @divTrunc(u, v);
const er = @mod(u, v);
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div trunc single-single -/+" {
@@ -1822,8 +1815,8 @@ test "big.int div trunc single-single -/+" {
const eq = -1;
const er = -2;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div trunc single-single +/-" {
@@ -1842,8 +1835,8 @@ test "big.int div trunc single-single +/-" {
const eq = -1;
const er = 2;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div trunc single-single -/-" {
@@ -1862,8 +1855,8 @@ test "big.int div trunc single-single -/-" {
const eq = 1;
const er = -2;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div floor single-single +/+" {
@@ -1882,8 +1875,8 @@ test "big.int div floor single-single +/+" {
const eq = 1;
const er = 2;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div floor single-single -/+" {
@@ -1902,8 +1895,8 @@ test "big.int div floor single-single -/+" {
const eq = -2;
const er = 1;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div floor single-single +/-" {
@@ -1922,8 +1915,8 @@ test "big.int div floor single-single +/-" {
const eq = -2;
const er = -1;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div floor single-single -/-" {
@@ -1942,8 +1935,8 @@ test "big.int div floor single-single -/-" {
const eq = 1;
const er = -2;
- debug.assert((try q.to(i32)) == eq);
- debug.assert((try r.to(i32)) == er);
+ testing.expect((try q.to(i32)) == eq);
+ testing.expect((try r.to(i32)) == er);
}
test "big.int div multi-multi with rem" {
@@ -1954,8 +1947,8 @@ test "big.int div multi-multi with rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
- debug.assert((try r.to(u128)) == 0x28de0acacd806823638);
+ testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
+ testing.expect((try r.to(u128)) == 0x28de0acacd806823638);
}
test "big.int div multi-multi no rem" {
@@ -1966,8 +1959,8 @@ test "big.int div multi-multi no rem" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
- debug.assert((try r.to(u128)) == 0);
+ testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
+ testing.expect((try r.to(u128)) == 0);
}
test "big.int div multi-multi (2 branch)" {
@@ -1978,8 +1971,8 @@ test "big.int div multi-multi (2 branch)" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == 0x10000000000000000);
- debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111);
+ testing.expect((try q.to(u128)) == 0x10000000000000000);
+ testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111);
}
test "big.int div multi-multi (3.1/3.3 branch)" {
@@ -1990,53 +1983,53 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
var r = try Int.init(al);
try Int.divTrunc(&q, &r, a, b);
- debug.assert((try q.to(u128)) == 0xfffffffffffffffffff);
- debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
+ testing.expect((try q.to(u128)) == 0xfffffffffffffffffff);
+ testing.expect((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
}
test "big.int shift-right single" {
var a = try Int.initSet(al, 0xffff0000);
try a.shiftRight(a, 16);
- debug.assert((try a.to(u32)) == 0xffff);
+ testing.expect((try a.to(u32)) == 0xffff);
}
test "big.int shift-right multi" {
var a = try Int.initSet(al, 0xffff0000eeee1111dddd2222cccc3333);
try a.shiftRight(a, 67);
- debug.assert((try a.to(u64)) == 0x1fffe0001dddc222);
+ testing.expect((try a.to(u64)) == 0x1fffe0001dddc222);
}
test "big.int shift-left single" {
var a = try Int.initSet(al, 0xffff);
try a.shiftLeft(a, 16);
- debug.assert((try a.to(u64)) == 0xffff0000);
+ testing.expect((try a.to(u64)) == 0xffff0000);
}
test "big.int shift-left multi" {
var a = try Int.initSet(al, 0x1fffe0001dddc222);
try a.shiftLeft(a, 67);
- debug.assert((try a.to(u128)) == 0xffff0000eeee11100000000000000000);
+ testing.expect((try a.to(u128)) == 0xffff0000eeee11100000000000000000);
}
test "big.int shift-right negative" {
var a = try Int.init(al);
try a.shiftRight(try Int.initSet(al, -20), 2);
- debug.assert((try a.to(i32)) == -20 >> 2);
+ testing.expect((try a.to(i32)) == -20 >> 2);
try a.shiftRight(try Int.initSet(al, -5), 10);
- debug.assert((try a.to(i32)) == -5 >> 10);
+ testing.expect((try a.to(i32)) == -5 >> 10);
}
test "big.int shift-left negative" {
var a = try Int.init(al);
try a.shiftRight(try Int.initSet(al, -10), 1232);
- debug.assert((try a.to(i32)) == -10 >> 1232);
+ testing.expect((try a.to(i32)) == -10 >> 1232);
}
test "big.int bitwise and simple" {
@@ -2045,7 +2038,7 @@ test "big.int bitwise and simple" {
try a.bitAnd(a, b);
- debug.assert((try a.to(u64)) == 0xeeeeeeee00000000);
+ testing.expect((try a.to(u64)) == 0xeeeeeeee00000000);
}
test "big.int bitwise and multi-limb" {
@@ -2054,7 +2047,7 @@ test "big.int bitwise and multi-limb" {
try a.bitAnd(a, b);
- debug.assert((try a.to(u128)) == 0);
+ testing.expect((try a.to(u128)) == 0);
}
test "big.int bitwise xor simple" {
@@ -2063,7 +2056,7 @@ test "big.int bitwise xor simple" {
try a.bitXor(a, b);
- debug.assert((try a.to(u64)) == 0x1111111133333333);
+ testing.expect((try a.to(u64)) == 0x1111111133333333);
}
test "big.int bitwise xor multi-limb" {
@@ -2072,7 +2065,7 @@ test "big.int bitwise xor multi-limb" {
try a.bitXor(a, b);
- debug.assert((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) ^ maxInt(Limb));
+ testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) ^ maxInt(Limb));
}
test "big.int bitwise or simple" {
@@ -2081,7 +2074,7 @@ test "big.int bitwise or simple" {
try a.bitOr(a, b);
- debug.assert((try a.to(u64)) == 0xffffffff33333333);
+ testing.expect((try a.to(u64)) == 0xffffffff33333333);
}
test "big.int bitwise or multi-limb" {
@@ -2091,15 +2084,15 @@ test "big.int bitwise or multi-limb" {
try a.bitOr(a, b);
// TODO: big.int.cpp or is wrong on multi-limb.
- debug.assert((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) + maxInt(Limb));
+ testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) + maxInt(Limb));
}
test "big.int var args" {
var a = try Int.initSet(al, 5);
try a.add(a, try Int.initSet(al, 6));
- debug.assert((try a.to(u64)) == 11);
+ testing.expect((try a.to(u64)) == 11);
- debug.assert(a.cmp(try Int.initSet(al, 11)) == 0);
- debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0);
+ testing.expect(a.cmp(try Int.initSet(al, 11)) == 0);
+ testing.expect(a.cmp(try Int.initSet(al, 14)) <= 0);
}
diff --git a/std/math/cbrt.zig b/std/math/cbrt.zig
index c067c5155a..957e026af4 100644
--- a/std/math/cbrt.zig
+++ b/std/math/cbrt.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn cbrt(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -114,44 +114,44 @@ fn cbrt64(x: f64) f64 {
}
test "math.cbrt" {
- assert(cbrt(f32(0.0)) == cbrt32(0.0));
- assert(cbrt(f64(0.0)) == cbrt64(0.0));
+ expect(cbrt(f32(0.0)) == cbrt32(0.0));
+ expect(cbrt(f64(0.0)) == cbrt64(0.0));
}
test "math.cbrt32" {
const epsilon = 0.000001;
- assert(cbrt32(0.0) == 0.0);
- assert(math.approxEq(f32, cbrt32(0.2), 0.584804, epsilon));
- assert(math.approxEq(f32, cbrt32(0.8923), 0.962728, epsilon));
- assert(math.approxEq(f32, cbrt32(1.5), 1.144714, epsilon));
- assert(math.approxEq(f32, cbrt32(37.45), 3.345676, epsilon));
- assert(math.approxEq(f32, cbrt32(123123.234375), 49.748501, epsilon));
+ expect(cbrt32(0.0) == 0.0);
+ expect(math.approxEq(f32, cbrt32(0.2), 0.584804, epsilon));
+ expect(math.approxEq(f32, cbrt32(0.8923), 0.962728, epsilon));
+ expect(math.approxEq(f32, cbrt32(1.5), 1.144714, epsilon));
+ expect(math.approxEq(f32, cbrt32(37.45), 3.345676, epsilon));
+ expect(math.approxEq(f32, cbrt32(123123.234375), 49.748501, epsilon));
}
test "math.cbrt64" {
const epsilon = 0.000001;
- assert(cbrt64(0.0) == 0.0);
- assert(math.approxEq(f64, cbrt64(0.2), 0.584804, epsilon));
- assert(math.approxEq(f64, cbrt64(0.8923), 0.962728, epsilon));
- assert(math.approxEq(f64, cbrt64(1.5), 1.144714, epsilon));
- assert(math.approxEq(f64, cbrt64(37.45), 3.345676, epsilon));
- assert(math.approxEq(f64, cbrt64(123123.234375), 49.748501, epsilon));
+ expect(cbrt64(0.0) == 0.0);
+ expect(math.approxEq(f64, cbrt64(0.2), 0.584804, epsilon));
+ expect(math.approxEq(f64, cbrt64(0.8923), 0.962728, epsilon));
+ expect(math.approxEq(f64, cbrt64(1.5), 1.144714, epsilon));
+ expect(math.approxEq(f64, cbrt64(37.45), 3.345676, epsilon));
+ expect(math.approxEq(f64, cbrt64(123123.234375), 49.748501, epsilon));
}
test "math.cbrt.special" {
- assert(cbrt32(0.0) == 0.0);
- assert(cbrt32(-0.0) == -0.0);
- assert(math.isPositiveInf(cbrt32(math.inf(f32))));
- assert(math.isNegativeInf(cbrt32(-math.inf(f32))));
- assert(math.isNan(cbrt32(math.nan(f32))));
+ expect(cbrt32(0.0) == 0.0);
+ expect(cbrt32(-0.0) == -0.0);
+ expect(math.isPositiveInf(cbrt32(math.inf(f32))));
+ expect(math.isNegativeInf(cbrt32(-math.inf(f32))));
+ expect(math.isNan(cbrt32(math.nan(f32))));
}
test "math.cbrt64.special" {
- assert(cbrt64(0.0) == 0.0);
- assert(cbrt64(-0.0) == -0.0);
- assert(math.isPositiveInf(cbrt64(math.inf(f64))));
- assert(math.isNegativeInf(cbrt64(-math.inf(f64))));
- assert(math.isNan(cbrt64(math.nan(f64))));
+ expect(cbrt64(0.0) == 0.0);
+ expect(cbrt64(-0.0) == -0.0);
+ expect(math.isPositiveInf(cbrt64(math.inf(f64))));
+ expect(math.isNegativeInf(cbrt64(-math.inf(f64))));
+ expect(math.isNan(cbrt64(math.nan(f64))));
}
diff --git a/std/math/ceil.zig b/std/math/ceil.zig
index 8a5221d862..5c6b98b2ca 100644
--- a/std/math/ceil.zig
+++ b/std/math/ceil.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn ceil(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -81,34 +81,34 @@ fn ceil64(x: f64) f64 {
}
test "math.ceil" {
- assert(ceil(f32(0.0)) == ceil32(0.0));
- assert(ceil(f64(0.0)) == ceil64(0.0));
+ expect(ceil(f32(0.0)) == ceil32(0.0));
+ expect(ceil(f64(0.0)) == ceil64(0.0));
}
test "math.ceil32" {
- assert(ceil32(1.3) == 2.0);
- assert(ceil32(-1.3) == -1.0);
- assert(ceil32(0.2) == 1.0);
+ expect(ceil32(1.3) == 2.0);
+ expect(ceil32(-1.3) == -1.0);
+ expect(ceil32(0.2) == 1.0);
}
test "math.ceil64" {
- assert(ceil64(1.3) == 2.0);
- assert(ceil64(-1.3) == -1.0);
- assert(ceil64(0.2) == 1.0);
+ expect(ceil64(1.3) == 2.0);
+ expect(ceil64(-1.3) == -1.0);
+ expect(ceil64(0.2) == 1.0);
}
test "math.ceil32.special" {
- assert(ceil32(0.0) == 0.0);
- assert(ceil32(-0.0) == -0.0);
- assert(math.isPositiveInf(ceil32(math.inf(f32))));
- assert(math.isNegativeInf(ceil32(-math.inf(f32))));
- assert(math.isNan(ceil32(math.nan(f32))));
+ expect(ceil32(0.0) == 0.0);
+ expect(ceil32(-0.0) == -0.0);
+ expect(math.isPositiveInf(ceil32(math.inf(f32))));
+ expect(math.isNegativeInf(ceil32(-math.inf(f32))));
+ expect(math.isNan(ceil32(math.nan(f32))));
}
test "math.ceil64.special" {
- assert(ceil64(0.0) == 0.0);
- assert(ceil64(-0.0) == -0.0);
- assert(math.isPositiveInf(ceil64(math.inf(f64))));
- assert(math.isNegativeInf(ceil64(-math.inf(f64))));
- assert(math.isNan(ceil64(math.nan(f64))));
+ expect(ceil64(0.0) == 0.0);
+ expect(ceil64(-0.0) == -0.0);
+ expect(math.isPositiveInf(ceil64(math.inf(f64))));
+ expect(math.isNegativeInf(ceil64(-math.inf(f64))));
+ expect(math.isNan(ceil64(math.nan(f64))));
}
diff --git a/std/math/complex/abs.zig b/std/math/complex/abs.zig
index 4cd095c46b..245d67d4c5 100644
--- a/std/math/complex/abs.zig
+++ b/std/math/complex/abs.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -14,5 +14,5 @@ const epsilon = 0.0001;
test "complex.cabs" {
const a = Complex(f32).new(5, 3);
const c = abs(a);
- debug.assert(math.approxEq(f32, c, 5.83095, epsilon));
+ testing.expect(math.approxEq(f32, c, 5.83095, epsilon));
}
diff --git a/std/math/complex/acos.zig b/std/math/complex/acos.zig
index a5760b4ace..1b314bc31a 100644
--- a/std/math/complex/acos.zig
+++ b/std/math/complex/acos.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -16,6 +16,6 @@ test "complex.cacos" {
const a = Complex(f32).new(5, 3);
const c = acos(a);
- debug.assert(math.approxEq(f32, c.re, 0.546975, epsilon));
- debug.assert(math.approxEq(f32, c.im, -2.452914, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 0.546975, epsilon));
+ testing.expect(math.approxEq(f32, c.im, -2.452914, epsilon));
}
diff --git a/std/math/complex/acosh.zig b/std/math/complex/acosh.zig
index 8dd91b2836..0e4c0121f4 100644
--- a/std/math/complex/acosh.zig
+++ b/std/math/complex/acosh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -16,6 +16,6 @@ test "complex.cacosh" {
const a = Complex(f32).new(5, 3);
const c = acosh(a);
- debug.assert(math.approxEq(f32, c.re, 2.452914, epsilon));
- debug.assert(math.approxEq(f32, c.im, 0.546975, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 2.452914, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 0.546975, epsilon));
}
diff --git a/std/math/complex/arg.zig b/std/math/complex/arg.zig
index f24512ac73..be117a5940 100644
--- a/std/math/complex/arg.zig
+++ b/std/math/complex/arg.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -14,5 +14,5 @@ const epsilon = 0.0001;
test "complex.carg" {
const a = Complex(f32).new(5, 3);
const c = arg(a);
- debug.assert(math.approxEq(f32, c, 0.540420, epsilon));
+ testing.expect(math.approxEq(f32, c, 0.540420, epsilon));
}
diff --git a/std/math/complex/asin.zig b/std/math/complex/asin.zig
index 584a3a1a9b..cf802ea206 100644
--- a/std/math/complex/asin.zig
+++ b/std/math/complex/asin.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -22,6 +22,6 @@ test "complex.casin" {
const a = Complex(f32).new(5, 3);
const c = asin(a);
- debug.assert(math.approxEq(f32, c.re, 1.023822, epsilon));
- debug.assert(math.approxEq(f32, c.im, 2.452914, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 1.023822, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 2.452914, epsilon));
}
diff --git a/std/math/complex/asinh.zig b/std/math/complex/asinh.zig
index 0c4dc2b6e4..0386a636b0 100644
--- a/std/math/complex/asinh.zig
+++ b/std/math/complex/asinh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -17,6 +17,6 @@ test "complex.casinh" {
const a = Complex(f32).new(5, 3);
const c = asinh(a);
- debug.assert(math.approxEq(f32, c.re, 2.459831, epsilon));
- debug.assert(math.approxEq(f32, c.im, 0.533999, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 2.459831, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 0.533999, epsilon));
}
diff --git a/std/math/complex/atan.zig b/std/math/complex/atan.zig
index de60f2546d..8e60e58e43 100644
--- a/std/math/complex/atan.zig
+++ b/std/math/complex/atan.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -117,14 +117,14 @@ test "complex.catan32" {
const a = Complex(f32).new(5, 3);
const c = atan(a);
- debug.assert(math.approxEq(f32, c.re, 1.423679, epsilon));
- debug.assert(math.approxEq(f32, c.im, 0.086569, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 1.423679, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 0.086569, epsilon));
}
test "complex.catan64" {
const a = Complex(f64).new(5, 3);
const c = atan(a);
- debug.assert(math.approxEq(f64, c.re, 1.423679, epsilon));
- debug.assert(math.approxEq(f64, c.im, 0.086569, epsilon));
+ testing.expect(math.approxEq(f64, c.re, 1.423679, epsilon));
+ testing.expect(math.approxEq(f64, c.im, 0.086569, epsilon));
}
diff --git a/std/math/complex/atanh.zig b/std/math/complex/atanh.zig
index f70c741765..5b18fe1992 100644
--- a/std/math/complex/atanh.zig
+++ b/std/math/complex/atanh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -17,6 +17,6 @@ test "complex.catanh" {
const a = Complex(f32).new(5, 3);
const c = atanh(a);
- debug.assert(math.approxEq(f32, c.re, 0.146947, epsilon));
- debug.assert(math.approxEq(f32, c.im, 1.480870, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 0.146947, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 1.480870, epsilon));
}
diff --git a/std/math/complex/conj.zig b/std/math/complex/conj.zig
index ad3e8b5036..143543f9e7 100644
--- a/std/math/complex/conj.zig
+++ b/std/math/complex/conj.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -13,5 +13,5 @@ test "complex.conj" {
const a = Complex(f32).new(5, 3);
const c = a.conjugate();
- debug.assert(c.re == 5 and c.im == -3);
+ testing.expect(c.re == 5 and c.im == -3);
}
diff --git a/std/math/complex/cos.zig b/std/math/complex/cos.zig
index 96e4ffcdb0..658d19c3b6 100644
--- a/std/math/complex/cos.zig
+++ b/std/math/complex/cos.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -16,6 +16,6 @@ test "complex.ccos" {
const a = Complex(f32).new(5, 3);
const c = cos(a);
- debug.assert(math.approxEq(f32, c.re, 2.855815, epsilon));
- debug.assert(math.approxEq(f32, c.im, 9.606383, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 2.855815, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 9.606383, epsilon));
}
diff --git a/std/math/complex/cosh.zig b/std/math/complex/cosh.zig
index 91875a0c47..5ce10b03f8 100644
--- a/std/math/complex/cosh.zig
+++ b/std/math/complex/cosh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -152,14 +152,14 @@ test "complex.ccosh32" {
const a = Complex(f32).new(5, 3);
const c = cosh(a);
- debug.assert(math.approxEq(f32, c.re, -73.467300, epsilon));
- debug.assert(math.approxEq(f32, c.im, 10.471557, epsilon));
+ testing.expect(math.approxEq(f32, c.re, -73.467300, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 10.471557, epsilon));
}
test "complex.ccosh64" {
const a = Complex(f64).new(5, 3);
const c = cosh(a);
- debug.assert(math.approxEq(f64, c.re, -73.467300, epsilon));
- debug.assert(math.approxEq(f64, c.im, 10.471557, epsilon));
+ testing.expect(math.approxEq(f64, c.re, -73.467300, epsilon));
+ testing.expect(math.approxEq(f64, c.im, 10.471557, epsilon));
}
diff --git a/std/math/complex/exp.zig b/std/math/complex/exp.zig
index 0473f653b6..9ded698d08 100644
--- a/std/math/complex/exp.zig
+++ b/std/math/complex/exp.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -118,14 +118,14 @@ test "complex.cexp32" {
const a = Complex(f32).new(5, 3);
const c = exp(a);
- debug.assert(math.approxEq(f32, c.re, -146.927917, epsilon));
- debug.assert(math.approxEq(f32, c.im, 20.944065, epsilon));
+ testing.expect(math.approxEq(f32, c.re, -146.927917, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 20.944065, epsilon));
}
test "complex.cexp64" {
const a = Complex(f64).new(5, 3);
const c = exp(a);
- debug.assert(math.approxEq(f64, c.re, -146.927917, epsilon));
- debug.assert(math.approxEq(f64, c.im, 20.944065, epsilon));
+ testing.expect(math.approxEq(f64, c.re, -146.927917, epsilon));
+ testing.expect(math.approxEq(f64, c.im, 20.944065, epsilon));
}
diff --git a/std/math/complex/index.zig b/std/math/complex/index.zig
index 171c4c5829..ffbf14d83e 100644
--- a/std/math/complex/index.zig
+++ b/std/math/complex/index.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
pub const abs = @import("abs.zig").abs;
@@ -97,7 +97,7 @@ test "complex.add" {
const b = Complex(f32).new(2, 7);
const c = a.add(b);
- debug.assert(c.re == 7 and c.im == 10);
+ testing.expect(c.re == 7 and c.im == 10);
}
test "complex.sub" {
@@ -105,7 +105,7 @@ test "complex.sub" {
const b = Complex(f32).new(2, 7);
const c = a.sub(b);
- debug.assert(c.re == 3 and c.im == -4);
+ testing.expect(c.re == 3 and c.im == -4);
}
test "complex.mul" {
@@ -113,7 +113,7 @@ test "complex.mul" {
const b = Complex(f32).new(2, 7);
const c = a.mul(b);
- debug.assert(c.re == -11 and c.im == 41);
+ testing.expect(c.re == -11 and c.im == 41);
}
test "complex.div" {
@@ -121,7 +121,7 @@ test "complex.div" {
const b = Complex(f32).new(2, 7);
const c = a.div(b);
- debug.assert(math.approxEq(f32, c.re, f32(31) / 53, epsilon) and
+ testing.expect(math.approxEq(f32, c.re, f32(31) / 53, epsilon) and
math.approxEq(f32, c.im, f32(-29) / 53, epsilon));
}
@@ -129,14 +129,14 @@ test "complex.conjugate" {
const a = Complex(f32).new(5, 3);
const c = a.conjugate();
- debug.assert(c.re == 5 and c.im == -3);
+ testing.expect(c.re == 5 and c.im == -3);
}
test "complex.reciprocal" {
const a = Complex(f32).new(5, 3);
const c = a.reciprocal();
- debug.assert(math.approxEq(f32, c.re, f32(5) / 34, epsilon) and
+ testing.expect(math.approxEq(f32, c.re, f32(5) / 34, epsilon) and
math.approxEq(f32, c.im, f32(-3) / 34, epsilon));
}
@@ -144,7 +144,7 @@ test "complex.magnitude" {
const a = Complex(f32).new(5, 3);
const c = a.magnitude();
- debug.assert(math.approxEq(f32, c, 5.83095, epsilon));
+ testing.expect(math.approxEq(f32, c, 5.83095, epsilon));
}
test "complex.cmath" {
diff --git a/std/math/complex/log.zig b/std/math/complex/log.zig
index a4a1d1664f..360bb7d21e 100644
--- a/std/math/complex/log.zig
+++ b/std/math/complex/log.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -18,6 +18,6 @@ test "complex.clog" {
const a = Complex(f32).new(5, 3);
const c = log(a);
- debug.assert(math.approxEq(f32, c.re, 1.763180, epsilon));
- debug.assert(math.approxEq(f32, c.im, 0.540419, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 1.763180, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 0.540419, epsilon));
}
diff --git a/std/math/complex/pow.zig b/std/math/complex/pow.zig
index edf68653b6..bd625626c8 100644
--- a/std/math/complex/pow.zig
+++ b/std/math/complex/pow.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -17,6 +17,6 @@ test "complex.cpow" {
const b = Complex(f32).new(2.3, -1.3);
const c = pow(Complex(f32), a, b);
- debug.assert(math.approxEq(f32, c.re, 58.049110, epsilon));
- debug.assert(math.approxEq(f32, c.im, -101.003433, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 58.049110, epsilon));
+ testing.expect(math.approxEq(f32, c.im, -101.003433, epsilon));
}
diff --git a/std/math/complex/proj.zig b/std/math/complex/proj.zig
index b6c4cc046e..d31006129e 100644
--- a/std/math/complex/proj.zig
+++ b/std/math/complex/proj.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -20,5 +20,5 @@ test "complex.cproj" {
const a = Complex(f32).new(5, 3);
const c = proj(a);
- debug.assert(c.re == 5 and c.im == 3);
+ testing.expect(c.re == 5 and c.im == 3);
}
diff --git a/std/math/complex/sin.zig b/std/math/complex/sin.zig
index d32b771d3b..9d54ab0969 100644
--- a/std/math/complex/sin.zig
+++ b/std/math/complex/sin.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -17,6 +17,6 @@ test "complex.csin" {
const a = Complex(f32).new(5, 3);
const c = sin(a);
- debug.assert(math.approxEq(f32, c.re, -9.654126, epsilon));
- debug.assert(math.approxEq(f32, c.im, 2.841692, epsilon));
+ testing.expect(math.approxEq(f32, c.re, -9.654126, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 2.841692, epsilon));
}
diff --git a/std/math/complex/sinh.zig b/std/math/complex/sinh.zig
index dc19a0ba1b..469ea6067a 100644
--- a/std/math/complex/sinh.zig
+++ b/std/math/complex/sinh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -151,14 +151,14 @@ test "complex.csinh32" {
const a = Complex(f32).new(5, 3);
const c = sinh(a);
- debug.assert(math.approxEq(f32, c.re, -73.460617, epsilon));
- debug.assert(math.approxEq(f32, c.im, 10.472508, epsilon));
+ testing.expect(math.approxEq(f32, c.re, -73.460617, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 10.472508, epsilon));
}
test "complex.csinh64" {
const a = Complex(f64).new(5, 3);
const c = sinh(a);
- debug.assert(math.approxEq(f64, c.re, -73.460617, epsilon));
- debug.assert(math.approxEq(f64, c.im, 10.472508, epsilon));
+ testing.expect(math.approxEq(f64, c.re, -73.460617, epsilon));
+ testing.expect(math.approxEq(f64, c.im, 10.472508, epsilon));
}
diff --git a/std/math/complex/sqrt.zig b/std/math/complex/sqrt.zig
index 47367816f7..60f6061baa 100644
--- a/std/math/complex/sqrt.zig
+++ b/std/math/complex/sqrt.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -125,14 +125,14 @@ test "complex.csqrt32" {
const a = Complex(f32).new(5, 3);
const c = sqrt(a);
- debug.assert(math.approxEq(f32, c.re, 2.327117, epsilon));
- debug.assert(math.approxEq(f32, c.im, 0.644574, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 2.327117, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 0.644574, epsilon));
}
test "complex.csqrt64" {
const a = Complex(f64).new(5, 3);
const c = sqrt(a);
- debug.assert(math.approxEq(f64, c.re, 2.3271175190399496, epsilon));
- debug.assert(math.approxEq(f64, c.im, 0.6445742373246469, epsilon));
+ testing.expect(math.approxEq(f64, c.re, 2.3271175190399496, epsilon));
+ testing.expect(math.approxEq(f64, c.im, 0.6445742373246469, epsilon));
}
diff --git a/std/math/complex/tan.zig b/std/math/complex/tan.zig
index 4ea5182fa7..db34580598 100644
--- a/std/math/complex/tan.zig
+++ b/std/math/complex/tan.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -17,6 +17,6 @@ test "complex.ctan" {
const a = Complex(f32).new(5, 3);
const c = tan(a);
- debug.assert(math.approxEq(f32, c.re, -0.002708233, epsilon));
- debug.assert(math.approxEq(f32, c.im, 1.004165, epsilon));
+ testing.expect(math.approxEq(f32, c.re, -0.002708233, epsilon));
+ testing.expect(math.approxEq(f32, c.im, 1.004165, epsilon));
}
diff --git a/std/math/complex/tanh.zig b/std/math/complex/tanh.zig
index e48d438783..03ab431312 100644
--- a/std/math/complex/tanh.zig
+++ b/std/math/complex/tanh.zig
@@ -1,5 +1,5 @@
const std = @import("../../index.zig");
-const debug = std.debug;
+const testing = std.testing;
const math = std.math;
const cmath = math.complex;
const Complex = cmath.Complex;
@@ -100,14 +100,14 @@ test "complex.ctanh32" {
const a = Complex(f32).new(5, 3);
const c = tanh(a);
- debug.assert(math.approxEq(f32, c.re, 0.999913, epsilon));
- debug.assert(math.approxEq(f32, c.im, -0.000025, epsilon));
+ testing.expect(math.approxEq(f32, c.re, 0.999913, epsilon));
+ testing.expect(math.approxEq(f32, c.im, -0.000025, epsilon));
}
test "complex.ctanh64" {
const a = Complex(f64).new(5, 3);
const c = tanh(a);
- debug.assert(math.approxEq(f64, c.re, 0.999913, epsilon));
- debug.assert(math.approxEq(f64, c.im, -0.000025, epsilon));
+ testing.expect(math.approxEq(f64, c.re, 0.999913, epsilon));
+ testing.expect(math.approxEq(f64, c.im, -0.000025, epsilon));
}
diff --git a/std/math/copysign.zig b/std/math/copysign.zig
index 4c6e333d6c..dbf8f6e1ef 100644
--- a/std/math/copysign.zig
+++ b/std/math/copysign.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn copysign(comptime T: type, x: T, y: T) T {
@@ -40,28 +40,28 @@ fn copysign64(x: f64, y: f64) f64 {
}
test "math.copysign" {
- assert(copysign(f16, 1.0, 1.0) == copysign16(1.0, 1.0));
- assert(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0));
- assert(copysign(f64, 1.0, 1.0) == copysign64(1.0, 1.0));
+ expect(copysign(f16, 1.0, 1.0) == copysign16(1.0, 1.0));
+ expect(copysign(f32, 1.0, 1.0) == copysign32(1.0, 1.0));
+ expect(copysign(f64, 1.0, 1.0) == copysign64(1.0, 1.0));
}
test "math.copysign16" {
- assert(copysign16(5.0, 1.0) == 5.0);
- assert(copysign16(5.0, -1.0) == -5.0);
- assert(copysign16(-5.0, -1.0) == -5.0);
- assert(copysign16(-5.0, 1.0) == 5.0);
+ expect(copysign16(5.0, 1.0) == 5.0);
+ expect(copysign16(5.0, -1.0) == -5.0);
+ expect(copysign16(-5.0, -1.0) == -5.0);
+ expect(copysign16(-5.0, 1.0) == 5.0);
}
test "math.copysign32" {
- assert(copysign32(5.0, 1.0) == 5.0);
- assert(copysign32(5.0, -1.0) == -5.0);
- assert(copysign32(-5.0, -1.0) == -5.0);
- assert(copysign32(-5.0, 1.0) == 5.0);
+ expect(copysign32(5.0, 1.0) == 5.0);
+ expect(copysign32(5.0, -1.0) == -5.0);
+ expect(copysign32(-5.0, -1.0) == -5.0);
+ expect(copysign32(-5.0, 1.0) == 5.0);
}
test "math.copysign64" {
- assert(copysign64(5.0, 1.0) == 5.0);
- assert(copysign64(5.0, -1.0) == -5.0);
- assert(copysign64(-5.0, -1.0) == -5.0);
- assert(copysign64(-5.0, 1.0) == 5.0);
+ expect(copysign64(5.0, 1.0) == 5.0);
+ expect(copysign64(5.0, -1.0) == -5.0);
+ expect(copysign64(-5.0, -1.0) == -5.0);
+ expect(copysign64(-5.0, 1.0) == 5.0);
}
diff --git a/std/math/cos.zig b/std/math/cos.zig
index b6a2fbffe6..7783ddc09b 100644
--- a/std/math/cos.zig
+++ b/std/math/cos.zig
@@ -6,7 +6,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn cos(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -139,40 +139,40 @@ fn cos64(x_: f64) f64 {
}
test "math.cos" {
- assert(cos(f32(0.0)) == cos32(0.0));
- assert(cos(f64(0.0)) == cos64(0.0));
+ expect(cos(f32(0.0)) == cos32(0.0));
+ expect(cos(f64(0.0)) == cos64(0.0));
}
test "math.cos32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, cos32(0.0), 1.0, epsilon));
- assert(math.approxEq(f32, cos32(0.2), 0.980067, epsilon));
- assert(math.approxEq(f32, cos32(0.8923), 0.627623, epsilon));
- assert(math.approxEq(f32, cos32(1.5), 0.070737, epsilon));
- assert(math.approxEq(f32, cos32(37.45), 0.969132, epsilon));
- assert(math.approxEq(f32, cos32(89.123), 0.400798, epsilon));
+ expect(math.approxEq(f32, cos32(0.0), 1.0, epsilon));
+ expect(math.approxEq(f32, cos32(0.2), 0.980067, epsilon));
+ expect(math.approxEq(f32, cos32(0.8923), 0.627623, epsilon));
+ expect(math.approxEq(f32, cos32(1.5), 0.070737, epsilon));
+ expect(math.approxEq(f32, cos32(37.45), 0.969132, epsilon));
+ expect(math.approxEq(f32, cos32(89.123), 0.400798, epsilon));
}
test "math.cos64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, cos64(0.0), 1.0, epsilon));
- assert(math.approxEq(f64, cos64(0.2), 0.980067, epsilon));
- assert(math.approxEq(f64, cos64(0.8923), 0.627623, epsilon));
- assert(math.approxEq(f64, cos64(1.5), 0.070737, epsilon));
- assert(math.approxEq(f64, cos64(37.45), 0.969132, epsilon));
- assert(math.approxEq(f64, cos64(89.123), 0.40080, epsilon));
+ expect(math.approxEq(f64, cos64(0.0), 1.0, epsilon));
+ expect(math.approxEq(f64, cos64(0.2), 0.980067, epsilon));
+ expect(math.approxEq(f64, cos64(0.8923), 0.627623, epsilon));
+ expect(math.approxEq(f64, cos64(1.5), 0.070737, epsilon));
+ expect(math.approxEq(f64, cos64(37.45), 0.969132, epsilon));
+ expect(math.approxEq(f64, cos64(89.123), 0.40080, epsilon));
}
test "math.cos32.special" {
- assert(math.isNan(cos32(math.inf(f32))));
- assert(math.isNan(cos32(-math.inf(f32))));
- assert(math.isNan(cos32(math.nan(f32))));
+ expect(math.isNan(cos32(math.inf(f32))));
+ expect(math.isNan(cos32(-math.inf(f32))));
+ expect(math.isNan(cos32(math.nan(f32))));
}
test "math.cos64.special" {
- assert(math.isNan(cos64(math.inf(f64))));
- assert(math.isNan(cos64(-math.inf(f64))));
- assert(math.isNan(cos64(math.nan(f64))));
+ expect(math.isNan(cos64(math.inf(f64))));
+ expect(math.isNan(cos64(-math.inf(f64))));
+ expect(math.isNan(cos64(math.nan(f64))));
}
diff --git a/std/math/cosh.zig b/std/math/cosh.zig
index 77e02855fd..57c5eef828 100644
--- a/std/math/cosh.zig
+++ b/std/math/cosh.zig
@@ -8,7 +8,7 @@ const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
const expo2 = @import("expo2.zig").expo2;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn cosh(x: var) @typeOf(x) {
@@ -82,40 +82,40 @@ fn cosh64(x: f64) f64 {
}
test "math.cosh" {
- assert(cosh(f32(1.5)) == cosh32(1.5));
- assert(cosh(f64(1.5)) == cosh64(1.5));
+ expect(cosh(f32(1.5)) == cosh32(1.5));
+ expect(cosh(f64(1.5)) == cosh64(1.5));
}
test "math.cosh32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, cosh32(0.0), 1.0, epsilon));
- assert(math.approxEq(f32, cosh32(0.2), 1.020067, epsilon));
- assert(math.approxEq(f32, cosh32(0.8923), 1.425225, epsilon));
- assert(math.approxEq(f32, cosh32(1.5), 2.352410, epsilon));
+ expect(math.approxEq(f32, cosh32(0.0), 1.0, epsilon));
+ expect(math.approxEq(f32, cosh32(0.2), 1.020067, epsilon));
+ expect(math.approxEq(f32, cosh32(0.8923), 1.425225, epsilon));
+ expect(math.approxEq(f32, cosh32(1.5), 2.352410, epsilon));
}
test "math.cosh64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, cosh64(0.0), 1.0, epsilon));
- assert(math.approxEq(f64, cosh64(0.2), 1.020067, epsilon));
- assert(math.approxEq(f64, cosh64(0.8923), 1.425225, epsilon));
- assert(math.approxEq(f64, cosh64(1.5), 2.352410, epsilon));
+ expect(math.approxEq(f64, cosh64(0.0), 1.0, epsilon));
+ expect(math.approxEq(f64, cosh64(0.2), 1.020067, epsilon));
+ expect(math.approxEq(f64, cosh64(0.8923), 1.425225, epsilon));
+ expect(math.approxEq(f64, cosh64(1.5), 2.352410, epsilon));
}
test "math.cosh32.special" {
- assert(cosh32(0.0) == 1.0);
- assert(cosh32(-0.0) == 1.0);
- assert(math.isPositiveInf(cosh32(math.inf(f32))));
- assert(math.isPositiveInf(cosh32(-math.inf(f32))));
- assert(math.isNan(cosh32(math.nan(f32))));
+ expect(cosh32(0.0) == 1.0);
+ expect(cosh32(-0.0) == 1.0);
+ expect(math.isPositiveInf(cosh32(math.inf(f32))));
+ expect(math.isPositiveInf(cosh32(-math.inf(f32))));
+ expect(math.isNan(cosh32(math.nan(f32))));
}
test "math.cosh64.special" {
- assert(cosh64(0.0) == 1.0);
- assert(cosh64(-0.0) == 1.0);
- assert(math.isPositiveInf(cosh64(math.inf(f64))));
- assert(math.isPositiveInf(cosh64(-math.inf(f64))));
- assert(math.isNan(cosh64(math.nan(f64))));
+ expect(cosh64(0.0) == 1.0);
+ expect(cosh64(-0.0) == 1.0);
+ expect(math.isPositiveInf(cosh64(math.inf(f64))));
+ expect(math.isPositiveInf(cosh64(-math.inf(f64))));
+ expect(math.isNan(cosh64(math.nan(f64))));
}
diff --git a/std/math/exp2.zig b/std/math/exp2.zig
index 3d8e5d692e..ba0001a09a 100644
--- a/std/math/exp2.zig
+++ b/std/math/exp2.zig
@@ -5,7 +5,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn exp2(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -415,35 +415,35 @@ fn exp2_64(x: f64) f64 {
}
test "math.exp2" {
- assert(exp2(f32(0.8923)) == exp2_32(0.8923));
- assert(exp2(f64(0.8923)) == exp2_64(0.8923));
+ expect(exp2(f32(0.8923)) == exp2_32(0.8923));
+ expect(exp2(f64(0.8923)) == exp2_64(0.8923));
}
test "math.exp2_32" {
const epsilon = 0.000001;
- assert(exp2_32(0.0) == 1.0);
- assert(math.approxEq(f32, exp2_32(0.2), 1.148698, epsilon));
- assert(math.approxEq(f32, exp2_32(0.8923), 1.856133, epsilon));
- assert(math.approxEq(f32, exp2_32(1.5), 2.828427, epsilon));
- assert(math.approxEq(f32, exp2_32(37.45), 187747237888, epsilon));
+ expect(exp2_32(0.0) == 1.0);
+ expect(math.approxEq(f32, exp2_32(0.2), 1.148698, epsilon));
+ expect(math.approxEq(f32, exp2_32(0.8923), 1.856133, epsilon));
+ expect(math.approxEq(f32, exp2_32(1.5), 2.828427, epsilon));
+ expect(math.approxEq(f32, exp2_32(37.45), 187747237888, epsilon));
}
test "math.exp2_64" {
const epsilon = 0.000001;
- assert(exp2_64(0.0) == 1.0);
- assert(math.approxEq(f64, exp2_64(0.2), 1.148698, epsilon));
- assert(math.approxEq(f64, exp2_64(0.8923), 1.856133, epsilon));
- assert(math.approxEq(f64, exp2_64(1.5), 2.828427, epsilon));
+ expect(exp2_64(0.0) == 1.0);
+ expect(math.approxEq(f64, exp2_64(0.2), 1.148698, epsilon));
+ expect(math.approxEq(f64, exp2_64(0.8923), 1.856133, epsilon));
+ expect(math.approxEq(f64, exp2_64(1.5), 2.828427, epsilon));
}
test "math.exp2_32.special" {
- assert(math.isPositiveInf(exp2_32(math.inf(f32))));
- assert(math.isNan(exp2_32(math.nan(f32))));
+ expect(math.isPositiveInf(exp2_32(math.inf(f32))));
+ expect(math.isNan(exp2_32(math.nan(f32))));
}
test "math.exp2_64.special" {
- assert(math.isPositiveInf(exp2_64(math.inf(f64))));
- assert(math.isNan(exp2_64(math.nan(f64))));
+ expect(math.isPositiveInf(exp2_64(math.inf(f64))));
+ expect(math.isNan(exp2_64(math.nan(f64))));
}
diff --git a/std/math/expm1.zig b/std/math/expm1.zig
index 6729417f60..ba00ec2561 100644
--- a/std/math/expm1.zig
+++ b/std/math/expm1.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn expm1(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -278,42 +278,42 @@ fn expm1_64(x_: f64) f64 {
}
test "math.exp1m" {
- assert(expm1(f32(0.0)) == expm1_32(0.0));
- assert(expm1(f64(0.0)) == expm1_64(0.0));
+ expect(expm1(f32(0.0)) == expm1_32(0.0));
+ expect(expm1(f64(0.0)) == expm1_64(0.0));
}
test "math.expm1_32" {
const epsilon = 0.000001;
- assert(expm1_32(0.0) == 0.0);
- assert(math.approxEq(f32, expm1_32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, expm1_32(0.2), 0.221403, epsilon));
- assert(math.approxEq(f32, expm1_32(0.8923), 1.440737, epsilon));
- assert(math.approxEq(f32, expm1_32(1.5), 3.481689, epsilon));
+ expect(expm1_32(0.0) == 0.0);
+ expect(math.approxEq(f32, expm1_32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, expm1_32(0.2), 0.221403, epsilon));
+ expect(math.approxEq(f32, expm1_32(0.8923), 1.440737, epsilon));
+ expect(math.approxEq(f32, expm1_32(1.5), 3.481689, epsilon));
}
test "math.expm1_64" {
const epsilon = 0.000001;
- assert(expm1_64(0.0) == 0.0);
- assert(math.approxEq(f64, expm1_64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, expm1_64(0.2), 0.221403, epsilon));
- assert(math.approxEq(f64, expm1_64(0.8923), 1.440737, epsilon));
- assert(math.approxEq(f64, expm1_64(1.5), 3.481689, epsilon));
+ expect(expm1_64(0.0) == 0.0);
+ expect(math.approxEq(f64, expm1_64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, expm1_64(0.2), 0.221403, epsilon));
+ expect(math.approxEq(f64, expm1_64(0.8923), 1.440737, epsilon));
+ expect(math.approxEq(f64, expm1_64(1.5), 3.481689, epsilon));
}
test "math.expm1_32.special" {
const epsilon = 0.000001;
- assert(math.isPositiveInf(expm1_32(math.inf(f32))));
- assert(expm1_32(-math.inf(f32)) == -1.0);
- assert(math.isNan(expm1_32(math.nan(f32))));
+ expect(math.isPositiveInf(expm1_32(math.inf(f32))));
+ expect(expm1_32(-math.inf(f32)) == -1.0);
+ expect(math.isNan(expm1_32(math.nan(f32))));
}
test "math.expm1_64.special" {
const epsilon = 0.000001;
- assert(math.isPositiveInf(expm1_64(math.inf(f64))));
- assert(expm1_64(-math.inf(f64)) == -1.0);
- assert(math.isNan(expm1_64(math.nan(f64))));
+ expect(math.isPositiveInf(expm1_64(math.inf(f64))));
+ expect(expm1_64(-math.inf(f64)) == -1.0);
+ expect(math.isNan(expm1_64(math.nan(f64))));
}
diff --git a/std/math/fabs.zig b/std/math/fabs.zig
index 443010ac7f..9fad5644c3 100644
--- a/std/math/fabs.zig
+++ b/std/math/fabs.zig
@@ -5,7 +5,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn fabs(x: var) @typeOf(x) {
@@ -37,40 +37,40 @@ fn fabs64(x: f64) f64 {
}
test "math.fabs" {
- assert(fabs(f16(1.0)) == fabs16(1.0));
- assert(fabs(f32(1.0)) == fabs32(1.0));
- assert(fabs(f64(1.0)) == fabs64(1.0));
+ expect(fabs(f16(1.0)) == fabs16(1.0));
+ expect(fabs(f32(1.0)) == fabs32(1.0));
+ expect(fabs(f64(1.0)) == fabs64(1.0));
}
test "math.fabs16" {
- assert(fabs16(1.0) == 1.0);
- assert(fabs16(-1.0) == 1.0);
+ expect(fabs16(1.0) == 1.0);
+ expect(fabs16(-1.0) == 1.0);
}
test "math.fabs32" {
- assert(fabs32(1.0) == 1.0);
- assert(fabs32(-1.0) == 1.0);
+ expect(fabs32(1.0) == 1.0);
+ expect(fabs32(-1.0) == 1.0);
}
test "math.fabs64" {
- assert(fabs64(1.0) == 1.0);
- assert(fabs64(-1.0) == 1.0);
+ expect(fabs64(1.0) == 1.0);
+ expect(fabs64(-1.0) == 1.0);
}
test "math.fabs16.special" {
- assert(math.isPositiveInf(fabs(math.inf(f16))));
- assert(math.isPositiveInf(fabs(-math.inf(f16))));
- assert(math.isNan(fabs(math.nan(f16))));
+ expect(math.isPositiveInf(fabs(math.inf(f16))));
+ expect(math.isPositiveInf(fabs(-math.inf(f16))));
+ expect(math.isNan(fabs(math.nan(f16))));
}
test "math.fabs32.special" {
- assert(math.isPositiveInf(fabs(math.inf(f32))));
- assert(math.isPositiveInf(fabs(-math.inf(f32))));
- assert(math.isNan(fabs(math.nan(f32))));
+ expect(math.isPositiveInf(fabs(math.inf(f32))));
+ expect(math.isPositiveInf(fabs(-math.inf(f32))));
+ expect(math.isNan(fabs(math.nan(f32))));
}
test "math.fabs64.special" {
- assert(math.isPositiveInf(fabs(math.inf(f64))));
- assert(math.isPositiveInf(fabs(-math.inf(f64))));
- assert(math.isNan(fabs(math.nan(f64))));
+ expect(math.isPositiveInf(fabs(math.inf(f64))));
+ expect(math.isPositiveInf(fabs(-math.inf(f64))));
+ expect(math.isNan(fabs(math.nan(f64))));
}
diff --git a/std/math/floor.zig b/std/math/floor.zig
index 6ce462b10f..c7c12e37ba 100644
--- a/std/math/floor.zig
+++ b/std/math/floor.zig
@@ -5,7 +5,7 @@
// - floor(nan) = nan
const builtin = @import("builtin");
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const std = @import("../index.zig");
const math = std.math;
@@ -117,49 +117,49 @@ fn floor64(x: f64) f64 {
}
test "math.floor" {
- assert(floor(f16(1.3)) == floor16(1.3));
- assert(floor(f32(1.3)) == floor32(1.3));
- assert(floor(f64(1.3)) == floor64(1.3));
+ expect(floor(f16(1.3)) == floor16(1.3));
+ expect(floor(f32(1.3)) == floor32(1.3));
+ expect(floor(f64(1.3)) == floor64(1.3));
}
test "math.floor16" {
- assert(floor16(1.3) == 1.0);
- assert(floor16(-1.3) == -2.0);
- assert(floor16(0.2) == 0.0);
+ expect(floor16(1.3) == 1.0);
+ expect(floor16(-1.3) == -2.0);
+ expect(floor16(0.2) == 0.0);
}
test "math.floor32" {
- assert(floor32(1.3) == 1.0);
- assert(floor32(-1.3) == -2.0);
- assert(floor32(0.2) == 0.0);
+ expect(floor32(1.3) == 1.0);
+ expect(floor32(-1.3) == -2.0);
+ expect(floor32(0.2) == 0.0);
}
test "math.floor64" {
- assert(floor64(1.3) == 1.0);
- assert(floor64(-1.3) == -2.0);
- assert(floor64(0.2) == 0.0);
+ expect(floor64(1.3) == 1.0);
+ expect(floor64(-1.3) == -2.0);
+ expect(floor64(0.2) == 0.0);
}
test "math.floor16.special" {
- assert(floor16(0.0) == 0.0);
- assert(floor16(-0.0) == -0.0);
- assert(math.isPositiveInf(floor16(math.inf(f16))));
- assert(math.isNegativeInf(floor16(-math.inf(f16))));
- assert(math.isNan(floor16(math.nan(f16))));
+ expect(floor16(0.0) == 0.0);
+ expect(floor16(-0.0) == -0.0);
+ expect(math.isPositiveInf(floor16(math.inf(f16))));
+ expect(math.isNegativeInf(floor16(-math.inf(f16))));
+ expect(math.isNan(floor16(math.nan(f16))));
}
test "math.floor32.special" {
- assert(floor32(0.0) == 0.0);
- assert(floor32(-0.0) == -0.0);
- assert(math.isPositiveInf(floor32(math.inf(f32))));
- assert(math.isNegativeInf(floor32(-math.inf(f32))));
- assert(math.isNan(floor32(math.nan(f32))));
+ expect(floor32(0.0) == 0.0);
+ expect(floor32(-0.0) == -0.0);
+ expect(math.isPositiveInf(floor32(math.inf(f32))));
+ expect(math.isNegativeInf(floor32(-math.inf(f32))));
+ expect(math.isNan(floor32(math.nan(f32))));
}
test "math.floor64.special" {
- assert(floor64(0.0) == 0.0);
- assert(floor64(-0.0) == -0.0);
- assert(math.isPositiveInf(floor64(math.inf(f64))));
- assert(math.isNegativeInf(floor64(-math.inf(f64))));
- assert(math.isNan(floor64(math.nan(f64))));
+ expect(floor64(0.0) == 0.0);
+ expect(floor64(-0.0) == -0.0);
+ expect(math.isPositiveInf(floor64(math.inf(f64))));
+ expect(math.isNegativeInf(floor64(-math.inf(f64))));
+ expect(math.isNan(floor64(math.nan(f64))));
}
diff --git a/std/math/fma.zig b/std/math/fma.zig
index 21faf4118d..b084cf3cbd 100644
--- a/std/math/fma.zig
+++ b/std/math/fma.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn fma(comptime T: type, x: T, y: T, z: T) T {
return switch (T) {
@@ -135,30 +135,30 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
}
test "math.fma" {
- assert(fma(f32, 0.0, 1.0, 1.0) == fma32(0.0, 1.0, 1.0));
- assert(fma(f64, 0.0, 1.0, 1.0) == fma64(0.0, 1.0, 1.0));
+ expect(fma(f32, 0.0, 1.0, 1.0) == fma32(0.0, 1.0, 1.0));
+ expect(fma(f64, 0.0, 1.0, 1.0) == fma64(0.0, 1.0, 1.0));
}
test "math.fma32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, fma32(0.0, 5.0, 9.124), 9.124, epsilon));
- assert(math.approxEq(f32, fma32(0.2, 5.0, 9.124), 10.124, epsilon));
- assert(math.approxEq(f32, fma32(0.8923, 5.0, 9.124), 13.5855, epsilon));
- assert(math.approxEq(f32, fma32(1.5, 5.0, 9.124), 16.624, epsilon));
- assert(math.approxEq(f32, fma32(37.45, 5.0, 9.124), 196.374004, epsilon));
- assert(math.approxEq(f32, fma32(89.123, 5.0, 9.124), 454.739005, epsilon));
- assert(math.approxEq(f32, fma32(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
+ expect(math.approxEq(f32, fma32(0.0, 5.0, 9.124), 9.124, epsilon));
+ expect(math.approxEq(f32, fma32(0.2, 5.0, 9.124), 10.124, epsilon));
+ expect(math.approxEq(f32, fma32(0.8923, 5.0, 9.124), 13.5855, epsilon));
+ expect(math.approxEq(f32, fma32(1.5, 5.0, 9.124), 16.624, epsilon));
+ expect(math.approxEq(f32, fma32(37.45, 5.0, 9.124), 196.374004, epsilon));
+ expect(math.approxEq(f32, fma32(89.123, 5.0, 9.124), 454.739005, epsilon));
+ expect(math.approxEq(f32, fma32(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
}
test "math.fma64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, fma64(0.0, 5.0, 9.124), 9.124, epsilon));
- assert(math.approxEq(f64, fma64(0.2, 5.0, 9.124), 10.124, epsilon));
- assert(math.approxEq(f64, fma64(0.8923, 5.0, 9.124), 13.5855, epsilon));
- assert(math.approxEq(f64, fma64(1.5, 5.0, 9.124), 16.624, epsilon));
- assert(math.approxEq(f64, fma64(37.45, 5.0, 9.124), 196.374, epsilon));
- assert(math.approxEq(f64, fma64(89.123, 5.0, 9.124), 454.739, epsilon));
- assert(math.approxEq(f64, fma64(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
+ expect(math.approxEq(f64, fma64(0.0, 5.0, 9.124), 9.124, epsilon));
+ expect(math.approxEq(f64, fma64(0.2, 5.0, 9.124), 10.124, epsilon));
+ expect(math.approxEq(f64, fma64(0.8923, 5.0, 9.124), 13.5855, epsilon));
+ expect(math.approxEq(f64, fma64(1.5, 5.0, 9.124), 16.624, epsilon));
+ expect(math.approxEq(f64, fma64(37.45, 5.0, 9.124), 196.374, epsilon));
+ expect(math.approxEq(f64, fma64(89.123, 5.0, 9.124), 454.739, epsilon));
+ expect(math.approxEq(f64, fma64(123123.234375, 5.0, 9.124), 615625.295875, epsilon));
}
diff --git a/std/math/frexp.zig b/std/math/frexp.zig
index dfc790fdd9..35f3e081a9 100644
--- a/std/math/frexp.zig
+++ b/std/math/frexp.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
fn frexp_result(comptime T: type) type {
return struct {
@@ -103,11 +103,11 @@ fn frexp64(x: f64) frexp64_result {
test "math.frexp" {
const a = frexp(f32(1.3));
const b = frexp32(1.3);
- assert(a.significand == b.significand and a.exponent == b.exponent);
+ expect(a.significand == b.significand and a.exponent == b.exponent);
const c = frexp(f64(1.3));
const d = frexp64(1.3);
- assert(c.significand == d.significand and c.exponent == d.exponent);
+ expect(c.significand == d.significand and c.exponent == d.exponent);
}
test "math.frexp32" {
@@ -115,10 +115,10 @@ test "math.frexp32" {
var r: frexp32_result = undefined;
r = frexp32(1.3);
- assert(math.approxEq(f32, r.significand, 0.65, epsilon) and r.exponent == 1);
+ expect(math.approxEq(f32, r.significand, 0.65, epsilon) and r.exponent == 1);
r = frexp32(78.0234);
- assert(math.approxEq(f32, r.significand, 0.609558, epsilon) and r.exponent == 7);
+ expect(math.approxEq(f32, r.significand, 0.609558, epsilon) and r.exponent == 7);
}
test "math.frexp64" {
@@ -126,46 +126,46 @@ test "math.frexp64" {
var r: frexp64_result = undefined;
r = frexp64(1.3);
- assert(math.approxEq(f64, r.significand, 0.65, epsilon) and r.exponent == 1);
+ expect(math.approxEq(f64, r.significand, 0.65, epsilon) and r.exponent == 1);
r = frexp64(78.0234);
- assert(math.approxEq(f64, r.significand, 0.609558, epsilon) and r.exponent == 7);
+ expect(math.approxEq(f64, r.significand, 0.609558, epsilon) and r.exponent == 7);
}
test "math.frexp32.special" {
var r: frexp32_result = undefined;
r = frexp32(0.0);
- assert(r.significand == 0.0 and r.exponent == 0);
+ expect(r.significand == 0.0 and r.exponent == 0);
r = frexp32(-0.0);
- assert(r.significand == -0.0 and r.exponent == 0);
+ expect(r.significand == -0.0 and r.exponent == 0);
r = frexp32(math.inf(f32));
- assert(math.isPositiveInf(r.significand) and r.exponent == 0);
+ expect(math.isPositiveInf(r.significand) and r.exponent == 0);
r = frexp32(-math.inf(f32));
- assert(math.isNegativeInf(r.significand) and r.exponent == 0);
+ expect(math.isNegativeInf(r.significand) and r.exponent == 0);
r = frexp32(math.nan(f32));
- assert(math.isNan(r.significand));
+ expect(math.isNan(r.significand));
}
test "math.frexp64.special" {
var r: frexp64_result = undefined;
r = frexp64(0.0);
- assert(r.significand == 0.0 and r.exponent == 0);
+ expect(r.significand == 0.0 and r.exponent == 0);
r = frexp64(-0.0);
- assert(r.significand == -0.0 and r.exponent == 0);
+ expect(r.significand == -0.0 and r.exponent == 0);
r = frexp64(math.inf(f64));
- assert(math.isPositiveInf(r.significand) and r.exponent == 0);
+ expect(math.isPositiveInf(r.significand) and r.exponent == 0);
r = frexp64(-math.inf(f64));
- assert(math.isNegativeInf(r.significand) and r.exponent == 0);
+ expect(math.isNegativeInf(r.significand) and r.exponent == 0);
r = frexp64(math.nan(f64));
- assert(math.isNan(r.significand));
+ expect(math.isNan(r.significand));
}
diff --git a/std/math/hypot.zig b/std/math/hypot.zig
index a63657a621..dea11e0a61 100644
--- a/std/math/hypot.zig
+++ b/std/math/hypot.zig
@@ -7,7 +7,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn hypot(comptime T: type, x: T, y: T) T {
@@ -115,48 +115,48 @@ fn hypot64(x: f64, y: f64) f64 {
}
test "math.hypot" {
- assert(hypot(f32, 0.0, -1.2) == hypot32(0.0, -1.2));
- assert(hypot(f64, 0.0, -1.2) == hypot64(0.0, -1.2));
+ expect(hypot(f32, 0.0, -1.2) == hypot32(0.0, -1.2));
+ expect(hypot(f64, 0.0, -1.2) == hypot64(0.0, -1.2));
}
test "math.hypot32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, hypot32(0.0, -1.2), 1.2, epsilon));
- assert(math.approxEq(f32, hypot32(0.2, -0.34), 0.394462, epsilon));
- assert(math.approxEq(f32, hypot32(0.8923, 2.636890), 2.783772, epsilon));
- assert(math.approxEq(f32, hypot32(1.5, 5.25), 5.460083, epsilon));
- assert(math.approxEq(f32, hypot32(37.45, 159.835), 164.163742, epsilon));
- assert(math.approxEq(f32, hypot32(89.123, 382.028905), 392.286865, epsilon));
- assert(math.approxEq(f32, hypot32(123123.234375, 529428.707813), 543556.875, epsilon));
+ expect(math.approxEq(f32, hypot32(0.0, -1.2), 1.2, epsilon));
+ expect(math.approxEq(f32, hypot32(0.2, -0.34), 0.394462, epsilon));
+ expect(math.approxEq(f32, hypot32(0.8923, 2.636890), 2.783772, epsilon));
+ expect(math.approxEq(f32, hypot32(1.5, 5.25), 5.460083, epsilon));
+ expect(math.approxEq(f32, hypot32(37.45, 159.835), 164.163742, epsilon));
+ expect(math.approxEq(f32, hypot32(89.123, 382.028905), 392.286865, epsilon));
+ expect(math.approxEq(f32, hypot32(123123.234375, 529428.707813), 543556.875, epsilon));
}
test "math.hypot64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, hypot64(0.0, -1.2), 1.2, epsilon));
- assert(math.approxEq(f64, hypot64(0.2, -0.34), 0.394462, epsilon));
- assert(math.approxEq(f64, hypot64(0.8923, 2.636890), 2.783772, epsilon));
- assert(math.approxEq(f64, hypot64(1.5, 5.25), 5.460082, epsilon));
- assert(math.approxEq(f64, hypot64(37.45, 159.835), 164.163728, epsilon));
- assert(math.approxEq(f64, hypot64(89.123, 382.028905), 392.286876, epsilon));
- assert(math.approxEq(f64, hypot64(123123.234375, 529428.707813), 543556.885247, epsilon));
+ expect(math.approxEq(f64, hypot64(0.0, -1.2), 1.2, epsilon));
+ expect(math.approxEq(f64, hypot64(0.2, -0.34), 0.394462, epsilon));
+ expect(math.approxEq(f64, hypot64(0.8923, 2.636890), 2.783772, epsilon));
+ expect(math.approxEq(f64, hypot64(1.5, 5.25), 5.460082, epsilon));
+ expect(math.approxEq(f64, hypot64(37.45, 159.835), 164.163728, epsilon));
+ expect(math.approxEq(f64, hypot64(89.123, 382.028905), 392.286876, epsilon));
+ expect(math.approxEq(f64, hypot64(123123.234375, 529428.707813), 543556.885247, epsilon));
}
test "math.hypot32.special" {
- assert(math.isPositiveInf(hypot32(math.inf(f32), 0.0)));
- assert(math.isPositiveInf(hypot32(-math.inf(f32), 0.0)));
- assert(math.isPositiveInf(hypot32(0.0, math.inf(f32))));
- assert(math.isPositiveInf(hypot32(0.0, -math.inf(f32))));
- assert(math.isNan(hypot32(math.nan(f32), 0.0)));
- assert(math.isNan(hypot32(0.0, math.nan(f32))));
+ expect(math.isPositiveInf(hypot32(math.inf(f32), 0.0)));
+ expect(math.isPositiveInf(hypot32(-math.inf(f32), 0.0)));
+ expect(math.isPositiveInf(hypot32(0.0, math.inf(f32))));
+ expect(math.isPositiveInf(hypot32(0.0, -math.inf(f32))));
+ expect(math.isNan(hypot32(math.nan(f32), 0.0)));
+ expect(math.isNan(hypot32(0.0, math.nan(f32))));
}
test "math.hypot64.special" {
- assert(math.isPositiveInf(hypot64(math.inf(f64), 0.0)));
- assert(math.isPositiveInf(hypot64(-math.inf(f64), 0.0)));
- assert(math.isPositiveInf(hypot64(0.0, math.inf(f64))));
- assert(math.isPositiveInf(hypot64(0.0, -math.inf(f64))));
- assert(math.isNan(hypot64(math.nan(f64), 0.0)));
- assert(math.isNan(hypot64(0.0, math.nan(f64))));
+ expect(math.isPositiveInf(hypot64(math.inf(f64), 0.0)));
+ expect(math.isPositiveInf(hypot64(-math.inf(f64), 0.0)));
+ expect(math.isPositiveInf(hypot64(0.0, math.inf(f64))));
+ expect(math.isPositiveInf(hypot64(0.0, -math.inf(f64))));
+ expect(math.isNan(hypot64(math.nan(f64), 0.0)));
+ expect(math.isNan(hypot64(0.0, math.nan(f64))));
}
diff --git a/std/math/ilogb.zig b/std/math/ilogb.zig
index e6bdb14012..e7b6485357 100644
--- a/std/math/ilogb.zig
+++ b/std/math/ilogb.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
const minInt = std.math.minInt;
@@ -95,38 +95,38 @@ fn ilogb64(x: f64) i32 {
}
test "math.ilogb" {
- assert(ilogb(f32(0.2)) == ilogb32(0.2));
- assert(ilogb(f64(0.2)) == ilogb64(0.2));
+ expect(ilogb(f32(0.2)) == ilogb32(0.2));
+ expect(ilogb(f64(0.2)) == ilogb64(0.2));
}
test "math.ilogb32" {
- assert(ilogb32(0.0) == fp_ilogb0);
- assert(ilogb32(0.5) == -1);
- assert(ilogb32(0.8923) == -1);
- assert(ilogb32(10.0) == 3);
- assert(ilogb32(-123984) == 16);
- assert(ilogb32(2398.23) == 11);
+ expect(ilogb32(0.0) == fp_ilogb0);
+ expect(ilogb32(0.5) == -1);
+ expect(ilogb32(0.8923) == -1);
+ expect(ilogb32(10.0) == 3);
+ expect(ilogb32(-123984) == 16);
+ expect(ilogb32(2398.23) == 11);
}
test "math.ilogb64" {
- assert(ilogb64(0.0) == fp_ilogb0);
- assert(ilogb64(0.5) == -1);
- assert(ilogb64(0.8923) == -1);
- assert(ilogb64(10.0) == 3);
- assert(ilogb64(-123984) == 16);
- assert(ilogb64(2398.23) == 11);
+ expect(ilogb64(0.0) == fp_ilogb0);
+ expect(ilogb64(0.5) == -1);
+ expect(ilogb64(0.8923) == -1);
+ expect(ilogb64(10.0) == 3);
+ expect(ilogb64(-123984) == 16);
+ expect(ilogb64(2398.23) == 11);
}
test "math.ilogb32.special" {
- assert(ilogb32(math.inf(f32)) == maxInt(i32));
- assert(ilogb32(-math.inf(f32)) == maxInt(i32));
- assert(ilogb32(0.0) == minInt(i32));
- assert(ilogb32(math.nan(f32)) == maxInt(i32));
+ expect(ilogb32(math.inf(f32)) == maxInt(i32));
+ expect(ilogb32(-math.inf(f32)) == maxInt(i32));
+ expect(ilogb32(0.0) == minInt(i32));
+ expect(ilogb32(math.nan(f32)) == maxInt(i32));
}
test "math.ilogb64.special" {
- assert(ilogb64(math.inf(f64)) == maxInt(i32));
- assert(ilogb64(-math.inf(f64)) == maxInt(i32));
- assert(ilogb64(0.0) == minInt(i32));
- assert(ilogb64(math.nan(f64)) == maxInt(i32));
+ expect(ilogb64(math.inf(f64)) == maxInt(i32));
+ expect(ilogb64(-math.inf(f64)) == maxInt(i32));
+ expect(ilogb64(0.0) == minInt(i32));
+ expect(ilogb64(math.nan(f64)) == maxInt(i32));
}
diff --git a/std/math/index.zig b/std/math/index.zig
index f37de2505b..ccfac03038 100644
--- a/std/math/index.zig
+++ b/std/math/index.zig
@@ -2,6 +2,7 @@ const builtin = @import("builtin");
const std = @import("../index.zig");
const TypeId = builtin.TypeId;
const assert = std.debug.assert;
+const testing = std.testing;
pub const e = 2.71828182845904523536028747135266249775724709369995;
pub const pi = 3.14159265358979323846264338327950288419716939937510;
@@ -240,7 +241,7 @@ pub fn min(x: var, y: var) @typeOf(x + y) {
}
test "math.min" {
- assert(min(i32(-1), i32(2)) == -1);
+ testing.expect(min(i32(-1), i32(2)) == -1);
}
pub fn max(x: var, y: var) @typeOf(x + y) {
@@ -248,7 +249,7 @@ pub fn max(x: var, y: var) @typeOf(x + y) {
}
test "math.max" {
- assert(max(i32(-1), i32(2)) == 2);
+ testing.expect(max(i32(-1), i32(2)) == 2);
}
pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {
@@ -293,10 +294,10 @@ pub fn shl(comptime T: type, a: T, shift_amt: var) T {
}
test "math.shl" {
- assert(shl(u8, 0b11111111, usize(3)) == 0b11111000);
- assert(shl(u8, 0b11111111, usize(8)) == 0);
- assert(shl(u8, 0b11111111, usize(9)) == 0);
- assert(shl(u8, 0b11111111, isize(-2)) == 0b00111111);
+ testing.expect(shl(u8, 0b11111111, usize(3)) == 0b11111000);
+ testing.expect(shl(u8, 0b11111111, usize(8)) == 0);
+ testing.expect(shl(u8, 0b11111111, usize(9)) == 0);
+ testing.expect(shl(u8, 0b11111111, isize(-2)) == 0b00111111);
}
/// Shifts right. Overflowed bits are truncated.
@@ -317,10 +318,10 @@ pub fn shr(comptime T: type, a: T, shift_amt: var) T {
}
test "math.shr" {
- assert(shr(u8, 0b11111111, usize(3)) == 0b00011111);
- assert(shr(u8, 0b11111111, usize(8)) == 0);
- assert(shr(u8, 0b11111111, usize(9)) == 0);
- assert(shr(u8, 0b11111111, isize(-2)) == 0b11111100);
+ testing.expect(shr(u8, 0b11111111, usize(3)) == 0b00011111);
+ testing.expect(shr(u8, 0b11111111, usize(8)) == 0);
+ testing.expect(shr(u8, 0b11111111, usize(9)) == 0);
+ testing.expect(shr(u8, 0b11111111, isize(-2)) == 0b11111100);
}
/// Rotates right. Only unsigned values can be rotated.
@@ -335,11 +336,11 @@ pub fn rotr(comptime T: type, x: T, r: var) T {
}
test "math.rotr" {
- assert(rotr(u8, 0b00000001, usize(0)) == 0b00000001);
- assert(rotr(u8, 0b00000001, usize(9)) == 0b10000000);
- assert(rotr(u8, 0b00000001, usize(8)) == 0b00000001);
- assert(rotr(u8, 0b00000001, usize(4)) == 0b00010000);
- assert(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);
+ testing.expect(rotr(u8, 0b00000001, usize(0)) == 0b00000001);
+ testing.expect(rotr(u8, 0b00000001, usize(9)) == 0b10000000);
+ testing.expect(rotr(u8, 0b00000001, usize(8)) == 0b00000001);
+ testing.expect(rotr(u8, 0b00000001, usize(4)) == 0b00010000);
+ testing.expect(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);
}
/// Rotates left. Only unsigned values can be rotated.
@@ -354,11 +355,11 @@ pub fn rotl(comptime T: type, x: T, r: var) T {
}
test "math.rotl" {
- assert(rotl(u8, 0b00000001, usize(0)) == 0b00000001);
- assert(rotl(u8, 0b00000001, usize(9)) == 0b00000010);
- assert(rotl(u8, 0b00000001, usize(8)) == 0b00000001);
- assert(rotl(u8, 0b00000001, usize(4)) == 0b00010000);
- assert(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);
+ testing.expect(rotl(u8, 0b00000001, usize(0)) == 0b00000001);
+ testing.expect(rotl(u8, 0b00000001, usize(9)) == 0b00000010);
+ testing.expect(rotl(u8, 0b00000001, usize(8)) == 0b00000001);
+ testing.expect(rotl(u8, 0b00000001, usize(4)) == 0b00010000);
+ testing.expect(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);
}
pub fn Log2Int(comptime T: type) type {
@@ -389,50 +390,50 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
}
test "math.IntFittingRange" {
- assert(IntFittingRange(0, 0) == u0);
- assert(IntFittingRange(0, 1) == u1);
- assert(IntFittingRange(0, 2) == u2);
- assert(IntFittingRange(0, 3) == u2);
- assert(IntFittingRange(0, 4) == u3);
- assert(IntFittingRange(0, 7) == u3);
- assert(IntFittingRange(0, 8) == u4);
- assert(IntFittingRange(0, 9) == u4);
- assert(IntFittingRange(0, 15) == u4);
- assert(IntFittingRange(0, 16) == u5);
- assert(IntFittingRange(0, 17) == u5);
- assert(IntFittingRange(0, 4095) == u12);
- assert(IntFittingRange(2000, 4095) == u12);
- assert(IntFittingRange(0, 4096) == u13);
- assert(IntFittingRange(2000, 4096) == u13);
- assert(IntFittingRange(0, 4097) == u13);
- assert(IntFittingRange(2000, 4097) == u13);
- assert(IntFittingRange(0, 123456789123456798123456789) == u87);
- assert(IntFittingRange(0, 123456789123456798123456789123456789123456798123456789) == u177);
+ testing.expect(IntFittingRange(0, 0) == u0);
+ testing.expect(IntFittingRange(0, 1) == u1);
+ testing.expect(IntFittingRange(0, 2) == u2);
+ testing.expect(IntFittingRange(0, 3) == u2);
+ testing.expect(IntFittingRange(0, 4) == u3);
+ testing.expect(IntFittingRange(0, 7) == u3);
+ testing.expect(IntFittingRange(0, 8) == u4);
+ testing.expect(IntFittingRange(0, 9) == u4);
+ testing.expect(IntFittingRange(0, 15) == u4);
+ testing.expect(IntFittingRange(0, 16) == u5);
+ testing.expect(IntFittingRange(0, 17) == u5);
+ testing.expect(IntFittingRange(0, 4095) == u12);
+ testing.expect(IntFittingRange(2000, 4095) == u12);
+ testing.expect(IntFittingRange(0, 4096) == u13);
+ testing.expect(IntFittingRange(2000, 4096) == u13);
+ testing.expect(IntFittingRange(0, 4097) == u13);
+ testing.expect(IntFittingRange(2000, 4097) == u13);
+ testing.expect(IntFittingRange(0, 123456789123456798123456789) == u87);
+ testing.expect(IntFittingRange(0, 123456789123456798123456789123456789123456798123456789) == u177);
- assert(IntFittingRange(-1, -1) == i1);
- assert(IntFittingRange(-1, 0) == i1);
- assert(IntFittingRange(-1, 1) == i2);
- assert(IntFittingRange(-2, -2) == i2);
- assert(IntFittingRange(-2, -1) == i2);
- assert(IntFittingRange(-2, 0) == i2);
- assert(IntFittingRange(-2, 1) == i2);
- assert(IntFittingRange(-2, 2) == i3);
- assert(IntFittingRange(-1, 2) == i3);
- assert(IntFittingRange(-1, 3) == i3);
- assert(IntFittingRange(-1, 4) == i4);
- assert(IntFittingRange(-1, 7) == i4);
- assert(IntFittingRange(-1, 8) == i5);
- assert(IntFittingRange(-1, 9) == i5);
- assert(IntFittingRange(-1, 15) == i5);
- assert(IntFittingRange(-1, 16) == i6);
- assert(IntFittingRange(-1, 17) == i6);
- assert(IntFittingRange(-1, 4095) == i13);
- assert(IntFittingRange(-4096, 4095) == i13);
- assert(IntFittingRange(-1, 4096) == i14);
- assert(IntFittingRange(-4097, 4095) == i14);
- assert(IntFittingRange(-1, 4097) == i14);
- assert(IntFittingRange(-1, 123456789123456798123456789) == i88);
- assert(IntFittingRange(-1, 123456789123456798123456789123456789123456798123456789) == i178);
+ testing.expect(IntFittingRange(-1, -1) == i1);
+ testing.expect(IntFittingRange(-1, 0) == i1);
+ testing.expect(IntFittingRange(-1, 1) == i2);
+ testing.expect(IntFittingRange(-2, -2) == i2);
+ testing.expect(IntFittingRange(-2, -1) == i2);
+ testing.expect(IntFittingRange(-2, 0) == i2);
+ testing.expect(IntFittingRange(-2, 1) == i2);
+ testing.expect(IntFittingRange(-2, 2) == i3);
+ testing.expect(IntFittingRange(-1, 2) == i3);
+ testing.expect(IntFittingRange(-1, 3) == i3);
+ testing.expect(IntFittingRange(-1, 4) == i4);
+ testing.expect(IntFittingRange(-1, 7) == i4);
+ testing.expect(IntFittingRange(-1, 8) == i5);
+ testing.expect(IntFittingRange(-1, 9) == i5);
+ testing.expect(IntFittingRange(-1, 15) == i5);
+ testing.expect(IntFittingRange(-1, 16) == i6);
+ testing.expect(IntFittingRange(-1, 17) == i6);
+ testing.expect(IntFittingRange(-1, 4095) == i13);
+ testing.expect(IntFittingRange(-4096, 4095) == i13);
+ testing.expect(IntFittingRange(-1, 4096) == i14);
+ testing.expect(IntFittingRange(-4097, 4095) == i14);
+ testing.expect(IntFittingRange(-1, 4097) == i14);
+ testing.expect(IntFittingRange(-1, 123456789123456798123456789) == i88);
+ testing.expect(IntFittingRange(-1, 123456789123456798123456789123456789123456798123456789) == i178);
}
test "math overflow functions" {
@@ -441,10 +442,10 @@ test "math overflow functions" {
}
fn testOverflow() void {
- assert((mul(i32, 3, 4) catch unreachable) == 12);
- assert((add(i32, 3, 4) catch unreachable) == 7);
- assert((sub(i32, 3, 4) catch unreachable) == -1);
- assert((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);
+ testing.expect((mul(i32, 3, 4) catch unreachable) == 12);
+ testing.expect((add(i32, 3, 4) catch unreachable) == 7);
+ testing.expect((sub(i32, 3, 4) catch unreachable) == -1);
+ testing.expect((shlExact(i32, 0b11, 4) catch unreachable) == 0b110000);
}
pub fn absInt(x: var) !@typeOf(x) {
@@ -465,8 +466,8 @@ test "math.absInt" {
comptime testAbsInt();
}
fn testAbsInt() void {
- assert((absInt(i32(-10)) catch unreachable) == 10);
- assert((absInt(i32(10)) catch unreachable) == 10);
+ testing.expect((absInt(i32(-10)) catch unreachable) == 10);
+ testing.expect((absInt(i32(10)) catch unreachable) == 10);
}
pub const absFloat = @import("fabs.zig").fabs;
@@ -483,13 +484,13 @@ test "math.divTrunc" {
comptime testDivTrunc();
}
fn testDivTrunc() void {
- assert((divTrunc(i32, 5, 3) catch unreachable) == 1);
- assert((divTrunc(i32, -5, 3) catch unreachable) == -1);
- if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
- if (divTrunc(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
+ testing.expect((divTrunc(i32, 5, 3) catch unreachable) == 1);
+ testing.expect((divTrunc(i32, -5, 3) catch unreachable) == -1);
+ testing.expectError(error.DivisionByZero, divTrunc(i8, -5, 0));
+ testing.expectError(error.Overflow, divTrunc(i8, -128, -1));
- assert((divTrunc(f32, 5.0, 3.0) catch unreachable) == 1.0);
- assert((divTrunc(f32, -5.0, 3.0) catch unreachable) == -1.0);
+ testing.expect((divTrunc(f32, 5.0, 3.0) catch unreachable) == 1.0);
+ testing.expect((divTrunc(f32, -5.0, 3.0) catch unreachable) == -1.0);
}
pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
@@ -504,13 +505,13 @@ test "math.divFloor" {
comptime testDivFloor();
}
fn testDivFloor() void {
- assert((divFloor(i32, 5, 3) catch unreachable) == 1);
- assert((divFloor(i32, -5, 3) catch unreachable) == -2);
- if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
- if (divFloor(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
+ testing.expect((divFloor(i32, 5, 3) catch unreachable) == 1);
+ testing.expect((divFloor(i32, -5, 3) catch unreachable) == -2);
+ testing.expectError(error.DivisionByZero, divFloor(i8, -5, 0));
+ testing.expectError(error.Overflow, divFloor(i8, -128, -1));
- assert((divFloor(f32, 5.0, 3.0) catch unreachable) == 1.0);
- assert((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0);
+ testing.expect((divFloor(f32, 5.0, 3.0) catch unreachable) == 1.0);
+ testing.expect((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0);
}
pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
@@ -527,15 +528,15 @@ test "math.divExact" {
comptime testDivExact();
}
fn testDivExact() void {
- assert((divExact(i32, 10, 5) catch unreachable) == 2);
- assert((divExact(i32, -10, 5) catch unreachable) == -2);
- if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
- if (divExact(i8, -128, -1)) |_| unreachable else |err| assert(err == error.Overflow);
- if (divExact(i32, 5, 2)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
+ testing.expect((divExact(i32, 10, 5) catch unreachable) == 2);
+ testing.expect((divExact(i32, -10, 5) catch unreachable) == -2);
+ testing.expectError(error.DivisionByZero, divExact(i8, -5, 0));
+ testing.expectError(error.Overflow, divExact(i8, -128, -1));
+ testing.expectError(error.UnexpectedRemainder, divExact(i32, 5, 2));
- assert((divExact(f32, 10.0, 5.0) catch unreachable) == 2.0);
- assert((divExact(f32, -10.0, 5.0) catch unreachable) == -2.0);
- if (divExact(f32, 5.0, 2.0)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
+ testing.expect((divExact(f32, 10.0, 5.0) catch unreachable) == 2.0);
+ testing.expect((divExact(f32, -10.0, 5.0) catch unreachable) == -2.0);
+ testing.expectError(error.UnexpectedRemainder, divExact(f32, 5.0, 2.0));
}
pub fn mod(comptime T: type, numerator: T, denominator: T) !T {
@@ -550,15 +551,15 @@ test "math.mod" {
comptime testMod();
}
fn testMod() void {
- assert((mod(i32, -5, 3) catch unreachable) == 1);
- assert((mod(i32, 5, 3) catch unreachable) == 2);
- if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
- if (mod(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
+ testing.expect((mod(i32, -5, 3) catch unreachable) == 1);
+ testing.expect((mod(i32, 5, 3) catch unreachable) == 2);
+ testing.expectError(error.NegativeDenominator, mod(i32, 10, -1));
+ testing.expectError(error.DivisionByZero, mod(i32, 10, 0));
- assert((mod(f32, -5, 3) catch unreachable) == 1);
- assert((mod(f32, 5, 3) catch unreachable) == 2);
- if (mod(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
- if (mod(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
+ testing.expect((mod(f32, -5, 3) catch unreachable) == 1);
+ testing.expect((mod(f32, 5, 3) catch unreachable) == 2);
+ testing.expectError(error.NegativeDenominator, mod(f32, 10, -1));
+ testing.expectError(error.DivisionByZero, mod(f32, 10, 0));
}
pub fn rem(comptime T: type, numerator: T, denominator: T) !T {
@@ -573,15 +574,15 @@ test "math.rem" {
comptime testRem();
}
fn testRem() void {
- assert((rem(i32, -5, 3) catch unreachable) == -2);
- assert((rem(i32, 5, 3) catch unreachable) == 2);
- if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
- if (rem(i32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
+ testing.expect((rem(i32, -5, 3) catch unreachable) == -2);
+ testing.expect((rem(i32, 5, 3) catch unreachable) == 2);
+ testing.expectError(error.NegativeDenominator, rem(i32, 10, -1));
+ testing.expectError(error.DivisionByZero, rem(i32, 10, 0));
- assert((rem(f32, -5, 3) catch unreachable) == -2);
- assert((rem(f32, 5, 3) catch unreachable) == 2);
- if (rem(f32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
- if (rem(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
+ testing.expect((rem(f32, -5, 3) catch unreachable) == -2);
+ testing.expect((rem(f32, 5, 3) catch unreachable) == 2);
+ testing.expectError(error.NegativeDenominator, rem(f32, 10, -1));
+ testing.expectError(error.DivisionByZero, rem(f32, 10, 0));
}
/// Returns the absolute value of the integer parameter.
@@ -594,14 +595,14 @@ pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
}
test "math.absCast" {
- assert(absCast(i32(-999)) == 999);
- assert(@typeOf(absCast(i32(-999))) == u32);
+ testing.expect(absCast(i32(-999)) == 999);
+ testing.expect(@typeOf(absCast(i32(-999))) == u32);
- assert(absCast(i32(999)) == 999);
- assert(@typeOf(absCast(i32(999))) == u32);
+ testing.expect(absCast(i32(999)) == 999);
+ testing.expect(@typeOf(absCast(i32(999))) == u32);
- assert(absCast(i32(minInt(i32))) == -minInt(i32));
- assert(@typeOf(absCast(i32(minInt(i32)))) == u32);
+ testing.expect(absCast(i32(minInt(i32))) == -minInt(i32));
+ testing.expect(@typeOf(absCast(i32(minInt(i32)))) == u32);
}
/// Returns the negation of the integer parameter.
@@ -618,13 +619,13 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
}
test "math.negateCast" {
- assert((negateCast(u32(999)) catch unreachable) == -999);
- assert(@typeOf(negateCast(u32(999)) catch unreachable) == i32);
+ testing.expect((negateCast(u32(999)) catch unreachable) == -999);
+ testing.expect(@typeOf(negateCast(u32(999)) catch unreachable) == i32);
- assert((negateCast(u32(-minInt(i32))) catch unreachable) == minInt(i32));
- assert(@typeOf(negateCast(u32(-minInt(i32))) catch unreachable) == i32);
+ testing.expect((negateCast(u32(-minInt(i32))) catch unreachable) == minInt(i32));
+ testing.expect(@typeOf(negateCast(u32(-minInt(i32))) catch unreachable) == i32);
- if (negateCast(u32(maxInt(i32) + 10))) |_| unreachable else |err| assert(err == error.Overflow);
+ testing.expectError(error.Overflow, negateCast(u32(maxInt(i32) + 10)));
}
/// Cast an integer to a different integer type. If the value doesn't fit,
@@ -642,13 +643,13 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
}
test "math.cast" {
- if (cast(u8, u32(300))) |_| @panic("fail") else |err| assert(err == error.Overflow);
- if (cast(i8, i32(-200))) |_| @panic("fail") else |err| assert(err == error.Overflow);
- if (cast(u8, i8(-1))) |_| @panic("fail") else |err| assert(err == error.Overflow);
- if (cast(u64, i8(-1))) |_| @panic("fail") else |err| assert(err == error.Overflow);
+ testing.expectError(error.Overflow, cast(u8, u32(300)));
+ testing.expectError(error.Overflow, cast(i8, i32(-200)));
+ testing.expectError(error.Overflow, cast(u8, i8(-1)));
+ testing.expectError(error.Overflow, cast(u64, i8(-1)));
- assert((try cast(u8, u32(255))) == u8(255));
- assert(@typeOf(try cast(u8, u32(255))) == u8);
+ testing.expect((try cast(u8, u32(255))) == u8(255));
+ testing.expect(@typeOf(try cast(u8, u32(255))) == u8);
}
pub const AlignCastError = error{UnalignedMemory};
@@ -692,25 +693,25 @@ pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {
}
test "std.math.log2_int_ceil" {
- assert(log2_int_ceil(u32, 1) == 0);
- assert(log2_int_ceil(u32, 2) == 1);
- assert(log2_int_ceil(u32, 3) == 2);
- assert(log2_int_ceil(u32, 4) == 2);
- assert(log2_int_ceil(u32, 5) == 3);
- assert(log2_int_ceil(u32, 6) == 3);
- assert(log2_int_ceil(u32, 7) == 3);
- assert(log2_int_ceil(u32, 8) == 3);
- assert(log2_int_ceil(u32, 9) == 4);
- assert(log2_int_ceil(u32, 10) == 4);
+ testing.expect(log2_int_ceil(u32, 1) == 0);
+ testing.expect(log2_int_ceil(u32, 2) == 1);
+ testing.expect(log2_int_ceil(u32, 3) == 2);
+ testing.expect(log2_int_ceil(u32, 4) == 2);
+ testing.expect(log2_int_ceil(u32, 5) == 3);
+ testing.expect(log2_int_ceil(u32, 6) == 3);
+ testing.expect(log2_int_ceil(u32, 7) == 3);
+ testing.expect(log2_int_ceil(u32, 8) == 3);
+ testing.expect(log2_int_ceil(u32, 9) == 4);
+ testing.expect(log2_int_ceil(u32, 10) == 4);
}
fn testFloorPowerOfTwo() void {
- assert(floorPowerOfTwo(u32, 63) == 32);
- assert(floorPowerOfTwo(u32, 64) == 64);
- assert(floorPowerOfTwo(u32, 65) == 64);
- assert(floorPowerOfTwo(u4, 7) == 4);
- assert(floorPowerOfTwo(u4, 8) == 8);
- assert(floorPowerOfTwo(u4, 9) == 8);
+ testing.expect(floorPowerOfTwo(u32, 63) == 32);
+ testing.expect(floorPowerOfTwo(u32, 64) == 64);
+ testing.expect(floorPowerOfTwo(u32, 65) == 64);
+ testing.expect(floorPowerOfTwo(u4, 7) == 4);
+ testing.expect(floorPowerOfTwo(u4, 8) == 8);
+ testing.expect(floorPowerOfTwo(u4, 9) == 8);
}
pub fn lossyCast(comptime T: type, value: var) T {
@@ -726,7 +727,7 @@ pub fn lossyCast(comptime T: type, value: var) T {
test "math.f64_min" {
const f64_min_u64 = 0x0010000000000000;
const fmin: f64 = f64_min;
- assert(@bitCast(u64, fmin) == f64_min_u64);
+ testing.expect(@bitCast(u64, fmin) == f64_min_u64);
}
pub fn maxInt(comptime T: type) comptime_int {
@@ -745,36 +746,36 @@ pub fn minInt(comptime T: type) comptime_int {
}
test "minInt and maxInt" {
- assert(maxInt(u0) == 0);
- assert(maxInt(u1) == 1);
- assert(maxInt(u8) == 255);
- assert(maxInt(u16) == 65535);
- assert(maxInt(u32) == 4294967295);
- assert(maxInt(u64) == 18446744073709551615);
+ testing.expect(maxInt(u0) == 0);
+ testing.expect(maxInt(u1) == 1);
+ testing.expect(maxInt(u8) == 255);
+ testing.expect(maxInt(u16) == 65535);
+ testing.expect(maxInt(u32) == 4294967295);
+ testing.expect(maxInt(u64) == 18446744073709551615);
- assert(maxInt(i0) == 0);
- assert(maxInt(i1) == 0);
- assert(maxInt(i8) == 127);
- assert(maxInt(i16) == 32767);
- assert(maxInt(i32) == 2147483647);
- assert(maxInt(i63) == 4611686018427387903);
- assert(maxInt(i64) == 9223372036854775807);
+ testing.expect(maxInt(i0) == 0);
+ testing.expect(maxInt(i1) == 0);
+ testing.expect(maxInt(i8) == 127);
+ testing.expect(maxInt(i16) == 32767);
+ testing.expect(maxInt(i32) == 2147483647);
+ testing.expect(maxInt(i63) == 4611686018427387903);
+ testing.expect(maxInt(i64) == 9223372036854775807);
- assert(minInt(u0) == 0);
- assert(minInt(u1) == 0);
- assert(minInt(u8) == 0);
- assert(minInt(u16) == 0);
- assert(minInt(u32) == 0);
- assert(minInt(u63) == 0);
- assert(minInt(u64) == 0);
+ testing.expect(minInt(u0) == 0);
+ testing.expect(minInt(u1) == 0);
+ testing.expect(minInt(u8) == 0);
+ testing.expect(minInt(u16) == 0);
+ testing.expect(minInt(u32) == 0);
+ testing.expect(minInt(u63) == 0);
+ testing.expect(minInt(u64) == 0);
- assert(minInt(i0) == 0);
- assert(minInt(i1) == -1);
- assert(minInt(i8) == -128);
- assert(minInt(i16) == -32768);
- assert(minInt(i32) == -2147483648);
- assert(minInt(i63) == -4611686018427387904);
- assert(minInt(i64) == -9223372036854775808);
+ testing.expect(minInt(i0) == 0);
+ testing.expect(minInt(i1) == -1);
+ testing.expect(minInt(i8) == -128);
+ testing.expect(minInt(i16) == -32768);
+ testing.expect(minInt(i32) == -2147483648);
+ testing.expect(minInt(i63) == -4611686018427387904);
+ testing.expect(minInt(i64) == -9223372036854775808);
}
test "max value type" {
@@ -782,5 +783,5 @@ test "max value type" {
// u32 would not work. But since the value is a number literal,
// it works fine.
const x: u32 = maxInt(i32);
- assert(x == 2147483647);
+ testing.expect(x == 2147483647);
}
diff --git a/std/math/isfinite.zig b/std/math/isfinite.zig
index bdfdff8f9f..bf1c9ac63c 100644
--- a/std/math/isfinite.zig
+++ b/std/math/isfinite.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn isFinite(x: var) bool {
@@ -25,16 +25,16 @@ pub fn isFinite(x: var) bool {
}
test "math.isFinite" {
- assert(isFinite(f16(0.0)));
- assert(isFinite(f16(-0.0)));
- assert(isFinite(f32(0.0)));
- assert(isFinite(f32(-0.0)));
- assert(isFinite(f64(0.0)));
- assert(isFinite(f64(-0.0)));
- assert(!isFinite(math.inf(f16)));
- assert(!isFinite(-math.inf(f16)));
- assert(!isFinite(math.inf(f32)));
- assert(!isFinite(-math.inf(f32)));
- assert(!isFinite(math.inf(f64)));
- assert(!isFinite(-math.inf(f64)));
+ expect(isFinite(f16(0.0)));
+ expect(isFinite(f16(-0.0)));
+ expect(isFinite(f32(0.0)));
+ expect(isFinite(f32(-0.0)));
+ expect(isFinite(f64(0.0)));
+ expect(isFinite(f64(-0.0)));
+ expect(!isFinite(math.inf(f16)));
+ expect(!isFinite(-math.inf(f16)));
+ expect(!isFinite(math.inf(f32)));
+ expect(!isFinite(-math.inf(f32)));
+ expect(!isFinite(math.inf(f64)));
+ expect(!isFinite(-math.inf(f64)));
}
diff --git a/std/math/isinf.zig b/std/math/isinf.zig
index 93f66cc870..e34e9c5971 100644
--- a/std/math/isinf.zig
+++ b/std/math/isinf.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn isInf(x: var) bool {
@@ -61,46 +61,46 @@ pub fn isNegativeInf(x: var) bool {
}
test "math.isInf" {
- assert(!isInf(f16(0.0)));
- assert(!isInf(f16(-0.0)));
- assert(!isInf(f32(0.0)));
- assert(!isInf(f32(-0.0)));
- assert(!isInf(f64(0.0)));
- assert(!isInf(f64(-0.0)));
- assert(isInf(math.inf(f16)));
- assert(isInf(-math.inf(f16)));
- assert(isInf(math.inf(f32)));
- assert(isInf(-math.inf(f32)));
- assert(isInf(math.inf(f64)));
- assert(isInf(-math.inf(f64)));
+ expect(!isInf(f16(0.0)));
+ expect(!isInf(f16(-0.0)));
+ expect(!isInf(f32(0.0)));
+ expect(!isInf(f32(-0.0)));
+ expect(!isInf(f64(0.0)));
+ expect(!isInf(f64(-0.0)));
+ expect(isInf(math.inf(f16)));
+ expect(isInf(-math.inf(f16)));
+ expect(isInf(math.inf(f32)));
+ expect(isInf(-math.inf(f32)));
+ expect(isInf(math.inf(f64)));
+ expect(isInf(-math.inf(f64)));
}
test "math.isPositiveInf" {
- assert(!isPositiveInf(f16(0.0)));
- assert(!isPositiveInf(f16(-0.0)));
- assert(!isPositiveInf(f32(0.0)));
- assert(!isPositiveInf(f32(-0.0)));
- assert(!isPositiveInf(f64(0.0)));
- assert(!isPositiveInf(f64(-0.0)));
- assert(isPositiveInf(math.inf(f16)));
- assert(!isPositiveInf(-math.inf(f16)));
- assert(isPositiveInf(math.inf(f32)));
- assert(!isPositiveInf(-math.inf(f32)));
- assert(isPositiveInf(math.inf(f64)));
- assert(!isPositiveInf(-math.inf(f64)));
+ expect(!isPositiveInf(f16(0.0)));
+ expect(!isPositiveInf(f16(-0.0)));
+ expect(!isPositiveInf(f32(0.0)));
+ expect(!isPositiveInf(f32(-0.0)));
+ expect(!isPositiveInf(f64(0.0)));
+ expect(!isPositiveInf(f64(-0.0)));
+ expect(isPositiveInf(math.inf(f16)));
+ expect(!isPositiveInf(-math.inf(f16)));
+ expect(isPositiveInf(math.inf(f32)));
+ expect(!isPositiveInf(-math.inf(f32)));
+ expect(isPositiveInf(math.inf(f64)));
+ expect(!isPositiveInf(-math.inf(f64)));
}
test "math.isNegativeInf" {
- assert(!isNegativeInf(f16(0.0)));
- assert(!isNegativeInf(f16(-0.0)));
- assert(!isNegativeInf(f32(0.0)));
- assert(!isNegativeInf(f32(-0.0)));
- assert(!isNegativeInf(f64(0.0)));
- assert(!isNegativeInf(f64(-0.0)));
- assert(!isNegativeInf(math.inf(f16)));
- assert(isNegativeInf(-math.inf(f16)));
- assert(!isNegativeInf(math.inf(f32)));
- assert(isNegativeInf(-math.inf(f32)));
- assert(!isNegativeInf(math.inf(f64)));
- assert(isNegativeInf(-math.inf(f64)));
+ expect(!isNegativeInf(f16(0.0)));
+ expect(!isNegativeInf(f16(-0.0)));
+ expect(!isNegativeInf(f32(0.0)));
+ expect(!isNegativeInf(f32(-0.0)));
+ expect(!isNegativeInf(f64(0.0)));
+ expect(!isNegativeInf(f64(-0.0)));
+ expect(!isNegativeInf(math.inf(f16)));
+ expect(isNegativeInf(-math.inf(f16)));
+ expect(!isNegativeInf(math.inf(f32)));
+ expect(isNegativeInf(-math.inf(f32)));
+ expect(!isNegativeInf(math.inf(f64)));
+ expect(isNegativeInf(-math.inf(f64)));
}
diff --git a/std/math/isnan.zig b/std/math/isnan.zig
index a2cb85b4f7..641da9e620 100644
--- a/std/math/isnan.zig
+++ b/std/math/isnan.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn isNan(x: var) bool {
@@ -31,10 +31,10 @@ pub fn isSignalNan(x: var) bool {
}
test "math.isNan" {
- assert(isNan(math.nan(f16)));
- assert(isNan(math.nan(f32)));
- assert(isNan(math.nan(f64)));
- assert(!isNan(f16(1.0)));
- assert(!isNan(f32(1.0)));
- assert(!isNan(f64(1.0)));
+ expect(isNan(math.nan(f16)));
+ expect(isNan(math.nan(f32)));
+ expect(isNan(math.nan(f64)));
+ expect(!isNan(f16(1.0)));
+ expect(!isNan(f32(1.0)));
+ expect(!isNan(f64(1.0)));
}
diff --git a/std/math/isnormal.zig b/std/math/isnormal.zig
index cc088e46a0..2c57aea7a9 100644
--- a/std/math/isnormal.zig
+++ b/std/math/isnormal.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn isNormal(x: var) bool {
@@ -25,13 +25,13 @@ pub fn isNormal(x: var) bool {
}
test "math.isNormal" {
- assert(!isNormal(math.nan(f16)));
- assert(!isNormal(math.nan(f32)));
- assert(!isNormal(math.nan(f64)));
- assert(!isNormal(f16(0)));
- assert(!isNormal(f32(0)));
- assert(!isNormal(f64(0)));
- assert(isNormal(f16(1.0)));
- assert(isNormal(f32(1.0)));
- assert(isNormal(f64(1.0)));
+ expect(!isNormal(math.nan(f16)));
+ expect(!isNormal(math.nan(f32)));
+ expect(!isNormal(math.nan(f64)));
+ expect(!isNormal(f16(0)));
+ expect(!isNormal(f32(0)));
+ expect(!isNormal(f64(0)));
+ expect(isNormal(f16(1.0)));
+ expect(isNormal(f32(1.0)));
+ expect(isNormal(f64(1.0)));
}
diff --git a/std/math/ln.zig b/std/math/ln.zig
index a560fee8ec..257ce8054f 100644
--- a/std/math/ln.zig
+++ b/std/math/ln.zig
@@ -7,7 +7,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
@@ -143,42 +143,42 @@ pub fn ln_64(x_: f64) f64 {
}
test "math.ln" {
- assert(ln(f32(0.2)) == ln_32(0.2));
- assert(ln(f64(0.2)) == ln_64(0.2));
+ expect(ln(f32(0.2)) == ln_32(0.2));
+ expect(ln(f64(0.2)) == ln_64(0.2));
}
test "math.ln32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, ln_32(0.2), -1.609438, epsilon));
- assert(math.approxEq(f32, ln_32(0.8923), -0.113953, epsilon));
- assert(math.approxEq(f32, ln_32(1.5), 0.405465, epsilon));
- assert(math.approxEq(f32, ln_32(37.45), 3.623007, epsilon));
- assert(math.approxEq(f32, ln_32(89.123), 4.490017, epsilon));
- assert(math.approxEq(f32, ln_32(123123.234375), 11.720941, epsilon));
+ expect(math.approxEq(f32, ln_32(0.2), -1.609438, epsilon));
+ expect(math.approxEq(f32, ln_32(0.8923), -0.113953, epsilon));
+ expect(math.approxEq(f32, ln_32(1.5), 0.405465, epsilon));
+ expect(math.approxEq(f32, ln_32(37.45), 3.623007, epsilon));
+ expect(math.approxEq(f32, ln_32(89.123), 4.490017, epsilon));
+ expect(math.approxEq(f32, ln_32(123123.234375), 11.720941, epsilon));
}
test "math.ln64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, ln_64(0.2), -1.609438, epsilon));
- assert(math.approxEq(f64, ln_64(0.8923), -0.113953, epsilon));
- assert(math.approxEq(f64, ln_64(1.5), 0.405465, epsilon));
- assert(math.approxEq(f64, ln_64(37.45), 3.623007, epsilon));
- assert(math.approxEq(f64, ln_64(89.123), 4.490017, epsilon));
- assert(math.approxEq(f64, ln_64(123123.234375), 11.720941, epsilon));
+ expect(math.approxEq(f64, ln_64(0.2), -1.609438, epsilon));
+ expect(math.approxEq(f64, ln_64(0.8923), -0.113953, epsilon));
+ expect(math.approxEq(f64, ln_64(1.5), 0.405465, epsilon));
+ expect(math.approxEq(f64, ln_64(37.45), 3.623007, epsilon));
+ expect(math.approxEq(f64, ln_64(89.123), 4.490017, epsilon));
+ expect(math.approxEq(f64, ln_64(123123.234375), 11.720941, epsilon));
}
test "math.ln32.special" {
- assert(math.isPositiveInf(ln_32(math.inf(f32))));
- assert(math.isNegativeInf(ln_32(0.0)));
- assert(math.isNan(ln_32(-1.0)));
- assert(math.isNan(ln_32(math.nan(f32))));
+ expect(math.isPositiveInf(ln_32(math.inf(f32))));
+ expect(math.isNegativeInf(ln_32(0.0)));
+ expect(math.isNan(ln_32(-1.0)));
+ expect(math.isNan(ln_32(math.nan(f32))));
}
test "math.ln64.special" {
- assert(math.isPositiveInf(ln_64(math.inf(f64))));
- assert(math.isNegativeInf(ln_64(0.0)));
- assert(math.isNan(ln_64(-1.0)));
- assert(math.isNan(ln_64(math.nan(f64))));
+ expect(math.isPositiveInf(ln_64(math.inf(f64))));
+ expect(math.isNegativeInf(ln_64(0.0)));
+ expect(math.isNan(ln_64(-1.0)));
+ expect(math.isNan(ln_64(math.nan(f64))));
}
diff --git a/std/math/log.zig b/std/math/log.zig
index 20b6d055e8..21cffcc078 100644
--- a/std/math/log.zig
+++ b/std/math/log.zig
@@ -2,7 +2,7 @@ const std = @import("../index.zig");
const math = std.math;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn log(comptime T: type, base: T, x: T) T {
if (base == 2) {
@@ -41,25 +41,25 @@ pub fn log(comptime T: type, base: T, x: T) T {
}
test "math.log integer" {
- assert(log(u8, 2, 0x1) == 0);
- assert(log(u8, 2, 0x2) == 1);
- assert(log(i16, 2, 0x72) == 6);
- assert(log(u32, 2, 0xFFFFFF) == 23);
- assert(log(u64, 2, 0x7FF0123456789ABC) == 62);
+ expect(log(u8, 2, 0x1) == 0);
+ expect(log(u8, 2, 0x2) == 1);
+ expect(log(i16, 2, 0x72) == 6);
+ expect(log(u32, 2, 0xFFFFFF) == 23);
+ expect(log(u64, 2, 0x7FF0123456789ABC) == 62);
}
test "math.log float" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, log(f32, 6, 0.23947), -0.797723, epsilon));
- assert(math.approxEq(f32, log(f32, 89, 0.23947), -0.318432, epsilon));
- assert(math.approxEq(f64, log(f64, 123897, 12389216414), 1.981724596, epsilon));
+ expect(math.approxEq(f32, log(f32, 6, 0.23947), -0.797723, epsilon));
+ expect(math.approxEq(f32, log(f32, 89, 0.23947), -0.318432, epsilon));
+ expect(math.approxEq(f64, log(f64, 123897, 12389216414), 1.981724596, epsilon));
}
test "math.log float_special" {
- assert(log(f32, 2, 0.2301974) == math.log2(f32(0.2301974)));
- assert(log(f32, 10, 0.2301974) == math.log10(f32(0.2301974)));
+ expect(log(f32, 2, 0.2301974) == math.log2(f32(0.2301974)));
+ expect(log(f32, 10, 0.2301974) == math.log10(f32(0.2301974)));
- assert(log(f64, 2, 213.23019799993) == math.log2(f64(213.23019799993)));
- assert(log(f64, 10, 213.23019799993) == math.log10(f64(213.23019799993)));
+ expect(log(f64, 2, 213.23019799993) == math.log2(f64(213.23019799993)));
+ expect(log(f64, 10, 213.23019799993) == math.log10(f64(213.23019799993)));
}
diff --git a/std/math/log10.zig b/std/math/log10.zig
index 2b53d8a6ae..8055f71280 100644
--- a/std/math/log10.zig
+++ b/std/math/log10.zig
@@ -7,7 +7,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
const maxInt = std.math.maxInt;
@@ -171,42 +171,42 @@ pub fn log10_64(x_: f64) f64 {
}
test "math.log10" {
- assert(log10(f32(0.2)) == log10_32(0.2));
- assert(log10(f64(0.2)) == log10_64(0.2));
+ testing.expect(log10(f32(0.2)) == log10_32(0.2));
+ testing.expect(log10(f64(0.2)) == log10_64(0.2));
}
test "math.log10_32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, log10_32(0.2), -0.698970, epsilon));
- assert(math.approxEq(f32, log10_32(0.8923), -0.049489, epsilon));
- assert(math.approxEq(f32, log10_32(1.5), 0.176091, epsilon));
- assert(math.approxEq(f32, log10_32(37.45), 1.573452, epsilon));
- assert(math.approxEq(f32, log10_32(89.123), 1.94999, epsilon));
- assert(math.approxEq(f32, log10_32(123123.234375), 5.09034, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(0.2), -0.698970, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(0.8923), -0.049489, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(1.5), 0.176091, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(37.45), 1.573452, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(89.123), 1.94999, epsilon));
+ testing.expect(math.approxEq(f32, log10_32(123123.234375), 5.09034, epsilon));
}
test "math.log10_64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, log10_64(0.2), -0.698970, epsilon));
- assert(math.approxEq(f64, log10_64(0.8923), -0.049489, epsilon));
- assert(math.approxEq(f64, log10_64(1.5), 0.176091, epsilon));
- assert(math.approxEq(f64, log10_64(37.45), 1.573452, epsilon));
- assert(math.approxEq(f64, log10_64(89.123), 1.94999, epsilon));
- assert(math.approxEq(f64, log10_64(123123.234375), 5.09034, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(0.2), -0.698970, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(0.8923), -0.049489, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(1.5), 0.176091, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(37.45), 1.573452, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(89.123), 1.94999, epsilon));
+ testing.expect(math.approxEq(f64, log10_64(123123.234375), 5.09034, epsilon));
}
test "math.log10_32.special" {
- assert(math.isPositiveInf(log10_32(math.inf(f32))));
- assert(math.isNegativeInf(log10_32(0.0)));
- assert(math.isNan(log10_32(-1.0)));
- assert(math.isNan(log10_32(math.nan(f32))));
+ testing.expect(math.isPositiveInf(log10_32(math.inf(f32))));
+ testing.expect(math.isNegativeInf(log10_32(0.0)));
+ testing.expect(math.isNan(log10_32(-1.0)));
+ testing.expect(math.isNan(log10_32(math.nan(f32))));
}
test "math.log10_64.special" {
- assert(math.isPositiveInf(log10_64(math.inf(f64))));
- assert(math.isNegativeInf(log10_64(0.0)));
- assert(math.isNan(log10_64(-1.0)));
- assert(math.isNan(log10_64(math.nan(f64))));
+ testing.expect(math.isPositiveInf(log10_64(math.inf(f64))));
+ testing.expect(math.isNegativeInf(log10_64(0.0)));
+ testing.expect(math.isNan(log10_64(-1.0)));
+ testing.expect(math.isNan(log10_64(math.nan(f64))));
}
diff --git a/std/math/log1p.zig b/std/math/log1p.zig
index 903fceac05..257e7b90d4 100644
--- a/std/math/log1p.zig
+++ b/std/math/log1p.zig
@@ -9,7 +9,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn log1p(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -177,48 +177,48 @@ fn log1p_64(x: f64) f64 {
}
test "math.log1p" {
- assert(log1p(f32(0.0)) == log1p_32(0.0));
- assert(log1p(f64(0.0)) == log1p_64(0.0));
+ expect(log1p(f32(0.0)) == log1p_32(0.0));
+ expect(log1p(f64(0.0)) == log1p_64(0.0));
}
test "math.log1p_32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, log1p_32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, log1p_32(0.2), 0.182322, epsilon));
- assert(math.approxEq(f32, log1p_32(0.8923), 0.637793, epsilon));
- assert(math.approxEq(f32, log1p_32(1.5), 0.916291, epsilon));
- assert(math.approxEq(f32, log1p_32(37.45), 3.649359, epsilon));
- assert(math.approxEq(f32, log1p_32(89.123), 4.501175, epsilon));
- assert(math.approxEq(f32, log1p_32(123123.234375), 11.720949, epsilon));
+ expect(math.approxEq(f32, log1p_32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, log1p_32(0.2), 0.182322, epsilon));
+ expect(math.approxEq(f32, log1p_32(0.8923), 0.637793, epsilon));
+ expect(math.approxEq(f32, log1p_32(1.5), 0.916291, epsilon));
+ expect(math.approxEq(f32, log1p_32(37.45), 3.649359, epsilon));
+ expect(math.approxEq(f32, log1p_32(89.123), 4.501175, epsilon));
+ expect(math.approxEq(f32, log1p_32(123123.234375), 11.720949, epsilon));
}
test "math.log1p_64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, log1p_64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, log1p_64(0.2), 0.182322, epsilon));
- assert(math.approxEq(f64, log1p_64(0.8923), 0.637793, epsilon));
- assert(math.approxEq(f64, log1p_64(1.5), 0.916291, epsilon));
- assert(math.approxEq(f64, log1p_64(37.45), 3.649359, epsilon));
- assert(math.approxEq(f64, log1p_64(89.123), 4.501175, epsilon));
- assert(math.approxEq(f64, log1p_64(123123.234375), 11.720949, epsilon));
+ expect(math.approxEq(f64, log1p_64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, log1p_64(0.2), 0.182322, epsilon));
+ expect(math.approxEq(f64, log1p_64(0.8923), 0.637793, epsilon));
+ expect(math.approxEq(f64, log1p_64(1.5), 0.916291, epsilon));
+ expect(math.approxEq(f64, log1p_64(37.45), 3.649359, epsilon));
+ expect(math.approxEq(f64, log1p_64(89.123), 4.501175, epsilon));
+ expect(math.approxEq(f64, log1p_64(123123.234375), 11.720949, epsilon));
}
test "math.log1p_32.special" {
- assert(math.isPositiveInf(log1p_32(math.inf(f32))));
- assert(log1p_32(0.0) == 0.0);
- assert(log1p_32(-0.0) == -0.0);
- assert(math.isNegativeInf(log1p_32(-1.0)));
- assert(math.isNan(log1p_32(-2.0)));
- assert(math.isNan(log1p_32(math.nan(f32))));
+ expect(math.isPositiveInf(log1p_32(math.inf(f32))));
+ expect(log1p_32(0.0) == 0.0);
+ expect(log1p_32(-0.0) == -0.0);
+ expect(math.isNegativeInf(log1p_32(-1.0)));
+ expect(math.isNan(log1p_32(-2.0)));
+ expect(math.isNan(log1p_32(math.nan(f32))));
}
test "math.log1p_64.special" {
- assert(math.isPositiveInf(log1p_64(math.inf(f64))));
- assert(log1p_64(0.0) == 0.0);
- assert(log1p_64(-0.0) == -0.0);
- assert(math.isNegativeInf(log1p_64(-1.0)));
- assert(math.isNan(log1p_64(-2.0)));
- assert(math.isNan(log1p_64(math.nan(f64))));
+ expect(math.isPositiveInf(log1p_64(math.inf(f64))));
+ expect(log1p_64(0.0) == 0.0);
+ expect(log1p_64(-0.0) == -0.0);
+ expect(math.isNegativeInf(log1p_64(-1.0)));
+ expect(math.isNan(log1p_64(-2.0)));
+ expect(math.isNan(log1p_64(math.nan(f64))));
}
diff --git a/std/math/log2.zig b/std/math/log2.zig
index 555c0bdf18..1bb51bf9f9 100644
--- a/std/math/log2.zig
+++ b/std/math/log2.zig
@@ -7,7 +7,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
const maxInt = std.math.maxInt;
@@ -169,40 +169,40 @@ pub fn log2_64(x_: f64) f64 {
}
test "math.log2" {
- assert(log2(f32(0.2)) == log2_32(0.2));
- assert(log2(f64(0.2)) == log2_64(0.2));
+ expect(log2(f32(0.2)) == log2_32(0.2));
+ expect(log2(f64(0.2)) == log2_64(0.2));
}
test "math.log2_32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, log2_32(0.2), -2.321928, epsilon));
- assert(math.approxEq(f32, log2_32(0.8923), -0.164399, epsilon));
- assert(math.approxEq(f32, log2_32(1.5), 0.584962, epsilon));
- assert(math.approxEq(f32, log2_32(37.45), 5.226894, epsilon));
- assert(math.approxEq(f32, log2_32(123123.234375), 16.909744, epsilon));
+ expect(math.approxEq(f32, log2_32(0.2), -2.321928, epsilon));
+ expect(math.approxEq(f32, log2_32(0.8923), -0.164399, epsilon));
+ expect(math.approxEq(f32, log2_32(1.5), 0.584962, epsilon));
+ expect(math.approxEq(f32, log2_32(37.45), 5.226894, epsilon));
+ expect(math.approxEq(f32, log2_32(123123.234375), 16.909744, epsilon));
}
test "math.log2_64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, log2_64(0.2), -2.321928, epsilon));
- assert(math.approxEq(f64, log2_64(0.8923), -0.164399, epsilon));
- assert(math.approxEq(f64, log2_64(1.5), 0.584962, epsilon));
- assert(math.approxEq(f64, log2_64(37.45), 5.226894, epsilon));
- assert(math.approxEq(f64, log2_64(123123.234375), 16.909744, epsilon));
+ expect(math.approxEq(f64, log2_64(0.2), -2.321928, epsilon));
+ expect(math.approxEq(f64, log2_64(0.8923), -0.164399, epsilon));
+ expect(math.approxEq(f64, log2_64(1.5), 0.584962, epsilon));
+ expect(math.approxEq(f64, log2_64(37.45), 5.226894, epsilon));
+ expect(math.approxEq(f64, log2_64(123123.234375), 16.909744, epsilon));
}
test "math.log2_32.special" {
- assert(math.isPositiveInf(log2_32(math.inf(f32))));
- assert(math.isNegativeInf(log2_32(0.0)));
- assert(math.isNan(log2_32(-1.0)));
- assert(math.isNan(log2_32(math.nan(f32))));
+ expect(math.isPositiveInf(log2_32(math.inf(f32))));
+ expect(math.isNegativeInf(log2_32(0.0)));
+ expect(math.isNan(log2_32(-1.0)));
+ expect(math.isNan(log2_32(math.nan(f32))));
}
test "math.log2_64.special" {
- assert(math.isPositiveInf(log2_64(math.inf(f64))));
- assert(math.isNegativeInf(log2_64(0.0)));
- assert(math.isNan(log2_64(-1.0)));
- assert(math.isNan(log2_64(math.nan(f64))));
+ expect(math.isPositiveInf(log2_64(math.inf(f64))));
+ expect(math.isNegativeInf(log2_64(0.0)));
+ expect(math.isNan(log2_64(-1.0)));
+ expect(math.isNan(log2_64(math.nan(f64))));
}
diff --git a/std/math/modf.zig b/std/math/modf.zig
index 0f619f25bc..2dadda76a9 100644
--- a/std/math/modf.zig
+++ b/std/math/modf.zig
@@ -5,7 +5,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
fn modf_result(comptime T: type) type {
@@ -119,11 +119,11 @@ test "math.modf" {
const a = modf(f32(1.0));
const b = modf32(1.0);
// NOTE: No struct comparison on generic return type function? non-named, makes sense, but still.
- assert(a.ipart == b.ipart and a.fpart == b.fpart);
+ expect(a.ipart == b.ipart and a.fpart == b.fpart);
const c = modf(f64(1.0));
const d = modf64(1.0);
- assert(a.ipart == b.ipart and a.fpart == b.fpart);
+ expect(a.ipart == b.ipart and a.fpart == b.fpart);
}
test "math.modf32" {
@@ -131,24 +131,24 @@ test "math.modf32" {
var r: modf32_result = undefined;
r = modf32(1.0);
- assert(math.approxEq(f32, r.ipart, 1.0, epsilon));
- assert(math.approxEq(f32, r.fpart, 0.0, epsilon));
+ expect(math.approxEq(f32, r.ipart, 1.0, epsilon));
+ expect(math.approxEq(f32, r.fpart, 0.0, epsilon));
r = modf32(2.545);
- assert(math.approxEq(f32, r.ipart, 2.0, epsilon));
- assert(math.approxEq(f32, r.fpart, 0.545, epsilon));
+ expect(math.approxEq(f32, r.ipart, 2.0, epsilon));
+ expect(math.approxEq(f32, r.fpart, 0.545, epsilon));
r = modf32(3.978123);
- assert(math.approxEq(f32, r.ipart, 3.0, epsilon));
- assert(math.approxEq(f32, r.fpart, 0.978123, epsilon));
+ expect(math.approxEq(f32, r.ipart, 3.0, epsilon));
+ expect(math.approxEq(f32, r.fpart, 0.978123, epsilon));
r = modf32(43874.3);
- assert(math.approxEq(f32, r.ipart, 43874, epsilon));
- assert(math.approxEq(f32, r.fpart, 0.300781, epsilon));
+ expect(math.approxEq(f32, r.ipart, 43874, epsilon));
+ expect(math.approxEq(f32, r.fpart, 0.300781, epsilon));
r = modf32(1234.340780);
- assert(math.approxEq(f32, r.ipart, 1234, epsilon));
- assert(math.approxEq(f32, r.fpart, 0.340820, epsilon));
+ expect(math.approxEq(f32, r.ipart, 1234, epsilon));
+ expect(math.approxEq(f32, r.fpart, 0.340820, epsilon));
}
test "math.modf64" {
@@ -156,48 +156,48 @@ test "math.modf64" {
var r: modf64_result = undefined;
r = modf64(1.0);
- assert(math.approxEq(f64, r.ipart, 1.0, epsilon));
- assert(math.approxEq(f64, r.fpart, 0.0, epsilon));
+ expect(math.approxEq(f64, r.ipart, 1.0, epsilon));
+ expect(math.approxEq(f64, r.fpart, 0.0, epsilon));
r = modf64(2.545);
- assert(math.approxEq(f64, r.ipart, 2.0, epsilon));
- assert(math.approxEq(f64, r.fpart, 0.545, epsilon));
+ expect(math.approxEq(f64, r.ipart, 2.0, epsilon));
+ expect(math.approxEq(f64, r.fpart, 0.545, epsilon));
r = modf64(3.978123);
- assert(math.approxEq(f64, r.ipart, 3.0, epsilon));
- assert(math.approxEq(f64, r.fpart, 0.978123, epsilon));
+ expect(math.approxEq(f64, r.ipart, 3.0, epsilon));
+ expect(math.approxEq(f64, r.fpart, 0.978123, epsilon));
r = modf64(43874.3);
- assert(math.approxEq(f64, r.ipart, 43874, epsilon));
- assert(math.approxEq(f64, r.fpart, 0.3, epsilon));
+ expect(math.approxEq(f64, r.ipart, 43874, epsilon));
+ expect(math.approxEq(f64, r.fpart, 0.3, epsilon));
r = modf64(1234.340780);
- assert(math.approxEq(f64, r.ipart, 1234, epsilon));
- assert(math.approxEq(f64, r.fpart, 0.340780, epsilon));
+ expect(math.approxEq(f64, r.ipart, 1234, epsilon));
+ expect(math.approxEq(f64, r.fpart, 0.340780, epsilon));
}
test "math.modf32.special" {
var r: modf32_result = undefined;
r = modf32(math.inf(f32));
- assert(math.isPositiveInf(r.ipart) and math.isNan(r.fpart));
+ expect(math.isPositiveInf(r.ipart) and math.isNan(r.fpart));
r = modf32(-math.inf(f32));
- assert(math.isNegativeInf(r.ipart) and math.isNan(r.fpart));
+ expect(math.isNegativeInf(r.ipart) and math.isNan(r.fpart));
r = modf32(math.nan(f32));
- assert(math.isNan(r.ipart) and math.isNan(r.fpart));
+ expect(math.isNan(r.ipart) and math.isNan(r.fpart));
}
test "math.modf64.special" {
var r: modf64_result = undefined;
r = modf64(math.inf(f64));
- assert(math.isPositiveInf(r.ipart) and math.isNan(r.fpart));
+ expect(math.isPositiveInf(r.ipart) and math.isNan(r.fpart));
r = modf64(-math.inf(f64));
- assert(math.isNegativeInf(r.ipart) and math.isNan(r.fpart));
+ expect(math.isNegativeInf(r.ipart) and math.isNan(r.fpart));
r = modf64(math.nan(f64));
- assert(math.isNan(r.ipart) and math.isNan(r.fpart));
+ expect(math.isNan(r.ipart) and math.isNan(r.fpart));
}
diff --git a/std/math/pow.zig b/std/math/pow.zig
index 39a2bfa9f7..f037f66d7e 100644
--- a/std/math/pow.zig
+++ b/std/math/pow.zig
@@ -24,7 +24,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
// This implementation is taken from the go stlib, musl is a bit more complex.
pub fn pow(comptime T: type, x: T, y: T) T {
@@ -179,56 +179,56 @@ fn isOddInteger(x: f64) bool {
test "math.pow" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, pow(f32, 0.0, 3.3), 0.0, epsilon));
- assert(math.approxEq(f32, pow(f32, 0.8923, 3.3), 0.686572, epsilon));
- assert(math.approxEq(f32, pow(f32, 0.2, 3.3), 0.004936, epsilon));
- assert(math.approxEq(f32, pow(f32, 1.5, 3.3), 3.811546, epsilon));
- assert(math.approxEq(f32, pow(f32, 37.45, 3.3), 155736.703125, epsilon));
- assert(math.approxEq(f32, pow(f32, 89.123, 3.3), 2722489.5, epsilon));
+ expect(math.approxEq(f32, pow(f32, 0.0, 3.3), 0.0, epsilon));
+ expect(math.approxEq(f32, pow(f32, 0.8923, 3.3), 0.686572, epsilon));
+ expect(math.approxEq(f32, pow(f32, 0.2, 3.3), 0.004936, epsilon));
+ expect(math.approxEq(f32, pow(f32, 1.5, 3.3), 3.811546, epsilon));
+ expect(math.approxEq(f32, pow(f32, 37.45, 3.3), 155736.703125, epsilon));
+ expect(math.approxEq(f32, pow(f32, 89.123, 3.3), 2722489.5, epsilon));
- assert(math.approxEq(f64, pow(f64, 0.0, 3.3), 0.0, epsilon));
- assert(math.approxEq(f64, pow(f64, 0.8923, 3.3), 0.686572, epsilon));
- assert(math.approxEq(f64, pow(f64, 0.2, 3.3), 0.004936, epsilon));
- assert(math.approxEq(f64, pow(f64, 1.5, 3.3), 3.811546, epsilon));
- assert(math.approxEq(f64, pow(f64, 37.45, 3.3), 155736.7160616, epsilon));
- assert(math.approxEq(f64, pow(f64, 89.123, 3.3), 2722490.231436, epsilon));
+ expect(math.approxEq(f64, pow(f64, 0.0, 3.3), 0.0, epsilon));
+ expect(math.approxEq(f64, pow(f64, 0.8923, 3.3), 0.686572, epsilon));
+ expect(math.approxEq(f64, pow(f64, 0.2, 3.3), 0.004936, epsilon));
+ expect(math.approxEq(f64, pow(f64, 1.5, 3.3), 3.811546, epsilon));
+ expect(math.approxEq(f64, pow(f64, 37.45, 3.3), 155736.7160616, epsilon));
+ expect(math.approxEq(f64, pow(f64, 89.123, 3.3), 2722490.231436, epsilon));
}
test "math.pow.special" {
const epsilon = 0.000001;
- assert(pow(f32, 4, 0.0) == 1.0);
- assert(pow(f32, 7, -0.0) == 1.0);
- assert(pow(f32, 45, 1.0) == 45);
- assert(pow(f32, -45, 1.0) == -45);
- assert(math.isNan(pow(f32, math.nan(f32), 5.0)));
- assert(math.isNan(pow(f32, 5.0, math.nan(f32))));
- assert(math.isPositiveInf(pow(f32, 0.0, -1.0)));
- //assert(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?
- assert(math.isPositiveInf(pow(f32, 0.0, -math.inf(f32))));
- assert(math.isPositiveInf(pow(f32, -0.0, -math.inf(f32))));
- assert(pow(f32, 0.0, math.inf(f32)) == 0.0);
- assert(pow(f32, -0.0, math.inf(f32)) == 0.0);
- assert(math.isPositiveInf(pow(f32, 0.0, -2.0)));
- assert(math.isPositiveInf(pow(f32, -0.0, -2.0)));
- assert(pow(f32, 0.0, 1.0) == 0.0);
- assert(pow(f32, -0.0, 1.0) == -0.0);
- assert(pow(f32, 0.0, 2.0) == 0.0);
- assert(pow(f32, -0.0, 2.0) == 0.0);
- assert(math.approxEq(f32, pow(f32, -1.0, math.inf(f32)), 1.0, epsilon));
- assert(math.approxEq(f32, pow(f32, -1.0, -math.inf(f32)), 1.0, epsilon));
- assert(math.isPositiveInf(pow(f32, 1.2, math.inf(f32))));
- assert(math.isPositiveInf(pow(f32, -1.2, math.inf(f32))));
- assert(pow(f32, 1.2, -math.inf(f32)) == 0.0);
- assert(pow(f32, -1.2, -math.inf(f32)) == 0.0);
- assert(pow(f32, 0.2, math.inf(f32)) == 0.0);
- assert(pow(f32, -0.2, math.inf(f32)) == 0.0);
- assert(math.isPositiveInf(pow(f32, 0.2, -math.inf(f32))));
- assert(math.isPositiveInf(pow(f32, -0.2, -math.inf(f32))));
- assert(math.isPositiveInf(pow(f32, math.inf(f32), 1.0)));
- assert(pow(f32, math.inf(f32), -1.0) == 0.0);
- //assert(pow(f32, -math.inf(f32), 5.0) == pow(f32, -0.0, -5.0)); TODO support negative 0?
- assert(pow(f32, -math.inf(f32), -5.2) == pow(f32, -0.0, 5.2));
- assert(math.isNan(pow(f32, -1.0, 1.2)));
- assert(math.isNan(pow(f32, -12.4, 78.5)));
+ expect(pow(f32, 4, 0.0) == 1.0);
+ expect(pow(f32, 7, -0.0) == 1.0);
+ expect(pow(f32, 45, 1.0) == 45);
+ expect(pow(f32, -45, 1.0) == -45);
+ expect(math.isNan(pow(f32, math.nan(f32), 5.0)));
+ expect(math.isNan(pow(f32, 5.0, math.nan(f32))));
+ expect(math.isPositiveInf(pow(f32, 0.0, -1.0)));
+ //expect(math.isNegativeInf(pow(f32, -0.0, -3.0))); TODO is this required?
+ expect(math.isPositiveInf(pow(f32, 0.0, -math.inf(f32))));
+ expect(math.isPositiveInf(pow(f32, -0.0, -math.inf(f32))));
+ expect(pow(f32, 0.0, math.inf(f32)) == 0.0);
+ expect(pow(f32, -0.0, math.inf(f32)) == 0.0);
+ expect(math.isPositiveInf(pow(f32, 0.0, -2.0)));
+ expect(math.isPositiveInf(pow(f32, -0.0, -2.0)));
+ expect(pow(f32, 0.0, 1.0) == 0.0);
+ expect(pow(f32, -0.0, 1.0) == -0.0);
+ expect(pow(f32, 0.0, 2.0) == 0.0);
+ expect(pow(f32, -0.0, 2.0) == 0.0);
+ expect(math.approxEq(f32, pow(f32, -1.0, math.inf(f32)), 1.0, epsilon));
+ expect(math.approxEq(f32, pow(f32, -1.0, -math.inf(f32)), 1.0, epsilon));
+ expect(math.isPositiveInf(pow(f32, 1.2, math.inf(f32))));
+ expect(math.isPositiveInf(pow(f32, -1.2, math.inf(f32))));
+ expect(pow(f32, 1.2, -math.inf(f32)) == 0.0);
+ expect(pow(f32, -1.2, -math.inf(f32)) == 0.0);
+ expect(pow(f32, 0.2, math.inf(f32)) == 0.0);
+ expect(pow(f32, -0.2, math.inf(f32)) == 0.0);
+ expect(math.isPositiveInf(pow(f32, 0.2, -math.inf(f32))));
+ expect(math.isPositiveInf(pow(f32, -0.2, -math.inf(f32))));
+ expect(math.isPositiveInf(pow(f32, math.inf(f32), 1.0)));
+ expect(pow(f32, math.inf(f32), -1.0) == 0.0);
+ //expect(pow(f32, -math.inf(f32), 5.0) == pow(f32, -0.0, -5.0)); TODO support negative 0?
+ expect(pow(f32, -math.inf(f32), -5.2) == pow(f32, -0.0, 5.2));
+ expect(math.isNan(pow(f32, -1.0, 1.2)));
+ expect(math.isNan(pow(f32, -12.4, 78.5)));
}
diff --git a/std/math/powi.zig b/std/math/powi.zig
index 13c09b192e..9c2a4a4965 100644
--- a/std/math/powi.zig
+++ b/std/math/powi.zig
@@ -12,7 +12,7 @@ const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
const assert = std.debug.assert;
-const assertError = std.debug.assertError;
+const testing = std.testing;
// This implementation is based on that from the rust stlib
pub fn powi(comptime T: type, x: T, y: T) (error{
@@ -103,75 +103,75 @@ pub fn powi(comptime T: type, x: T, y: T) (error{
}
test "math.powi" {
- assertError(powi(i8, -66, 6), error.Underflow);
- assertError(powi(i16, -13, 13), error.Underflow);
- assertError(powi(i32, -32, 21), error.Underflow);
- assertError(powi(i64, -24, 61), error.Underflow);
- assertError(powi(i17, -15, 15), error.Underflow);
- assertError(powi(i42, -6, 40), error.Underflow);
+ testing.expectError(error.Underflow, powi(i8, -66, 6));
+ testing.expectError(error.Underflow, powi(i16, -13, 13));
+ testing.expectError(error.Underflow, powi(i32, -32, 21));
+ testing.expectError(error.Underflow, powi(i64, -24, 61));
+ testing.expectError(error.Underflow, powi(i17, -15, 15));
+ testing.expectError(error.Underflow, powi(i42, -6, 40));
- assert((try powi(i8, -5, 3)) == -125);
- assert((try powi(i16, -16, 3)) == -4096);
- assert((try powi(i32, -91, 3)) == -753571);
- assert((try powi(i64, -36, 6)) == 2176782336);
- assert((try powi(i17, -2, 15)) == -32768);
- assert((try powi(i42, -5, 7)) == -78125);
+ testing.expect((try powi(i8, -5, 3)) == -125);
+ testing.expect((try powi(i16, -16, 3)) == -4096);
+ testing.expect((try powi(i32, -91, 3)) == -753571);
+ testing.expect((try powi(i64, -36, 6)) == 2176782336);
+ testing.expect((try powi(i17, -2, 15)) == -32768);
+ testing.expect((try powi(i42, -5, 7)) == -78125);
- assert((try powi(u8, 6, 2)) == 36);
- assert((try powi(u16, 5, 4)) == 625);
- assert((try powi(u32, 12, 6)) == 2985984);
- assert((try powi(u64, 34, 2)) == 1156);
- assert((try powi(u17, 16, 3)) == 4096);
- assert((try powi(u42, 34, 6)) == 1544804416);
+ testing.expect((try powi(u8, 6, 2)) == 36);
+ testing.expect((try powi(u16, 5, 4)) == 625);
+ testing.expect((try powi(u32, 12, 6)) == 2985984);
+ testing.expect((try powi(u64, 34, 2)) == 1156);
+ testing.expect((try powi(u17, 16, 3)) == 4096);
+ testing.expect((try powi(u42, 34, 6)) == 1544804416);
- assertError(powi(i8, 120, 7), error.Overflow);
- assertError(powi(i16, 73, 15), error.Overflow);
- assertError(powi(i32, 23, 31), error.Overflow);
- assertError(powi(i64, 68, 61), error.Overflow);
- assertError(powi(i17, 15, 15), error.Overflow);
- assertError(powi(i42, 121312, 41), error.Overflow);
+ testing.expectError(error.Overflow, powi(i8, 120, 7));
+ testing.expectError(error.Overflow, powi(i16, 73, 15));
+ testing.expectError(error.Overflow, powi(i32, 23, 31));
+ testing.expectError(error.Overflow, powi(i64, 68, 61));
+ testing.expectError(error.Overflow, powi(i17, 15, 15));
+ testing.expectError(error.Overflow, powi(i42, 121312, 41));
- assertError(powi(u8, 123, 7), error.Overflow);
- assertError(powi(u16, 2313, 15), error.Overflow);
- assertError(powi(u32, 8968, 31), error.Overflow);
- assertError(powi(u64, 2342, 63), error.Overflow);
- assertError(powi(u17, 2723, 16), error.Overflow);
- assertError(powi(u42, 8234, 41), error.Overflow);
+ testing.expectError(error.Overflow, powi(u8, 123, 7));
+ testing.expectError(error.Overflow, powi(u16, 2313, 15));
+ testing.expectError(error.Overflow, powi(u32, 8968, 31));
+ testing.expectError(error.Overflow, powi(u64, 2342, 63));
+ testing.expectError(error.Overflow, powi(u17, 2723, 16));
+ testing.expectError(error.Overflow, powi(u42, 8234, 41));
}
test "math.powi.special" {
- assertError(powi(i8, -2, 8), error.Underflow);
- assertError(powi(i16, -2, 16), error.Underflow);
- assertError(powi(i32, -2, 32), error.Underflow);
- assertError(powi(i64, -2, 64), error.Underflow);
- assertError(powi(i17, -2, 17), error.Underflow);
- assertError(powi(i42, -2, 42), error.Underflow);
+ testing.expectError(error.Underflow, powi(i8, -2, 8));
+ testing.expectError(error.Underflow, powi(i16, -2, 16));
+ testing.expectError(error.Underflow, powi(i32, -2, 32));
+ testing.expectError(error.Underflow, powi(i64, -2, 64));
+ testing.expectError(error.Underflow, powi(i17, -2, 17));
+ testing.expectError(error.Underflow, powi(i42, -2, 42));
- assert((try powi(i8, -1, 3)) == -1);
- assert((try powi(i16, -1, 2)) == 1);
- assert((try powi(i32, -1, 16)) == 1);
- assert((try powi(i64, -1, 6)) == 1);
- assert((try powi(i17, -1, 15)) == -1);
- assert((try powi(i42, -1, 7)) == -1);
+ testing.expect((try powi(i8, -1, 3)) == -1);
+ testing.expect((try powi(i16, -1, 2)) == 1);
+ testing.expect((try powi(i32, -1, 16)) == 1);
+ testing.expect((try powi(i64, -1, 6)) == 1);
+ testing.expect((try powi(i17, -1, 15)) == -1);
+ testing.expect((try powi(i42, -1, 7)) == -1);
- assert((try powi(u8, 1, 2)) == 1);
- assert((try powi(u16, 1, 4)) == 1);
- assert((try powi(u32, 1, 6)) == 1);
- assert((try powi(u64, 1, 2)) == 1);
- assert((try powi(u17, 1, 3)) == 1);
- assert((try powi(u42, 1, 6)) == 1);
+ testing.expect((try powi(u8, 1, 2)) == 1);
+ testing.expect((try powi(u16, 1, 4)) == 1);
+ testing.expect((try powi(u32, 1, 6)) == 1);
+ testing.expect((try powi(u64, 1, 2)) == 1);
+ testing.expect((try powi(u17, 1, 3)) == 1);
+ testing.expect((try powi(u42, 1, 6)) == 1);
- assertError(powi(i8, 2, 7), error.Overflow);
- assertError(powi(i16, 2, 15), error.Overflow);
- assertError(powi(i32, 2, 31), error.Overflow);
- assertError(powi(i64, 2, 63), error.Overflow);
- assertError(powi(i17, 2, 16), error.Overflow);
- assertError(powi(i42, 2, 41), error.Overflow);
+ testing.expectError(error.Overflow, powi(i8, 2, 7));
+ testing.expectError(error.Overflow, powi(i16, 2, 15));
+ testing.expectError(error.Overflow, powi(i32, 2, 31));
+ testing.expectError(error.Overflow, powi(i64, 2, 63));
+ testing.expectError(error.Overflow, powi(i17, 2, 16));
+ testing.expectError(error.Overflow, powi(i42, 2, 41));
- assertError(powi(u8, 2, 8), error.Overflow);
- assertError(powi(u16, 2, 16), error.Overflow);
- assertError(powi(u32, 2, 32), error.Overflow);
- assertError(powi(u64, 2, 64), error.Overflow);
- assertError(powi(u17, 2, 17), error.Overflow);
- assertError(powi(u42, 2, 42), error.Overflow);
+ testing.expectError(error.Overflow, powi(u8, 2, 8));
+ testing.expectError(error.Overflow, powi(u16, 2, 16));
+ testing.expectError(error.Overflow, powi(u32, 2, 32));
+ testing.expectError(error.Overflow, powi(u64, 2, 64));
+ testing.expectError(error.Overflow, powi(u17, 2, 17));
+ testing.expectError(error.Overflow, powi(u42, 2, 42));
}
diff --git a/std/math/round.zig b/std/math/round.zig
index 4fe35365c8..7346b703c9 100644
--- a/std/math/round.zig
+++ b/std/math/round.zig
@@ -5,7 +5,7 @@
// - round(nan) = nan
const builtin = @import("builtin");
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const std = @import("../index.zig");
const math = std.math;
@@ -85,36 +85,36 @@ fn round64(x_: f64) f64 {
}
test "math.round" {
- assert(round(f32(1.3)) == round32(1.3));
- assert(round(f64(1.3)) == round64(1.3));
+ expect(round(f32(1.3)) == round32(1.3));
+ expect(round(f64(1.3)) == round64(1.3));
}
test "math.round32" {
- assert(round32(1.3) == 1.0);
- assert(round32(-1.3) == -1.0);
- assert(round32(0.2) == 0.0);
- assert(round32(1.8) == 2.0);
+ expect(round32(1.3) == 1.0);
+ expect(round32(-1.3) == -1.0);
+ expect(round32(0.2) == 0.0);
+ expect(round32(1.8) == 2.0);
}
test "math.round64" {
- assert(round64(1.3) == 1.0);
- assert(round64(-1.3) == -1.0);
- assert(round64(0.2) == 0.0);
- assert(round64(1.8) == 2.0);
+ expect(round64(1.3) == 1.0);
+ expect(round64(-1.3) == -1.0);
+ expect(round64(0.2) == 0.0);
+ expect(round64(1.8) == 2.0);
}
test "math.round32.special" {
- assert(round32(0.0) == 0.0);
- assert(round32(-0.0) == -0.0);
- assert(math.isPositiveInf(round32(math.inf(f32))));
- assert(math.isNegativeInf(round32(-math.inf(f32))));
- assert(math.isNan(round32(math.nan(f32))));
+ expect(round32(0.0) == 0.0);
+ expect(round32(-0.0) == -0.0);
+ expect(math.isPositiveInf(round32(math.inf(f32))));
+ expect(math.isNegativeInf(round32(-math.inf(f32))));
+ expect(math.isNan(round32(math.nan(f32))));
}
test "math.round64.special" {
- assert(round64(0.0) == 0.0);
- assert(round64(-0.0) == -0.0);
- assert(math.isPositiveInf(round64(math.inf(f64))));
- assert(math.isNegativeInf(round64(-math.inf(f64))));
- assert(math.isNan(round64(math.nan(f64))));
+ expect(round64(0.0) == 0.0);
+ expect(round64(-0.0) == -0.0);
+ expect(math.isPositiveInf(round64(math.inf(f64))));
+ expect(math.isNegativeInf(round64(-math.inf(f64))));
+ expect(math.isNan(round64(math.nan(f64))));
}
diff --git a/std/math/scalbn.zig b/std/math/scalbn.zig
index f72c7e866f..d37a8659a9 100644
--- a/std/math/scalbn.zig
+++ b/std/math/scalbn.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn scalbn(x: var, n: i32) @typeOf(x) {
const T = @typeOf(x);
@@ -72,14 +72,14 @@ fn scalbn64(x: f64, n_: i32) f64 {
}
test "math.scalbn" {
- assert(scalbn(f32(1.5), 4) == scalbn32(1.5, 4));
- assert(scalbn(f64(1.5), 4) == scalbn64(1.5, 4));
+ expect(scalbn(f32(1.5), 4) == scalbn32(1.5, 4));
+ expect(scalbn(f64(1.5), 4) == scalbn64(1.5, 4));
}
test "math.scalbn32" {
- assert(scalbn32(1.5, 4) == 24.0);
+ expect(scalbn32(1.5, 4) == 24.0);
}
test "math.scalbn64" {
- assert(scalbn64(1.5, 4) == 24.0);
+ expect(scalbn64(1.5, 4) == 24.0);
}
diff --git a/std/math/signbit.zig b/std/math/signbit.zig
index 8c6829dfcd..728f651aec 100644
--- a/std/math/signbit.zig
+++ b/std/math/signbit.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn signbit(x: var) bool {
const T = @typeOf(x);
@@ -28,22 +28,22 @@ fn signbit64(x: f64) bool {
}
test "math.signbit" {
- assert(signbit(f16(4.0)) == signbit16(4.0));
- assert(signbit(f32(4.0)) == signbit32(4.0));
- assert(signbit(f64(4.0)) == signbit64(4.0));
+ expect(signbit(f16(4.0)) == signbit16(4.0));
+ expect(signbit(f32(4.0)) == signbit32(4.0));
+ expect(signbit(f64(4.0)) == signbit64(4.0));
}
test "math.signbit16" {
- assert(!signbit16(4.0));
- assert(signbit16(-3.0));
+ expect(!signbit16(4.0));
+ expect(signbit16(-3.0));
}
test "math.signbit32" {
- assert(!signbit32(4.0));
- assert(signbit32(-3.0));
+ expect(!signbit32(4.0));
+ expect(signbit32(-3.0));
}
test "math.signbit64" {
- assert(!signbit64(4.0));
- assert(signbit64(-3.0));
+ expect(!signbit64(4.0));
+ expect(signbit64(-3.0));
}
diff --git a/std/math/sin.zig b/std/math/sin.zig
index 15b2f9f17a..5ade6636c7 100644
--- a/std/math/sin.zig
+++ b/std/math/sin.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn sin(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -142,45 +142,45 @@ fn sin64(x_: f64) f64 {
}
test "math.sin" {
- assert(sin(f32(0.0)) == sin32(0.0));
- assert(sin(f64(0.0)) == sin64(0.0));
- assert(comptime (math.sin(f64(2))) == math.sin(f64(2)));
+ expect(sin(f32(0.0)) == sin32(0.0));
+ expect(sin(f64(0.0)) == sin64(0.0));
+ expect(comptime (math.sin(f64(2))) == math.sin(f64(2)));
}
test "math.sin32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, sin32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, sin32(0.2), 0.198669, epsilon));
- assert(math.approxEq(f32, sin32(0.8923), 0.778517, epsilon));
- assert(math.approxEq(f32, sin32(1.5), 0.997495, epsilon));
- assert(math.approxEq(f32, sin32(37.45), -0.246544, epsilon));
- assert(math.approxEq(f32, sin32(89.123), 0.916166, epsilon));
+ expect(math.approxEq(f32, sin32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, sin32(0.2), 0.198669, epsilon));
+ expect(math.approxEq(f32, sin32(0.8923), 0.778517, epsilon));
+ expect(math.approxEq(f32, sin32(1.5), 0.997495, epsilon));
+ expect(math.approxEq(f32, sin32(37.45), -0.246544, epsilon));
+ expect(math.approxEq(f32, sin32(89.123), 0.916166, epsilon));
}
test "math.sin64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, sin64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, sin64(0.2), 0.198669, epsilon));
- assert(math.approxEq(f64, sin64(0.8923), 0.778517, epsilon));
- assert(math.approxEq(f64, sin64(1.5), 0.997495, epsilon));
- assert(math.approxEq(f64, sin64(37.45), -0.246543, epsilon));
- assert(math.approxEq(f64, sin64(89.123), 0.916166, epsilon));
+ expect(math.approxEq(f64, sin64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, sin64(0.2), 0.198669, epsilon));
+ expect(math.approxEq(f64, sin64(0.8923), 0.778517, epsilon));
+ expect(math.approxEq(f64, sin64(1.5), 0.997495, epsilon));
+ expect(math.approxEq(f64, sin64(37.45), -0.246543, epsilon));
+ expect(math.approxEq(f64, sin64(89.123), 0.916166, epsilon));
}
test "math.sin32.special" {
- assert(sin32(0.0) == 0.0);
- assert(sin32(-0.0) == -0.0);
- assert(math.isNan(sin32(math.inf(f32))));
- assert(math.isNan(sin32(-math.inf(f32))));
- assert(math.isNan(sin32(math.nan(f32))));
+ expect(sin32(0.0) == 0.0);
+ expect(sin32(-0.0) == -0.0);
+ expect(math.isNan(sin32(math.inf(f32))));
+ expect(math.isNan(sin32(-math.inf(f32))));
+ expect(math.isNan(sin32(math.nan(f32))));
}
test "math.sin64.special" {
- assert(sin64(0.0) == 0.0);
- assert(sin64(-0.0) == -0.0);
- assert(math.isNan(sin64(math.inf(f64))));
- assert(math.isNan(sin64(-math.inf(f64))));
- assert(math.isNan(sin64(math.nan(f64))));
+ expect(sin64(0.0) == 0.0);
+ expect(sin64(-0.0) == -0.0);
+ expect(math.isNan(sin64(math.inf(f64))));
+ expect(math.isNan(sin64(-math.inf(f64))));
+ expect(math.isNan(sin64(math.nan(f64))));
}
diff --git a/std/math/sinh.zig b/std/math/sinh.zig
index 733b89754a..95924ba55a 100644
--- a/std/math/sinh.zig
+++ b/std/math/sinh.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const expo2 = @import("expo2.zig").expo2;
const maxInt = std.math.maxInt;
@@ -87,40 +87,40 @@ fn sinh64(x: f64) f64 {
}
test "math.sinh" {
- assert(sinh(f32(1.5)) == sinh32(1.5));
- assert(sinh(f64(1.5)) == sinh64(1.5));
+ expect(sinh(f32(1.5)) == sinh32(1.5));
+ expect(sinh(f64(1.5)) == sinh64(1.5));
}
test "math.sinh32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, sinh32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, sinh32(0.2), 0.201336, epsilon));
- assert(math.approxEq(f32, sinh32(0.8923), 1.015512, epsilon));
- assert(math.approxEq(f32, sinh32(1.5), 2.129279, epsilon));
+ expect(math.approxEq(f32, sinh32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, sinh32(0.2), 0.201336, epsilon));
+ expect(math.approxEq(f32, sinh32(0.8923), 1.015512, epsilon));
+ expect(math.approxEq(f32, sinh32(1.5), 2.129279, epsilon));
}
test "math.sinh64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, sinh64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, sinh64(0.2), 0.201336, epsilon));
- assert(math.approxEq(f64, sinh64(0.8923), 1.015512, epsilon));
- assert(math.approxEq(f64, sinh64(1.5), 2.129279, epsilon));
+ expect(math.approxEq(f64, sinh64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, sinh64(0.2), 0.201336, epsilon));
+ expect(math.approxEq(f64, sinh64(0.8923), 1.015512, epsilon));
+ expect(math.approxEq(f64, sinh64(1.5), 2.129279, epsilon));
}
test "math.sinh32.special" {
- assert(sinh32(0.0) == 0.0);
- assert(sinh32(-0.0) == -0.0);
- assert(math.isPositiveInf(sinh32(math.inf(f32))));
- assert(math.isNegativeInf(sinh32(-math.inf(f32))));
- assert(math.isNan(sinh32(math.nan(f32))));
+ expect(sinh32(0.0) == 0.0);
+ expect(sinh32(-0.0) == -0.0);
+ expect(math.isPositiveInf(sinh32(math.inf(f32))));
+ expect(math.isNegativeInf(sinh32(-math.inf(f32))));
+ expect(math.isNan(sinh32(math.nan(f32))));
}
test "math.sinh64.special" {
- assert(sinh64(0.0) == 0.0);
- assert(sinh64(-0.0) == -0.0);
- assert(math.isPositiveInf(sinh64(math.inf(f64))));
- assert(math.isNegativeInf(sinh64(-math.inf(f64))));
- assert(math.isNan(sinh64(math.nan(f64))));
+ expect(sinh64(0.0) == 0.0);
+ expect(sinh64(-0.0) == -0.0);
+ expect(math.isPositiveInf(sinh64(math.inf(f64))));
+ expect(math.isNegativeInf(sinh64(-math.inf(f64))));
+ expect(math.isNan(sinh64(math.nan(f64))));
}
diff --git a/std/math/sqrt.zig b/std/math/sqrt.zig
index 4300f20f5a..9996b44b20 100644
--- a/std/math/sqrt.zig
+++ b/std/math/sqrt.zig
@@ -7,7 +7,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const TypeId = builtin.TypeId;
const maxInt = std.math.maxInt;
@@ -32,75 +32,75 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ
}
test "math.sqrt" {
- assert(sqrt(f16(0.0)) == @sqrt(f16, 0.0));
- assert(sqrt(f32(0.0)) == @sqrt(f32, 0.0));
- assert(sqrt(f64(0.0)) == @sqrt(f64, 0.0));
+ expect(sqrt(f16(0.0)) == @sqrt(f16, 0.0));
+ expect(sqrt(f32(0.0)) == @sqrt(f32, 0.0));
+ expect(sqrt(f64(0.0)) == @sqrt(f64, 0.0));
}
test "math.sqrt16" {
const epsilon = 0.000001;
- assert(@sqrt(f16, 0.0) == 0.0);
- assert(math.approxEq(f16, @sqrt(f16, 2.0), 1.414214, epsilon));
- assert(math.approxEq(f16, @sqrt(f16, 3.6), 1.897367, epsilon));
- assert(@sqrt(f16, 4.0) == 2.0);
- assert(math.approxEq(f16, @sqrt(f16, 7.539840), 2.745877, epsilon));
- assert(math.approxEq(f16, @sqrt(f16, 19.230934), 4.385309, epsilon));
- assert(@sqrt(f16, 64.0) == 8.0);
- assert(math.approxEq(f16, @sqrt(f16, 64.1), 8.006248, epsilon));
- assert(math.approxEq(f16, @sqrt(f16, 8942.230469), 94.563370, epsilon));
+ expect(@sqrt(f16, 0.0) == 0.0);
+ expect(math.approxEq(f16, @sqrt(f16, 2.0), 1.414214, epsilon));
+ expect(math.approxEq(f16, @sqrt(f16, 3.6), 1.897367, epsilon));
+ expect(@sqrt(f16, 4.0) == 2.0);
+ expect(math.approxEq(f16, @sqrt(f16, 7.539840), 2.745877, epsilon));
+ expect(math.approxEq(f16, @sqrt(f16, 19.230934), 4.385309, epsilon));
+ expect(@sqrt(f16, 64.0) == 8.0);
+ expect(math.approxEq(f16, @sqrt(f16, 64.1), 8.006248, epsilon));
+ expect(math.approxEq(f16, @sqrt(f16, 8942.230469), 94.563370, epsilon));
}
test "math.sqrt32" {
const epsilon = 0.000001;
- assert(@sqrt(f32, 0.0) == 0.0);
- assert(math.approxEq(f32, @sqrt(f32, 2.0), 1.414214, epsilon));
- assert(math.approxEq(f32, @sqrt(f32, 3.6), 1.897367, epsilon));
- assert(@sqrt(f32, 4.0) == 2.0);
- assert(math.approxEq(f32, @sqrt(f32, 7.539840), 2.745877, epsilon));
- assert(math.approxEq(f32, @sqrt(f32, 19.230934), 4.385309, epsilon));
- assert(@sqrt(f32, 64.0) == 8.0);
- assert(math.approxEq(f32, @sqrt(f32, 64.1), 8.006248, epsilon));
- assert(math.approxEq(f32, @sqrt(f32, 8942.230469), 94.563370, epsilon));
+ expect(@sqrt(f32, 0.0) == 0.0);
+ expect(math.approxEq(f32, @sqrt(f32, 2.0), 1.414214, epsilon));
+ expect(math.approxEq(f32, @sqrt(f32, 3.6), 1.897367, epsilon));
+ expect(@sqrt(f32, 4.0) == 2.0);
+ expect(math.approxEq(f32, @sqrt(f32, 7.539840), 2.745877, epsilon));
+ expect(math.approxEq(f32, @sqrt(f32, 19.230934), 4.385309, epsilon));
+ expect(@sqrt(f32, 64.0) == 8.0);
+ expect(math.approxEq(f32, @sqrt(f32, 64.1), 8.006248, epsilon));
+ expect(math.approxEq(f32, @sqrt(f32, 8942.230469), 94.563370, epsilon));
}
test "math.sqrt64" {
const epsilon = 0.000001;
- assert(@sqrt(f64, 0.0) == 0.0);
- assert(math.approxEq(f64, @sqrt(f64, 2.0), 1.414214, epsilon));
- assert(math.approxEq(f64, @sqrt(f64, 3.6), 1.897367, epsilon));
- assert(@sqrt(f64, 4.0) == 2.0);
- assert(math.approxEq(f64, @sqrt(f64, 7.539840), 2.745877, epsilon));
- assert(math.approxEq(f64, @sqrt(f64, 19.230934), 4.385309, epsilon));
- assert(@sqrt(f64, 64.0) == 8.0);
- assert(math.approxEq(f64, @sqrt(f64, 64.1), 8.006248, epsilon));
- assert(math.approxEq(f64, @sqrt(f64, 8942.230469), 94.563367, epsilon));
+ expect(@sqrt(f64, 0.0) == 0.0);
+ expect(math.approxEq(f64, @sqrt(f64, 2.0), 1.414214, epsilon));
+ expect(math.approxEq(f64, @sqrt(f64, 3.6), 1.897367, epsilon));
+ expect(@sqrt(f64, 4.0) == 2.0);
+ expect(math.approxEq(f64, @sqrt(f64, 7.539840), 2.745877, epsilon));
+ expect(math.approxEq(f64, @sqrt(f64, 19.230934), 4.385309, epsilon));
+ expect(@sqrt(f64, 64.0) == 8.0);
+ expect(math.approxEq(f64, @sqrt(f64, 64.1), 8.006248, epsilon));
+ expect(math.approxEq(f64, @sqrt(f64, 8942.230469), 94.563367, epsilon));
}
test "math.sqrt16.special" {
- assert(math.isPositiveInf(@sqrt(f16, math.inf(f16))));
- assert(@sqrt(f16, 0.0) == 0.0);
- assert(@sqrt(f16, -0.0) == -0.0);
- assert(math.isNan(@sqrt(f16, -1.0)));
- assert(math.isNan(@sqrt(f16, math.nan(f16))));
+ expect(math.isPositiveInf(@sqrt(f16, math.inf(f16))));
+ expect(@sqrt(f16, 0.0) == 0.0);
+ expect(@sqrt(f16, -0.0) == -0.0);
+ expect(math.isNan(@sqrt(f16, -1.0)));
+ expect(math.isNan(@sqrt(f16, math.nan(f16))));
}
test "math.sqrt32.special" {
- assert(math.isPositiveInf(@sqrt(f32, math.inf(f32))));
- assert(@sqrt(f32, 0.0) == 0.0);
- assert(@sqrt(f32, -0.0) == -0.0);
- assert(math.isNan(@sqrt(f32, -1.0)));
- assert(math.isNan(@sqrt(f32, math.nan(f32))));
+ expect(math.isPositiveInf(@sqrt(f32, math.inf(f32))));
+ expect(@sqrt(f32, 0.0) == 0.0);
+ expect(@sqrt(f32, -0.0) == -0.0);
+ expect(math.isNan(@sqrt(f32, -1.0)));
+ expect(math.isNan(@sqrt(f32, math.nan(f32))));
}
test "math.sqrt64.special" {
- assert(math.isPositiveInf(@sqrt(f64, math.inf(f64))));
- assert(@sqrt(f64, 0.0) == 0.0);
- assert(@sqrt(f64, -0.0) == -0.0);
- assert(math.isNan(@sqrt(f64, -1.0)));
- assert(math.isNan(@sqrt(f64, math.nan(f64))));
+ expect(math.isPositiveInf(@sqrt(f64, math.inf(f64))));
+ expect(@sqrt(f64, 0.0) == 0.0);
+ expect(@sqrt(f64, -0.0) == -0.0);
+ expect(math.isNan(@sqrt(f64, -1.0)));
+ expect(math.isNan(@sqrt(f64, math.nan(f64))));
}
fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
@@ -127,10 +127,10 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
}
test "math.sqrt_int" {
- assert(sqrt_int(u32, 3) == 1);
- assert(sqrt_int(u32, 4) == 2);
- assert(sqrt_int(u32, 5) == 2);
- assert(sqrt_int(u32, 8) == 2);
- assert(sqrt_int(u32, 9) == 3);
- assert(sqrt_int(u32, 10) == 3);
+ expect(sqrt_int(u32, 3) == 1);
+ expect(sqrt_int(u32, 4) == 2);
+ expect(sqrt_int(u32, 5) == 2);
+ expect(sqrt_int(u32, 8) == 2);
+ expect(sqrt_int(u32, 9) == 3);
+ expect(sqrt_int(u32, 10) == 3);
}
diff --git a/std/math/tan.zig b/std/math/tan.zig
index a71a17e625..ec43092320 100644
--- a/std/math/tan.zig
+++ b/std/math/tan.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
pub fn tan(x: var) @typeOf(x) {
const T = @typeOf(x);
@@ -129,44 +129,44 @@ fn tan64(x_: f64) f64 {
}
test "math.tan" {
- assert(tan(f32(0.0)) == tan32(0.0));
- assert(tan(f64(0.0)) == tan64(0.0));
+ expect(tan(f32(0.0)) == tan32(0.0));
+ expect(tan(f64(0.0)) == tan64(0.0));
}
test "math.tan32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, tan32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, tan32(0.2), 0.202710, epsilon));
- assert(math.approxEq(f32, tan32(0.8923), 1.240422, epsilon));
- assert(math.approxEq(f32, tan32(1.5), 14.101420, epsilon));
- assert(math.approxEq(f32, tan32(37.45), -0.254397, epsilon));
- assert(math.approxEq(f32, tan32(89.123), 2.285852, epsilon));
+ expect(math.approxEq(f32, tan32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, tan32(0.2), 0.202710, epsilon));
+ expect(math.approxEq(f32, tan32(0.8923), 1.240422, epsilon));
+ expect(math.approxEq(f32, tan32(1.5), 14.101420, epsilon));
+ expect(math.approxEq(f32, tan32(37.45), -0.254397, epsilon));
+ expect(math.approxEq(f32, tan32(89.123), 2.285852, epsilon));
}
test "math.tan64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, tan64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, tan64(0.2), 0.202710, epsilon));
- assert(math.approxEq(f64, tan64(0.8923), 1.240422, epsilon));
- assert(math.approxEq(f64, tan64(1.5), 14.101420, epsilon));
- assert(math.approxEq(f64, tan64(37.45), -0.254397, epsilon));
- assert(math.approxEq(f64, tan64(89.123), 2.2858376, epsilon));
+ expect(math.approxEq(f64, tan64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, tan64(0.2), 0.202710, epsilon));
+ expect(math.approxEq(f64, tan64(0.8923), 1.240422, epsilon));
+ expect(math.approxEq(f64, tan64(1.5), 14.101420, epsilon));
+ expect(math.approxEq(f64, tan64(37.45), -0.254397, epsilon));
+ expect(math.approxEq(f64, tan64(89.123), 2.2858376, epsilon));
}
test "math.tan32.special" {
- assert(tan32(0.0) == 0.0);
- assert(tan32(-0.0) == -0.0);
- assert(math.isNan(tan32(math.inf(f32))));
- assert(math.isNan(tan32(-math.inf(f32))));
- assert(math.isNan(tan32(math.nan(f32))));
+ expect(tan32(0.0) == 0.0);
+ expect(tan32(-0.0) == -0.0);
+ expect(math.isNan(tan32(math.inf(f32))));
+ expect(math.isNan(tan32(-math.inf(f32))));
+ expect(math.isNan(tan32(math.nan(f32))));
}
test "math.tan64.special" {
- assert(tan64(0.0) == 0.0);
- assert(tan64(-0.0) == -0.0);
- assert(math.isNan(tan64(math.inf(f64))));
- assert(math.isNan(tan64(-math.inf(f64))));
- assert(math.isNan(tan64(math.nan(f64))));
+ expect(tan64(0.0) == 0.0);
+ expect(tan64(-0.0) == -0.0);
+ expect(math.isNan(tan64(math.inf(f64))));
+ expect(math.isNan(tan64(-math.inf(f64))));
+ expect(math.isNan(tan64(math.nan(f64))));
}
diff --git a/std/math/tanh.zig b/std/math/tanh.zig
index faeb2641cc..a35449a053 100644
--- a/std/math/tanh.zig
+++ b/std/math/tanh.zig
@@ -7,7 +7,7 @@
const builtin = @import("builtin");
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const expo2 = @import("expo2.zig").expo2;
const maxInt = std.math.maxInt;
@@ -113,42 +113,42 @@ fn tanh64(x: f64) f64 {
}
test "math.tanh" {
- assert(tanh(f32(1.5)) == tanh32(1.5));
- assert(tanh(f64(1.5)) == tanh64(1.5));
+ expect(tanh(f32(1.5)) == tanh32(1.5));
+ expect(tanh(f64(1.5)) == tanh64(1.5));
}
test "math.tanh32" {
const epsilon = 0.000001;
- assert(math.approxEq(f32, tanh32(0.0), 0.0, epsilon));
- assert(math.approxEq(f32, tanh32(0.2), 0.197375, epsilon));
- assert(math.approxEq(f32, tanh32(0.8923), 0.712528, epsilon));
- assert(math.approxEq(f32, tanh32(1.5), 0.905148, epsilon));
- assert(math.approxEq(f32, tanh32(37.45), 1.0, epsilon));
+ expect(math.approxEq(f32, tanh32(0.0), 0.0, epsilon));
+ expect(math.approxEq(f32, tanh32(0.2), 0.197375, epsilon));
+ expect(math.approxEq(f32, tanh32(0.8923), 0.712528, epsilon));
+ expect(math.approxEq(f32, tanh32(1.5), 0.905148, epsilon));
+ expect(math.approxEq(f32, tanh32(37.45), 1.0, epsilon));
}
test "math.tanh64" {
const epsilon = 0.000001;
- assert(math.approxEq(f64, tanh64(0.0), 0.0, epsilon));
- assert(math.approxEq(f64, tanh64(0.2), 0.197375, epsilon));
- assert(math.approxEq(f64, tanh64(0.8923), 0.712528, epsilon));
- assert(math.approxEq(f64, tanh64(1.5), 0.905148, epsilon));
- assert(math.approxEq(f64, tanh64(37.45), 1.0, epsilon));
+ expect(math.approxEq(f64, tanh64(0.0), 0.0, epsilon));
+ expect(math.approxEq(f64, tanh64(0.2), 0.197375, epsilon));
+ expect(math.approxEq(f64, tanh64(0.8923), 0.712528, epsilon));
+ expect(math.approxEq(f64, tanh64(1.5), 0.905148, epsilon));
+ expect(math.approxEq(f64, tanh64(37.45), 1.0, epsilon));
}
test "math.tanh32.special" {
- assert(tanh32(0.0) == 0.0);
- assert(tanh32(-0.0) == -0.0);
- assert(tanh32(math.inf(f32)) == 1.0);
- assert(tanh32(-math.inf(f32)) == -1.0);
- assert(math.isNan(tanh32(math.nan(f32))));
+ expect(tanh32(0.0) == 0.0);
+ expect(tanh32(-0.0) == -0.0);
+ expect(tanh32(math.inf(f32)) == 1.0);
+ expect(tanh32(-math.inf(f32)) == -1.0);
+ expect(math.isNan(tanh32(math.nan(f32))));
}
test "math.tanh64.special" {
- assert(tanh64(0.0) == 0.0);
- assert(tanh64(-0.0) == -0.0);
- assert(tanh64(math.inf(f64)) == 1.0);
- assert(tanh64(-math.inf(f64)) == -1.0);
- assert(math.isNan(tanh64(math.nan(f64))));
+ expect(tanh64(0.0) == 0.0);
+ expect(tanh64(-0.0) == -0.0);
+ expect(tanh64(math.inf(f64)) == 1.0);
+ expect(tanh64(-math.inf(f64)) == -1.0);
+ expect(math.isNan(tanh64(math.nan(f64))));
}
diff --git a/std/math/trunc.zig b/std/math/trunc.zig
index bb309a1e24..8c91ccc568 100644
--- a/std/math/trunc.zig
+++ b/std/math/trunc.zig
@@ -6,7 +6,7 @@
const std = @import("../index.zig");
const math = std.math;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
pub fn trunc(x: var) @typeOf(x) {
@@ -61,34 +61,34 @@ fn trunc64(x: f64) f64 {
}
test "math.trunc" {
- assert(trunc(f32(1.3)) == trunc32(1.3));
- assert(trunc(f64(1.3)) == trunc64(1.3));
+ expect(trunc(f32(1.3)) == trunc32(1.3));
+ expect(trunc(f64(1.3)) == trunc64(1.3));
}
test "math.trunc32" {
- assert(trunc32(1.3) == 1.0);
- assert(trunc32(-1.3) == -1.0);
- assert(trunc32(0.2) == 0.0);
+ expect(trunc32(1.3) == 1.0);
+ expect(trunc32(-1.3) == -1.0);
+ expect(trunc32(0.2) == 0.0);
}
test "math.trunc64" {
- assert(trunc64(1.3) == 1.0);
- assert(trunc64(-1.3) == -1.0);
- assert(trunc64(0.2) == 0.0);
+ expect(trunc64(1.3) == 1.0);
+ expect(trunc64(-1.3) == -1.0);
+ expect(trunc64(0.2) == 0.0);
}
test "math.trunc32.special" {
- assert(trunc32(0.0) == 0.0); // 0x3F800000
- assert(trunc32(-0.0) == -0.0);
- assert(math.isPositiveInf(trunc32(math.inf(f32))));
- assert(math.isNegativeInf(trunc32(-math.inf(f32))));
- assert(math.isNan(trunc32(math.nan(f32))));
+ expect(trunc32(0.0) == 0.0); // 0x3F800000
+ expect(trunc32(-0.0) == -0.0);
+ expect(math.isPositiveInf(trunc32(math.inf(f32))));
+ expect(math.isNegativeInf(trunc32(-math.inf(f32))));
+ expect(math.isNan(trunc32(math.nan(f32))));
}
test "math.trunc64.special" {
- assert(trunc64(0.0) == 0.0);
- assert(trunc64(-0.0) == -0.0);
- assert(math.isPositiveInf(trunc64(math.inf(f64))));
- assert(math.isNegativeInf(trunc64(-math.inf(f64))));
- assert(math.isNan(trunc64(math.nan(f64))));
+ expect(trunc64(0.0) == 0.0);
+ expect(trunc64(-0.0) == -0.0);
+ expect(math.isPositiveInf(trunc64(math.inf(f64))));
+ expect(math.isNegativeInf(trunc64(-math.inf(f64))));
+ expect(math.isNan(trunc64(math.nan(f64))));
}
diff --git a/std/mem.zig b/std/mem.zig
index a6cbae744f..1c7523bf13 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -6,6 +6,7 @@ const builtin = @import("builtin");
const mem = @This();
const meta = std.meta;
const trait = meta.trait;
+const testing = std.testing;
pub const Allocator = struct {
pub const Error = error{OutOfMemory};
@@ -181,7 +182,7 @@ test "mem.secureZero" {
set(u8, a[0..], 0);
secureZero(u8, b[0..]);
- assert(eql(u8, a[0..], b[0..]));
+ testing.expectEqualSlices(u8, a[0..], b[0..]);
}
pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare {
@@ -210,11 +211,11 @@ pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare {
}
test "mem.compare" {
- assert(compare(u8, "abcd", "bee") == Compare.LessThan);
- assert(compare(u8, "abc", "abc") == Compare.Equal);
- assert(compare(u8, "abc", "abc0") == Compare.LessThan);
- assert(compare(u8, "", "") == Compare.Equal);
- assert(compare(u8, "", "a") == Compare.LessThan);
+ testing.expect(compare(u8, "abcd", "bee") == Compare.LessThan);
+ testing.expect(compare(u8, "abc", "abc") == Compare.Equal);
+ testing.expect(compare(u8, "abc", "abc0") == Compare.LessThan);
+ testing.expect(compare(u8, "", "") == Compare.Equal);
+ testing.expect(compare(u8, "", "a") == Compare.LessThan);
}
/// Returns true if lhs < rhs, false otherwise
@@ -227,11 +228,11 @@ pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
}
test "mem.lessThan" {
- assert(lessThan(u8, "abcd", "bee"));
- assert(!lessThan(u8, "abc", "abc"));
- assert(lessThan(u8, "abc", "abc0"));
- assert(!lessThan(u8, "", ""));
- assert(lessThan(u8, "", "a"));
+ testing.expect(lessThan(u8, "abcd", "bee"));
+ testing.expect(!lessThan(u8, "abc", "abc"));
+ testing.expect(lessThan(u8, "abc", "abc0"));
+ testing.expect(!lessThan(u8, "", ""));
+ testing.expect(lessThan(u8, "", "a"));
}
/// Compares two slices and returns whether they are equal.
@@ -296,10 +297,10 @@ pub fn trim(comptime T: type, slice: []const T, values_to_strip: []const T) []co
}
test "mem.trim" {
- assert(eql(u8, trimLeft(u8, " foo\n ", " \n"), "foo\n "));
- assert(eql(u8, trimRight(u8, " foo\n ", " \n"), " foo"));
- assert(eql(u8, trim(u8, " foo\n ", " \n"), "foo"));
- assert(eql(u8, trim(u8, "foo", " \n"), "foo"));
+ testing.expectEqualSlices(u8, "foo\n ", trimLeft(u8, " foo\n ", " \n"));
+ testing.expectEqualSlices(u8, " foo", trimRight(u8, " foo\n ", " \n"));
+ testing.expectEqualSlices(u8, "foo", trim(u8, " foo\n ", " \n"));
+ testing.expectEqualSlices(u8, "foo", trim(u8, "foo", " \n"));
}
/// Linear search for the index of a scalar value inside a slice.
@@ -380,20 +381,20 @@ pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, nee
}
test "mem.indexOf" {
- assert(indexOf(u8, "one two three four", "four").? == 14);
- assert(lastIndexOf(u8, "one two three two four", "two").? == 14);
- assert(indexOf(u8, "one two three four", "gour") == null);
- assert(lastIndexOf(u8, "one two three four", "gour") == null);
- assert(indexOf(u8, "foo", "foo").? == 0);
- assert(lastIndexOf(u8, "foo", "foo").? == 0);
- assert(indexOf(u8, "foo", "fool") == null);
- assert(lastIndexOf(u8, "foo", "lfoo") == null);
- assert(lastIndexOf(u8, "foo", "fool") == null);
+ testing.expect(indexOf(u8, "one two three four", "four").? == 14);
+ testing.expect(lastIndexOf(u8, "one two three two four", "two").? == 14);
+ testing.expect(indexOf(u8, "one two three four", "gour") == null);
+ testing.expect(lastIndexOf(u8, "one two three four", "gour") == null);
+ testing.expect(indexOf(u8, "foo", "foo").? == 0);
+ testing.expect(lastIndexOf(u8, "foo", "foo").? == 0);
+ testing.expect(indexOf(u8, "foo", "fool") == null);
+ testing.expect(lastIndexOf(u8, "foo", "lfoo") == null);
+ testing.expect(lastIndexOf(u8, "foo", "fool") == null);
- assert(indexOf(u8, "foo foo", "foo").? == 0);
- assert(lastIndexOf(u8, "foo foo", "foo").? == 4);
- assert(lastIndexOfAny(u8, "boo, cat", "abo").? == 6);
- assert(lastIndexOfScalar(u8, "boo", 'o').? == 2);
+ testing.expect(indexOf(u8, "foo foo", "foo").? == 0);
+ testing.expect(lastIndexOf(u8, "foo foo", "foo").? == 4);
+ testing.expect(lastIndexOfAny(u8, "boo, cat", "abo").? == 6);
+ testing.expect(lastIndexOfScalar(u8, "boo", 'o').? == 2);
}
/// Reads an integer from memory with size equal to bytes.len.
@@ -504,34 +505,34 @@ test "comptime read/write int" {
var bytes: [2]u8 = undefined;
std.mem.writeIntLittle(u16, &bytes, 0x1234);
const result = std.mem.readIntBig(u16, &bytes);
- std.debug.assert(result == 0x3412);
+ testing.expect(result == 0x3412);
}
comptime {
var bytes: [2]u8 = undefined;
std.mem.writeIntBig(u16, &bytes, 0x1234);
const result = std.mem.readIntLittle(u16, &bytes);
- std.debug.assert(result == 0x3412);
+ testing.expect(result == 0x3412);
}
}
test "readIntBig and readIntLittle" {
- assert(readIntSliceBig(u0, []u8{}) == 0x0);
- assert(readIntSliceLittle(u0, []u8{}) == 0x0);
+ testing.expect(readIntSliceBig(u0, []u8{}) == 0x0);
+ testing.expect(readIntSliceLittle(u0, []u8{}) == 0x0);
- assert(readIntSliceBig(u8, []u8{0x32}) == 0x32);
- assert(readIntSliceLittle(u8, []u8{0x12}) == 0x12);
+ testing.expect(readIntSliceBig(u8, []u8{0x32}) == 0x32);
+ testing.expect(readIntSliceLittle(u8, []u8{0x12}) == 0x12);
- assert(readIntSliceBig(u16, []u8{ 0x12, 0x34 }) == 0x1234);
- assert(readIntSliceLittle(u16, []u8{ 0x12, 0x34 }) == 0x3412);
+ testing.expect(readIntSliceBig(u16, []u8{ 0x12, 0x34 }) == 0x1234);
+ testing.expect(readIntSliceLittle(u16, []u8{ 0x12, 0x34 }) == 0x3412);
- assert(readIntSliceBig(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024);
- assert(readIntSliceLittle(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec);
+ testing.expect(readIntSliceBig(u72, []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }) == 0x123456789abcdef024);
+ testing.expect(readIntSliceLittle(u72, []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }) == 0xfedcba9876543210ec);
- assert(readIntSliceBig(i8, []u8{0xff}) == -1);
- assert(readIntSliceLittle(i8, []u8{0xfe}) == -2);
+ testing.expect(readIntSliceBig(i8, []u8{0xff}) == -1);
+ testing.expect(readIntSliceLittle(i8, []u8{0xfe}) == -2);
- assert(readIntSliceBig(i16, []u8{ 0xff, 0xfd }) == -3);
- assert(readIntSliceLittle(i16, []u8{ 0xfc, 0xff }) == -4);
+ testing.expect(readIntSliceBig(i16, []u8{ 0xff, 0xfd }) == -3);
+ testing.expect(readIntSliceLittle(i16, []u8{ 0xfc, 0xff }) == -4);
}
/// Writes an integer to memory, storing it in twos-complement.
@@ -645,34 +646,34 @@ test "writeIntBig and writeIntLittle" {
var buf9: [9]u8 = undefined;
writeIntBig(u0, &buf0, 0x0);
- assert(eql_slice_u8(buf0[0..], []u8{}));
+ testing.expect(eql_slice_u8(buf0[0..], []u8{}));
writeIntLittle(u0, &buf0, 0x0);
- assert(eql_slice_u8(buf0[0..], []u8{}));
+ testing.expect(eql_slice_u8(buf0[0..], []u8{}));
writeIntBig(u8, &buf1, 0x12);
- assert(eql_slice_u8(buf1[0..], []u8{0x12}));
+ testing.expect(eql_slice_u8(buf1[0..], []u8{0x12}));
writeIntLittle(u8, &buf1, 0x34);
- assert(eql_slice_u8(buf1[0..], []u8{0x34}));
+ testing.expect(eql_slice_u8(buf1[0..], []u8{0x34}));
writeIntBig(u16, &buf2, 0x1234);
- assert(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 }));
+ testing.expect(eql_slice_u8(buf2[0..], []u8{ 0x12, 0x34 }));
writeIntLittle(u16, &buf2, 0x5678);
- assert(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 }));
+ testing.expect(eql_slice_u8(buf2[0..], []u8{ 0x78, 0x56 }));
writeIntBig(u72, &buf9, 0x123456789abcdef024);
- assert(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }));
+ testing.expect(eql_slice_u8(buf9[0..], []u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }));
writeIntLittle(u72, &buf9, 0xfedcba9876543210ec);
- assert(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }));
+ testing.expect(eql_slice_u8(buf9[0..], []u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }));
writeIntBig(i8, &buf1, -1);
- assert(eql_slice_u8(buf1[0..], []u8{0xff}));
+ testing.expect(eql_slice_u8(buf1[0..], []u8{0xff}));
writeIntLittle(i8, &buf1, -2);
- assert(eql_slice_u8(buf1[0..], []u8{0xfe}));
+ testing.expect(eql_slice_u8(buf1[0..], []u8{0xfe}));
writeIntBig(i16, &buf2, -3);
- assert(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd }));
+ testing.expect(eql_slice_u8(buf2[0..], []u8{ 0xff, 0xfd }));
writeIntLittle(i16, &buf2, -4);
- assert(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff }));
+ testing.expect(eql_slice_u8(buf2[0..], []u8{ 0xfc, 0xff }));
}
pub fn hash_slice_u8(k: []const u8) u32 {
@@ -706,46 +707,46 @@ pub fn tokenize(buffer: []const u8, delimiter_bytes: []const u8) TokenIterator {
test "mem.tokenize" {
var it = tokenize(" abc def ghi ", " ");
- assert(eql(u8, it.next().?, "abc"));
- assert(eql(u8, it.next().?, "def"));
- assert(eql(u8, it.next().?, "ghi"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "abc"));
+ testing.expect(eql(u8, it.next().?, "def"));
+ testing.expect(eql(u8, it.next().?, "ghi"));
+ testing.expect(it.next() == null);
it = tokenize("..\\bob", "\\");
- assert(eql(u8, it.next().?, ".."));
- assert(eql(u8, "..", "..\\bob"[0..it.index]));
- assert(eql(u8, it.next().?, "bob"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, ".."));
+ testing.expect(eql(u8, "..", "..\\bob"[0..it.index]));
+ testing.expect(eql(u8, it.next().?, "bob"));
+ testing.expect(it.next() == null);
it = tokenize("//a/b", "/");
- assert(eql(u8, it.next().?, "a"));
- assert(eql(u8, it.next().?, "b"));
- assert(eql(u8, "//a/b", "//a/b"[0..it.index]));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "a"));
+ testing.expect(eql(u8, it.next().?, "b"));
+ testing.expect(eql(u8, "//a/b", "//a/b"[0..it.index]));
+ testing.expect(it.next() == null);
it = tokenize("|", "|");
- assert(it.next() == null);
+ testing.expect(it.next() == null);
it = tokenize("", "|");
- assert(it.next() == null);
+ testing.expect(it.next() == null);
it = tokenize("hello", "");
- assert(eql(u8, it.next().?, "hello"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "hello"));
+ testing.expect(it.next() == null);
it = tokenize("hello", " ");
- assert(eql(u8, it.next().?, "hello"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "hello"));
+ testing.expect(it.next() == null);
}
test "mem.tokenize (multibyte)" {
var it = tokenize("a|b,c/d e", " /,|");
- assert(eql(u8, it.next().?, "a"));
- assert(eql(u8, it.next().?, "b"));
- assert(eql(u8, it.next().?, "c"));
- assert(eql(u8, it.next().?, "d"));
- assert(eql(u8, it.next().?, "e"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "a"));
+ testing.expect(eql(u8, it.next().?, "b"));
+ testing.expect(eql(u8, it.next().?, "c"));
+ testing.expect(eql(u8, it.next().?, "d"));
+ testing.expect(eql(u8, it.next().?, "e"));
+ testing.expect(it.next() == null);
}
/// Returns an iterator that iterates over the slices of `buffer` that
@@ -769,34 +770,34 @@ pub fn separate(buffer: []const u8, delimiter: []const u8) SplitIterator {
test "mem.separate" {
var it = separate("abc|def||ghi", "|");
- assert(eql(u8, it.next().?, "abc"));
- assert(eql(u8, it.next().?, "def"));
- assert(eql(u8, it.next().?, ""));
- assert(eql(u8, it.next().?, "ghi"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "abc"));
+ testing.expect(eql(u8, it.next().?, "def"));
+ testing.expect(eql(u8, it.next().?, ""));
+ testing.expect(eql(u8, it.next().?, "ghi"));
+ testing.expect(it.next() == null);
it = separate("", "|");
- assert(eql(u8, it.next().?, ""));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, ""));
+ testing.expect(it.next() == null);
it = separate("|", "|");
- assert(eql(u8, it.next().?, ""));
- assert(eql(u8, it.next().?, ""));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, ""));
+ testing.expect(eql(u8, it.next().?, ""));
+ testing.expect(it.next() == null);
it = separate("hello", " ");
- assert(eql(u8, it.next().?, "hello"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "hello"));
+ testing.expect(it.next() == null);
}
test "mem.separate (multibyte)" {
var it = separate("a, b ,, c, d, e", ", ");
- assert(eql(u8, it.next().?, "a"));
- assert(eql(u8, it.next().?, "b ,"));
- assert(eql(u8, it.next().?, "c"));
- assert(eql(u8, it.next().?, "d"));
- assert(eql(u8, it.next().?, "e"));
- assert(it.next() == null);
+ testing.expect(eql(u8, it.next().?, "a"));
+ testing.expect(eql(u8, it.next().?, "b ,"));
+ testing.expect(eql(u8, it.next().?, "c"));
+ testing.expect(eql(u8, it.next().?, "d"));
+ testing.expect(eql(u8, it.next().?, "e"));
+ testing.expect(it.next() == null);
}
pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
@@ -804,8 +805,8 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool
}
test "mem.startsWith" {
- assert(startsWith(u8, "Bob", "Bo"));
- assert(!startsWith(u8, "Needle in haystack", "haystack"));
+ testing.expect(startsWith(u8, "Bob", "Bo"));
+ testing.expect(!startsWith(u8, "Needle in haystack", "haystack"));
}
pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
@@ -813,8 +814,8 @@ pub fn endsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
}
test "mem.endsWith" {
- assert(endsWith(u8, "Needle in haystack", "haystack"));
- assert(!endsWith(u8, "Bob", "Bo"));
+ testing.expect(endsWith(u8, "Needle in haystack", "haystack"));
+ testing.expect(!endsWith(u8, "Bob", "Bo"));
}
pub const TokenIterator = struct {
@@ -913,15 +914,15 @@ pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []cons
test "mem.join" {
var buf: [1024]u8 = undefined;
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
- assert(eql(u8, try join(a, ",", [][]const u8{ "a", "b", "c" }), "a,b,c"));
- assert(eql(u8, try join(a, ",", [][]const u8{"a"}), "a"));
- assert(eql(u8, try join(a, ",", [][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c"));
+ testing.expect(eql(u8, try join(a, ",", [][]const u8{ "a", "b", "c" }), "a,b,c"));
+ testing.expect(eql(u8, try join(a, ",", [][]const u8{"a"}), "a"));
+ testing.expect(eql(u8, try join(a, ",", [][]const u8{ "a", "", "b", "", "c" }), "a,,b,,c"));
}
test "testStringEquality" {
- assert(eql(u8, "abcd", "abcd"));
- assert(!eql(u8, "abcdef", "abZdef"));
- assert(!eql(u8, "abcdefg", "abcdef"));
+ testing.expect(eql(u8, "abcd", "abcd"));
+ testing.expect(!eql(u8, "abcdef", "abZdef"));
+ testing.expect(!eql(u8, "abcdefg", "abcdef"));
}
test "testReadInt" {
@@ -936,12 +937,12 @@ fn testReadIntImpl() void {
0x56,
0x78,
};
- assert(readInt(u32, &bytes, builtin.Endian.Big) == 0x12345678);
- assert(readIntBig(u32, &bytes) == 0x12345678);
- assert(readIntBig(i32, &bytes) == 0x12345678);
- assert(readInt(u32, &bytes, builtin.Endian.Little) == 0x78563412);
- assert(readIntLittle(u32, &bytes) == 0x78563412);
- assert(readIntLittle(i32, &bytes) == 0x78563412);
+ testing.expect(readInt(u32, &bytes, builtin.Endian.Big) == 0x12345678);
+ testing.expect(readIntBig(u32, &bytes) == 0x12345678);
+ testing.expect(readIntBig(i32, &bytes) == 0x12345678);
+ testing.expect(readInt(u32, &bytes, builtin.Endian.Little) == 0x78563412);
+ testing.expect(readIntLittle(u32, &bytes) == 0x78563412);
+ testing.expect(readIntLittle(i32, &bytes) == 0x78563412);
}
{
const buf = []u8{
@@ -951,7 +952,7 @@ fn testReadIntImpl() void {
0x34,
};
const answer = readInt(u32, &buf, builtin.Endian.Big);
- assert(answer == 0x00001234);
+ testing.expect(answer == 0x00001234);
}
{
const buf = []u8{
@@ -961,17 +962,17 @@ fn testReadIntImpl() void {
0x00,
};
const answer = readInt(u32, &buf, builtin.Endian.Little);
- assert(answer == 0x00003412);
+ testing.expect(answer == 0x00003412);
}
{
const bytes = []u8{
0xff,
0xfe,
};
- assert(readIntBig(u16, &bytes) == 0xfffe);
- assert(readIntBig(i16, &bytes) == -0x0002);
- assert(readIntLittle(u16, &bytes) == 0xfeff);
- assert(readIntLittle(i16, &bytes) == -0x0101);
+ testing.expect(readIntBig(u16, &bytes) == 0xfffe);
+ testing.expect(readIntBig(i16, &bytes) == -0x0002);
+ testing.expect(readIntLittle(u16, &bytes) == 0xfeff);
+ testing.expect(readIntLittle(i16, &bytes) == -0x0101);
}
}
@@ -983,19 +984,19 @@ fn testWriteIntImpl() void {
var bytes: [8]u8 = undefined;
writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Big);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}));
writeIntSlice(u0, bytes[0..], 0, builtin.Endian.Little);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}));
writeIntSlice(u64, bytes[0..], 0x12345678CAFEBABE, builtin.Endian.Big);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x12,
0x34,
0x56,
@@ -1007,7 +1008,7 @@ fn testWriteIntImpl() void {
}));
writeIntSlice(u64, bytes[0..], 0xBEBAFECA78563412, builtin.Endian.Little);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x12,
0x34,
0x56,
@@ -1019,7 +1020,7 @@ fn testWriteIntImpl() void {
}));
writeIntSlice(u32, bytes[0..], 0x12345678, builtin.Endian.Big);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x00,
0x00,
0x00,
@@ -1031,7 +1032,7 @@ fn testWriteIntImpl() void {
}));
writeIntSlice(u32, bytes[0..], 0x78563412, builtin.Endian.Little);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x12,
0x34,
0x56,
@@ -1043,7 +1044,7 @@ fn testWriteIntImpl() void {
}));
writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Big);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x00,
0x00,
0x00,
@@ -1055,7 +1056,7 @@ fn testWriteIntImpl() void {
}));
writeIntSlice(u16, bytes[0..], 0x1234, builtin.Endian.Little);
- assert(eql(u8, bytes, []u8{
+ testing.expect(eql(u8, bytes, []u8{
0x34,
0x12,
0x00,
@@ -1076,7 +1077,7 @@ pub fn min(comptime T: type, slice: []const T) T {
}
test "mem.min" {
- assert(min(u8, "abcdefg") == 'a');
+ testing.expect(min(u8, "abcdefg") == 'a');
}
pub fn max(comptime T: type, slice: []const T) T {
@@ -1088,7 +1089,7 @@ pub fn max(comptime T: type, slice: []const T) T {
}
test "mem.max" {
- assert(max(u8, "abcdefg") == 'g');
+ testing.expect(max(u8, "abcdefg") == 'g');
}
pub fn swap(comptime T: type, a: *T, b: *T) void {
@@ -1116,7 +1117,7 @@ test "std.mem.reverse" {
};
reverse(i32, arr[0..]);
- assert(eql(i32, arr, []i32{
+ testing.expect(eql(i32, arr, []i32{
4,
2,
1,
@@ -1143,7 +1144,7 @@ test "std.mem.rotate" {
};
rotate(i32, arr[0..], 2);
- assert(eql(i32, arr, []i32{
+ testing.expect(eql(i32, arr, []i32{
1,
2,
4,
@@ -1225,12 +1226,12 @@ test "std.mem.asBytes" {
builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
};
- debug.assert(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes));
+ testing.expect(std.mem.eql(u8, asBytes(&deadbeef), deadbeef_bytes));
var codeface = u32(0xC0DEFACE);
for (asBytes(&codeface).*) |*b|
b.* = 0;
- debug.assert(codeface == 0);
+ testing.expect(codeface == 0);
const S = packed struct {
a: u8,
@@ -1245,7 +1246,7 @@ test "std.mem.asBytes" {
.c = 0xDE,
.d = 0xA1,
};
- debug.assert(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
+ testing.expect(std.mem.eql(u8, asBytes(&inst), "\xBE\xEF\xDE\xA1"));
}
///Given any value, returns a copy of its bytes in an array.
@@ -1256,14 +1257,14 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {
test "std.mem.toBytes" {
var my_bytes = toBytes(u32(0x12345678));
switch (builtin.endian) {
- builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")),
- builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")),
+ builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x12\x34\x56\x78")),
+ builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x78\x56\x34\x12")),
}
my_bytes[0] = '\x99';
switch (builtin.endian) {
- builtin.Endian.Big => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")),
- builtin.Endian.Little => debug.assert(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")),
+ builtin.Endian.Big => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x34\x56\x78")),
+ builtin.Endian.Little => testing.expect(std.mem.eql(u8, my_bytes, "\x99\x56\x34\x12")),
}
}
@@ -1292,17 +1293,17 @@ test "std.mem.bytesAsValue" {
builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
};
- debug.assert(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*);
+ testing.expect(deadbeef == bytesAsValue(u32, &deadbeef_bytes).*);
var codeface_bytes = switch (builtin.endian) {
builtin.Endian.Big => "\xC0\xDE\xFA\xCE",
builtin.Endian.Little => "\xCE\xFA\xDE\xC0",
};
var codeface = bytesAsValue(u32, &codeface_bytes);
- debug.assert(codeface.* == 0xC0DEFACE);
+ testing.expect(codeface.* == 0xC0DEFACE);
codeface.* = 0;
for (codeface_bytes) |b|
- debug.assert(b == 0);
+ testing.expect(b == 0);
const S = packed struct {
a: u8,
@@ -1319,7 +1320,7 @@ test "std.mem.bytesAsValue" {
};
const inst_bytes = "\xBE\xEF\xDE\xA1";
const inst2 = bytesAsValue(S, &inst_bytes);
- debug.assert(meta.eql(inst, inst2.*));
+ testing.expect(meta.eql(inst, inst2.*));
}
///Given a pointer to an array of bytes, returns a value of the specified type backed by a
@@ -1334,7 +1335,7 @@ test "std.mem.bytesToValue" {
};
const deadbeef = bytesToValue(u32, deadbeef_bytes);
- debug.assert(deadbeef == u32(0xDEADBEEF));
+ testing.expect(deadbeef == u32(0xDEADBEEF));
}
fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
@@ -1345,7 +1346,7 @@ fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
///Given a pointer to an array, returns a pointer to a portion of that array, preserving constness.
pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubArrayPtrReturnType(@typeOf(ptr), length) {
- debug.assert(start + length <= ptr.*.len);
+ assert(start + length <= ptr.*.len);
const ReturnType = SubArrayPtrReturnType(@typeOf(ptr), length);
const T = meta.Child(meta.Child(@typeOf(ptr)));
@@ -1355,14 +1356,14 @@ pub fn subArrayPtr(ptr: var, comptime start: usize, comptime length: usize) SubA
test "std.mem.subArrayPtr" {
const a1 = "abcdef";
const sub1 = subArrayPtr(&a1, 2, 3);
- debug.assert(std.mem.eql(u8, sub1.*, "cde"));
+ testing.expect(std.mem.eql(u8, sub1.*, "cde"));
var a2 = "abcdef";
var sub2 = subArrayPtr(&a2, 2, 3);
- debug.assert(std.mem.eql(u8, sub2, "cde"));
+ testing.expect(std.mem.eql(u8, sub2, "cde"));
sub2[1] = 'X';
- debug.assert(std.mem.eql(u8, a2, "abcXef"));
+ testing.expect(std.mem.eql(u8, a2, "abcXef"));
}
/// Round an address up to the nearest aligned address
@@ -1371,16 +1372,16 @@ pub fn alignForward(addr: usize, alignment: usize) usize {
}
test "std.mem.alignForward" {
- debug.assertOrPanic(alignForward(1, 1) == 1);
- debug.assertOrPanic(alignForward(2, 1) == 2);
- debug.assertOrPanic(alignForward(1, 2) == 2);
- debug.assertOrPanic(alignForward(2, 2) == 2);
- debug.assertOrPanic(alignForward(3, 2) == 4);
- debug.assertOrPanic(alignForward(4, 2) == 4);
- debug.assertOrPanic(alignForward(7, 8) == 8);
- debug.assertOrPanic(alignForward(8, 8) == 8);
- debug.assertOrPanic(alignForward(9, 8) == 16);
- debug.assertOrPanic(alignForward(15, 8) == 16);
- debug.assertOrPanic(alignForward(16, 8) == 16);
- debug.assertOrPanic(alignForward(17, 8) == 24);
+ testing.expect(alignForward(1, 1) == 1);
+ testing.expect(alignForward(2, 1) == 2);
+ testing.expect(alignForward(1, 2) == 2);
+ testing.expect(alignForward(2, 2) == 2);
+ testing.expect(alignForward(3, 2) == 4);
+ testing.expect(alignForward(4, 2) == 4);
+ testing.expect(alignForward(7, 8) == 8);
+ testing.expect(alignForward(8, 8) == 8);
+ testing.expect(alignForward(9, 8) == 16);
+ testing.expect(alignForward(15, 8) == 16);
+ testing.expect(alignForward(16, 8) == 16);
+ testing.expect(alignForward(17, 8) == 24);
}
diff --git a/std/meta/index.zig b/std/meta/index.zig
index 4d195a6a12..3f8ea762a6 100644
--- a/std/meta/index.zig
+++ b/std/meta/index.zig
@@ -3,6 +3,7 @@ const builtin = @import("builtin");
const debug = std.debug;
const mem = std.mem;
const math = std.math;
+const testing = std.testing;
pub const trait = @import("trait.zig");
@@ -64,16 +65,16 @@ test "std.meta.tagName" {
var u2a = U2{ .C = 0 };
var u2b = U2{ .D = 0 };
- debug.assert(mem.eql(u8, tagName(E1.A), "A"));
- debug.assert(mem.eql(u8, tagName(E1.B), "B"));
- debug.assert(mem.eql(u8, tagName(E2.C), "C"));
- debug.assert(mem.eql(u8, tagName(E2.D), "D"));
- debug.assert(mem.eql(u8, tagName(error.E), "E"));
- debug.assert(mem.eql(u8, tagName(error.F), "F"));
- debug.assert(mem.eql(u8, tagName(u1g), "G"));
- debug.assert(mem.eql(u8, tagName(u1h), "H"));
- debug.assert(mem.eql(u8, tagName(u2a), "C"));
- debug.assert(mem.eql(u8, tagName(u2b), "D"));
+ testing.expect(mem.eql(u8, tagName(E1.A), "A"));
+ testing.expect(mem.eql(u8, tagName(E1.B), "B"));
+ testing.expect(mem.eql(u8, tagName(E2.C), "C"));
+ testing.expect(mem.eql(u8, tagName(E2.D), "D"));
+ testing.expect(mem.eql(u8, tagName(error.E), "E"));
+ testing.expect(mem.eql(u8, tagName(error.F), "F"));
+ testing.expect(mem.eql(u8, tagName(u1g), "G"));
+ testing.expect(mem.eql(u8, tagName(u1h), "H"));
+ testing.expect(mem.eql(u8, tagName(u2a), "C"));
+ testing.expect(mem.eql(u8, tagName(u2b), "D"));
}
pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
@@ -90,9 +91,9 @@ test "std.meta.stringToEnum" {
A,
B,
};
- debug.assert(E1.A == stringToEnum(E1, "A").?);
- debug.assert(E1.B == stringToEnum(E1, "B").?);
- debug.assert(null == stringToEnum(E1, "C"));
+ testing.expect(E1.A == stringToEnum(E1, "A").?);
+ testing.expect(E1.B == stringToEnum(E1, "B").?);
+ testing.expect(null == stringToEnum(E1, "C"));
}
pub fn bitCount(comptime T: type) comptime_int {
@@ -104,8 +105,8 @@ pub fn bitCount(comptime T: type) comptime_int {
}
test "std.meta.bitCount" {
- debug.assert(bitCount(u8) == 8);
- debug.assert(bitCount(f32) == 32);
+ testing.expect(bitCount(u8) == 8);
+ testing.expect(bitCount(f32) == 32);
}
pub fn alignment(comptime T: type) comptime_int {
@@ -115,11 +116,11 @@ pub fn alignment(comptime T: type) comptime_int {
}
test "std.meta.alignment" {
- debug.assert(alignment(u8) == 1);
- debug.assert(alignment(*align(1) u8) == 1);
- debug.assert(alignment(*align(2) u8) == 2);
- debug.assert(alignment([]align(1) u8) == 1);
- debug.assert(alignment([]align(2) u8) == 2);
+ testing.expect(alignment(u8) == 1);
+ testing.expect(alignment(*align(1) u8) == 1);
+ testing.expect(alignment(*align(2) u8) == 2);
+ testing.expect(alignment([]align(1) u8) == 1);
+ testing.expect(alignment([]align(2) u8) == 2);
}
pub fn Child(comptime T: type) type {
@@ -133,11 +134,11 @@ pub fn Child(comptime T: type) type {
}
test "std.meta.Child" {
- debug.assert(Child([1]u8) == u8);
- debug.assert(Child(*u8) == u8);
- debug.assert(Child([]u8) == u8);
- debug.assert(Child(?u8) == u8);
- debug.assert(Child(promise->u8) == u8);
+ testing.expect(Child([1]u8) == u8);
+ testing.expect(Child(*u8) == u8);
+ testing.expect(Child([]u8) == u8);
+ testing.expect(Child(?u8) == u8);
+ testing.expect(Child(promise->u8) == u8);
}
pub fn containerLayout(comptime T: type) TypeInfo.ContainerLayout {
@@ -172,15 +173,15 @@ test "std.meta.containerLayout" {
a: u8,
};
- debug.assert(containerLayout(E1) == TypeInfo.ContainerLayout.Auto);
- debug.assert(containerLayout(E2) == TypeInfo.ContainerLayout.Packed);
- debug.assert(containerLayout(E3) == TypeInfo.ContainerLayout.Extern);
- debug.assert(containerLayout(S1) == TypeInfo.ContainerLayout.Auto);
- debug.assert(containerLayout(S2) == TypeInfo.ContainerLayout.Packed);
- debug.assert(containerLayout(S3) == TypeInfo.ContainerLayout.Extern);
- debug.assert(containerLayout(U1) == TypeInfo.ContainerLayout.Auto);
- debug.assert(containerLayout(U2) == TypeInfo.ContainerLayout.Packed);
- debug.assert(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
+ testing.expect(containerLayout(E1) == TypeInfo.ContainerLayout.Auto);
+ testing.expect(containerLayout(E2) == TypeInfo.ContainerLayout.Packed);
+ testing.expect(containerLayout(E3) == TypeInfo.ContainerLayout.Extern);
+ testing.expect(containerLayout(S1) == TypeInfo.ContainerLayout.Auto);
+ testing.expect(containerLayout(S2) == TypeInfo.ContainerLayout.Packed);
+ testing.expect(containerLayout(S3) == TypeInfo.ContainerLayout.Extern);
+ testing.expect(containerLayout(U1) == TypeInfo.ContainerLayout.Auto);
+ testing.expect(containerLayout(U2) == TypeInfo.ContainerLayout.Packed);
+ testing.expect(containerLayout(U3) == TypeInfo.ContainerLayout.Extern);
}
pub fn definitions(comptime T: type) []TypeInfo.Definition {
@@ -214,8 +215,8 @@ test "std.meta.definitions" {
};
inline for (defs) |def| {
- debug.assert(def.len == 1);
- debug.assert(comptime mem.eql(u8, def[0].name, "a"));
+ testing.expect(def.len == 1);
+ testing.expect(comptime mem.eql(u8, def[0].name, "a"));
}
}
@@ -250,8 +251,8 @@ test "std.meta.definitionInfo" {
};
inline for (infos) |info| {
- debug.assert(comptime mem.eql(u8, info.name, "a"));
- debug.assert(!info.is_pub);
+ testing.expect(comptime mem.eql(u8, info.name, "a"));
+ testing.expect(!info.is_pub);
}
}
@@ -288,16 +289,16 @@ test "std.meta.fields" {
const sf = comptime fields(S1);
const uf = comptime fields(U1);
- debug.assert(e1f.len == 1);
- debug.assert(e2f.len == 1);
- debug.assert(sf.len == 1);
- debug.assert(uf.len == 1);
- debug.assert(mem.eql(u8, e1f[0].name, "A"));
- debug.assert(mem.eql(u8, e2f[0].name, "A"));
- debug.assert(mem.eql(u8, sf[0].name, "a"));
- debug.assert(mem.eql(u8, uf[0].name, "a"));
- debug.assert(comptime sf[0].field_type == u8);
- debug.assert(comptime uf[0].field_type == u8);
+ testing.expect(e1f.len == 1);
+ testing.expect(e2f.len == 1);
+ testing.expect(sf.len == 1);
+ testing.expect(uf.len == 1);
+ testing.expect(mem.eql(u8, e1f[0].name, "A"));
+ testing.expect(mem.eql(u8, e2f[0].name, "A"));
+ testing.expect(mem.eql(u8, sf[0].name, "a"));
+ testing.expect(mem.eql(u8, uf[0].name, "a"));
+ testing.expect(comptime sf[0].field_type == u8);
+ testing.expect(comptime uf[0].field_type == u8);
}
pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typeInfo(T)) {
@@ -332,12 +333,12 @@ test "std.meta.fieldInfo" {
const sf = comptime fieldInfo(S1, "a");
const uf = comptime fieldInfo(U1, "a");
- debug.assert(mem.eql(u8, e1f.name, "A"));
- debug.assert(mem.eql(u8, e2f.name, "A"));
- debug.assert(mem.eql(u8, sf.name, "a"));
- debug.assert(mem.eql(u8, uf.name, "a"));
- debug.assert(comptime sf.field_type == u8);
- debug.assert(comptime uf.field_type == u8);
+ testing.expect(mem.eql(u8, e1f.name, "A"));
+ testing.expect(mem.eql(u8, e2f.name, "A"));
+ testing.expect(mem.eql(u8, sf.name, "a"));
+ testing.expect(mem.eql(u8, uf.name, "a"));
+ testing.expect(comptime sf.field_type == u8);
+ testing.expect(comptime uf.field_type == u8);
}
pub fn TagType(comptime T: type) type {
@@ -358,8 +359,8 @@ test "std.meta.TagType" {
D: u16,
};
- debug.assert(TagType(E) == u8);
- debug.assert(TagType(U) == E);
+ testing.expect(TagType(E) == u8);
+ testing.expect(TagType(U) == E);
}
///Returns the active tag of a tagged union
@@ -380,18 +381,18 @@ test "std.meta.activeTag" {
};
var u = U{ .Int = 32 };
- debug.assert(activeTag(u) == UE.Int);
+ testing.expect(activeTag(u) == UE.Int);
u = U{ .Float = 112.9876 };
- debug.assert(activeTag(u) == UE.Float);
+ testing.expect(activeTag(u) == UE.Float);
}
///Given a tagged union type, and an enum, return the type of the union
/// field corresponding to the enum tag.
pub fn TagPayloadType(comptime U: type, tag: var) type {
const Tag = @typeOf(tag);
- debug.assert(trait.is(builtin.TypeId.Union)(U));
- debug.assert(trait.is(builtin.TypeId.Enum)(Tag));
+ testing.expect(trait.is(builtin.TypeId.Union)(U));
+ testing.expect(trait.is(builtin.TypeId.Enum)(Tag));
const info = @typeInfo(U).Union;
@@ -410,7 +411,7 @@ test "std.meta.TagPayloadType" {
};
const MovedEvent = TagPayloadType(Event, Event.Moved);
var e: Event = undefined;
- debug.assert(MovedEvent == @typeOf(e.Moved));
+ testing.expect(MovedEvent == @typeOf(e.Moved));
}
///Compares two of any type for equality. Containers are compared on a field-by-field basis,
@@ -509,19 +510,19 @@ test "std.meta.eql" {
const u_2 = U{ .s = s_1 };
const u_3 = U{ .f = 24 };
- debug.assert(eql(s_1, s_3));
- debug.assert(eql(&s_1, &s_1));
- debug.assert(!eql(&s_1, &s_3));
- debug.assert(eql(u_1, u_3));
- debug.assert(!eql(u_1, u_2));
+ testing.expect(eql(s_1, s_3));
+ testing.expect(eql(&s_1, &s_1));
+ testing.expect(!eql(&s_1, &s_3));
+ testing.expect(eql(u_1, u_3));
+ testing.expect(!eql(u_1, u_2));
var a1 = "abcdef";
var a2 = "abcdef";
var a3 = "ghijkl";
- debug.assert(eql(a1, a2));
- debug.assert(!eql(a1, a3));
- debug.assert(!eql(a1[0..], a2[0..]));
+ testing.expect(eql(a1, a2));
+ testing.expect(!eql(a1, a3));
+ testing.expect(!eql(a1[0..], a2[0..]));
const EU = struct {
fn tst(err: bool) !u8 {
@@ -530,9 +531,9 @@ test "std.meta.eql" {
}
};
- debug.assert(eql(EU.tst(true), EU.tst(true)));
- debug.assert(eql(EU.tst(false), EU.tst(false)));
- debug.assert(!eql(EU.tst(false), EU.tst(true)));
+ testing.expect(eql(EU.tst(true), EU.tst(true)));
+ testing.expect(eql(EU.tst(false), EU.tst(false)));
+ testing.expect(!eql(EU.tst(false), EU.tst(true)));
}
test "intToEnum with error return" {
@@ -546,9 +547,9 @@ test "intToEnum with error return" {
var zero: u8 = 0;
var one: u16 = 1;
- debug.assert(intToEnum(E1, zero) catch unreachable == E1.A);
- debug.assert(intToEnum(E2, one) catch unreachable == E2.B);
- debug.assertError(intToEnum(E1, one), error.InvalidEnumTag);
+ testing.expect(intToEnum(E1, zero) catch unreachable == E1.A);
+ testing.expect(intToEnum(E2, one) catch unreachable == E2.B);
+ testing.expectError(error.InvalidEnumTag, intToEnum(E1, one));
}
pub const IntToEnumError = error{InvalidEnumTag};
diff --git a/std/meta/trait.zig b/std/meta/trait.zig
index c9d9e971c9..7fca5f4dcd 100644
--- a/std/meta/trait.zig
+++ b/std/meta/trait.zig
@@ -2,6 +2,7 @@ const std = @import("../index.zig");
const builtin = @import("builtin");
const mem = std.mem;
const debug = std.debug;
+const testing = std.testing;
const warn = debug.warn;
const meta = @import("index.zig");
@@ -50,8 +51,8 @@ test "std.meta.trait.multiTrait" {
hasField("x"),
hasField("y"),
});
- debug.assert(isVector(Vector2));
- debug.assert(!isVector(u8));
+ testing.expect(isVector(Vector2));
+ testing.expect(!isVector(u8));
}
///
@@ -85,12 +86,12 @@ test "std.meta.trait.hasDef" {
const value = u8(16);
};
- debug.assert(hasDef("value")(TestStruct));
- debug.assert(!hasDef("value")(TestStructFail));
- debug.assert(!hasDef("value")(*TestStruct));
- debug.assert(!hasDef("value")(**TestStructFail));
- debug.assert(!hasDef("x")(TestStruct));
- debug.assert(!hasDef("value")(u8));
+ testing.expect(hasDef("value")(TestStruct));
+ testing.expect(!hasDef("value")(TestStructFail));
+ testing.expect(!hasDef("value")(*TestStruct));
+ testing.expect(!hasDef("value")(**TestStructFail));
+ testing.expect(!hasDef("x")(TestStruct));
+ testing.expect(!hasDef("value")(u8));
}
///
@@ -111,9 +112,9 @@ test "std.meta.trait.hasFn" {
pub fn useless() void {}
};
- debug.assert(hasFn("useless")(TestStruct));
- debug.assert(!hasFn("append")(TestStruct));
- debug.assert(!hasFn("useless")(u8));
+ testing.expect(hasFn("useless")(TestStruct));
+ testing.expect(!hasFn("append")(TestStruct));
+ testing.expect(!hasFn("useless")(u8));
}
///
@@ -143,11 +144,11 @@ test "std.meta.trait.hasField" {
value: u32,
};
- debug.assert(hasField("value")(TestStruct));
- debug.assert(!hasField("value")(*TestStruct));
- debug.assert(!hasField("x")(TestStruct));
- debug.assert(!hasField("x")(**TestStruct));
- debug.assert(!hasField("value")(u8));
+ testing.expect(hasField("value")(TestStruct));
+ testing.expect(!hasField("value")(*TestStruct));
+ testing.expect(!hasField("x")(TestStruct));
+ testing.expect(!hasField("x")(**TestStruct));
+ testing.expect(!hasField("value")(u8));
}
///
@@ -161,11 +162,11 @@ pub fn is(comptime id: builtin.TypeId) TraitFn {
}
test "std.meta.trait.is" {
- debug.assert(is(builtin.TypeId.Int)(u8));
- debug.assert(!is(builtin.TypeId.Int)(f32));
- debug.assert(is(builtin.TypeId.Pointer)(*u8));
- debug.assert(is(builtin.TypeId.Void)(void));
- debug.assert(!is(builtin.TypeId.Optional)(anyerror));
+ testing.expect(is(builtin.TypeId.Int)(u8));
+ testing.expect(!is(builtin.TypeId.Int)(f32));
+ testing.expect(is(builtin.TypeId.Pointer)(*u8));
+ testing.expect(is(builtin.TypeId.Void)(void));
+ testing.expect(!is(builtin.TypeId.Optional)(anyerror));
}
///
@@ -180,9 +181,9 @@ pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
}
test "std.meta.trait.isPtrTo" {
- debug.assert(!isPtrTo(builtin.TypeId.Struct)(struct {}));
- debug.assert(isPtrTo(builtin.TypeId.Struct)(*struct {}));
- debug.assert(!isPtrTo(builtin.TypeId.Struct)(**struct {}));
+ testing.expect(!isPtrTo(builtin.TypeId.Struct)(struct {}));
+ testing.expect(isPtrTo(builtin.TypeId.Struct)(*struct {}));
+ testing.expect(!isPtrTo(builtin.TypeId.Struct)(**struct {}));
}
///////////Strait trait Fns
@@ -205,9 +206,9 @@ test "std.meta.trait.isExtern" {
const TestExStruct = extern struct {};
const TestStruct = struct {};
- debug.assert(isExtern(TestExStruct));
- debug.assert(!isExtern(TestStruct));
- debug.assert(!isExtern(u8));
+ testing.expect(isExtern(TestExStruct));
+ testing.expect(!isExtern(TestStruct));
+ testing.expect(!isExtern(u8));
}
///
@@ -226,9 +227,9 @@ test "std.meta.trait.isPacked" {
const TestPStruct = packed struct {};
const TestStruct = struct {};
- debug.assert(isPacked(TestPStruct));
- debug.assert(!isPacked(TestStruct));
- debug.assert(!isPacked(u8));
+ testing.expect(isPacked(TestPStruct));
+ testing.expect(!isPacked(TestStruct));
+ testing.expect(!isPacked(u8));
}
///
@@ -240,10 +241,10 @@ pub fn isUnsignedInt(comptime T: type) bool {
}
test "isUnsignedInt" {
- debug.assert(isUnsignedInt(u32) == true);
- debug.assert(isUnsignedInt(comptime_int) == false);
- debug.assert(isUnsignedInt(i64) == false);
- debug.assert(isUnsignedInt(f64) == false);
+ testing.expect(isUnsignedInt(u32) == true);
+ testing.expect(isUnsignedInt(comptime_int) == false);
+ testing.expect(isUnsignedInt(i64) == false);
+ testing.expect(isUnsignedInt(f64) == false);
}
///
@@ -256,10 +257,10 @@ pub fn isSignedInt(comptime T: type) bool {
}
test "isSignedInt" {
- debug.assert(isSignedInt(u32) == false);
- debug.assert(isSignedInt(comptime_int) == true);
- debug.assert(isSignedInt(i64) == true);
- debug.assert(isSignedInt(f64) == false);
+ testing.expect(isSignedInt(u32) == false);
+ testing.expect(isSignedInt(comptime_int) == true);
+ testing.expect(isSignedInt(i64) == true);
+ testing.expect(isSignedInt(f64) == false);
}
///
@@ -273,9 +274,9 @@ pub fn isSingleItemPtr(comptime T: type) bool {
test "std.meta.trait.isSingleItemPtr" {
const array = []u8{0} ** 10;
- debug.assert(isSingleItemPtr(@typeOf(&array[0])));
- debug.assert(!isSingleItemPtr(@typeOf(array)));
- debug.assert(!isSingleItemPtr(@typeOf(array[0..1])));
+ testing.expect(isSingleItemPtr(@typeOf(&array[0])));
+ testing.expect(!isSingleItemPtr(@typeOf(array)));
+ testing.expect(!isSingleItemPtr(@typeOf(array[0..1])));
}
///
@@ -290,9 +291,9 @@ pub fn isManyItemPtr(comptime T: type) bool {
test "std.meta.trait.isManyItemPtr" {
const array = []u8{0} ** 10;
const mip = @ptrCast([*]const u8, &array[0]);
- debug.assert(isManyItemPtr(@typeOf(mip)));
- debug.assert(!isManyItemPtr(@typeOf(array)));
- debug.assert(!isManyItemPtr(@typeOf(array[0..1])));
+ testing.expect(isManyItemPtr(@typeOf(mip)));
+ testing.expect(!isManyItemPtr(@typeOf(array)));
+ testing.expect(!isManyItemPtr(@typeOf(array[0..1])));
}
///
@@ -306,9 +307,9 @@ pub fn isSlice(comptime T: type) bool {
test "std.meta.trait.isSlice" {
const array = []u8{0} ** 10;
- debug.assert(isSlice(@typeOf(array[0..])));
- debug.assert(!isSlice(@typeOf(array)));
- debug.assert(!isSlice(@typeOf(&array[0])));
+ testing.expect(isSlice(@typeOf(array[0..])));
+ testing.expect(!isSlice(@typeOf(array)));
+ testing.expect(!isSlice(@typeOf(&array[0])));
}
///
@@ -328,10 +329,10 @@ test "std.meta.trait.isIndexable" {
const array = []u8{0} ** 10;
const slice = array[0..];
- debug.assert(isIndexable(@typeOf(array)));
- debug.assert(isIndexable(@typeOf(&array)));
- debug.assert(isIndexable(@typeOf(slice)));
- debug.assert(!isIndexable(meta.Child(@typeOf(slice))));
+ testing.expect(isIndexable(@typeOf(array)));
+ testing.expect(isIndexable(@typeOf(&array)));
+ testing.expect(isIndexable(@typeOf(slice)));
+ testing.expect(!isIndexable(meta.Child(@typeOf(slice))));
}
///
@@ -347,13 +348,13 @@ test "std.meta.trait.isNumber" {
number: u8,
};
- debug.assert(isNumber(u32));
- debug.assert(isNumber(f32));
- debug.assert(isNumber(u64));
- debug.assert(isNumber(@typeOf(102)));
- debug.assert(isNumber(@typeOf(102.123)));
- debug.assert(!isNumber([]u8));
- debug.assert(!isNumber(NotANumber));
+ testing.expect(isNumber(u32));
+ testing.expect(isNumber(f32));
+ testing.expect(isNumber(u64));
+ testing.expect(isNumber(@typeOf(102)));
+ testing.expect(isNumber(@typeOf(102.123)));
+ testing.expect(!isNumber([]u8));
+ testing.expect(!isNumber(NotANumber));
}
///
@@ -366,10 +367,10 @@ pub fn isConstPtr(comptime T: type) bool {
test "std.meta.trait.isConstPtr" {
var t = u8(0);
const c = u8(0);
- debug.assert(isConstPtr(*const @typeOf(t)));
- debug.assert(isConstPtr(@typeOf(&c)));
- debug.assert(!isConstPtr(*@typeOf(t)));
- debug.assert(!isConstPtr(@typeOf(6)));
+ testing.expect(isConstPtr(*const @typeOf(t)));
+ testing.expect(isConstPtr(@typeOf(&c)));
+ testing.expect(!isConstPtr(*@typeOf(t)));
+ testing.expect(!isConstPtr(@typeOf(6)));
}
///
@@ -393,8 +394,8 @@ test "std.meta.trait.isContainer" {
B,
};
- debug.assert(isContainer(TestStruct));
- debug.assert(isContainer(TestUnion));
- debug.assert(isContainer(TestEnum));
- debug.assert(!isContainer(u8));
+ testing.expect(isContainer(TestStruct));
+ testing.expect(isContainer(TestUnion));
+ testing.expect(isContainer(TestEnum));
+ testing.expect(!isContainer(u8));
}
diff --git a/std/mutex.zig b/std/mutex.zig
index 54173fa38a..a13b1c06c7 100644
--- a/std/mutex.zig
+++ b/std/mutex.zig
@@ -2,7 +2,7 @@ const std = @import("index.zig");
const builtin = @import("builtin");
const AtomicOrder = builtin.AtomicOrder;
const AtomicRmwOp = builtin.AtomicRmwOp;
-const assert = std.debug.assert;
+const testing = std.testing;
const SpinLock = std.SpinLock;
const linux = std.os.linux;
const windows = std.os.windows;
@@ -149,7 +149,7 @@ test "std.Mutex" {
if (builtin.single_threaded) {
worker(&context);
- std.debug.assertOrPanic(context.data == TestContext.incr_count);
+ testing.expect(context.data == TestContext.incr_count);
} else {
const thread_count = 10;
var threads: [thread_count]*std.os.Thread = undefined;
@@ -159,7 +159,7 @@ test "std.Mutex" {
for (threads) |t|
t.wait();
- std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ testing.expect(context.data == thread_count * TestContext.incr_count);
}
}
diff --git a/std/os/child_process.zig b/std/os/child_process.zig
index 6635b76976..1da0b3492b 100644
--- a/std/os/child_process.zig
+++ b/std/os/child_process.zig
@@ -7,7 +7,6 @@ const posix = os.posix;
const windows = os.windows;
const mem = std.mem;
const debug = std.debug;
-const assert = debug.assert;
const BufMap = std.BufMap;
const Buffer = std.Buffer;
const builtin = @import("builtin");
diff --git a/std/os/index.zig b/std/os/index.zig
index 8e9876c36b..f52c12c2b6 100644
--- a/std/os/index.zig
+++ b/std/os/index.zig
@@ -91,6 +91,7 @@ pub const GetAppDataDirError = @import("get_app_data_dir.zig").GetAppDataDirErro
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const c = std.c;
@@ -172,7 +173,7 @@ test "os.getRandomBytes" {
try getRandomBytes(buf_b[0..]);
// Check if random (not 100% conclusive)
- assert(!mem.eql(u8, buf_a, buf_b));
+ testing.expect(!mem.eql(u8, buf_a, buf_b));
}
/// Raises a signal in the current kernel thread, ending its execution.
@@ -828,7 +829,7 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
test "os.getEnvVarOwned" {
var ga = debug.global_allocator;
- debug.assertError(getEnvVarOwned(ga, "BADENV"), error.EnvironmentVariableNotFound);
+ testing.expectError(error.EnvironmentVariableNotFound, getEnvVarOwned(ga, "BADENV"));
}
/// Caller must free the returned memory.
@@ -2219,9 +2220,9 @@ fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []cons
var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
for (expected_args) |expected_arg| {
const arg = it.next(debug.global_allocator).? catch unreachable;
- assert(mem.eql(u8, arg, expected_arg));
+ testing.expectEqualSlices(u8, expected_arg, arg);
}
- assert(it.next(debug.global_allocator) == null);
+ testing.expect(it.next(debug.global_allocator) == null);
}
// TODO make this a build variable that you can set
diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig
index 4de26012c7..40fb7823d2 100644
--- a/std/os/linux/test.zig
+++ b/std/os/linux/test.zig
@@ -1,19 +1,19 @@
const std = @import("../../index.zig");
const builtin = @import("builtin");
const linux = std.os.linux;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
test "getpid" {
- assert(linux.getpid() != 0);
+ expect(linux.getpid() != 0);
}
test "timer" {
const epoll_fd = linux.epoll_create();
var err = linux.getErrno(epoll_fd);
- assert(err == 0);
+ expect(err == 0);
const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);
- assert(linux.getErrno(timer_fd) == 0);
+ expect(linux.getErrno(timer_fd) == 0);
const time_interval = linux.timespec{
.tv_sec = 0,
@@ -26,7 +26,7 @@ test "timer" {
};
err = linux.timerfd_settime(@intCast(i32, timer_fd), 0, &new_time, null);
- assert(err == 0);
+ expect(err == 0);
var event = linux.epoll_event{
.events = linux.EPOLLIN | linux.EPOLLOUT | linux.EPOLLET,
@@ -34,7 +34,7 @@ test "timer" {
};
err = linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event);
- assert(err == 0);
+ expect(err == 0);
const events_one: linux.epoll_event = undefined;
var events = []linux.epoll_event{events_one} ** 8;
diff --git a/std/os/path.zig b/std/os/path.zig
index 266a77b97c..5ba345fceb 100644
--- a/std/os/path.zig
+++ b/std/os/path.zig
@@ -3,6 +3,7 @@ const builtin = @import("builtin");
const Os = builtin.Os;
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const mem = std.mem;
const fmt = std.fmt;
const Allocator = mem.Allocator;
@@ -94,14 +95,14 @@ fn testJoinWindows(paths: []const []const u8, expected: []const u8) void {
var buf: [1024]u8 = undefined;
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
const actual = joinWindows(a, paths) catch @panic("fail");
- debug.assertOrPanic(mem.eql(u8, actual, expected));
+ testing.expectEqualSlices(u8, expected, actual);
}
fn testJoinPosix(paths: []const []const u8, expected: []const u8) void {
var buf: [1024]u8 = undefined;
const a = &std.heap.FixedBufferAllocator.init(&buf).allocator;
const actual = joinPosix(a, paths) catch @panic("fail");
- debug.assertOrPanic(mem.eql(u8, actual, expected));
+ testing.expectEqualSlices(u8, expected, actual);
}
test "os.path.join" {
@@ -193,11 +194,11 @@ test "os.path.isAbsolutePosix" {
}
fn testIsAbsoluteWindows(path: []const u8, expected_result: bool) void {
- assert(isAbsoluteWindows(path) == expected_result);
+ testing.expectEqual(expected_result, isAbsoluteWindows(path));
}
fn testIsAbsolutePosix(path: []const u8, expected_result: bool) void {
- assert(isAbsolutePosix(path) == expected_result);
+ testing.expectEqual(expected_result, isAbsolutePosix(path));
}
pub const WindowsPath = struct {
@@ -281,33 +282,33 @@ pub fn windowsParsePath(path: []const u8) WindowsPath {
test "os.path.windowsParsePath" {
{
const parsed = windowsParsePath("//a/b");
- assert(parsed.is_abs);
- assert(parsed.kind == WindowsPath.Kind.NetworkShare);
- assert(mem.eql(u8, parsed.disk_designator, "//a/b"));
+ testing.expect(parsed.is_abs);
+ testing.expect(parsed.kind == WindowsPath.Kind.NetworkShare);
+ testing.expect(mem.eql(u8, parsed.disk_designator, "//a/b"));
}
{
const parsed = windowsParsePath("\\\\a\\b");
- assert(parsed.is_abs);
- assert(parsed.kind == WindowsPath.Kind.NetworkShare);
- assert(mem.eql(u8, parsed.disk_designator, "\\\\a\\b"));
+ testing.expect(parsed.is_abs);
+ testing.expect(parsed.kind == WindowsPath.Kind.NetworkShare);
+ testing.expect(mem.eql(u8, parsed.disk_designator, "\\\\a\\b"));
}
{
const parsed = windowsParsePath("\\\\a\\");
- assert(!parsed.is_abs);
- assert(parsed.kind == WindowsPath.Kind.None);
- assert(mem.eql(u8, parsed.disk_designator, ""));
+ testing.expect(!parsed.is_abs);
+ testing.expect(parsed.kind == WindowsPath.Kind.None);
+ testing.expect(mem.eql(u8, parsed.disk_designator, ""));
}
{
const parsed = windowsParsePath("/usr/local");
- assert(parsed.is_abs);
- assert(parsed.kind == WindowsPath.Kind.None);
- assert(mem.eql(u8, parsed.disk_designator, ""));
+ testing.expect(parsed.is_abs);
+ testing.expect(parsed.kind == WindowsPath.Kind.None);
+ testing.expect(mem.eql(u8, parsed.disk_designator, ""));
}
{
const parsed = windowsParsePath("c:../");
- assert(!parsed.is_abs);
- assert(parsed.kind == WindowsPath.Kind.Drive);
- assert(mem.eql(u8, parsed.disk_designator, "c:"));
+ testing.expect(!parsed.is_abs);
+ testing.expect(parsed.kind == WindowsPath.Kind.Drive);
+ testing.expect(mem.eql(u8, parsed.disk_designator, "c:"));
}
}
@@ -642,10 +643,10 @@ test "os.path.resolve" {
if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
cwd[0] = asciiUpper(cwd[0]);
}
- assert(mem.eql(u8, testResolveWindows([][]const u8{"."}), cwd));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{"."}), cwd));
} else {
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "a/b/c/", "../../.." }), cwd));
- assert(mem.eql(u8, testResolvePosix([][]const u8{"."}), cwd));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "a/b/c/", "../../.." }), cwd));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{"."}), cwd));
}
}
@@ -662,7 +663,7 @@ test "os.path.resolveWindows" {
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
- assert(mem.eql(u8, result, expected));
+ testing.expect(mem.eql(u8, result, expected));
}
{
const result = testResolveWindows([][]const u8{ "usr/local", "lib\\zig" });
@@ -673,36 +674,36 @@ test "os.path.resolveWindows" {
if (parsed_cwd.kind == WindowsPath.Kind.Drive) {
expected[0] = asciiUpper(parsed_cwd.disk_designator[0]);
}
- assert(mem.eql(u8, result, expected));
+ testing.expect(mem.eql(u8, result, expected));
}
}
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//" }), "C:\\"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//dir" }), "C:\\dir"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir"));
- assert(mem.eql(u8, testResolveWindows([][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:\\a\\b\\c", "/hi", "ok" }), "C:\\hi\\ok"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "c:../a" }), "C:\\blah\\a"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/blah\\blah", "d:/games", "C:../a" }), "C:\\blah\\a"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "d:\\a/b\\c/d", "\\e.exe" }), "D:\\e.exe"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/ignore", "c:/some/file" }), "C:\\some\\file"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "d:/ignore", "d:some/dir//" }), "D:\\ignore\\some\\dir"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "//server/share", "..", "relative\\" }), "\\\\server\\share\\relative"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//" }), "C:\\"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//dir" }), "C:\\dir"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server/share" }), "\\\\server\\share\\"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "//server//share" }), "\\\\server\\share\\"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "c:/", "///some//dir" }), "C:\\some\\dir"));
+ testing.expect(mem.eql(u8, testResolveWindows([][]const u8{ "C:\\foo\\tmp.3\\", "..\\tmp.3\\cycles\\root.js" }), "C:\\foo\\tmp.3\\cycles\\root.js"));
}
test "os.path.resolvePosix" {
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c" }), "/a/b/c"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b/c", "..", "../" }), "/a"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/", "..", ".." }), "/"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{"/a/b/c/"}), "/a/b/c"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c" }), "/a/b/c"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b", "c", "//d", "e///" }), "/d/e"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/a/b/c", "..", "../" }), "/a"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/", "..", ".." }), "/"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{"/a/b/c/"}), "/a/b/c"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "../", "file/" }), "/var/file"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "/../", "file/" }), "/file"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute"));
- assert(mem.eql(u8, testResolvePosix([][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "../", "file/" }), "/var/file"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/var/lib", "/../", "file/" }), "/file"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/some/dir", ".", "/absolute/" }), "/absolute"));
+ testing.expect(mem.eql(u8, testResolvePosix([][]const u8{ "/foo/tmp.3/", "../tmp.3/cycles/root.js" }), "/foo/tmp.3/cycles/root.js"));
}
fn testResolveWindows(paths: []const []const u8) []u8 {
@@ -833,17 +834,17 @@ test "os.path.dirnameWindows" {
fn testDirnamePosix(input: []const u8, expected_output: ?[]const u8) void {
if (dirnamePosix(input)) |output| {
- assert(mem.eql(u8, output, expected_output.?));
+ testing.expect(mem.eql(u8, output, expected_output.?));
} else {
- assert(expected_output == null);
+ testing.expect(expected_output == null);
}
}
fn testDirnameWindows(input: []const u8, expected_output: ?[]const u8) void {
if (dirnameWindows(input)) |output| {
- assert(mem.eql(u8, output, expected_output.?));
+ testing.expect(mem.eql(u8, output, expected_output.?));
} else {
- assert(expected_output == null);
+ testing.expect(expected_output == null);
}
}
@@ -948,15 +949,15 @@ test "os.path.basename" {
}
fn testBasename(input: []const u8, expected_output: []const u8) void {
- assert(mem.eql(u8, basename(input), expected_output));
+ testing.expectEqualSlices(u8, expected_output, basename(input));
}
fn testBasenamePosix(input: []const u8, expected_output: []const u8) void {
- assert(mem.eql(u8, basenamePosix(input), expected_output));
+ testing.expectEqualSlices(u8, expected_output, basenamePosix(input));
}
fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
- assert(mem.eql(u8, basenameWindows(input), expected_output));
+ testing.expectEqualSlices(u8, expected_output, basenameWindows(input));
}
/// Returns the relative path from `from` to `to`. If `from` and `to` each
@@ -1131,12 +1132,12 @@ test "os.path.relative" {
fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) void {
const result = relativePosix(debug.global_allocator, from, to) catch unreachable;
- assert(mem.eql(u8, result, expected_output));
+ testing.expectEqualSlices(u8, expected_output, result);
}
fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) void {
const result = relativeWindows(debug.global_allocator, from, to) catch unreachable;
- assert(mem.eql(u8, result, expected_output));
+ testing.expectEqualSlices(u8, expected_output, result);
}
pub const RealError = error{
@@ -1283,5 +1284,5 @@ pub fn realAlloc(allocator: *Allocator, pathname: []const u8) ![]u8 {
test "os.path.real" {
// at least call it so it gets compiled
var buf: [os.MAX_PATH_BYTES]u8 = undefined;
- std.debug.assertError(real(&buf, "definitely_bogus_does_not_exist1234"), error.FileNotFound);
+ testing.expectError(error.FileNotFound, real(&buf, "definitely_bogus_does_not_exist1234"));
}
diff --git a/std/os/test.zig b/std/os/test.zig
index bd9148d1b1..b2a4d96651 100644
--- a/std/os/test.zig
+++ b/std/os/test.zig
@@ -1,6 +1,6 @@
const std = @import("../index.zig");
const os = std.os;
-const assert = std.debug.assert;
+const expect = std.testing.expect;
const io = std.io;
const mem = std.mem;
@@ -18,7 +18,7 @@ test "makePath, put some files in it, deleteTree" {
if (os.Dir.open(a, "os_test_tmp")) |dir| {
@panic("expected error");
} else |err| {
- assert(err == error.FileNotFound);
+ expect(err == error.FileNotFound);
}
}
@@ -27,7 +27,7 @@ test "access file" {
if (os.File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt")) |ok| {
@panic("expected error");
} else |err| {
- assert(err == error.FileNotFound);
+ expect(err == error.FileNotFound);
}
try io.writeFile("os_test_tmp" ++ os.path.sep_str ++ "file.txt", "");
@@ -47,9 +47,9 @@ test "std.os.Thread.getCurrentId" {
const thread_id = thread.handle();
thread.wait();
switch (builtin.os) {
- builtin.Os.windows => assert(os.Thread.getCurrentId() != thread_current_id),
+ builtin.Os.windows => expect(os.Thread.getCurrentId() != thread_current_id),
else => {
- assert(thread_current_id == thread_id);
+ expect(thread_current_id == thread_id);
},
}
}
@@ -69,7 +69,7 @@ test "spawn threads" {
thread3.wait();
thread4.wait();
- assert(shared_ctx == 4);
+ expect(shared_ctx == 4);
}
fn start1(ctx: void) u8 {
@@ -83,7 +83,7 @@ fn start2(ctx: *i32) u8 {
test "cpu count" {
const cpu_count = try std.os.cpuCount(a);
- assert(cpu_count >= 1);
+ expect(cpu_count >= 1);
}
test "AtomicFile" {
@@ -101,7 +101,7 @@ test "AtomicFile" {
try af.finish();
}
const content = try io.readFileAlloc(allocator, test_out_file);
- assert(mem.eql(u8, content, test_content));
+ expect(mem.eql(u8, content, test_content));
try os.deleteFile(test_out_file);
}
diff --git a/std/os/time.zig b/std/os/time.zig
index 4b11a69376..638fb41ff1 100644
--- a/std/os/time.zig
+++ b/std/os/time.zig
@@ -2,6 +2,7 @@ const std = @import("../index.zig");
const builtin = @import("builtin");
const Os = builtin.Os;
const debug = std.debug;
+const testing = std.testing;
const windows = std.os.windows;
const linux = std.os.linux;
@@ -270,7 +271,7 @@ test "os.time.timestamp" {
sleep(ns_per_ms);
const time_1 = milliTimestamp();
const interval = time_1 - time_0;
- debug.assert(interval > 0 and interval < margin);
+ testing.expect(interval > 0 and interval < margin);
}
test "os.time.Timer" {
@@ -280,11 +281,11 @@ test "os.time.Timer" {
var timer = try Timer.start();
sleep(10 * ns_per_ms);
const time_0 = timer.read();
- debug.assert(time_0 > 0 and time_0 < margin);
+ testing.expect(time_0 > 0 and time_0 < margin);
const time_1 = timer.lap();
- debug.assert(time_1 >= time_0);
+ testing.expect(time_1 >= time_0);
timer.reset();
- debug.assert(timer.read() < time_1);
+ testing.expect(timer.read() < time_1);
}
diff --git a/std/rand/index.zig b/std/rand/index.zig
index c335063e64..12dd763aee 100644
--- a/std/rand/index.zig
+++ b/std/rand/index.zig
@@ -17,6 +17,7 @@
const std = @import("../index.zig");
const builtin = @import("builtin");
const assert = std.debug.assert;
+const expect = std.testing.expect;
const mem = std.mem;
const math = std.math;
const ziggurat = @import("ziggurat.zig");
@@ -316,43 +317,43 @@ test "Random int" {
fn testRandomInt() void {
var r = SequentialPrng.init();
- assert(r.random.int(u0) == 0);
+ expect(r.random.int(u0) == 0);
r.next_value = 0;
- assert(r.random.int(u1) == 0);
- assert(r.random.int(u1) == 1);
- assert(r.random.int(u2) == 2);
- assert(r.random.int(u2) == 3);
- assert(r.random.int(u2) == 0);
+ expect(r.random.int(u1) == 0);
+ expect(r.random.int(u1) == 1);
+ expect(r.random.int(u2) == 2);
+ expect(r.random.int(u2) == 3);
+ expect(r.random.int(u2) == 0);
r.next_value = 0xff;
- assert(r.random.int(u8) == 0xff);
+ expect(r.random.int(u8) == 0xff);
r.next_value = 0x11;
- assert(r.random.int(u8) == 0x11);
+ expect(r.random.int(u8) == 0x11);
r.next_value = 0xff;
- assert(r.random.int(u32) == 0xffffffff);
+ expect(r.random.int(u32) == 0xffffffff);
r.next_value = 0x11;
- assert(r.random.int(u32) == 0x11111111);
+ expect(r.random.int(u32) == 0x11111111);
r.next_value = 0xff;
- assert(r.random.int(i32) == -1);
+ expect(r.random.int(i32) == -1);
r.next_value = 0x11;
- assert(r.random.int(i32) == 0x11111111);
+ expect(r.random.int(i32) == 0x11111111);
r.next_value = 0xff;
- assert(r.random.int(i8) == -1);
+ expect(r.random.int(i8) == -1);
r.next_value = 0x11;
- assert(r.random.int(i8) == 0x11);
+ expect(r.random.int(i8) == 0x11);
r.next_value = 0xff;
- assert(r.random.int(u33) == 0x1ffffffff);
+ expect(r.random.int(u33) == 0x1ffffffff);
r.next_value = 0xff;
- assert(r.random.int(i1) == -1);
+ expect(r.random.int(i1) == -1);
r.next_value = 0xff;
- assert(r.random.int(i2) == -1);
+ expect(r.random.int(i2) == -1);
r.next_value = 0xff;
- assert(r.random.int(i33) == -1);
+ expect(r.random.int(i33) == -1);
}
test "Random boolean" {
@@ -361,10 +362,10 @@ test "Random boolean" {
}
fn testRandomBoolean() void {
var r = SequentialPrng.init();
- assert(r.random.boolean() == false);
- assert(r.random.boolean() == true);
- assert(r.random.boolean() == false);
- assert(r.random.boolean() == true);
+ expect(r.random.boolean() == false);
+ expect(r.random.boolean() == true);
+ expect(r.random.boolean() == false);
+ expect(r.random.boolean() == true);
}
test "Random intLessThan" {
@@ -375,36 +376,36 @@ test "Random intLessThan" {
fn testRandomIntLessThan() void {
var r = SequentialPrng.init();
r.next_value = 0xff;
- assert(r.random.uintLessThan(u8, 4) == 3);
- assert(r.next_value == 0);
- assert(r.random.uintLessThan(u8, 4) == 0);
- assert(r.next_value == 1);
+ expect(r.random.uintLessThan(u8, 4) == 3);
+ expect(r.next_value == 0);
+ expect(r.random.uintLessThan(u8, 4) == 0);
+ expect(r.next_value == 1);
r.next_value = 0;
- assert(r.random.uintLessThan(u64, 32) == 0);
+ expect(r.random.uintLessThan(u64, 32) == 0);
// trigger the bias rejection code path
r.next_value = 0;
- assert(r.random.uintLessThan(u8, 3) == 0);
+ expect(r.random.uintLessThan(u8, 3) == 0);
// verify we incremented twice
- assert(r.next_value == 2);
+ expect(r.next_value == 2);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(u8, 0, 0x80) == 0x7f);
+ expect(r.random.intRangeLessThan(u8, 0, 0x80) == 0x7f);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(u8, 0x7f, 0xff) == 0xfe);
+ expect(r.random.intRangeLessThan(u8, 0x7f, 0xff) == 0xfe);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(i8, 0, 0x40) == 0x3f);
+ expect(r.random.intRangeLessThan(i8, 0, 0x40) == 0x3f);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(i8, -0x40, 0x40) == 0x3f);
+ expect(r.random.intRangeLessThan(i8, -0x40, 0x40) == 0x3f);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(i8, -0x80, 0) == -1);
+ expect(r.random.intRangeLessThan(i8, -0x80, 0) == -1);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(i3, -4, 0) == -1);
+ expect(r.random.intRangeLessThan(i3, -4, 0) == -1);
r.next_value = 0xff;
- assert(r.random.intRangeLessThan(i3, -2, 2) == 1);
+ expect(r.random.intRangeLessThan(i3, -2, 2) == 1);
}
test "Random intAtMost" {
@@ -415,34 +416,34 @@ test "Random intAtMost" {
fn testRandomIntAtMost() void {
var r = SequentialPrng.init();
r.next_value = 0xff;
- assert(r.random.uintAtMost(u8, 3) == 3);
- assert(r.next_value == 0);
- assert(r.random.uintAtMost(u8, 3) == 0);
+ expect(r.random.uintAtMost(u8, 3) == 3);
+ expect(r.next_value == 0);
+ expect(r.random.uintAtMost(u8, 3) == 0);
// trigger the bias rejection code path
r.next_value = 0;
- assert(r.random.uintAtMost(u8, 2) == 0);
+ expect(r.random.uintAtMost(u8, 2) == 0);
// verify we incremented twice
- assert(r.next_value == 2);
+ expect(r.next_value == 2);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(u8, 0, 0x7f) == 0x7f);
+ expect(r.random.intRangeAtMost(u8, 0, 0x7f) == 0x7f);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(u8, 0x7f, 0xfe) == 0xfe);
+ expect(r.random.intRangeAtMost(u8, 0x7f, 0xfe) == 0xfe);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(i8, 0, 0x3f) == 0x3f);
+ expect(r.random.intRangeAtMost(i8, 0, 0x3f) == 0x3f);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(i8, -0x40, 0x3f) == 0x3f);
+ expect(r.random.intRangeAtMost(i8, -0x40, 0x3f) == 0x3f);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(i8, -0x80, -1) == -1);
+ expect(r.random.intRangeAtMost(i8, -0x80, -1) == -1);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(i3, -4, -1) == -1);
+ expect(r.random.intRangeAtMost(i3, -4, -1) == -1);
r.next_value = 0xff;
- assert(r.random.intRangeAtMost(i3, -2, 1) == 1);
+ expect(r.random.intRangeAtMost(i3, -2, 1) == 1);
- assert(r.random.uintAtMost(u0, 0) == 0);
+ expect(r.random.uintAtMost(u0, 0) == 0);
}
test "Random Biased" {
@@ -450,30 +451,30 @@ test "Random Biased" {
// Not thoroughly checking the logic here.
// Just want to execute all the paths with different types.
- assert(r.random.uintLessThanBiased(u1, 1) == 0);
- assert(r.random.uintLessThanBiased(u32, 10) < 10);
- assert(r.random.uintLessThanBiased(u64, 20) < 20);
+ expect(r.random.uintLessThanBiased(u1, 1) == 0);
+ expect(r.random.uintLessThanBiased(u32, 10) < 10);
+ expect(r.random.uintLessThanBiased(u64, 20) < 20);
- assert(r.random.uintAtMostBiased(u0, 0) == 0);
- assert(r.random.uintAtMostBiased(u1, 0) <= 0);
- assert(r.random.uintAtMostBiased(u32, 10) <= 10);
- assert(r.random.uintAtMostBiased(u64, 20) <= 20);
+ expect(r.random.uintAtMostBiased(u0, 0) == 0);
+ expect(r.random.uintAtMostBiased(u1, 0) <= 0);
+ expect(r.random.uintAtMostBiased(u32, 10) <= 10);
+ expect(r.random.uintAtMostBiased(u64, 20) <= 20);
- assert(r.random.intRangeLessThanBiased(u1, 0, 1) == 0);
- assert(r.random.intRangeLessThanBiased(i1, -1, 0) == -1);
- assert(r.random.intRangeLessThanBiased(u32, 10, 20) >= 10);
- assert(r.random.intRangeLessThanBiased(i32, 10, 20) >= 10);
- assert(r.random.intRangeLessThanBiased(u64, 20, 40) >= 20);
- assert(r.random.intRangeLessThanBiased(i64, 20, 40) >= 20);
+ expect(r.random.intRangeLessThanBiased(u1, 0, 1) == 0);
+ expect(r.random.intRangeLessThanBiased(i1, -1, 0) == -1);
+ expect(r.random.intRangeLessThanBiased(u32, 10, 20) >= 10);
+ expect(r.random.intRangeLessThanBiased(i32, 10, 20) >= 10);
+ expect(r.random.intRangeLessThanBiased(u64, 20, 40) >= 20);
+ expect(r.random.intRangeLessThanBiased(i64, 20, 40) >= 20);
// uncomment for broken module error:
- //assert(r.random.intRangeAtMostBiased(u0, 0, 0) == 0);
- assert(r.random.intRangeAtMostBiased(u1, 0, 1) >= 0);
- assert(r.random.intRangeAtMostBiased(i1, -1, 0) >= -1);
- assert(r.random.intRangeAtMostBiased(u32, 10, 20) >= 10);
- assert(r.random.intRangeAtMostBiased(i32, 10, 20) >= 10);
- assert(r.random.intRangeAtMostBiased(u64, 20, 40) >= 20);
- assert(r.random.intRangeAtMostBiased(i64, 20, 40) >= 20);
+ //expect(r.random.intRangeAtMostBiased(u0, 0, 0) == 0);
+ expect(r.random.intRangeAtMostBiased(u1, 0, 1) >= 0);
+ expect(r.random.intRangeAtMostBiased(i1, -1, 0) >= -1);
+ expect(r.random.intRangeAtMostBiased(u32, 10, 20) >= 10);
+ expect(r.random.intRangeAtMostBiased(i32, 10, 20) >= 10);
+ expect(r.random.intRangeAtMostBiased(u64, 20, 40) >= 20);
+ expect(r.random.intRangeAtMostBiased(i64, 20, 40) >= 20);
}
// Generator to extend 64-bit seed values into longer sequences.
@@ -510,7 +511,7 @@ test "splitmix64 sequence" {
};
for (seq) |s| {
- std.debug.assert(s == r.next());
+ expect(s == r.next());
}
}
@@ -603,7 +604,7 @@ test "pcg sequence" {
};
for (seq) |s| {
- std.debug.assert(s == r.next());
+ expect(s == r.next());
}
}
@@ -712,7 +713,7 @@ test "xoroshiro sequence" {
};
for (seq1) |s| {
- std.debug.assert(s == r.next());
+ expect(s == r.next());
}
r.jump();
@@ -727,7 +728,7 @@ test "xoroshiro sequence" {
};
for (seq2) |s| {
- std.debug.assert(s == r.next());
+ expect(s == r.next());
}
}
@@ -930,7 +931,7 @@ test "isaac64 sequence" {
};
for (seq) |s| {
- std.debug.assert(s == r.next());
+ expect(s == r.next());
}
}
@@ -941,12 +942,12 @@ test "Random float" {
var i: usize = 0;
while (i < 1000) : (i += 1) {
const val1 = prng.random.float(f32);
- std.debug.assert(val1 >= 0.0);
- std.debug.assert(val1 < 1.0);
+ expect(val1 >= 0.0);
+ expect(val1 < 1.0);
const val2 = prng.random.float(f64);
- std.debug.assert(val2 >= 0.0);
- std.debug.assert(val2 < 1.0);
+ expect(val2 >= 0.0);
+ expect(val2 < 1.0);
}
}
@@ -960,12 +961,12 @@ test "Random shuffle" {
while (i < 1000) : (i += 1) {
prng.random.shuffle(u8, seq[0..]);
seen[seq[0]] = true;
- std.debug.assert(sumArray(seq[0..]) == 10);
+ expect(sumArray(seq[0..]) == 10);
}
// we should see every entry at the head at least once
for (seen) |e| {
- std.debug.assert(e == true);
+ expect(e == true);
}
}
diff --git a/std/rb.zig b/std/rb.zig
index beb7f3aae9..27e60dca6a 100644
--- a/std/rb.zig
+++ b/std/rb.zig
@@ -1,5 +1,6 @@
const std = @import("index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem; // For mem.Compare
const Color = enum(u1) {
@@ -533,13 +534,13 @@ test "rb" {
_ = tree.insert(&ns[8].node);
_ = tree.insert(&ns[9].node);
tree.remove(&ns[3].node);
- assert(tree.insert(&dup.node) == &ns[7].node);
+ testing.expect(tree.insert(&dup.node) == &ns[7].node);
try tree.replace(&ns[7].node, &dup.node);
var num: *testNumber = undefined;
num = testGetNumber(tree.first().?);
while (num.node.next() != null) {
- assert(testGetNumber(num.node.next().?).value > num.value);
+ testing.expect(testGetNumber(num.node.next().?).value > num.value);
num = testGetNumber(num.node.next().?);
}
}
diff --git a/std/segmented_list.zig b/std/segmented_list.zig
index d786e0becd..26b7fa48f5 100644
--- a/std/segmented_list.zig
+++ b/std/segmented_list.zig
@@ -1,5 +1,6 @@
const std = @import("index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const Allocator = std.mem.Allocator;
// Imagine that `fn at(self: *Self, index: usize) &T` is a customer asking for a box
@@ -352,14 +353,14 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
var i: usize = 0;
while (i < 100) : (i += 1) {
try list.push(@intCast(i32, i + 1));
- assert(list.len == i + 1);
+ testing.expect(list.len == i + 1);
}
}
{
var i: usize = 0;
while (i < 100) : (i += 1) {
- assert(list.at(i).* == @intCast(i32, i + 1));
+ testing.expect(list.at(i).* == @intCast(i32, i + 1));
}
}
@@ -368,35 +369,35 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
var x: i32 = 0;
while (it.next()) |item| {
x += 1;
- assert(item.* == x);
+ testing.expect(item.* == x);
}
- assert(x == 100);
+ testing.expect(x == 100);
while (it.prev()) |item| : (x -= 1) {
- assert(item.* == x);
+ testing.expect(item.* == x);
}
- assert(x == 0);
+ testing.expect(x == 0);
}
- assert(list.pop().? == 100);
- assert(list.len == 99);
+ testing.expect(list.pop().? == 100);
+ testing.expect(list.len == 99);
try list.pushMany([]i32{
1,
2,
3,
});
- assert(list.len == 102);
- assert(list.pop().? == 3);
- assert(list.pop().? == 2);
- assert(list.pop().? == 1);
- assert(list.len == 99);
+ testing.expect(list.len == 102);
+ testing.expect(list.pop().? == 3);
+ testing.expect(list.pop().? == 2);
+ testing.expect(list.pop().? == 1);
+ testing.expect(list.len == 99);
try list.pushMany([]const i32{});
- assert(list.len == 99);
+ testing.expect(list.len == 99);
var i: i32 = 99;
while (list.pop()) |item| : (i -= 1) {
- assert(item == i);
+ testing.expect(item == i);
list.shrinkCapacity(list.len);
}
}
diff --git a/std/sort.zig b/std/sort.zig
index f29f51b7cf..86a6724fee 100644
--- a/std/sort.zig
+++ b/std/sort.zig
@@ -1,5 +1,6 @@
const std = @import("index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
const math = std.math;
const builtin = @import("builtin");
@@ -1031,8 +1032,8 @@ fn testStableSort() void {
for (cases) |*case| {
insertionSort(IdAndValue, (case.*)[0..], cmpByValue);
for (case.*) |item, i| {
- assert(item.id == expected[i].id);
- assert(item.value == expected[i].value);
+ testing.expect(item.id == expected[i].id);
+ testing.expect(item.value == expected[i].value);
}
}
}
@@ -1077,7 +1078,7 @@ test "std.sort" {
const slice = buf[0..case[0].len];
mem.copy(u8, slice, case[0]);
sort(u8, slice, asc(u8));
- assert(mem.eql(u8, slice, case[1]));
+ testing.expect(mem.eql(u8, slice, case[1]));
}
const i32cases = [][]const []const i32{
@@ -1112,7 +1113,7 @@ test "std.sort" {
const slice = buf[0..case[0].len];
mem.copy(i32, slice, case[0]);
sort(i32, slice, asc(i32));
- assert(mem.eql(i32, slice, case[1]));
+ testing.expect(mem.eql(i32, slice, case[1]));
}
}
@@ -1149,7 +1150,7 @@ test "std.sort descending" {
const slice = buf[0..case[0].len];
mem.copy(i32, slice, case[0]);
sort(i32, slice, desc(i32));
- assert(mem.eql(i32, slice, case[1]));
+ testing.expect(mem.eql(i32, slice, case[1]));
}
}
@@ -1157,7 +1158,7 @@ test "another sort case" {
var arr = []i32{ 5, 3, 1, 2, 4 };
sort(i32, arr[0..], asc(i32));
- assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));
+ testing.expect(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));
}
test "sort fuzz testing" {
@@ -1185,9 +1186,9 @@ fn fuzzTest(rng: *std.rand.Random) void {
var index: usize = 1;
while (index < array.len) : (index += 1) {
if (array[index].value == array[index - 1].value) {
- assert(array[index].id > array[index - 1].id);
+ testing.expect(array[index].id > array[index - 1].id);
} else {
- assert(array[index].value > array[index - 1].value);
+ testing.expect(array[index].value > array[index - 1].value);
}
}
}
diff --git a/std/special/compiler_rt/divti3_test.zig b/std/special/compiler_rt/divti3_test.zig
index eef5a9b812..e1c1babae7 100644
--- a/std/special/compiler_rt/divti3_test.zig
+++ b/std/special/compiler_rt/divti3_test.zig
@@ -1,9 +1,9 @@
const __divti3 = @import("divti3.zig").__divti3;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__divti3(a: i128, b: i128, expected: i128) void {
const x = __divti3(a, b);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "divti3" {
diff --git a/std/special/compiler_rt/extendXfYf2_test.zig b/std/special/compiler_rt/extendXfYf2_test.zig
index 9969607011..050a799823 100644
--- a/std/special/compiler_rt/extendXfYf2_test.zig
+++ b/std/special/compiler_rt/extendXfYf2_test.zig
@@ -1,7 +1,6 @@
const __extenddftf2 = @import("extendXfYf2.zig").__extenddftf2;
const __extendhfsf2 = @import("extendXfYf2.zig").__extendhfsf2;
const __extendsftf2 = @import("extendXfYf2.zig").__extendsftf2;
-const assert = @import("std").debug.assert;
fn test__extenddftf2(a: f64, expectedHi: u64, expectedLo: u64) void {
const x = __extenddftf2(a);
diff --git a/std/special/compiler_rt/fixdfdi_test.zig b/std/special/compiler_rt/fixdfdi_test.zig
index 72bcf452d2..a55245210b 100644
--- a/std/special/compiler_rt/fixdfdi_test.zig
+++ b/std/special/compiler_rt/fixdfdi_test.zig
@@ -1,13 +1,13 @@
const __fixdfdi = @import("fixdfdi.zig").__fixdfdi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixdfdi(a: f64, expected: i64) void {
const x = __fixdfdi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixdfdi" {
diff --git a/std/special/compiler_rt/fixdfsi_test.zig b/std/special/compiler_rt/fixdfsi_test.zig
index 147f46534a..5cb9bef1d9 100644
--- a/std/special/compiler_rt/fixdfsi_test.zig
+++ b/std/special/compiler_rt/fixdfsi_test.zig
@@ -1,13 +1,13 @@
const __fixdfsi = @import("fixdfsi.zig").__fixdfsi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixdfsi(a: f64, expected: i32) void {
const x = __fixdfsi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixdfsi" {
diff --git a/std/special/compiler_rt/fixdfti_test.zig b/std/special/compiler_rt/fixdfti_test.zig
index 5bb3a31a3f..5fbcd206ed 100644
--- a/std/special/compiler_rt/fixdfti_test.zig
+++ b/std/special/compiler_rt/fixdfti_test.zig
@@ -1,13 +1,13 @@
const __fixdfti = @import("fixdfti.zig").__fixdfti;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixdfti(a: f64, expected: i128) void {
const x = __fixdfti(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixdfti" {
diff --git a/std/special/compiler_rt/fixint_test.zig b/std/special/compiler_rt/fixint_test.zig
index 6676bddbee..0b0936d1e2 100644
--- a/std/special/compiler_rt/fixint_test.zig
+++ b/std/special/compiler_rt/fixint_test.zig
@@ -1,7 +1,7 @@
const is_test = @import("builtin").is_test;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
const fixint = @import("fixint.zig").fixint;
@@ -9,7 +9,7 @@ const fixint = @import("fixint.zig").fixint;
fn test__fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t, expected: fixint_t) void {
const x = fixint(fp_t, fixint_t, a);
//warn("a={} x={}:{x} expected={}:{x})\n", a, x, x, expected, expected);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixint.i1" {
diff --git a/std/special/compiler_rt/fixsfdi_test.zig b/std/special/compiler_rt/fixsfdi_test.zig
index ef8e50e38e..276670421b 100644
--- a/std/special/compiler_rt/fixsfdi_test.zig
+++ b/std/special/compiler_rt/fixsfdi_test.zig
@@ -1,13 +1,13 @@
const __fixsfdi = @import("fixsfdi.zig").__fixsfdi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixsfdi(a: f32, expected: i64) void {
const x = __fixsfdi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixsfdi" {
diff --git a/std/special/compiler_rt/fixsfsi_test.zig b/std/special/compiler_rt/fixsfsi_test.zig
index d5c0ba5c2a..a05c15e536 100644
--- a/std/special/compiler_rt/fixsfsi_test.zig
+++ b/std/special/compiler_rt/fixsfsi_test.zig
@@ -1,13 +1,13 @@
const __fixsfsi = @import("fixsfsi.zig").__fixsfsi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixsfsi(a: f32, expected: i32) void {
const x = __fixsfsi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixsfsi" {
diff --git a/std/special/compiler_rt/fixsfti_test.zig b/std/special/compiler_rt/fixsfti_test.zig
index d693143b18..32410e2dee 100644
--- a/std/special/compiler_rt/fixsfti_test.zig
+++ b/std/special/compiler_rt/fixsfti_test.zig
@@ -1,13 +1,13 @@
const __fixsfti = @import("fixsfti.zig").__fixsfti;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixsfti(a: f32, expected: i128) void {
const x = __fixsfti(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixsfti" {
diff --git a/std/special/compiler_rt/fixtfdi_test.zig b/std/special/compiler_rt/fixtfdi_test.zig
index 58ccbc5832..a31bcb7d6f 100644
--- a/std/special/compiler_rt/fixtfdi_test.zig
+++ b/std/special/compiler_rt/fixtfdi_test.zig
@@ -1,13 +1,13 @@
const __fixtfdi = @import("fixtfdi.zig").__fixtfdi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixtfdi(a: f128, expected: i64) void {
const x = __fixtfdi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixtfdi" {
diff --git a/std/special/compiler_rt/fixtfsi_test.zig b/std/special/compiler_rt/fixtfsi_test.zig
index 7a3cc7f46c..7b37e4e09f 100644
--- a/std/special/compiler_rt/fixtfsi_test.zig
+++ b/std/special/compiler_rt/fixtfsi_test.zig
@@ -1,13 +1,13 @@
const __fixtfsi = @import("fixtfsi.zig").__fixtfsi;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixtfsi(a: f128, expected: i32) void {
const x = __fixtfsi(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixtfsi" {
diff --git a/std/special/compiler_rt/fixtfti_test.zig b/std/special/compiler_rt/fixtfti_test.zig
index 520009486a..be461a1c91 100644
--- a/std/special/compiler_rt/fixtfti_test.zig
+++ b/std/special/compiler_rt/fixtfti_test.zig
@@ -1,13 +1,13 @@
const __fixtfti = @import("fixtfti.zig").__fixtfti;
const std = @import("std");
const math = std.math;
-const assert = std.debug.assert;
+const testing = std.testing;
const warn = std.debug.warn;
fn test__fixtfti(a: f128, expected: i128) void {
const x = __fixtfti(a);
//warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixtfti" {
diff --git a/std/special/compiler_rt/fixunsdfdi_test.zig b/std/special/compiler_rt/fixunsdfdi_test.zig
index e59d09f8de..67eeb70520 100644
--- a/std/special/compiler_rt/fixunsdfdi_test.zig
+++ b/std/special/compiler_rt/fixunsdfdi_test.zig
@@ -1,9 +1,9 @@
const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunsdfdi(a: f64, expected: u64) void {
const x = __fixunsdfdi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunsdfdi" {
diff --git a/std/special/compiler_rt/fixunsdfsi_test.zig b/std/special/compiler_rt/fixunsdfsi_test.zig
index db6e32e23d..c006473fb9 100644
--- a/std/special/compiler_rt/fixunsdfsi_test.zig
+++ b/std/special/compiler_rt/fixunsdfsi_test.zig
@@ -1,9 +1,9 @@
const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunsdfsi(a: f64, expected: u32) void {
const x = __fixunsdfsi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunsdfsi" {
diff --git a/std/special/compiler_rt/fixunsdfti_test.zig b/std/special/compiler_rt/fixunsdfti_test.zig
index 7f7b083d19..8241900692 100644
--- a/std/special/compiler_rt/fixunsdfti_test.zig
+++ b/std/special/compiler_rt/fixunsdfti_test.zig
@@ -1,9 +1,9 @@
const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunsdfti(a: f64, expected: u128) void {
const x = __fixunsdfti(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunsdfti" {
diff --git a/std/special/compiler_rt/fixunssfdi_test.zig b/std/special/compiler_rt/fixunssfdi_test.zig
index e4e6c1736d..e2089822d2 100644
--- a/std/special/compiler_rt/fixunssfdi_test.zig
+++ b/std/special/compiler_rt/fixunssfdi_test.zig
@@ -1,9 +1,9 @@
const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunssfdi(a: f32, expected: u64) void {
const x = __fixunssfdi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunssfdi" {
diff --git a/std/special/compiler_rt/fixunssfsi_test.zig b/std/special/compiler_rt/fixunssfsi_test.zig
index 614c648dfe..4aee84d2d2 100644
--- a/std/special/compiler_rt/fixunssfsi_test.zig
+++ b/std/special/compiler_rt/fixunssfsi_test.zig
@@ -1,9 +1,9 @@
const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunssfsi(a: f32, expected: u32) void {
const x = __fixunssfsi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunssfsi" {
diff --git a/std/special/compiler_rt/fixunssfti_test.zig b/std/special/compiler_rt/fixunssfti_test.zig
index 43ad527f53..4cb27cbb8a 100644
--- a/std/special/compiler_rt/fixunssfti_test.zig
+++ b/std/special/compiler_rt/fixunssfti_test.zig
@@ -1,9 +1,9 @@
const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunssfti(a: f32, expected: u128) void {
const x = __fixunssfti(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunssfti" {
diff --git a/std/special/compiler_rt/fixunstfdi_test.zig b/std/special/compiler_rt/fixunstfdi_test.zig
index 6b1b9b7bd2..0d47641c09 100644
--- a/std/special/compiler_rt/fixunstfdi_test.zig
+++ b/std/special/compiler_rt/fixunstfdi_test.zig
@@ -1,9 +1,9 @@
const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunstfdi(a: f128, expected: u64) void {
const x = __fixunstfdi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "fixunstfdi" {
diff --git a/std/special/compiler_rt/fixunstfsi_test.zig b/std/special/compiler_rt/fixunstfsi_test.zig
index f47fcb3c86..e709636912 100644
--- a/std/special/compiler_rt/fixunstfsi_test.zig
+++ b/std/special/compiler_rt/fixunstfsi_test.zig
@@ -1,9 +1,9 @@
const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunstfsi(a: f128, expected: u32) void {
const x = __fixunstfsi(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
diff --git a/std/special/compiler_rt/fixunstfti_test.zig b/std/special/compiler_rt/fixunstfti_test.zig
index 9128ac6c08..833e4779dd 100644
--- a/std/special/compiler_rt/fixunstfti_test.zig
+++ b/std/special/compiler_rt/fixunstfti_test.zig
@@ -1,9 +1,9 @@
const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__fixunstfti(a: f128, expected: u128) void {
const x = __fixunstfti(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));
diff --git a/std/special/compiler_rt/floattidf_test.zig b/std/special/compiler_rt/floattidf_test.zig
index 25dc595052..4914342c31 100644
--- a/std/special/compiler_rt/floattidf_test.zig
+++ b/std/special/compiler_rt/floattidf_test.zig
@@ -1,9 +1,9 @@
const __floattidf = @import("floattidf.zig").__floattidf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floattidf(a: i128, expected: f64) void {
const x = __floattidf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floattidf" {
diff --git a/std/special/compiler_rt/floattisf_test.zig b/std/special/compiler_rt/floattisf_test.zig
index ecb8eac60a..a6aa115307 100644
--- a/std/special/compiler_rt/floattisf_test.zig
+++ b/std/special/compiler_rt/floattisf_test.zig
@@ -1,9 +1,9 @@
const __floattisf = @import("floattisf.zig").__floattisf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floattisf(a: i128, expected: f32) void {
const x = __floattisf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floattisf" {
diff --git a/std/special/compiler_rt/floattitf_test.zig b/std/special/compiler_rt/floattitf_test.zig
index da2ccc8b35..53e3e48bdb 100644
--- a/std/special/compiler_rt/floattitf_test.zig
+++ b/std/special/compiler_rt/floattitf_test.zig
@@ -1,9 +1,9 @@
const __floattitf = @import("floattitf.zig").__floattitf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floattitf(a: i128, expected: f128) void {
const x = __floattitf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floattitf" {
diff --git a/std/special/compiler_rt/floatunditf_test.zig b/std/special/compiler_rt/floatunditf_test.zig
index 8533c75070..5b4e195870 100644
--- a/std/special/compiler_rt/floatunditf_test.zig
+++ b/std/special/compiler_rt/floatunditf_test.zig
@@ -1,5 +1,4 @@
const __floatunditf = @import("floatunditf.zig").__floatunditf;
-const assert = @import("std").debug.assert;
fn test__floatunditf(a: u128, expected_hi: u64, expected_lo: u64) void {
const x = __floatunditf(a);
diff --git a/std/special/compiler_rt/floatunsitf_test.zig b/std/special/compiler_rt/floatunsitf_test.zig
index 06f54cde03..52e4786903 100644
--- a/std/special/compiler_rt/floatunsitf_test.zig
+++ b/std/special/compiler_rt/floatunsitf_test.zig
@@ -1,5 +1,4 @@
const __floatunsitf = @import("floatunsitf.zig").__floatunsitf;
-const assert = @import("std").debug.assert;
fn test__floatunsitf(a: u64, expected_hi: u64, expected_lo: u64) void {
const x = __floatunsitf(a);
diff --git a/std/special/compiler_rt/floatuntidf_test.zig b/std/special/compiler_rt/floatuntidf_test.zig
index e2c79378e2..974f3e4be3 100644
--- a/std/special/compiler_rt/floatuntidf_test.zig
+++ b/std/special/compiler_rt/floatuntidf_test.zig
@@ -1,9 +1,9 @@
const __floatuntidf = @import("floatuntidf.zig").__floatuntidf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floatuntidf(a: u128, expected: f64) void {
const x = __floatuntidf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floatuntidf" {
diff --git a/std/special/compiler_rt/floatuntisf_test.zig b/std/special/compiler_rt/floatuntisf_test.zig
index 7f84c1f963..3a97807066 100644
--- a/std/special/compiler_rt/floatuntisf_test.zig
+++ b/std/special/compiler_rt/floatuntisf_test.zig
@@ -1,9 +1,9 @@
const __floatuntisf = @import("floatuntisf.zig").__floatuntisf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floatuntisf(a: u128, expected: f32) void {
const x = __floatuntisf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floatuntisf" {
diff --git a/std/special/compiler_rt/floatuntitf_test.zig b/std/special/compiler_rt/floatuntitf_test.zig
index 8e67fee108..09f3eabb3e 100644
--- a/std/special/compiler_rt/floatuntitf_test.zig
+++ b/std/special/compiler_rt/floatuntitf_test.zig
@@ -1,9 +1,9 @@
const __floatuntitf = @import("floatuntitf.zig").__floatuntitf;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__floatuntitf(a: u128, expected: f128) void {
const x = __floatuntitf(a);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "floatuntitf" {
diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig
index 4bbfc2b290..3df94db589 100644
--- a/std/special/compiler_rt/index.zig
+++ b/std/special/compiler_rt/index.zig
@@ -110,6 +110,7 @@ comptime {
const std = @import("std");
const assert = std.debug.assert;
+const testing = std.testing;
const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
@@ -417,7 +418,7 @@ test "test_umoddi3" {
fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
const r = __umoddi3(a, b);
- assert(r == expected_r);
+ testing.expect(r == expected_r);
}
test "test_udivsi3" {
@@ -1091,5 +1092,5 @@ test "test_udivsi3" {
fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
const q: u32 = __udivsi3(a, b);
- assert(q == expected_q);
+ testing.expect(q == expected_q);
}
diff --git a/std/special/compiler_rt/muloti4_test.zig b/std/special/compiler_rt/muloti4_test.zig
index 6b3671323f..00144a8839 100644
--- a/std/special/compiler_rt/muloti4_test.zig
+++ b/std/special/compiler_rt/muloti4_test.zig
@@ -1,10 +1,10 @@
const __muloti4 = @import("muloti4.zig").__muloti4;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__muloti4(a: i128, b: i128, expected: i128, expected_overflow: c_int) void {
var overflow: c_int = undefined;
const x = __muloti4(a, b, &overflow);
- assert(overflow == expected_overflow and (expected_overflow != 0 or x == expected));
+ testing.expect(overflow == expected_overflow and (expected_overflow != 0 or x == expected));
}
test "muloti4" {
diff --git a/std/special/compiler_rt/multi3_test.zig b/std/special/compiler_rt/multi3_test.zig
index 413ff20a79..92c580e20f 100644
--- a/std/special/compiler_rt/multi3_test.zig
+++ b/std/special/compiler_rt/multi3_test.zig
@@ -1,9 +1,9 @@
const __multi3 = @import("multi3.zig").__multi3;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__multi3(a: i128, b: i128, expected: i128) void {
const x = __multi3(a, b);
- assert(x == expected);
+ testing.expect(x == expected);
}
test "multi3" {
diff --git a/std/special/compiler_rt/udivmoddi4_test.zig b/std/special/compiler_rt/udivmoddi4_test.zig
index 34b9dda1ea..5e6924f290 100644
--- a/std/special/compiler_rt/udivmoddi4_test.zig
+++ b/std/special/compiler_rt/udivmoddi4_test.zig
@@ -1,13 +1,13 @@
// Disable formatting to avoid unnecessary source repository bloat.
// zig fmt: off
const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) void {
var r: u64 = undefined;
const q = __udivmoddi4(a, b, &r);
- assert(q == expected_q);
- assert(r == expected_r);
+ testing.expect(q == expected_q);
+ testing.expect(r == expected_r);
}
test "udivmoddi4" {
diff --git a/std/special/compiler_rt/udivmodti4_test.zig b/std/special/compiler_rt/udivmodti4_test.zig
index f6b370c26e..0c7880f346 100644
--- a/std/special/compiler_rt/udivmodti4_test.zig
+++ b/std/special/compiler_rt/udivmodti4_test.zig
@@ -1,13 +1,13 @@
// Disable formatting to avoid unnecessary source repository bloat.
// zig fmt: off
const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
-const assert = @import("std").debug.assert;
+const testing = @import("std").testing;
fn test__udivmodti4(a: u128, b: u128, expected_q: u128, expected_r: u128) void {
var r: u128 = undefined;
const q = __udivmodti4(a, b, &r);
- assert(q == expected_q);
- assert(r == expected_r);
+ testing.expect(q == expected_q);
+ testing.expect(r == expected_r);
}
test "udivmodti4" {
diff --git a/std/special/init-lib/src/main.zig b/std/special/init-lib/src/main.zig
index 27fdeb2030..747bb08573 100644
--- a/std/special/init-lib/src/main.zig
+++ b/std/special/init-lib/src/main.zig
@@ -1,10 +1,10 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const testing = std.testing;
export fn add(a: i32, b: i32) i32 {
return a + b;
}
test "basic add functionality" {
- assertOrPanic(add(3, 7) == 10);
+ testing.expect(add(3, 7) == 10);
}
diff --git a/std/statically_initialized_mutex.zig b/std/statically_initialized_mutex.zig
index 37582d49c1..16bcd7adaf 100644
--- a/std/statically_initialized_mutex.zig
+++ b/std/statically_initialized_mutex.zig
@@ -3,6 +3,7 @@ const builtin = @import("builtin");
const AtomicOrder = builtin.AtomicOrder;
const AtomicRmwOp = builtin.AtomicRmwOp;
const assert = std.debug.assert;
+const expect = std.testing.expect;
const windows = std.os.windows;
/// Lock may be held only once. If the same thread
@@ -95,7 +96,7 @@ test "std.StaticallyInitializedMutex" {
if (builtin.single_threaded) {
TestContext.worker(&context);
- std.debug.assertOrPanic(context.data == TestContext.incr_count);
+ expect(context.data == TestContext.incr_count);
} else {
const thread_count = 10;
var threads: [thread_count]*std.os.Thread = undefined;
@@ -105,6 +106,6 @@ test "std.StaticallyInitializedMutex" {
for (threads) |t|
t.wait();
- std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
+ expect(context.data == thread_count * TestContext.incr_count);
}
}
diff --git a/std/testing.zig b/std/testing.zig
new file mode 100644
index 0000000000..ade6e8b0dd
--- /dev/null
+++ b/std/testing.zig
@@ -0,0 +1,152 @@
+const builtin = @import("builtin");
+const TypeId = builtin.TypeId;
+const std = @import("index.zig");
+
+/// This function is intended to be used only in tests. It prints diagnostics to stderr
+/// and then aborts when actual_error_union is not expected_error.
+pub fn expectError(expected_error: anyerror, actual_error_union: var) void {
+ // TODO remove the workaround here for https://github.com/ziglang/zig/issues/1936
+ if (actual_error_union) |actual_payload| {
+ // TODO remove workaround here for https://github.com/ziglang/zig/issues/557
+ if (@sizeOf(@typeOf(actual_payload)) == 0) {
+ std.debug.panic("expected error.{}, found {} value", @errorName(expected_error), @typeName(@typeOf(actual_payload)));
+ } else {
+ std.debug.panic("expected error.{}, found {}", @errorName(expected_error), actual_payload);
+ }
+ } else |actual_error| {
+ if (expected_error != actual_error) {
+ std.debug.panic("expected error.{}, found error.{}", @errorName(expected_error), @errorName(actual_error));
+ }
+ }
+}
+
+/// This function is intended to be used only in tests. When the two values are not
+/// equal, prints diagnostics to stderr to show exactly how they are not equal,
+/// then aborts.
+/// The types must match exactly.
+pub fn expectEqual(expected: var, actual: var) void {
+ if (@typeOf(actual) != @typeOf(expected)) {
+ @compileError("type mismatch. expected " ++ @typeName(@typeOf(expected)) ++ ", found " ++ @typeName(@typeOf(actual)));
+ }
+
+ switch (@typeInfo(@typeOf(actual))) {
+ TypeId.NoReturn,
+ TypeId.BoundFn,
+ TypeId.ArgTuple,
+ TypeId.Opaque,
+ => @compileError("value of type " ++ @typeName(@typeOf(actual)) ++ " encountered"),
+
+ TypeId.Undefined,
+ TypeId.Null,
+ TypeId.Void,
+ => return,
+
+ TypeId.Type,
+ TypeId.Bool,
+ TypeId.Int,
+ TypeId.Float,
+ TypeId.ComptimeFloat,
+ TypeId.ComptimeInt,
+ TypeId.Enum,
+ TypeId.Namespace,
+ TypeId.Fn,
+ TypeId.Promise,
+ TypeId.Vector,
+ TypeId.ErrorSet,
+ => {
+ if (actual != expected) {
+ std.debug.panic("expected {}, found {}", expected, actual);
+ }
+ },
+
+ TypeId.Pointer => |pointer| {
+ switch (pointer.size) {
+ builtin.TypeInfo.Pointer.Size.One,
+ builtin.TypeInfo.Pointer.Size.Many,
+ => {
+ if (actual != expected) {
+ std.debug.panic("expected {}, found {}", expected, actual);
+ }
+ },
+
+ builtin.TypeInfo.Pointer.Size.Slice => {
+ if (actual.ptr != expected.ptr) {
+ std.debug.panic("expected slice ptr {}, found {}", expected.ptr, actual.ptr);
+ }
+ if (actual.len != expected.len) {
+ std.debug.panic("expected slice len {}, found {}", expected.len, actual.len);
+ }
+ },
+ }
+ },
+
+ TypeId.Array => |array| expectEqualSlices(array.child, &expected, &actual),
+
+ TypeId.Struct => {
+ @compileError("TODO implement testing.expectEqual for structs");
+ },
+
+ TypeId.Union => |union_info| {
+ if (union_info.tag_type == null) {
+ @compileError("Unable to compare untagged union values");
+ }
+ @compileError("TODO implement testing.expectEqual for tagged unions");
+ },
+
+ TypeId.Optional => {
+ if (expected) |expected_payload| {
+ if (actual) |actual_payload| {
+ expectEqual(expected_payload, actual_payload);
+ } else {
+ std.debug.panic("expected {}, found null", expected_payload);
+ }
+ } else {
+ if (actual) |actual_payload| {
+ std.debug.panic("expected null, found {}", actual_payload);
+ }
+ }
+ },
+
+ TypeId.ErrorUnion => {
+ if (expected) |expected_payload| {
+ if (actual) |actual_payload| {
+ expectEqual(expected_payload, actual_payload);
+ } else |actual_err| {
+ std.debug.panic("expected {}, found {}", expected_payload, actual_err);
+ }
+ } else |expected_err| {
+ if (actual) |actual_payload| {
+ std.debug.panic("expected {}, found {}", expected_err, actual_payload);
+ } else |actual_err| {
+ expectEqual(expected_err, actual_err);
+ }
+ }
+ },
+
+ }
+}
+
+/// This function is intended to be used only in tests. When the two slices are not
+/// equal, prints diagnostics to stderr to show exactly how they are not equal,
+/// then aborts.
+pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) void {
+ // TODO better printing of the difference
+ // If the arrays are small enough we could print the whole thing
+ // If the child type is u8 and no weird bytes, we could print it as strings
+ // Even for the length difference, it would be useful to see the values of the slices probably.
+ if (expected.len != actual.len) {
+ std.debug.panic("slice lengths differ. expected {}, found {}", expected.len, actual.len);
+ }
+ var i: usize = 0;
+ while (i < expected.len) : (i += 1) {
+ if (expected[i] != actual[i]) {
+ std.debug.panic("index {} incorrect. expected {}, found {}", i, expected[i], actual[i]);
+ }
+ }
+}
+
+/// This function is intended to be used only in tests. When `ok` is false, the test fails.
+/// A message is printed to stderr and then abort is called.
+pub fn expect(ok: bool) void {
+ if (!ok) @panic("test failure");
+}
diff --git a/std/unicode.zig b/std/unicode.zig
index 2e542bcb19..fccdf513b9 100644
--- a/std/unicode.zig
+++ b/std/unicode.zig
@@ -1,7 +1,7 @@
const std = @import("./index.zig");
const builtin = @import("builtin");
-const debug = std.debug;
const assert = std.debug.assert;
+const testing = std.testing;
const mem = std.mem;
/// Returns how many bytes the UTF-8 representation would require
@@ -32,7 +32,7 @@ pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {
/// Returns: the number of bytes written to out.
pub fn utf8Encode(c: u32, out: []u8) !u3 {
const length = try utf8CodepointSequenceLength(c);
- debug.assert(out.len >= length);
+ assert(out.len >= length);
switch (length) {
// The pattern for each is the same
// - Increasing the initial shift by 6 each time
@@ -81,8 +81,8 @@ const Utf8Decode2Error = error{
Utf8OverlongEncoding,
};
pub fn utf8Decode2(bytes: []const u8) Utf8Decode2Error!u32 {
- debug.assert(bytes.len == 2);
- debug.assert(bytes[0] & 0b11100000 == 0b11000000);
+ assert(bytes.len == 2);
+ assert(bytes[0] & 0b11100000 == 0b11000000);
var value: u32 = bytes[0] & 0b00011111;
if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
@@ -100,8 +100,8 @@ const Utf8Decode3Error = error{
Utf8EncodesSurrogateHalf,
};
pub fn utf8Decode3(bytes: []const u8) Utf8Decode3Error!u32 {
- debug.assert(bytes.len == 3);
- debug.assert(bytes[0] & 0b11110000 == 0b11100000);
+ assert(bytes.len == 3);
+ assert(bytes[0] & 0b11110000 == 0b11100000);
var value: u32 = bytes[0] & 0b00001111;
if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
@@ -124,8 +124,8 @@ const Utf8Decode4Error = error{
Utf8CodepointTooLarge,
};
pub fn utf8Decode4(bytes: []const u8) Utf8Decode4Error!u32 {
- debug.assert(bytes.len == 4);
- debug.assert(bytes[0] & 0b11111000 == 0b11110000);
+ assert(bytes.len == 4);
+ assert(bytes[0] & 0b11111000 == 0b11110000);
var value: u32 = bytes[0] & 0b00000111;
if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
@@ -274,23 +274,23 @@ test "utf8 encode" {
fn testUtf8Encode() !void {
// A few taken from wikipedia a few taken elsewhere
var array: [4]u8 = undefined;
- debug.assert((try utf8Encode(try utf8Decode("€"), array[0..])) == 3);
- debug.assert(array[0] == 0b11100010);
- debug.assert(array[1] == 0b10000010);
- debug.assert(array[2] == 0b10101100);
+ testing.expect((try utf8Encode(try utf8Decode("€"), array[0..])) == 3);
+ testing.expect(array[0] == 0b11100010);
+ testing.expect(array[1] == 0b10000010);
+ testing.expect(array[2] == 0b10101100);
- debug.assert((try utf8Encode(try utf8Decode("$"), array[0..])) == 1);
- debug.assert(array[0] == 0b00100100);
+ testing.expect((try utf8Encode(try utf8Decode("$"), array[0..])) == 1);
+ testing.expect(array[0] == 0b00100100);
- debug.assert((try utf8Encode(try utf8Decode("¢"), array[0..])) == 2);
- debug.assert(array[0] == 0b11000010);
- debug.assert(array[1] == 0b10100010);
+ testing.expect((try utf8Encode(try utf8Decode("¢"), array[0..])) == 2);
+ testing.expect(array[0] == 0b11000010);
+ testing.expect(array[1] == 0b10100010);
- debug.assert((try utf8Encode(try utf8Decode("𐍈"), array[0..])) == 4);
- debug.assert(array[0] == 0b11110000);
- debug.assert(array[1] == 0b10010000);
- debug.assert(array[2] == 0b10001101);
- debug.assert(array[3] == 0b10001000);
+ testing.expect((try utf8Encode(try utf8Decode("𐍈"), array[0..])) == 4);
+ testing.expect(array[0] == 0b11110000);
+ testing.expect(array[1] == 0b10010000);
+ testing.expect(array[2] == 0b10001101);
+ testing.expect(array[3] == 0b10001000);
}
test "utf8 encode error" {
@@ -306,11 +306,7 @@ fn testUtf8EncodeError() void {
}
fn testErrorEncode(codePoint: u32, array: []u8, expectedErr: anyerror) void {
- if (utf8Encode(codePoint, array)) |_| {
- unreachable;
- } else |err| {
- debug.assert(err == expectedErr);
- }
+ testing.expectError(expectedErr, utf8Encode(codePoint, array));
}
test "utf8 iterator on ascii" {
@@ -321,16 +317,16 @@ fn testUtf8IteratorOnAscii() void {
const s = Utf8View.initComptime("abc");
var it1 = s.iterator();
- debug.assert(std.mem.eql(u8, "a", it1.nextCodepointSlice().?));
- debug.assert(std.mem.eql(u8, "b", it1.nextCodepointSlice().?));
- debug.assert(std.mem.eql(u8, "c", it1.nextCodepointSlice().?));
- debug.assert(it1.nextCodepointSlice() == null);
+ testing.expect(std.mem.eql(u8, "a", it1.nextCodepointSlice().?));
+ testing.expect(std.mem.eql(u8, "b", it1.nextCodepointSlice().?));
+ testing.expect(std.mem.eql(u8, "c", it1.nextCodepointSlice().?));
+ testing.expect(it1.nextCodepointSlice() == null);
var it2 = s.iterator();
- debug.assert(it2.nextCodepoint().? == 'a');
- debug.assert(it2.nextCodepoint().? == 'b');
- debug.assert(it2.nextCodepoint().? == 'c');
- debug.assert(it2.nextCodepoint() == null);
+ testing.expect(it2.nextCodepoint().? == 'a');
+ testing.expect(it2.nextCodepoint().? == 'b');
+ testing.expect(it2.nextCodepoint().? == 'c');
+ testing.expect(it2.nextCodepoint() == null);
}
test "utf8 view bad" {
@@ -340,12 +336,7 @@ test "utf8 view bad" {
fn testUtf8ViewBad() void {
// Compile-time error.
// const s3 = Utf8View.initComptime("\xfe\xf2");
- const s = Utf8View.init("hel\xadlo");
- if (s) |_| {
- unreachable;
- } else |err| {
- debug.assert(err == error.InvalidUtf8);
- }
+ testing.expectError(error.InvalidUtf8, Utf8View.init("hel\xadlo"));
}
test "utf8 view ok" {
@@ -356,16 +347,16 @@ fn testUtf8ViewOk() void {
const s = Utf8View.initComptime("東京市");
var it1 = s.iterator();
- debug.assert(std.mem.eql(u8, "東", it1.nextCodepointSlice().?));
- debug.assert(std.mem.eql(u8, "京", it1.nextCodepointSlice().?));
- debug.assert(std.mem.eql(u8, "市", it1.nextCodepointSlice().?));
- debug.assert(it1.nextCodepointSlice() == null);
+ testing.expect(std.mem.eql(u8, "東", it1.nextCodepointSlice().?));
+ testing.expect(std.mem.eql(u8, "京", it1.nextCodepointSlice().?));
+ testing.expect(std.mem.eql(u8, "市", it1.nextCodepointSlice().?));
+ testing.expect(it1.nextCodepointSlice() == null);
var it2 = s.iterator();
- debug.assert(it2.nextCodepoint().? == 0x6771);
- debug.assert(it2.nextCodepoint().? == 0x4eac);
- debug.assert(it2.nextCodepoint().? == 0x5e02);
- debug.assert(it2.nextCodepoint() == null);
+ testing.expect(it2.nextCodepoint().? == 0x6771);
+ testing.expect(it2.nextCodepoint().? == 0x4eac);
+ testing.expect(it2.nextCodepoint().? == 0x5e02);
+ testing.expect(it2.nextCodepoint() == null);
}
test "bad utf8 slice" {
@@ -373,10 +364,10 @@ test "bad utf8 slice" {
testBadUtf8Slice();
}
fn testBadUtf8Slice() void {
- debug.assert(utf8ValidateSlice("abc"));
- debug.assert(!utf8ValidateSlice("abc\xc0"));
- debug.assert(!utf8ValidateSlice("abc\xc0abc"));
- debug.assert(utf8ValidateSlice("abc\xdf\xbf"));
+ testing.expect(utf8ValidateSlice("abc"));
+ testing.expect(!utf8ValidateSlice("abc\xc0"));
+ testing.expect(!utf8ValidateSlice("abc\xc0abc"));
+ testing.expect(utf8ValidateSlice("abc\xdf\xbf"));
}
test "valid utf8" {
@@ -459,21 +450,17 @@ fn testMiscInvalidUtf8() void {
}
fn testError(bytes: []const u8, expected_err: anyerror) void {
- if (testDecode(bytes)) |_| {
- unreachable;
- } else |err| {
- debug.assert(err == expected_err);
- }
+ testing.expectError(expected_err, testDecode(bytes));
}
fn testValid(bytes: []const u8, expected_codepoint: u32) void {
- debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);
+ testing.expect((testDecode(bytes) catch unreachable) == expected_codepoint);
}
fn testDecode(bytes: []const u8) !u32 {
const length = try utf8ByteSequenceLength(bytes[0]);
if (bytes.len < length) return error.UnexpectedEof;
- debug.assert(bytes.len == length);
+ testing.expect(bytes.len == length);
return utf8Decode(bytes);
}
@@ -513,14 +500,14 @@ test "utf16leToUtf8" {
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 'a');
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "Aa"));
+ testing.expect(mem.eql(u8, utf8, "Aa"));
}
{
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0x80);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xffff);
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf"));
+ testing.expect(mem.eql(u8, utf8, "\xc2\x80" ++ "\xef\xbf\xbf"));
}
{
@@ -528,7 +515,7 @@ test "utf16leToUtf8" {
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd7ff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xe000);
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80"));
+ testing.expect(mem.eql(u8, utf8, "\xed\x9f\xbf" ++ "\xee\x80\x80"));
}
{
@@ -536,7 +523,7 @@ test "utf16leToUtf8" {
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xd800);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "\xf0\x90\x80\x80"));
+ testing.expect(mem.eql(u8, utf8, "\xf0\x90\x80\x80"));
}
{
@@ -544,14 +531,14 @@ test "utf16leToUtf8" {
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdfff);
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf"));
+ testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xbf\xbf"));
}
{
mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 0xdbff);
mem.writeIntSliceLittle(u16, utf16le_as_bytes[2..], 0xdc00);
const utf8 = try utf16leToUtf8Alloc(std.debug.global_allocator, utf16le);
- assert(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80"));
+ testing.expect(mem.eql(u8, utf8, "\xf4\x8f\xb0\x80"));
}
}
diff --git a/std/zig/ast.zig b/std/zig/ast.zig
index bb2099fb75..f6ac4ed98c 100644
--- a/std/zig/ast.zig
+++ b/std/zig/ast.zig
@@ -1,5 +1,6 @@
const std = @import("../index.zig");
const assert = std.debug.assert;
+const testing = std.testing;
const SegmentedList = std.SegmentedList;
const mem = std.mem;
const Token = std.zig.Token;
@@ -2224,5 +2225,5 @@ test "iterate" {
.shebang = null,
};
var base = &root.base;
- assert(base.iterate(0) == null);
+ testing.expect(base.iterate(0) == null);
}
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 2b60fb9b00..7ad842e4b6 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -1940,7 +1940,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
warn("std.zig.render returned {} instead of {}\n", anything_changed, changes_expected);
return error.TestFailed;
}
- std.debug.assert(anything_changed == changes_expected);
+ std.testing.expect(anything_changed == changes_expected);
failing_allocator.allocator.free(result_source);
break :x failing_allocator.index;
};
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index 4941fe2cc2..e71babe4e8 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -1345,5 +1345,5 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
}
}
const last_token = tokenizer.next();
- std.debug.assert(last_token.id == Token.Id.Eof);
+ std.testing.expect(last_token.id == Token.Id.Eof);
}
diff --git a/test/cli.zig b/test/cli.zig
index 745da4dd80..1520b3bde0 100644
--- a/test/cli.zig
+++ b/test/cli.zig
@@ -1,7 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const os = std.os;
-const assertOrPanic = std.debug.assertOrPanic;
+const testing = std.testing;
var a: *std.mem.Allocator = undefined;
@@ -87,13 +87,13 @@ fn exec(cwd: []const u8, argv: []const []const u8) !os.ChildProcess.ExecResult {
fn testZigInitLib(zig_exe: []const u8, dir_path: []const u8) !void {
_ = try exec(dir_path, [][]const u8{ zig_exe, "init-lib" });
const test_result = try exec(dir_path, [][]const u8{ zig_exe, "build", "test" });
- assertOrPanic(std.mem.endsWith(u8, test_result.stderr, "All tests passed.\n"));
+ testing.expect(std.mem.endsWith(u8, test_result.stderr, "All tests passed.\n"));
}
fn testZigInitExe(zig_exe: []const u8, dir_path: []const u8) !void {
_ = try exec(dir_path, [][]const u8{ zig_exe, "init-exe" });
const run_result = try exec(dir_path, [][]const u8{ zig_exe, "build", "run" });
- assertOrPanic(std.mem.eql(u8, run_result.stderr, "All your base are belong to us.\n"));
+ testing.expect(std.mem.eql(u8, run_result.stderr, "All your base are belong to us.\n"));
}
fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
@@ -126,6 +126,6 @@ fn testGodboltApi(zig_exe: []const u8, dir_path: []const u8) anyerror!void {
_ = try exec(dir_path, args);
const out_asm = try std.io.readFileAlloc(a, example_s_path);
- assertOrPanic(std.mem.indexOf(u8, out_asm, "square:") != null);
- assertOrPanic(std.mem.indexOf(u8, out_asm, "imul\tedi, edi") != null);
+ testing.expect(std.mem.indexOf(u8, out_asm, "square:") != null);
+ testing.expect(std.mem.indexOf(u8, out_asm, "imul\tedi, edi") != null);
}
diff --git a/test/stage1/behavior/align.zig b/test/stage1/behavior/align.zig
index aa7a93ad84..dbd705ddc4 100644
--- a/test/stage1/behavior/align.zig
+++ b/test/stage1/behavior/align.zig
@@ -1,13 +1,13 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const builtin = @import("builtin");
var foo: u8 align(4) = 100;
test "global variable alignment" {
- assertOrPanic(@typeOf(&foo).alignment == 4);
- assertOrPanic(@typeOf(&foo) == *align(4) u8);
+ expect(@typeOf(&foo).alignment == 4);
+ expect(@typeOf(&foo) == *align(4) u8);
const slice = (*[1]u8)(&foo)[0..];
- assertOrPanic(@typeOf(slice) == []align(4) u8);
+ expect(@typeOf(slice) == []align(4) u8);
}
fn derp() align(@sizeOf(usize) * 2) i32 {
@@ -17,9 +17,9 @@ fn noop1() align(1) void {}
fn noop4() align(4) void {}
test "function alignment" {
- assertOrPanic(derp() == 1234);
- assertOrPanic(@typeOf(noop1) == fn () align(1) void);
- assertOrPanic(@typeOf(noop4) == fn () align(4) void);
+ expect(derp() == 1234);
+ expect(@typeOf(noop1) == fn () align(1) void);
+ expect(@typeOf(noop4) == fn () align(4) void);
noop1();
noop4();
}
@@ -30,7 +30,7 @@ var baz: packed struct {
} = undefined;
test "packed struct alignment" {
- assertOrPanic(@typeOf(&baz.b) == *align(1) u32);
+ expect(@typeOf(&baz.b) == *align(1) u32);
}
const blah: packed struct {
@@ -40,17 +40,17 @@ const blah: packed struct {
} = undefined;
test "bit field alignment" {
- assertOrPanic(@typeOf(&blah.b) == *align(1:3:1) const u3);
+ expect(@typeOf(&blah.b) == *align(1:3:1) const u3);
}
test "default alignment allows unspecified in type syntax" {
- assertOrPanic(*u32 == *align(@alignOf(u32)) u32);
+ expect(*u32 == *align(@alignOf(u32)) u32);
}
test "implicitly decreasing pointer alignment" {
const a: u32 align(4) = 3;
const b: u32 align(8) = 4;
- assertOrPanic(addUnaligned(&a, &b) == 7);
+ expect(addUnaligned(&a, &b) == 7);
}
fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
@@ -60,7 +60,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
test "implicitly decreasing slice alignment" {
const a: u32 align(4) = 3;
const b: u32 align(8) = 4;
- assertOrPanic(addUnalignedSlice((*[1]u32)(&a)[0..], (*[1]u32)(&b)[0..]) == 7);
+ expect(addUnalignedSlice((*[1]u32)(&a)[0..], (*[1]u32)(&b)[0..]) == 7);
}
fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
return a[0] + b[0];
@@ -77,7 +77,7 @@ fn testBytesAlign(b: u8) void {
b,
};
const ptr = @ptrCast(*u32, &bytes[0]);
- assertOrPanic(ptr.* == 0x33333333);
+ expect(ptr.* == 0x33333333);
}
test "specifying alignment allows slice cast" {
@@ -91,13 +91,13 @@ fn testBytesAlignSlice(b: u8) void {
b,
};
const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
- assertOrPanic(slice[0] == 0x33333333);
+ expect(slice[0] == 0x33333333);
}
test "@alignCast pointers" {
var x: u32 align(4) = 1;
expectsOnly1(&x);
- assertOrPanic(x == 2);
+ expect(x == 2);
}
fn expectsOnly1(x: *align(1) u32) void {
expects4(@alignCast(4, x));
@@ -113,7 +113,7 @@ test "@alignCast slices" {
};
const slice = array[0..];
sliceExpectsOnly1(slice);
- assertOrPanic(slice[0] == 2);
+ expect(slice[0] == 2);
}
fn sliceExpectsOnly1(slice: []align(1) u32) void {
sliceExpects4(@alignCast(4, slice));
@@ -128,7 +128,7 @@ test "implicitly decreasing fn alignment" {
}
fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {
- assertOrPanic(ptr() == answer);
+ expect(ptr() == answer);
}
fn alignedSmall() align(8) i32 {
@@ -139,7 +139,7 @@ fn alignedBig() align(16) i32 {
}
test "@alignCast functions" {
- assertOrPanic(fnExpectsOnly1(simple4) == 0x19);
+ expect(fnExpectsOnly1(simple4) == 0x19);
}
fn fnExpectsOnly1(ptr: fn () align(1) i32) i32 {
return fnExpects4(@alignCast(4, ptr));
@@ -152,9 +152,9 @@ fn simple4() align(4) i32 {
}
test "generic function with align param" {
- assertOrPanic(whyWouldYouEverDoThis(1) == 0x1);
- assertOrPanic(whyWouldYouEverDoThis(4) == 0x1);
- assertOrPanic(whyWouldYouEverDoThis(8) == 0x1);
+ expect(whyWouldYouEverDoThis(1) == 0x1);
+ expect(whyWouldYouEverDoThis(4) == 0x1);
+ expect(whyWouldYouEverDoThis(8) == 0x1);
}
fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
@@ -164,28 +164,28 @@ fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
test "@ptrCast preserves alignment of bigger source" {
var x: u32 align(16) = 1234;
const ptr = @ptrCast(*u8, &x);
- assertOrPanic(@typeOf(ptr) == *align(16) u8);
+ expect(@typeOf(ptr) == *align(16) u8);
}
test "runtime known array index has best alignment possible" {
// take full advantage of over-alignment
var array align(4) = []u8{ 1, 2, 3, 4 };
- assertOrPanic(@typeOf(&array[0]) == *align(4) u8);
- assertOrPanic(@typeOf(&array[1]) == *u8);
- assertOrPanic(@typeOf(&array[2]) == *align(2) u8);
- assertOrPanic(@typeOf(&array[3]) == *u8);
+ expect(@typeOf(&array[0]) == *align(4) u8);
+ expect(@typeOf(&array[1]) == *u8);
+ expect(@typeOf(&array[2]) == *align(2) u8);
+ expect(@typeOf(&array[3]) == *u8);
// because align is too small but we still figure out to use 2
var bigger align(2) = []u64{ 1, 2, 3, 4 };
- assertOrPanic(@typeOf(&bigger[0]) == *align(2) u64);
- assertOrPanic(@typeOf(&bigger[1]) == *align(2) u64);
- assertOrPanic(@typeOf(&bigger[2]) == *align(2) u64);
- assertOrPanic(@typeOf(&bigger[3]) == *align(2) u64);
+ expect(@typeOf(&bigger[0]) == *align(2) u64);
+ expect(@typeOf(&bigger[1]) == *align(2) u64);
+ expect(@typeOf(&bigger[2]) == *align(2) u64);
+ expect(@typeOf(&bigger[3]) == *align(2) u64);
// because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
var smaller align(2) = []u32{ 1, 2, 3, 4 };
- comptime assertOrPanic(@typeOf(smaller[0..]) == []align(2) u32);
- comptime assertOrPanic(@typeOf(smaller[0..].ptr) == [*]align(2) u32);
+ comptime expect(@typeOf(smaller[0..]) == []align(2) u32);
+ comptime expect(@typeOf(smaller[0..].ptr) == [*]align(2) u32);
testIndex(smaller[0..].ptr, 0, *align(2) u32);
testIndex(smaller[0..].ptr, 1, *align(2) u32);
testIndex(smaller[0..].ptr, 2, *align(2) u32);
@@ -198,14 +198,14 @@ test "runtime known array index has best alignment possible" {
testIndex2(array[0..].ptr, 3, *u8);
}
fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {
- comptime assertOrPanic(@typeOf(&smaller[index]) == T);
+ comptime expect(@typeOf(&smaller[index]) == T);
}
fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) void {
- comptime assertOrPanic(@typeOf(&ptr[index]) == T);
+ comptime expect(@typeOf(&ptr[index]) == T);
}
test "alignstack" {
- assertOrPanic(fnWithAlignedStack() == 1234);
+ expect(fnWithAlignedStack() == 1234);
}
fn fnWithAlignedStack() i32 {
@@ -214,7 +214,7 @@ fn fnWithAlignedStack() i32 {
}
test "alignment of structs" {
- assertOrPanic(@alignOf(struct {
+ expect(@alignOf(struct {
a: i32,
b: *i32,
}) == @alignOf(usize));
diff --git a/test/stage1/behavior/alignof.zig b/test/stage1/behavior/alignof.zig
index 98c805908b..d4d9661ead 100644
--- a/test/stage1/behavior/alignof.zig
+++ b/test/stage1/behavior/alignof.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const maxInt = std.math.maxInt;
@@ -10,9 +10,9 @@ const Foo = struct {
};
test "@alignOf(T) before referencing T" {
- comptime assertOrPanic(@alignOf(Foo) != maxInt(usize));
+ comptime expect(@alignOf(Foo) != maxInt(usize));
if (builtin.arch == builtin.Arch.x86_64) {
- comptime assertOrPanic(@alignOf(Foo) == 4);
+ comptime expect(@alignOf(Foo) == 4);
}
}
diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig
index 1183305209..99b828e53c 100644
--- a/test/stage1/behavior/array.zig
+++ b/test/stage1/behavior/array.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
test "arrays" {
@@ -18,8 +18,8 @@ test "arrays" {
i += 1;
}
- assertOrPanic(accumulator == 15);
- assertOrPanic(getArrayLen(array) == 5);
+ expect(accumulator == 15);
+ expect(getArrayLen(array) == 5);
}
fn getArrayLen(a: []const u32) usize {
return a.len;
@@ -29,8 +29,8 @@ test "void arrays" {
var array: [4]void = undefined;
array[0] = void{};
array[1] = array[2];
- assertOrPanic(@sizeOf(@typeOf(array)) == 0);
- assertOrPanic(array.len == 4);
+ expect(@sizeOf(@typeOf(array)) == 0);
+ expect(array.len == 4);
}
test "array literal" {
@@ -41,12 +41,12 @@ test "array literal" {
1,
};
- assertOrPanic(hex_mult.len == 4);
- assertOrPanic(hex_mult[1] == 256);
+ expect(hex_mult.len == 4);
+ expect(hex_mult[1] == 256);
}
test "array dot len const expr" {
- assertOrPanic(comptime x: {
+ expect(comptime x: {
break :x some_array.len == 4;
});
}
@@ -70,11 +70,11 @@ test "nested arrays" {
"thing",
};
for (array_of_strings) |s, i| {
- if (i == 0) assertOrPanic(mem.eql(u8, s, "hello"));
- if (i == 1) assertOrPanic(mem.eql(u8, s, "this"));
- if (i == 2) assertOrPanic(mem.eql(u8, s, "is"));
- if (i == 3) assertOrPanic(mem.eql(u8, s, "my"));
- if (i == 4) assertOrPanic(mem.eql(u8, s, "thing"));
+ if (i == 0) expect(mem.eql(u8, s, "hello"));
+ if (i == 1) expect(mem.eql(u8, s, "this"));
+ if (i == 2) expect(mem.eql(u8, s, "is"));
+ if (i == 3) expect(mem.eql(u8, s, "my"));
+ if (i == 4) expect(mem.eql(u8, s, "thing"));
}
}
@@ -92,9 +92,9 @@ test "set global var array via slice embedded in struct" {
s.a[1].b = 2;
s.a[2].b = 3;
- assertOrPanic(s_array[0].b == 1);
- assertOrPanic(s_array[1].b == 2);
- assertOrPanic(s_array[2].b == 3);
+ expect(s_array[0].b == 1);
+ expect(s_array[1].b == 2);
+ expect(s_array[2].b == 3);
}
test "array literal with specified size" {
@@ -102,27 +102,27 @@ test "array literal with specified size" {
1,
2,
};
- assertOrPanic(array[0] == 1);
- assertOrPanic(array[1] == 2);
+ expect(array[0] == 1);
+ expect(array[1] == 2);
}
test "array child property" {
var x: [5]i32 = undefined;
- assertOrPanic(@typeOf(x).Child == i32);
+ expect(@typeOf(x).Child == i32);
}
test "array len property" {
var x: [5]i32 = undefined;
- assertOrPanic(@typeOf(x).len == 5);
+ expect(@typeOf(x).len == 5);
}
test "array len field" {
var arr = [4]u8{ 0, 0, 0, 0 };
var ptr = &arr;
- assertOrPanic(arr.len == 4);
- comptime assertOrPanic(arr.len == 4);
- assertOrPanic(ptr.len == 4);
- comptime assertOrPanic(ptr.len == 4);
+ expect(arr.len == 4);
+ comptime expect(arr.len == 4);
+ expect(ptr.len == 4);
+ comptime expect(ptr.len == 4);
}
test "single-item pointer to array indexing and slicing" {
@@ -133,7 +133,7 @@ test "single-item pointer to array indexing and slicing" {
fn testSingleItemPtrArrayIndexSlice() void {
var array = "aaaa";
doSomeMangling(&array);
- assertOrPanic(mem.eql(u8, "azya", array));
+ expect(mem.eql(u8, "azya", array));
}
fn doSomeMangling(array: *[4]u8) void {
@@ -150,7 +150,7 @@ fn testImplicitCastSingleItemPtr() void {
var byte: u8 = 100;
const slice = (*[1]u8)(&byte)[0..];
slice[0] += 1;
- assertOrPanic(byte == 101);
+ expect(byte == 101);
}
fn testArrayByValAtComptime(b: [2]u8) u8 {
@@ -165,7 +165,7 @@ test "comptime evalutating function that takes array by value" {
test "implicit comptime in array type size" {
var arr: [plusOne(10)]bool = undefined;
- assertOrPanic(arr.len == 11);
+ expect(arr.len == 11);
}
fn plusOne(x: u32) u32 {
@@ -197,15 +197,15 @@ test "array literal as argument to function" {
});
}
fn foo(x: []const i32) void {
- assertOrPanic(x[0] == 1);
- assertOrPanic(x[1] == 2);
- assertOrPanic(x[2] == 3);
+ expect(x[0] == 1);
+ expect(x[1] == 2);
+ expect(x[2] == 3);
}
fn foo2(trash: bool, x: []const i32) void {
- assertOrPanic(trash);
- assertOrPanic(x[0] == 1);
- assertOrPanic(x[1] == 2);
- assertOrPanic(x[2] == 3);
+ expect(trash);
+ expect(x[0] == 1);
+ expect(x[1] == 2);
+ expect(x[2] == 3);
}
};
S.entry(2);
@@ -229,12 +229,12 @@ test "double nested array to const slice cast in array literal" {
[]i32{1},
[]i32{ two, 3 },
};
- assertOrPanic(cases2.len == 2);
- assertOrPanic(cases2[0].len == 1);
- assertOrPanic(cases2[0][0] == 1);
- assertOrPanic(cases2[1].len == 2);
- assertOrPanic(cases2[1][0] == 2);
- assertOrPanic(cases2[1][1] == 3);
+ expect(cases2.len == 2);
+ expect(cases2[0].len == 1);
+ expect(cases2[0][0] == 1);
+ expect(cases2[1].len == 2);
+ expect(cases2[1][0] == 2);
+ expect(cases2[1][1] == 3);
const cases3 = [][]const []const i32{
[][]const i32{[]i32{1}},
@@ -248,21 +248,21 @@ test "double nested array to const slice cast in array literal" {
}
fn check(cases: []const []const []const i32) void {
- assertOrPanic(cases.len == 3);
- assertOrPanic(cases[0].len == 1);
- assertOrPanic(cases[0][0].len == 1);
- assertOrPanic(cases[0][0][0] == 1);
- assertOrPanic(cases[1].len == 1);
- assertOrPanic(cases[1][0].len == 2);
- assertOrPanic(cases[1][0][0] == 2);
- assertOrPanic(cases[1][0][1] == 3);
- assertOrPanic(cases[2].len == 2);
- assertOrPanic(cases[2][0].len == 1);
- assertOrPanic(cases[2][0][0] == 4);
- assertOrPanic(cases[2][1].len == 3);
- assertOrPanic(cases[2][1][0] == 5);
- assertOrPanic(cases[2][1][1] == 6);
- assertOrPanic(cases[2][1][2] == 7);
+ expect(cases.len == 3);
+ expect(cases[0].len == 1);
+ expect(cases[0][0].len == 1);
+ expect(cases[0][0][0] == 1);
+ expect(cases[1].len == 1);
+ expect(cases[1][0].len == 2);
+ expect(cases[1][0][0] == 2);
+ expect(cases[1][0][1] == 3);
+ expect(cases[2].len == 2);
+ expect(cases[2][0].len == 1);
+ expect(cases[2][0][0] == 4);
+ expect(cases[2][1].len == 3);
+ expect(cases[2][1][0] == 5);
+ expect(cases[2][1][1] == 6);
+ expect(cases[2][1][2] == 7);
}
};
S.entry(2);
diff --git a/test/stage1/behavior/asm.zig b/test/stage1/behavior/asm.zig
index 48701c5836..845d80777a 100644
--- a/test/stage1/behavior/asm.zig
+++ b/test/stage1/behavior/asm.zig
@@ -1,5 +1,5 @@
const config = @import("builtin");
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
comptime {
if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
@@ -13,7 +13,7 @@ comptime {
test "module level assembly" {
if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
- assertOrPanic(aoeu() == 1234);
+ expect(aoeu() == 1234);
}
}
diff --git a/test/stage1/behavior/atomics.zig b/test/stage1/behavior/atomics.zig
index fa3c5f29a6..daa463fd45 100644
--- a/test/stage1/behavior/atomics.zig
+++ b/test/stage1/behavior/atomics.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
@@ -7,18 +7,18 @@ const AtomicOrder = builtin.AtomicOrder;
test "cmpxchg" {
var x: i32 = 1234;
if (@cmpxchgWeak(i32, &x, 99, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
- assertOrPanic(x1 == 1234);
+ expect(x1 == 1234);
} else {
@panic("cmpxchg should have failed");
}
while (@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
- assertOrPanic(x1 == 1234);
+ expect(x1 == 1234);
}
- assertOrPanic(x == 5678);
+ expect(x == 5678);
- assertOrPanic(@cmpxchgStrong(i32, &x, 5678, 42, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
- assertOrPanic(x == 42);
+ expect(@cmpxchgStrong(i32, &x, 5678, 42, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
+ expect(x == 42);
}
test "fence" {
@@ -30,24 +30,24 @@ test "fence" {
test "atomicrmw and atomicload" {
var data: u8 = 200;
testAtomicRmw(&data);
- assertOrPanic(data == 42);
+ expect(data == 42);
testAtomicLoad(&data);
}
fn testAtomicRmw(ptr: *u8) void {
const prev_value = @atomicRmw(u8, ptr, AtomicRmwOp.Xchg, 42, AtomicOrder.SeqCst);
- assertOrPanic(prev_value == 200);
+ expect(prev_value == 200);
comptime {
var x: i32 = 1234;
const y: i32 = 12345;
- assertOrPanic(@atomicLoad(i32, &x, AtomicOrder.SeqCst) == 1234);
- assertOrPanic(@atomicLoad(i32, &y, AtomicOrder.SeqCst) == 12345);
+ expect(@atomicLoad(i32, &x, AtomicOrder.SeqCst) == 1234);
+ expect(@atomicLoad(i32, &y, AtomicOrder.SeqCst) == 12345);
}
}
fn testAtomicLoad(ptr: *u8) void {
const x = @atomicLoad(u8, ptr, AtomicOrder.SeqCst);
- assertOrPanic(x == 42);
+ expect(x == 42);
}
test "cmpxchg with ptr" {
@@ -56,16 +56,16 @@ test "cmpxchg with ptr" {
var data3: i32 = 9101;
var x: *i32 = &data1;
if (@cmpxchgWeak(*i32, &x, &data2, &data3, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
- assertOrPanic(x1 == &data1);
+ expect(x1 == &data1);
} else {
@panic("cmpxchg should have failed");
}
while (@cmpxchgWeak(*i32, &x, &data1, &data3, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
- assertOrPanic(x1 == &data1);
+ expect(x1 == &data1);
}
- assertOrPanic(x == &data3);
+ expect(x == &data3);
- assertOrPanic(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
- assertOrPanic(x == &data2);
+ expect(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
+ expect(x == &data2);
}
diff --git a/test/stage1/behavior/bit_shifting.zig b/test/stage1/behavior/bit_shifting.zig
index 3290688358..610acc06c2 100644
--- a/test/stage1/behavior/bit_shifting.zig
+++ b/test/stage1/behavior/bit_shifting.zig
@@ -1,9 +1,9 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type {
- assertOrPanic(Key == @IntType(false, Key.bit_count));
- assertOrPanic(Key.bit_count >= mask_bit_count);
+ expect(Key == @IntType(false, Key.bit_count));
+ expect(Key.bit_count >= mask_bit_count);
const ShardKey = @IntType(false, mask_bit_count);
const shift_amount = Key.bit_count - ShardKey.bit_count;
return struct {
@@ -77,12 +77,12 @@ fn testShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, c
var node_buffer: [node_count]Table.Node = undefined;
for (node_buffer) |*node, i| {
const key = @intCast(Key, i);
- assertOrPanic(table.get(key) == null);
+ expect(table.get(key) == null);
node.init(key, {});
table.put(node);
}
for (node_buffer) |*node, i| {
- assertOrPanic(table.get(@intCast(Key, i)) == node);
+ expect(table.get(@intCast(Key, i)) == node);
}
}
diff --git a/test/stage1/behavior/bitcast.zig b/test/stage1/behavior/bitcast.zig
index 19030255e4..9607d2e3ef 100644
--- a/test/stage1/behavior/bitcast.zig
+++ b/test/stage1/behavior/bitcast.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
test "@bitCast i32 -> u32" {
@@ -8,8 +8,8 @@ test "@bitCast i32 -> u32" {
}
fn testBitCast_i32_u32() void {
- assertOrPanic(conv(-1) == maxInt(u32));
- assertOrPanic(conv2(maxInt(u32)) == -1);
+ expect(conv(-1) == maxInt(u32));
+ expect(conv2(maxInt(u32)) == -1);
}
fn conv(x: i32) u32 {
@@ -27,7 +27,7 @@ test "@bitCast extern enum to its integer type" {
fn testBitCastExternEnum() void {
var SOCK_DGRAM = @This().B;
var sock_dgram = @bitCast(c_int, SOCK_DGRAM);
- assertOrPanic(sock_dgram == 1);
+ expect(sock_dgram == 1);
}
};
diff --git a/test/stage1/behavior/bitreverse.zig b/test/stage1/behavior/bitreverse.zig
index 97787ace84..3897a3eab7 100644
--- a/test/stage1/behavior/bitreverse.zig
+++ b/test/stage1/behavior/bitreverse.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const minInt = std.math.minInt;
test "@bitreverse" {
@@ -9,73 +9,73 @@ test "@bitreverse" {
fn testBitReverse() void {
// using comptime_ints, unsigned
- assertOrPanic(@bitreverse(u0, 0) == 0);
- assertOrPanic(@bitreverse(u5, 0x12) == 0x9);
- assertOrPanic(@bitreverse(u8, 0x12) == 0x48);
- assertOrPanic(@bitreverse(u16, 0x1234) == 0x2c48);
- assertOrPanic(@bitreverse(u24, 0x123456) == 0x6a2c48);
- assertOrPanic(@bitreverse(u32, 0x12345678) == 0x1e6a2c48);
- assertOrPanic(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48);
- assertOrPanic(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48);
- assertOrPanic(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48);
- assertOrPanic(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48);
- assertOrPanic(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48);
+ expect(@bitreverse(u0, 0) == 0);
+ expect(@bitreverse(u5, 0x12) == 0x9);
+ expect(@bitreverse(u8, 0x12) == 0x48);
+ expect(@bitreverse(u16, 0x1234) == 0x2c48);
+ expect(@bitreverse(u24, 0x123456) == 0x6a2c48);
+ expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48);
+ expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48);
+ expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48);
+ expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48);
+ expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48);
+ expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48);
// using runtime uints, unsigned
var num0: u0 = 0;
- assertOrPanic(@bitreverse(u0, num0) == 0);
+ expect(@bitreverse(u0, num0) == 0);
var num5: u5 = 0x12;
- assertOrPanic(@bitreverse(u5, num5) == 0x9);
+ expect(@bitreverse(u5, num5) == 0x9);
var num8: u8 = 0x12;
- assertOrPanic(@bitreverse(u8, num8) == 0x48);
+ expect(@bitreverse(u8, num8) == 0x48);
var num16: u16 = 0x1234;
- assertOrPanic(@bitreverse(u16, num16) == 0x2c48);
+ expect(@bitreverse(u16, num16) == 0x2c48);
var num24: u24 = 0x123456;
- assertOrPanic(@bitreverse(u24, num24) == 0x6a2c48);
+ expect(@bitreverse(u24, num24) == 0x6a2c48);
var num32: u32 = 0x12345678;
- assertOrPanic(@bitreverse(u32, num32) == 0x1e6a2c48);
+ expect(@bitreverse(u32, num32) == 0x1e6a2c48);
var num40: u40 = 0x123456789a;
- assertOrPanic(@bitreverse(u40, num40) == 0x591e6a2c48);
+ expect(@bitreverse(u40, num40) == 0x591e6a2c48);
var num48: u48 = 0x123456789abc;
- assertOrPanic(@bitreverse(u48, num48) == 0x3d591e6a2c48);
+ expect(@bitreverse(u48, num48) == 0x3d591e6a2c48);
var num56: u56 = 0x123456789abcde;
- assertOrPanic(@bitreverse(u56, num56) == 0x7b3d591e6a2c48);
+ expect(@bitreverse(u56, num56) == 0x7b3d591e6a2c48);
var num64: u64 = 0x123456789abcdef1;
- assertOrPanic(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48);
+ expect(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48);
var num128: u128 = 0x123456789abcdef11121314151617181;
- assertOrPanic(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
+ expect(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
// using comptime_ints, signed, positive
- assertOrPanic(@bitreverse(i0, 0) == 0);
- assertOrPanic(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
- assertOrPanic(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
- assertOrPanic(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
- assertOrPanic(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
- assertOrPanic(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
- assertOrPanic(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
- assertOrPanic(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
- assertOrPanic(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
- assertOrPanic(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
+ expect(@bitreverse(i0, 0) == 0);
+ expect(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
+ expect(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
+ expect(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
+ expect(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
+ expect(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
+ expect(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
+ expect(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
+ expect(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
+ expect(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
// using comptime_ints, signed, negative. Compare to runtime ints returned from llvm.
var neg5: i5 = minInt(i5) + 1;
- assertOrPanic(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5));
+ expect(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5));
var neg8: i8 = -18;
- assertOrPanic(@bitreverse(i8, -18) == @bitreverse(i8, neg8));
+ expect(@bitreverse(i8, -18) == @bitreverse(i8, neg8));
var neg16: i16 = -32694;
- assertOrPanic(@bitreverse(i16, -32694) == @bitreverse(i16, neg16));
+ expect(@bitreverse(i16, -32694) == @bitreverse(i16, neg16));
var neg24: i24 = -6773785;
- assertOrPanic(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24));
+ expect(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24));
var neg32: i32 = -16773785;
- assertOrPanic(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32));
+ expect(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32));
var neg40: i40 = minInt(i40) + 12345;
- assertOrPanic(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40));
+ expect(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40));
var neg48: i48 = minInt(i48) + 12345;
- assertOrPanic(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48));
+ expect(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48));
var neg56: i56 = minInt(i56) + 12345;
- assertOrPanic(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56));
+ expect(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56));
var neg64: i64 = minInt(i64) + 12345;
- assertOrPanic(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64));
+ expect(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64));
var neg128: i128 = minInt(i128) + 12345;
- assertOrPanic(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128));
+ expect(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128));
}
diff --git a/test/stage1/behavior/bool.zig b/test/stage1/behavior/bool.zig
index 2d7241526f..dfc2279005 100644
--- a/test/stage1/behavior/bool.zig
+++ b/test/stage1/behavior/bool.zig
@@ -1,25 +1,25 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "bool literals" {
- assertOrPanic(true);
- assertOrPanic(!false);
+ expect(true);
+ expect(!false);
}
test "cast bool to int" {
const t = true;
const f = false;
- assertOrPanic(@boolToInt(t) == u32(1));
- assertOrPanic(@boolToInt(f) == u32(0));
+ expect(@boolToInt(t) == u32(1));
+ expect(@boolToInt(f) == u32(0));
nonConstCastBoolToInt(t, f);
}
fn nonConstCastBoolToInt(t: bool, f: bool) void {
- assertOrPanic(@boolToInt(t) == u32(1));
- assertOrPanic(@boolToInt(f) == u32(0));
+ expect(@boolToInt(t) == u32(1));
+ expect(@boolToInt(f) == u32(0));
}
test "bool cmp" {
- assertOrPanic(testBoolCmp(true, false) == false);
+ expect(testBoolCmp(true, false) == false);
}
fn testBoolCmp(a: bool, b: bool) bool {
return a == b;
@@ -30,6 +30,6 @@ const global_t = true;
const not_global_f = !global_f;
const not_global_t = !global_t;
test "compile time bool not" {
- assertOrPanic(not_global_f);
- assertOrPanic(!not_global_t);
+ expect(not_global_f);
+ expect(!not_global_t);
}
diff --git a/test/stage1/behavior/bswap.zig b/test/stage1/behavior/bswap.zig
index 8084538e03..beffa0f73a 100644
--- a/test/stage1/behavior/bswap.zig
+++ b/test/stage1/behavior/bswap.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "@bswap" {
comptime testByteSwap();
@@ -7,26 +7,26 @@ test "@bswap" {
}
fn testByteSwap() void {
- assertOrPanic(@bswap(u0, 0) == 0);
- assertOrPanic(@bswap(u8, 0x12) == 0x12);
- assertOrPanic(@bswap(u16, 0x1234) == 0x3412);
- assertOrPanic(@bswap(u24, 0x123456) == 0x563412);
- assertOrPanic(@bswap(u32, 0x12345678) == 0x78563412);
- assertOrPanic(@bswap(u40, 0x123456789a) == 0x9a78563412);
- assertOrPanic(@bswap(u48, 0x123456789abc) == 0xbc9a78563412);
- assertOrPanic(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412);
- assertOrPanic(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412);
- assertOrPanic(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412);
+ expect(@bswap(u0, 0) == 0);
+ expect(@bswap(u8, 0x12) == 0x12);
+ expect(@bswap(u16, 0x1234) == 0x3412);
+ expect(@bswap(u24, 0x123456) == 0x563412);
+ expect(@bswap(u32, 0x12345678) == 0x78563412);
+ expect(@bswap(u40, 0x123456789a) == 0x9a78563412);
+ expect(@bswap(u48, 0x123456789abc) == 0xbc9a78563412);
+ expect(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412);
+ expect(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412);
+ expect(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412);
- assertOrPanic(@bswap(i0, 0) == 0);
- assertOrPanic(@bswap(i8, -50) == -50);
- assertOrPanic(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412)));
- assertOrPanic(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412)));
- assertOrPanic(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412)));
- assertOrPanic(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412)));
- assertOrPanic(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412)));
- assertOrPanic(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412)));
- assertOrPanic(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412)));
- assertOrPanic(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) ==
+ expect(@bswap(i0, 0) == 0);
+ expect(@bswap(i8, -50) == -50);
+ expect(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412)));
+ expect(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412)));
+ expect(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412)));
+ expect(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412)));
+ expect(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412)));
+ expect(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412)));
+ expect(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412)));
+ expect(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) ==
@bitCast(i128, u128(0x8171615141312111f1debc9a78563412)));
}
diff --git a/test/stage1/behavior/bugs/1076.zig b/test/stage1/behavior/bugs/1076.zig
index 69a7e70f7d..9dc1d111ea 100644
--- a/test/stage1/behavior/bugs/1076.zig
+++ b/test/stage1/behavior/bugs/1076.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const mem = std.mem;
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "comptime code should not modify constant data" {
testCastPtrOfArrayToSliceAndPtr();
@@ -11,6 +11,6 @@ fn testCastPtrOfArrayToSliceAndPtr() void {
var array = "aoeu";
const x: [*]u8 = &array;
x[0] += 1;
- assertOrPanic(mem.eql(u8, array[0..], "boeu"));
+ expect(mem.eql(u8, array[0..], "boeu"));
}
diff --git a/test/stage1/behavior/bugs/1277.zig b/test/stage1/behavior/bugs/1277.zig
index a83e7653e2..3aa1db2ea0 100644
--- a/test/stage1/behavior/bugs/1277.zig
+++ b/test/stage1/behavior/bugs/1277.zig
@@ -11,5 +11,5 @@ fn f() i32 {
}
test "don't emit an LLVM global for a const function when it's in an optional in a struct" {
- std.debug.assertOrPanic(s.f.?() == 1234);
+ std.testing.expect(s.f.?() == 1234);
}
diff --git a/test/stage1/behavior/bugs/1322.zig b/test/stage1/behavior/bugs/1322.zig
index 2e67f4473f..f1d61baa3a 100644
--- a/test/stage1/behavior/bugs/1322.zig
+++ b/test/stage1/behavior/bugs/1322.zig
@@ -13,7 +13,7 @@ const C = struct {};
test "tagged union with all void fields but a meaningful tag" {
var a: A = A{ .b = B{ .c = C{} } };
- std.debug.assertOrPanic(@TagType(B)(a.b) == @TagType(B).c);
+ std.testing.expect(@TagType(B)(a.b) == @TagType(B).c);
a = A{ .b = B.None };
- std.debug.assertOrPanic(@TagType(B)(a.b) == @TagType(B).None);
+ std.testing.expect(@TagType(B)(a.b) == @TagType(B).None);
}
diff --git a/test/stage1/behavior/bugs/1381.zig b/test/stage1/behavior/bugs/1381.zig
index 2d452da156..91c994d7c0 100644
--- a/test/stage1/behavior/bugs/1381.zig
+++ b/test/stage1/behavior/bugs/1381.zig
@@ -17,5 +17,5 @@ test "union that needs padding bytes inside an array" {
};
const a = as[0].B;
- std.debug.assertOrPanic(a.D == 1);
+ std.testing.expect(a.D == 1);
}
diff --git a/test/stage1/behavior/bugs/1421.zig b/test/stage1/behavior/bugs/1421.zig
index fbc932781a..48cf1ae2a6 100644
--- a/test/stage1/behavior/bugs/1421.zig
+++ b/test/stage1/behavior/bugs/1421.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const S = struct {
fn method() builtin.TypeInfo {
@@ -10,5 +10,5 @@ const S = struct {
test "functions with return type required to be comptime are generic" {
const ti = S.method();
- assertOrPanic(builtin.TypeId(ti) == builtin.TypeId.Struct);
+ expect(builtin.TypeId(ti) == builtin.TypeId.Struct);
}
diff --git a/test/stage1/behavior/bugs/1442.zig b/test/stage1/behavior/bugs/1442.zig
index e9dfd5d2ce..d5ea3f66fe 100644
--- a/test/stage1/behavior/bugs/1442.zig
+++ b/test/stage1/behavior/bugs/1442.zig
@@ -7,5 +7,5 @@ const Union = union(enum) {
test "const error union field alignment" {
var union_or_err: anyerror!Union = Union{ .Color = 1234 };
- std.debug.assertOrPanic((union_or_err catch unreachable).Color == 1234);
+ std.testing.expect((union_or_err catch unreachable).Color == 1234);
}
diff --git a/test/stage1/behavior/bugs/1486.zig b/test/stage1/behavior/bugs/1486.zig
index 0483e3828c..d1bb8d7053 100644
--- a/test/stage1/behavior/bugs/1486.zig
+++ b/test/stage1/behavior/bugs/1486.zig
@@ -1,11 +1,11 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const ptr = &global;
var global: u64 = 123;
test "constant pointer to global variable causes runtime load" {
global = 1234;
- assertOrPanic(&global == ptr);
- assertOrPanic(ptr.* == 1234);
+ expect(&global == ptr);
+ expect(ptr.* == 1234);
}
diff --git a/test/stage1/behavior/bugs/394.zig b/test/stage1/behavior/bugs/394.zig
index 766ad9e157..b1f0b6b605 100644
--- a/test/stage1/behavior/bugs/394.zig
+++ b/test/stage1/behavior/bugs/394.zig
@@ -7,12 +7,12 @@ const S = struct {
y: E,
};
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "bug 394 fixed" {
const x = S{
.x = 3,
.y = E{ .B = 1 },
};
- assertOrPanic(x.x == 3);
+ expect(x.x == 3);
}
diff --git a/test/stage1/behavior/bugs/655.zig b/test/stage1/behavior/bugs/655.zig
index 67ba6a231f..d4491bfc27 100644
--- a/test/stage1/behavior/bugs/655.zig
+++ b/test/stage1/behavior/bugs/655.zig
@@ -3,10 +3,10 @@ const other_file = @import("655_other_file.zig");
test "function with *const parameter with type dereferenced by namespace" {
const x: other_file.Integer = 1234;
- comptime std.debug.assertOrPanic(@typeOf(&x) == *const other_file.Integer);
+ comptime std.testing.expect(@typeOf(&x) == *const other_file.Integer);
foo(&x);
}
fn foo(x: *const other_file.Integer) void {
- std.debug.assertOrPanic(x.* == 1234);
+ std.testing.expect(x.* == 1234);
}
diff --git a/test/stage1/behavior/bugs/656.zig b/test/stage1/behavior/bugs/656.zig
index cb37fe67fe..159ec52d43 100644
--- a/test/stage1/behavior/bugs/656.zig
+++ b/test/stage1/behavior/bugs/656.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const PrefixOp = union(enum) {
Return,
@@ -22,7 +22,7 @@ fn foo(a: bool, b: bool) void {
PrefixOp.AddrOf => |addr_of_info| {
if (b) {}
if (addr_of_info.align_expr) |align_expr| {
- assertOrPanic(align_expr == 1234);
+ expect(align_expr == 1234);
}
},
PrefixOp.Return => {},
diff --git a/test/stage1/behavior/bugs/726.zig b/test/stage1/behavior/bugs/726.zig
index ce20480c63..dd2a135b56 100644
--- a/test/stage1/behavior/bugs/726.zig
+++ b/test/stage1/behavior/bugs/726.zig
@@ -1,9 +1,9 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "@ptrCast from const to nullable" {
const c: u8 = 4;
var x: ?*const u8 = @ptrCast(?*const u8, &c);
- assertOrPanic(x.?.* == 4);
+ expect(x.?.* == 4);
}
test "@ptrCast from var in empty struct to nullable" {
@@ -11,6 +11,6 @@ test "@ptrCast from var in empty struct to nullable" {
var c: u8 = 4;
};
var x: ?*const u8 = @ptrCast(?*const u8, &container.c);
- assertOrPanic(x.?.* == 4);
+ expect(x.?.* == 4);
}
diff --git a/test/stage1/behavior/bugs/920.zig b/test/stage1/behavior/bugs/920.zig
index e29c5c4acf..10c002f6ba 100644
--- a/test/stage1/behavior/bugs/920.zig
+++ b/test/stage1/behavior/bugs/920.zig
@@ -60,6 +60,6 @@ test "bug 920 fixed" {
};
for (NormalDist1.f) |_, i| {
- std.debug.assertOrPanic(NormalDist1.f[i] == NormalDist.f[i]);
+ std.testing.expect(NormalDist1.f[i] == NormalDist.f[i]);
}
}
diff --git a/test/stage1/behavior/byval_arg_var.zig b/test/stage1/behavior/byval_arg_var.zig
index 14ee212ce0..3794a965c6 100644
--- a/test/stage1/behavior/byval_arg_var.zig
+++ b/test/stage1/behavior/byval_arg_var.zig
@@ -6,7 +6,7 @@ test "pass string literal byvalue to a generic var param" {
start();
blowUpStack(10);
- std.debug.assertOrPanic(std.mem.eql(u8, result, "string literal"));
+ std.testing.expect(std.mem.eql(u8, result, "string literal"));
}
fn start() void {
diff --git a/test/stage1/behavior/cancel.zig b/test/stage1/behavior/cancel.zig
index 863da4bdb8..7fadf7f230 100644
--- a/test/stage1/behavior/cancel.zig
+++ b/test/stage1/behavior/cancel.zig
@@ -10,9 +10,9 @@ test "cancel forwards" {
const p = async<&da.allocator> f1() catch unreachable;
cancel p;
- std.debug.assertOrPanic(defer_f1);
- std.debug.assertOrPanic(defer_f2);
- std.debug.assertOrPanic(defer_f3);
+ std.testing.expect(defer_f1);
+ std.testing.expect(defer_f2);
+ std.testing.expect(defer_f3);
}
async fn f1() void {
@@ -47,10 +47,10 @@ test "cancel backwards" {
const p = async<&da.allocator> b1() catch unreachable;
cancel p;
- std.debug.assertOrPanic(defer_b1);
- std.debug.assertOrPanic(defer_b2);
- std.debug.assertOrPanic(defer_b3);
- std.debug.assertOrPanic(defer_b4);
+ std.testing.expect(defer_b1);
+ std.testing.expect(defer_b2);
+ std.testing.expect(defer_b3);
+ std.testing.expect(defer_b4);
}
async fn b1() void {
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 27f685a96e..8ed03f4936 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const mem = std.mem;
const maxInt = std.math.maxInt;
@@ -7,12 +7,12 @@ test "int to ptr cast" {
const x = usize(13);
const y = @intToPtr(*u8, x);
const z = @ptrToInt(y);
- assertOrPanic(z == 13);
+ expect(z == 13);
}
test "integer literal to pointer cast" {
const vga_mem = @intToPtr(*u16, 0xB8000);
- assertOrPanic(@ptrToInt(vga_mem) == 0xB8000);
+ expect(@ptrToInt(vga_mem) == 0xB8000);
}
test "pointer reinterpret const float to int" {
@@ -20,7 +20,7 @@ test "pointer reinterpret const float to int" {
const float_ptr = &float;
const int_ptr = @ptrCast(*const i32, float_ptr);
const int_val = int_ptr.*;
- assertOrPanic(int_val == 858993411);
+ expect(int_val == 858993411);
}
test "implicitly cast indirect pointer to maybe-indirect pointer" {
@@ -44,10 +44,10 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {
const p = &s;
const q = &p;
const r = &q;
- assertOrPanic(42 == S.constConst(q));
- assertOrPanic(42 == S.maybeConstConst(q));
- assertOrPanic(42 == S.constConstConst(r));
- assertOrPanic(42 == S.maybeConstConstConst(r));
+ expect(42 == S.constConst(q));
+ expect(42 == S.maybeConstConst(q));
+ expect(42 == S.constConstConst(r));
+ expect(42 == S.maybeConstConstConst(r));
}
test "explicit cast from integer to error type" {
@@ -57,14 +57,14 @@ test "explicit cast from integer to error type" {
fn testCastIntToErr(err: anyerror) void {
const x = @errorToInt(err);
const y = @intToError(x);
- assertOrPanic(error.ItBroke == y);
+ expect(error.ItBroke == y);
}
test "peer resolve arrays of different size to const slice" {
- assertOrPanic(mem.eql(u8, boolToStr(true), "true"));
- assertOrPanic(mem.eql(u8, boolToStr(false), "false"));
- comptime assertOrPanic(mem.eql(u8, boolToStr(true), "true"));
- comptime assertOrPanic(mem.eql(u8, boolToStr(false), "false"));
+ expect(mem.eql(u8, boolToStr(true), "true"));
+ expect(mem.eql(u8, boolToStr(false), "false"));
+ comptime expect(mem.eql(u8, boolToStr(true), "true"));
+ comptime expect(mem.eql(u8, boolToStr(false), "false"));
}
fn boolToStr(b: bool) []const u8 {
return if (b) "true" else "false";
@@ -77,8 +77,8 @@ test "peer resolve array and const slice" {
fn testPeerResolveArrayConstSlice(b: bool) void {
const value1 = if (b) "aoeu" else ([]const u8)("zz");
const value2 = if (b) ([]const u8)("zz") else "aoeu";
- assertOrPanic(mem.eql(u8, value1, "aoeu"));
- assertOrPanic(mem.eql(u8, value2, "zz"));
+ expect(mem.eql(u8, value1, "aoeu"));
+ expect(mem.eql(u8, value2, "zz"));
}
test "implicitly cast from T to anyerror!?T" {
@@ -92,14 +92,14 @@ const A = struct {
fn castToOptionalTypeError(z: i32) void {
const x = i32(1);
const y: anyerror!?i32 = x;
- assertOrPanic((try y).? == 1);
+ expect((try y).? == 1);
const f = z;
const g: anyerror!?i32 = f;
const a = A{ .a = z };
const b: anyerror!?A = a;
- assertOrPanic((b catch unreachable).?.a == 1);
+ expect((b catch unreachable).?.a == 1);
}
test "implicitly cast from int to anyerror!?T" {
@@ -114,7 +114,7 @@ fn implicitIntLitToOptional() void {
test "return null from fn() anyerror!?&T" {
const a = returnNullFromOptionalTypeErrorRef();
const b = returnNullLitFromOptionalTypeErrorRef();
- assertOrPanic((try a) == null and (try b) == null);
+ expect((try a) == null and (try b) == null);
}
fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
const a: ?*A = null;
@@ -125,11 +125,11 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
}
test "peer type resolution: ?T and T" {
- assertOrPanic(peerTypeTAndOptionalT(true, false).? == 0);
- assertOrPanic(peerTypeTAndOptionalT(false, false).? == 3);
+ expect(peerTypeTAndOptionalT(true, false).? == 0);
+ expect(peerTypeTAndOptionalT(false, false).? == 3);
comptime {
- assertOrPanic(peerTypeTAndOptionalT(true, false).? == 0);
- assertOrPanic(peerTypeTAndOptionalT(false, false).? == 3);
+ expect(peerTypeTAndOptionalT(true, false).? == 0);
+ expect(peerTypeTAndOptionalT(false, false).? == 3);
}
}
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
@@ -141,11 +141,11 @@ fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
}
test "peer type resolution: [0]u8 and []const u8" {
- assertOrPanic(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
- assertOrPanic(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+ expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+ expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
comptime {
- assertOrPanic(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
- assertOrPanic(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+ expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+ expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
}
}
fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
@@ -157,8 +157,8 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
}
test "implicitly cast from [N]T to ?[]const T" {
- assertOrPanic(mem.eql(u8, castToOptionalSlice().?, "hi"));
- comptime assertOrPanic(mem.eql(u8, castToOptionalSlice().?, "hi"));
+ expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
+ comptime expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
}
fn castToOptionalSlice() ?[]const u8 {
@@ -171,7 +171,7 @@ test "implicitly cast from [0]T to anyerror![]T" {
}
fn testCastZeroArrayToErrSliceMut() void {
- assertOrPanic((gimmeErrOrSlice() catch unreachable).len == 0);
+ expect((gimmeErrOrSlice() catch unreachable).len == 0);
}
fn gimmeErrOrSlice() anyerror![]u8 {
@@ -182,14 +182,14 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
{
var data = "hi";
const slice = data[0..];
- assertOrPanic((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
- assertOrPanic((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+ expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+ expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
}
comptime {
var data = "hi";
const slice = data[0..];
- assertOrPanic((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
- assertOrPanic((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
+ expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
+ expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
}
}
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
@@ -207,7 +207,7 @@ test "resolve undefined with integer" {
fn testResolveUndefWithInt(b: bool, x: i32) void {
const value = if (b) x else undefined;
if (b) {
- assertOrPanic(value == x);
+ expect(value == x);
}
}
@@ -219,17 +219,17 @@ test "implicit cast from &const [N]T to []const T" {
fn testCastConstArrayRefToConstSlice() void {
const blah = "aoeu";
const const_array_ref = &blah;
- assertOrPanic(@typeOf(const_array_ref) == *const [4]u8);
+ expect(@typeOf(const_array_ref) == *const [4]u8);
const slice: []const u8 = const_array_ref;
- assertOrPanic(mem.eql(u8, slice, "aoeu"));
+ expect(mem.eql(u8, slice, "aoeu"));
}
test "peer type resolution: error and [N]T" {
// TODO: implicit error!T to error!U where T can implicitly cast to U
- //assertOrPanic(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
- //comptime assertOrPanic(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
- assertOrPanic(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
- comptime assertOrPanic(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
+ //expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
+ //comptime expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
+ expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
+ comptime expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
}
//fn testPeerErrorAndArray(x: u8) error![]const u8 {
@@ -253,9 +253,9 @@ test "@floatToInt" {
fn testFloatToInts() void {
const x = i32(1e4);
- assertOrPanic(x == 10000);
+ expect(x == 10000);
const y = @floatToInt(i32, f32(1e4));
- assertOrPanic(y == 10000);
+ expect(y == 10000);
expectFloatToInt(f16, 255.1, u8, 255);
expectFloatToInt(f16, 127.2, i8, 127);
expectFloatToInt(f16, -128.2, i8, -128);
@@ -266,7 +266,7 @@ fn testFloatToInts() void {
}
fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void {
- assertOrPanic(@floatToInt(I, f) == i);
+ expect(@floatToInt(I, f) == i);
}
test "cast u128 to f128 and back" {
@@ -275,7 +275,7 @@ test "cast u128 to f128 and back" {
}
fn testCast128() void {
- assertOrPanic(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
+ expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
}
fn cast128Int(x: f128) u128 {
@@ -295,9 +295,9 @@ test "const slice widen cast" {
};
const u32_value = @bytesToSlice(u32, bytes[0..])[0];
- assertOrPanic(u32_value == 0x12121212);
+ expect(u32_value == 0x12121212);
- assertOrPanic(@bitCast(u32, bytes) == 0x12121212);
+ expect(@bitCast(u32, bytes) == 0x12121212);
}
test "single-item pointer of array to slice and to unknown length pointer" {
@@ -309,76 +309,76 @@ fn testCastPtrOfArrayToSliceAndPtr() void {
var array = "aoeu";
const x: [*]u8 = &array;
x[0] += 1;
- assertOrPanic(mem.eql(u8, array[0..], "boeu"));
+ expect(mem.eql(u8, array[0..], "boeu"));
const y: []u8 = &array;
y[0] += 1;
- assertOrPanic(mem.eql(u8, array[0..], "coeu"));
+ expect(mem.eql(u8, array[0..], "coeu"));
}
test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
const window_name = [1][*]const u8{c"window name"};
const x: [*]const ?[*]const u8 = &window_name;
- assertOrPanic(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name"));
+ expect(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name"));
}
test "@intCast comptime_int" {
const result = @intCast(i32, 1234);
- assertOrPanic(@typeOf(result) == i32);
- assertOrPanic(result == 1234);
+ expect(@typeOf(result) == i32);
+ expect(result == 1234);
}
test "@floatCast comptime_int and comptime_float" {
{
const result = @floatCast(f16, 1234);
- assertOrPanic(@typeOf(result) == f16);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f16);
+ expect(result == 1234.0);
}
{
const result = @floatCast(f16, 1234.0);
- assertOrPanic(@typeOf(result) == f16);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f16);
+ expect(result == 1234.0);
}
{
const result = @floatCast(f32, 1234);
- assertOrPanic(@typeOf(result) == f32);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f32);
+ expect(result == 1234.0);
}
{
const result = @floatCast(f32, 1234.0);
- assertOrPanic(@typeOf(result) == f32);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f32);
+ expect(result == 1234.0);
}
}
test "comptime_int @intToFloat" {
{
const result = @intToFloat(f16, 1234);
- assertOrPanic(@typeOf(result) == f16);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f16);
+ expect(result == 1234.0);
}
{
const result = @intToFloat(f32, 1234);
- assertOrPanic(@typeOf(result) == f32);
- assertOrPanic(result == 1234.0);
+ expect(@typeOf(result) == f32);
+ expect(result == 1234.0);
}
}
test "@bytesToSlice keeps pointer alignment" {
var bytes = []u8{ 0x01, 0x02, 0x03, 0x04 };
const numbers = @bytesToSlice(u32, bytes[0..]);
- comptime assertOrPanic(@typeOf(numbers) == []align(@alignOf(@typeOf(bytes))) u32);
+ comptime expect(@typeOf(numbers) == []align(@alignOf(@typeOf(bytes))) u32);
}
test "@intCast i32 to u7" {
var x: u128 = maxInt(u128);
var y: i32 = 120;
var z = x >> @intCast(u7, y);
- assertOrPanic(z == 0xff);
+ expect(z == 0xff);
}
test "implicit cast undefined to optional" {
- assertOrPanic(MakeType(void).getNull() == null);
- assertOrPanic(MakeType(void).getNonNull() != null);
+ expect(MakeType(void).getNull() == null);
+ expect(MakeType(void).getNonNull() != null);
}
fn MakeType(comptime T: type) type {
@@ -398,16 +398,16 @@ test "implicit cast from *[N]T to ?[*]T" {
var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
x = &y;
- assertOrPanic(std.mem.eql(u16, x.?[0..4], y[0..4]));
+ expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
x.?[0] = 8;
y[3] = 6;
- assertOrPanic(std.mem.eql(u16, x.?[0..4], y[0..4]));
+ expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
}
test "implicit cast from *T to ?*c_void" {
var a: u8 = 1;
incrementVoidPtrValue(&a);
- std.debug.assertOrPanic(a == 2);
+ std.testing.expect(a == 2);
}
fn incrementVoidPtrValue(value: ?*c_void) void {
@@ -417,7 +417,7 @@ fn incrementVoidPtrValue(value: ?*c_void) void {
test "implicit cast from [*]T to ?*c_void" {
var a = []u8{ 3, 2, 1 };
incrementVoidPtrArray(a[0..].ptr, 3);
- assertOrPanic(std.mem.eql(u8, a, []u8{ 4, 3, 2 }));
+ expect(std.mem.eql(u8, a, []u8{ 4, 3, 2 }));
}
fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
@@ -441,27 +441,27 @@ pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
pub const PFN_void = extern fn (*c_void) void;
fn foobar(func: PFN_void) void {
- std.debug.assertOrPanic(@ptrToInt(func) == maxInt(usize));
+ std.testing.expect(@ptrToInt(func) == maxInt(usize));
}
test "implicit ptr to *c_void" {
var a: u32 = 1;
var ptr: *c_void = &a;
var b: *u32 = @ptrCast(*u32, ptr);
- assertOrPanic(b.* == 1);
+ expect(b.* == 1);
var ptr2: ?*c_void = &a;
var c: *u32 = @ptrCast(*u32, ptr2.?);
- assertOrPanic(c.* == 1);
+ expect(c.* == 1);
}
test "@intCast to comptime_int" {
- assertOrPanic(@intCast(comptime_int, 0) == 0);
+ expect(@intCast(comptime_int, 0) == 0);
}
test "implicit cast comptime numbers to any type when the value fits" {
const a: u64 = 255;
var b: u8 = a;
- assertOrPanic(b == 255);
+ expect(b == 255);
}
test "@intToEnum passed a comptime_int to an enum with one item" {
@@ -469,14 +469,14 @@ test "@intToEnum passed a comptime_int to an enum with one item" {
A,
};
const x = @intToEnum(E, 0);
- assertOrPanic(x == E.A);
+ expect(x == E.A);
}
test "@intCast to u0 and use the result" {
const S = struct {
fn doTheTest(zero: u1, one: u1, bigzero: i32) void {
- assertOrPanic((one << @intCast(u0, bigzero)) == 1);
- assertOrPanic((zero << @intCast(u0, bigzero)) == 0);
+ expect((one << @intCast(u0, bigzero)) == 1);
+ expect((zero << @intCast(u0, bigzero)) == 0);
}
};
S.doTheTest(0, 1, 0);
diff --git a/test/stage1/behavior/const_slice_child.zig b/test/stage1/behavior/const_slice_child.zig
index 5b9b70a558..57044d8aae 100644
--- a/test/stage1/behavior/const_slice_child.zig
+++ b/test/stage1/behavior/const_slice_child.zig
@@ -1,5 +1,6 @@
-const debug = @import("std").debug;
-const assertOrPanic = debug.assertOrPanic;
+const std = @import("std");
+const debug = std.debug;
+const expect = std.testing.expect;
var argv: [*]const [*]const u8 = undefined;
@@ -15,10 +16,10 @@ test "const slice child" {
}
fn foo(args: [][]const u8) void {
- assertOrPanic(args.len == 3);
- assertOrPanic(streql(args[0], "one"));
- assertOrPanic(streql(args[1], "two"));
- assertOrPanic(streql(args[2], "three"));
+ expect(args.len == 3);
+ expect(streql(args[0], "one"));
+ expect(streql(args[1], "two"));
+ expect(streql(args[2], "three"));
}
fn bar(argc: usize) void {
diff --git a/test/stage1/behavior/coroutine_await_struct.zig b/test/stage1/behavior/coroutine_await_struct.zig
index 6ca2a301ec..29f77bf67c 100644
--- a/test/stage1/behavior/coroutine_await_struct.zig
+++ b/test/stage1/behavior/coroutine_await_struct.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const Foo = struct {
x: i32,
@@ -18,8 +18,8 @@ test "coroutine await struct" {
await_seq('f');
resume await_a_promise;
await_seq('i');
- assertOrPanic(await_final_result.x == 1234);
- assertOrPanic(std.mem.eql(u8, await_points, "abcdefghi"));
+ expect(await_final_result.x == 1234);
+ expect(std.mem.eql(u8, await_points, "abcdefghi"));
}
async fn await_amain() void {
await_seq('b');
diff --git a/test/stage1/behavior/coroutines.zig b/test/stage1/behavior/coroutines.zig
index a2327c5060..be977bbfce 100644
--- a/test/stage1/behavior/coroutines.zig
+++ b/test/stage1/behavior/coroutines.zig
@@ -1,6 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
var x: i32 = 1;
@@ -9,9 +9,9 @@ test "create a coroutine and cancel it" {
defer da.deinit();
const p = try async<&da.allocator> simpleAsyncFn();
- comptime assertOrPanic(@typeOf(p) == promise->void);
+ comptime expect(@typeOf(p) == promise->void);
cancel p;
- assertOrPanic(x == 2);
+ expect(x == 2);
}
async fn simpleAsyncFn() void {
x += 1;
@@ -31,7 +31,7 @@ test "coroutine suspend, resume, cancel" {
cancel p;
seq('g');
- assertOrPanic(std.mem.eql(u8, points, "abcdefg"));
+ expect(std.mem.eql(u8, points, "abcdefg"));
}
async fn testAsyncSeq() void {
defer seq('e');
@@ -53,9 +53,9 @@ test "coroutine suspend with block" {
defer da.deinit();
const p = try async<&da.allocator> testSuspendBlock();
- std.debug.assertOrPanic(!result);
+ std.testing.expect(!result);
resume a_promise;
- std.debug.assertOrPanic(result);
+ std.testing.expect(result);
cancel p;
}
@@ -63,13 +63,13 @@ var a_promise: promise = undefined;
var result = false;
async fn testSuspendBlock() void {
suspend {
- comptime assertOrPanic(@typeOf(@handle()) == promise->void);
+ comptime expect(@typeOf(@handle()) == promise->void);
a_promise = @handle();
}
//Test to make sure that @handle() works as advertised (issue #1296)
//var our_handle: promise = @handle();
- assertOrPanic(a_promise == @handle());
+ expect(a_promise == @handle());
result = true;
}
@@ -86,8 +86,8 @@ test "coroutine await" {
await_seq('f');
resume await_a_promise;
await_seq('i');
- assertOrPanic(await_final_result == 1234);
- assertOrPanic(std.mem.eql(u8, await_points, "abcdefghi"));
+ expect(await_final_result == 1234);
+ expect(std.mem.eql(u8, await_points, "abcdefghi"));
}
async fn await_amain() void {
await_seq('b');
@@ -123,8 +123,8 @@ test "coroutine await early return" {
early_seq('a');
const p = async<&da.allocator> early_amain() catch @panic("out of memory");
early_seq('f');
- assertOrPanic(early_final_result == 1234);
- assertOrPanic(std.mem.eql(u8, early_points, "abcdef"));
+ expect(early_final_result == 1234);
+ expect(std.mem.eql(u8, early_points, "abcdef"));
}
async fn early_amain() void {
early_seq('b');
@@ -170,7 +170,7 @@ test "async function with dot syntax" {
defer da.deinit();
const p = try async<&da.allocator> S.foo();
cancel p;
- assertOrPanic(S.y == 2);
+ expect(S.y == 2);
}
test "async fn pointer in a struct field" {
@@ -182,9 +182,9 @@ test "async fn pointer in a struct field" {
var da = std.heap.DirectAllocator.init();
defer da.deinit();
const p = (async<&da.allocator> foo.bar(&data)) catch unreachable;
- assertOrPanic(data == 2);
+ expect(data == 2);
cancel p;
- assertOrPanic(data == 4);
+ expect(data == 4);
}
async<*std.mem.Allocator> fn simpleAsyncFn2(y: *i32) void {
defer y.* += 2;
@@ -230,9 +230,9 @@ async fn suspendThenFail() anyerror!void {
}
async fn printTrace(p: promise->(anyerror!void)) void {
(await p) catch |e| {
- std.debug.assertOrPanic(e == error.Fail);
+ std.testing.expect(e == error.Fail);
if (@errorReturnTrace()) |trace| {
- assertOrPanic(trace.index == 1);
+ expect(trace.index == 1);
} else switch (builtin.mode) {
builtin.Mode.Debug, builtin.Mode.ReleaseSafe => @panic("expected return trace"),
builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => {},
@@ -246,7 +246,7 @@ test "break from suspend" {
var my_result: i32 = 1;
const p = try async testBreakFromSuspend(&my_result);
cancel p;
- std.debug.assertOrPanic(my_result == 2);
+ std.testing.expect(my_result == 2);
}
async fn testBreakFromSuspend(my_result: *i32) void {
suspend {
diff --git a/test/stage1/behavior/defer.zig b/test/stage1/behavior/defer.zig
index 6c6c60311e..0bb9125e7c 100644
--- a/test/stage1/behavior/defer.zig
+++ b/test/stage1/behavior/defer.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
var result: [3]u8 = undefined;
var index: usize = undefined;
@@ -21,18 +21,18 @@ fn runSomeErrorDefers(x: bool) !bool {
}
test "mixing normal and error defers" {
- assertOrPanic(runSomeErrorDefers(true) catch unreachable);
- assertOrPanic(result[0] == 'c');
- assertOrPanic(result[1] == 'a');
+ expect(runSomeErrorDefers(true) catch unreachable);
+ expect(result[0] == 'c');
+ expect(result[1] == 'a');
const ok = runSomeErrorDefers(false) catch |err| x: {
- assertOrPanic(err == error.FalseNotAllowed);
+ expect(err == error.FalseNotAllowed);
break :x true;
};
- assertOrPanic(ok);
- assertOrPanic(result[0] == 'c');
- assertOrPanic(result[1] == 'b');
- assertOrPanic(result[2] == 'a');
+ expect(ok);
+ expect(result[0] == 'c');
+ expect(result[1] == 'b');
+ expect(result[2] == 'a');
}
test "break and continue inside loop inside defer expression" {
@@ -47,7 +47,7 @@ fn testBreakContInDefer(x: usize) void {
if (i < 5) continue;
if (i == 5) break;
}
- assertOrPanic(i == 5);
+ expect(i == 5);
}
}
@@ -59,11 +59,11 @@ test "defer and labeled break" {
break :blk;
}
- assertOrPanic(i == 1);
+ expect(i == 1);
}
test "errdefer does not apply to fn inside fn" {
- if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| assertOrPanic(e == error.Bad);
+ if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| expect(e == error.Bad);
}
fn testNestedFnErrDefer() anyerror!void {
diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig
index 9de138ef78..899aeea67d 100644
--- a/test/stage1/behavior/enum.zig
+++ b/test/stage1/behavior/enum.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
test "enum type" {
@@ -11,16 +11,16 @@ test "enum type" {
};
const bar = Bar.B;
- assertOrPanic(bar == Bar.B);
- assertOrPanic(@memberCount(Foo) == 3);
- assertOrPanic(@memberCount(Bar) == 4);
- assertOrPanic(@sizeOf(Foo) == @sizeOf(FooNoVoid));
- assertOrPanic(@sizeOf(Bar) == 1);
+ expect(bar == Bar.B);
+ expect(@memberCount(Foo) == 3);
+ expect(@memberCount(Bar) == 4);
+ expect(@sizeOf(Foo) == @sizeOf(FooNoVoid));
+ expect(@sizeOf(Bar) == 1);
}
test "enum as return value" {
switch (returnAnInt(13)) {
- Foo.One => |value| assertOrPanic(value == 13),
+ Foo.One => |value| expect(value == 13),
else => unreachable,
}
}
@@ -92,14 +92,14 @@ test "enum to int" {
}
fn shouldEqual(n: Number, expected: u3) void {
- assertOrPanic(@enumToInt(n) == expected);
+ expect(@enumToInt(n) == expected);
}
test "int to enum" {
testIntToEnumEval(3);
}
fn testIntToEnumEval(x: i32) void {
- assertOrPanic(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three);
+ expect(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three);
}
const IntToEnumNumber = enum {
Zero,
@@ -110,8 +110,8 @@ const IntToEnumNumber = enum {
};
test "@tagName" {
- assertOrPanic(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
- comptime assertOrPanic(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+ expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
+ comptime expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
}
fn testEnumTagNameBare(n: BareNumber) []const u8 {
@@ -126,8 +126,8 @@ const BareNumber = enum {
test "enum alignment" {
comptime {
- assertOrPanic(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
- assertOrPanic(@alignOf(AlignTestEnum) >= @alignOf(u64));
+ expect(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
+ expect(@alignOf(AlignTestEnum) >= @alignOf(u64));
}
}
@@ -663,10 +663,10 @@ const ValueCount257 = enum {
test "enum sizes" {
comptime {
- assertOrPanic(@sizeOf(ValueCount1) == 0);
- assertOrPanic(@sizeOf(ValueCount2) == 1);
- assertOrPanic(@sizeOf(ValueCount256) == 1);
- assertOrPanic(@sizeOf(ValueCount257) == 2);
+ expect(@sizeOf(ValueCount1) == 0);
+ expect(@sizeOf(ValueCount2) == 1);
+ expect(@sizeOf(ValueCount256) == 1);
+ expect(@sizeOf(ValueCount257) == 2);
}
}
@@ -685,12 +685,12 @@ test "set enum tag type" {
{
var x = Small.One;
x = Small.Two;
- comptime assertOrPanic(@TagType(Small) == u2);
+ comptime expect(@TagType(Small) == u2);
}
{
var x = Small2.One;
x = Small2.Two;
- comptime assertOrPanic(@TagType(Small2) == u2);
+ comptime expect(@TagType(Small2) == u2);
}
}
@@ -737,17 +737,17 @@ const bit_field_1 = BitFieldOfEnums{
test "bit field access with enum fields" {
var data = bit_field_1;
- assertOrPanic(getA(&data) == A.Two);
- assertOrPanic(getB(&data) == B.Three3);
- assertOrPanic(getC(&data) == C.Four4);
- comptime assertOrPanic(@sizeOf(BitFieldOfEnums) == 1);
+ expect(getA(&data) == A.Two);
+ expect(getB(&data) == B.Three3);
+ expect(getC(&data) == C.Four4);
+ comptime expect(@sizeOf(BitFieldOfEnums) == 1);
data.b = B.Four3;
- assertOrPanic(data.b == B.Four3);
+ expect(data.b == B.Four3);
data.a = A.Three;
- assertOrPanic(data.a == A.Three);
- assertOrPanic(data.b == B.Four3);
+ expect(data.a == A.Three);
+ expect(data.b == B.Four3);
}
fn getA(data: *const BitFieldOfEnums) A {
@@ -768,7 +768,7 @@ test "casting enum to its tag type" {
}
fn testCastEnumToTagType(value: Small2) void {
- assertOrPanic(@enumToInt(value) == 1);
+ expect(@enumToInt(value) == 1);
}
const MultipleChoice = enum(u32) {
@@ -784,8 +784,8 @@ test "enum with specified tag values" {
}
fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
- assertOrPanic(@enumToInt(x) == 60);
- assertOrPanic(1234 == switch (x) {
+ expect(@enumToInt(x) == 60);
+ expect(1234 == switch (x) {
MultipleChoice.A => 1,
MultipleChoice.B => 2,
MultipleChoice.C => u32(1234),
@@ -811,8 +811,8 @@ test "enum with specified and unspecified tag values" {
}
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
- assertOrPanic(@enumToInt(x) == 1000);
- assertOrPanic(1234 == switch (x) {
+ expect(@enumToInt(x) == 1000);
+ expect(1234 == switch (x) {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
MultipleChoice2.C => 3,
@@ -826,8 +826,8 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
}
test "cast integer literal to enum" {
- assertOrPanic(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1);
- assertOrPanic(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B);
+ expect(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1);
+ expect(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B);
}
const EnumWithOneMember = enum {
@@ -865,14 +865,14 @@ const EnumWithTagValues = enum(u4) {
D = 1 << 3,
};
test "enum with tag values don't require parens" {
- assertOrPanic(@enumToInt(EnumWithTagValues.C) == 0b0100);
+ expect(@enumToInt(EnumWithTagValues.C) == 0b0100);
}
test "enum with 1 field but explicit tag type should still have the tag type" {
const Enum = enum(u8) {
B = 2,
};
- comptime @import("std").debug.assertOrPanic(@sizeOf(Enum) == @sizeOf(u8));
+ comptime @import("std").testing.expect(@sizeOf(Enum) == @sizeOf(u8));
}
test "empty extern enum with members" {
@@ -881,7 +881,7 @@ test "empty extern enum with members" {
B,
C,
};
- assertOrPanic(@sizeOf(E) == @sizeOf(c_int));
+ expect(@sizeOf(E) == @sizeOf(c_int));
}
test "tag name with assigned enum values" {
@@ -890,5 +890,5 @@ test "tag name with assigned enum values" {
B = 0,
};
var b = LocalFoo.B;
- assertOrPanic(mem.eql(u8, @tagName(b), "B"));
+ expect(mem.eql(u8, @tagName(b), "B"));
}
diff --git a/test/stage1/behavior/enum_with_members.zig b/test/stage1/behavior/enum_with_members.zig
index 49af1ceae7..2e022a3427 100644
--- a/test/stage1/behavior/enum_with_members.zig
+++ b/test/stage1/behavior/enum_with_members.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
const fmt = @import("std").fmt;
@@ -19,9 +19,9 @@ test "enum with members" {
const b = ET{ .UINT = 42 };
var buf: [20]u8 = undefined;
- assertOrPanic((a.print(buf[0..]) catch unreachable) == 3);
- assertOrPanic(mem.eql(u8, buf[0..3], "-42"));
+ expect((a.print(buf[0..]) catch unreachable) == 3);
+ expect(mem.eql(u8, buf[0..3], "-42"));
- assertOrPanic((b.print(buf[0..]) catch unreachable) == 2);
- assertOrPanic(mem.eql(u8, buf[0..2], "42"));
+ expect((b.print(buf[0..]) catch unreachable) == 2);
+ expect(mem.eql(u8, buf[0..2], "42"));
}
diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig
index c7e38712bc..265ddd9d6c 100644
--- a/test/stage1/behavior/error.zig
+++ b/test/stage1/behavior/error.zig
@@ -1,6 +1,6 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
-const assertError = std.debug.assertError;
+const expect = std.testing.expect;
+const expectError = std.testing.expectError;
const mem = std.mem;
const builtin = @import("builtin");
@@ -19,7 +19,7 @@ pub fn baz() anyerror!i32 {
}
test "error wrapping" {
- assertOrPanic((baz() catch unreachable) == 15);
+ expect((baz() catch unreachable) == 15);
}
fn gimmeItBroke() []const u8 {
@@ -27,14 +27,14 @@ fn gimmeItBroke() []const u8 {
}
test "@errorName" {
- assertOrPanic(mem.eql(u8, @errorName(error.AnError), "AnError"));
- assertOrPanic(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
+ expect(mem.eql(u8, @errorName(error.AnError), "AnError"));
+ expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
}
test "error values" {
const a = @errorToInt(error.err1);
const b = @errorToInt(error.err2);
- assertOrPanic(a != b);
+ expect(a != b);
}
test "redefinition of error values allowed" {
@@ -47,8 +47,8 @@ fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
test "error binary operator" {
const a = errBinaryOperatorG(true) catch 3;
const b = errBinaryOperatorG(false) catch 3;
- assertOrPanic(a == 3);
- assertOrPanic(b == 10);
+ expect(a == 3);
+ expect(b == 10);
}
fn errBinaryOperatorG(x: bool) anyerror!isize {
return if (x) error.ItBroke else isize(10);
@@ -56,7 +56,7 @@ fn errBinaryOperatorG(x: bool) anyerror!isize {
test "unwrap simple value from error" {
const i = unwrapSimpleValueFromErrorDo() catch unreachable;
- assertOrPanic(i == 13);
+ expect(i == 13);
}
fn unwrapSimpleValueFromErrorDo() anyerror!isize {
return 13;
@@ -82,10 +82,10 @@ test "error union type " {
fn testErrorUnionType() void {
const x: anyerror!i32 = 1234;
- if (x) |value| assertOrPanic(value == 1234) else |_| unreachable;
- assertOrPanic(@typeId(@typeOf(x)) == builtin.TypeId.ErrorUnion);
- assertOrPanic(@typeId(@typeOf(x).ErrorSet) == builtin.TypeId.ErrorSet);
- assertOrPanic(@typeOf(x).ErrorSet == anyerror);
+ if (x) |value| expect(value == 1234) else |_| unreachable;
+ expect(@typeId(@typeOf(x)) == builtin.TypeId.ErrorUnion);
+ expect(@typeId(@typeOf(x).ErrorSet) == builtin.TypeId.ErrorSet);
+ expect(@typeOf(x).ErrorSet == anyerror);
}
test "error set type" {
@@ -99,12 +99,12 @@ const MyErrSet = error{
};
fn testErrorSetType() void {
- assertOrPanic(@memberCount(MyErrSet) == 2);
+ expect(@memberCount(MyErrSet) == 2);
const a: MyErrSet!i32 = 5678;
const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
- if (a) |value| assertOrPanic(value == 5678) else |err| switch (err) {
+ if (a) |value| expect(value == 5678) else |err| switch (err) {
error.OutOfMemory => unreachable,
error.FileNotFound => unreachable,
}
@@ -127,7 +127,7 @@ const Set2 = error{
fn testExplicitErrorSetCast(set1: Set1) void {
var x = @errSetCast(Set2, set1);
var y = @errSetCast(Set1, x);
- assertOrPanic(y == error.A);
+ expect(y == error.A);
}
test "comptime test error for empty error set" {
@@ -138,12 +138,12 @@ test "comptime test error for empty error set" {
const EmptyErrorSet = error{};
fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
- if (x) |v| assertOrPanic(v == 1234) else |err| @compileError("bad");
+ if (x) |v| expect(v == 1234) else |err| @compileError("bad");
}
test "syntax: optional operator in front of error union operator" {
comptime {
- assertOrPanic(?(anyerror!i32) == ?(anyerror!i32));
+ expect(?(anyerror!i32) == ?(anyerror!i32));
}
}
@@ -173,7 +173,7 @@ fn testErrorUnionPeerTypeResolution(x: i32) void {
if (y) |_| {
@panic("expected error");
} else |e| {
- assertOrPanic(e == error.A);
+ expect(e == error.A);
}
}
@@ -282,13 +282,13 @@ test "nested error union function call in optional unwrap" {
return null;
}
};
- assertOrPanic((try S.errorable()) == 1234);
- assertError(S.errorable2(), error.Failure);
- assertError(S.errorable3(), error.Other);
+ expect((try S.errorable()) == 1234);
+ expectError(error.Failure, S.errorable2());
+ expectError(error.Other, S.errorable3());
comptime {
- assertOrPanic((try S.errorable()) == 1234);
- assertError(S.errorable2(), error.Failure);
- assertError(S.errorable3(), error.Other);
+ expect((try S.errorable()) == 1234);
+ expectError(error.Failure, S.errorable2());
+ expectError(error.Other, S.errorable3());
}
}
@@ -303,7 +303,7 @@ test "widen cast integer payload of error union function call" {
return 1234;
}
};
- assertOrPanic((try S.errorable()) == 1234);
+ expect((try S.errorable()) == 1234);
}
test "return function call to error set from error union function" {
@@ -316,17 +316,17 @@ test "return function call to error set from error union function" {
return error.Failure;
}
};
- assertError(S.errorable(), error.Failure);
- comptime assertError(S.errorable(), error.Failure);
+ expectError(error.Failure, S.errorable());
+ comptime expectError(error.Failure, S.errorable());
}
test "optional error set is the same size as error set" {
- comptime assertOrPanic(@sizeOf(?anyerror) == @sizeOf(anyerror));
+ comptime expect(@sizeOf(?anyerror) == @sizeOf(anyerror));
const S = struct {
fn returnsOptErrSet() ?anyerror {
return null;
}
};
- assertOrPanic(S.returnsOptErrSet() == null);
- comptime assertOrPanic(S.returnsOptErrSet() == null);
+ expect(S.returnsOptErrSet() == null);
+ comptime expect(S.returnsOptErrSet() == null);
}
diff --git a/test/stage1/behavior/eval.zig b/test/stage1/behavior/eval.zig
index 0d1ecfab5b..5976761f77 100644
--- a/test/stage1/behavior/eval.zig
+++ b/test/stage1/behavior/eval.zig
@@ -1,9 +1,9 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const builtin = @import("builtin");
test "compile time recursion" {
- assertOrPanic(some_data.len == 21);
+ expect(some_data.len == 21);
}
var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined;
fn fibonacci(x: i32) i32 {
@@ -16,7 +16,7 @@ fn unwrapAndAddOne(blah: ?i32) i32 {
}
const should_be_1235 = unwrapAndAddOne(1234);
test "static add one" {
- assertOrPanic(should_be_1235 == 1235);
+ expect(should_be_1235 == 1235);
}
test "inlined loop" {
@@ -24,7 +24,7 @@ test "inlined loop" {
comptime var sum = 0;
inline while (i <= 5) : (i += 1)
sum += i;
- assertOrPanic(sum == 15);
+ expect(sum == 15);
}
fn gimme1or2(comptime a: bool) i32 {
@@ -34,12 +34,12 @@ fn gimme1or2(comptime a: bool) i32 {
return z;
}
test "inline variable gets result of const if" {
- assertOrPanic(gimme1or2(true) == 1);
- assertOrPanic(gimme1or2(false) == 2);
+ expect(gimme1or2(true) == 1);
+ expect(gimme1or2(false) == 2);
}
test "static function evaluation" {
- assertOrPanic(statically_added_number == 3);
+ expect(statically_added_number == 3);
}
const statically_added_number = staticAdd(1, 2);
fn staticAdd(a: i32, b: i32) i32 {
@@ -47,8 +47,8 @@ fn staticAdd(a: i32, b: i32) i32 {
}
test "const expr eval on single expr blocks" {
- assertOrPanic(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
- comptime assertOrPanic(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
+ expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
+ comptime expect(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
}
fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
@@ -64,10 +64,10 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
}
test "statically initialized list" {
- assertOrPanic(static_point_list[0].x == 1);
- assertOrPanic(static_point_list[0].y == 2);
- assertOrPanic(static_point_list[1].x == 3);
- assertOrPanic(static_point_list[1].y == 4);
+ expect(static_point_list[0].x == 1);
+ expect(static_point_list[0].y == 2);
+ expect(static_point_list[1].x == 3);
+ expect(static_point_list[1].y == 4);
}
const Point = struct {
x: i32,
@@ -85,8 +85,8 @@ fn makePoint(x: i32, y: i32) Point {
}
test "static eval list init" {
- assertOrPanic(static_vec3.data[2] == 1.0);
- assertOrPanic(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
+ expect(static_vec3.data[2] == 1.0);
+ expect(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
}
const static_vec3 = vec3(0.0, 0.0, 1.0);
pub const Vec3 = struct {
@@ -102,12 +102,12 @@ pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
test "constant expressions" {
var array: [array_size]u8 = undefined;
- assertOrPanic(@sizeOf(@typeOf(array)) == 20);
+ expect(@sizeOf(@typeOf(array)) == 20);
}
const array_size: u8 = 20;
test "constant struct with negation" {
- assertOrPanic(vertices[0].x == -0.6);
+ expect(vertices[0].x == -0.6);
}
const Vertex = struct {
x: f32,
@@ -142,7 +142,7 @@ const vertices = []Vertex{
test "statically initialized struct" {
st_init_str_foo.x += 1;
- assertOrPanic(st_init_str_foo.x == 14);
+ expect(st_init_str_foo.x == 14);
}
const StInitStrFoo = struct {
x: i32,
@@ -155,7 +155,7 @@ var st_init_str_foo = StInitStrFoo{
test "statically initalized array literal" {
const y: [4]u8 = st_init_arr_lit_x;
- assertOrPanic(y[3] == 4);
+ expect(y[3] == 4);
}
const st_init_arr_lit_x = []u8{
1,
@@ -167,15 +167,15 @@ const st_init_arr_lit_x = []u8{
test "const slice" {
comptime {
const a = "1234567890";
- assertOrPanic(a.len == 10);
+ expect(a.len == 10);
const b = a[1..2];
- assertOrPanic(b.len == 1);
- assertOrPanic(b[0] == '2');
+ expect(b.len == 1);
+ expect(b[0] == '2');
}
}
test "try to trick eval with runtime if" {
- assertOrPanic(testTryToTrickEvalWithRuntimeIf(true) == 10);
+ expect(testTryToTrickEvalWithRuntimeIf(true) == 10);
}
fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
@@ -201,16 +201,16 @@ fn letsTryToCompareBools(a: bool, b: bool) bool {
return max(bool, a, b);
}
test "inlined block and runtime block phi" {
- assertOrPanic(letsTryToCompareBools(true, true));
- assertOrPanic(letsTryToCompareBools(true, false));
- assertOrPanic(letsTryToCompareBools(false, true));
- assertOrPanic(!letsTryToCompareBools(false, false));
+ expect(letsTryToCompareBools(true, true));
+ expect(letsTryToCompareBools(true, false));
+ expect(letsTryToCompareBools(false, true));
+ expect(!letsTryToCompareBools(false, false));
comptime {
- assertOrPanic(letsTryToCompareBools(true, true));
- assertOrPanic(letsTryToCompareBools(true, false));
- assertOrPanic(letsTryToCompareBools(false, true));
- assertOrPanic(!letsTryToCompareBools(false, false));
+ expect(letsTryToCompareBools(true, true));
+ expect(letsTryToCompareBools(true, false));
+ expect(letsTryToCompareBools(false, true));
+ expect(!letsTryToCompareBools(false, false));
}
}
@@ -255,14 +255,14 @@ fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
}
test "comptime iterate over fn ptr list" {
- assertOrPanic(performFn('t', 1) == 6);
- assertOrPanic(performFn('o', 0) == 1);
- assertOrPanic(performFn('w', 99) == 99);
+ expect(performFn('t', 1) == 6);
+ expect(performFn('o', 0) == 1);
+ expect(performFn('w', 99) == 99);
}
test "eval @setRuntimeSafety at compile-time" {
const result = comptime fnWithSetRuntimeSafety();
- assertOrPanic(result == 1234);
+ expect(result == 1234);
}
fn fnWithSetRuntimeSafety() i32 {
@@ -272,7 +272,7 @@ fn fnWithSetRuntimeSafety() i32 {
test "eval @setFloatMode at compile-time" {
const result = comptime fnWithFloatMode();
- assertOrPanic(result == 1234.0);
+ expect(result == 1234.0);
}
fn fnWithFloatMode() f32 {
@@ -293,15 +293,15 @@ var simple_struct = SimpleStruct{ .field = 1234 };
const bound_fn = simple_struct.method;
test "call method on bound fn referring to var instance" {
- assertOrPanic(bound_fn() == 1237);
+ expect(bound_fn() == 1237);
}
test "ptr to local array argument at comptime" {
comptime {
var bytes: [10]u8 = undefined;
modifySomeBytes(bytes[0..]);
- assertOrPanic(bytes[0] == 'a');
- assertOrPanic(bytes[9] == 'b');
+ expect(bytes[0] == 'a');
+ expect(bytes[9] == 'b');
}
}
@@ -329,9 +329,9 @@ fn testCompTimeUIntComparisons(x: u32) void {
}
test "const ptr to variable data changes at runtime" {
- assertOrPanic(foo_ref.name[0] == 'a');
+ expect(foo_ref.name[0] == 'a');
foo_ref.name = "b";
- assertOrPanic(foo_ref.name[0] == 'b');
+ expect(foo_ref.name[0] == 'b');
}
const Foo = struct {
@@ -342,8 +342,8 @@ var foo_contents = Foo{ .name = "a" };
const foo_ref = &foo_contents;
test "create global array with for loop" {
- assertOrPanic(global_array[5] == 5 * 5);
- assertOrPanic(global_array[9] == 9 * 9);
+ expect(global_array[5] == 5 * 5);
+ expect(global_array[9] == 9 * 9);
}
const global_array = x: {
@@ -358,7 +358,7 @@ test "compile-time downcast when the bits fit" {
comptime {
const spartan_count: u16 = 255;
const byte = @intCast(u8, spartan_count);
- assertOrPanic(byte == 255);
+ expect(byte == 255);
}
}
@@ -366,44 +366,44 @@ const hi1 = "hi";
const hi2 = hi1;
test "const global shares pointer with other same one" {
assertEqualPtrs(&hi1[0], &hi2[0]);
- comptime assertOrPanic(&hi1[0] == &hi2[0]);
+ comptime expect(&hi1[0] == &hi2[0]);
}
fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) void {
- assertOrPanic(ptr1 == ptr2);
+ expect(ptr1 == ptr2);
}
test "@setEvalBranchQuota" {
comptime {
- // 1001 for the loop and then 1 more for the assertOrPanic fn call
+ // 1001 for the loop and then 1 more for the expect fn call
@setEvalBranchQuota(1002);
var i = 0;
var sum = 0;
while (i < 1001) : (i += 1) {
sum += i;
}
- assertOrPanic(sum == 500500);
+ expect(sum == 500500);
}
}
// TODO test "float literal at compile time not lossy" {
-// TODO assertOrPanic(16777216.0 + 1.0 == 16777217.0);
-// TODO assertOrPanic(9007199254740992.0 + 1.0 == 9007199254740993.0);
+// TODO expect(16777216.0 + 1.0 == 16777217.0);
+// TODO expect(9007199254740992.0 + 1.0 == 9007199254740993.0);
// TODO }
test "f32 at compile time is lossy" {
- assertOrPanic(f32(1 << 24) + 1 == 1 << 24);
+ expect(f32(1 << 24) + 1 == 1 << 24);
}
test "f64 at compile time is lossy" {
- assertOrPanic(f64(1 << 53) + 1 == 1 << 53);
+ expect(f64(1 << 53) + 1 == 1 << 53);
}
test "f128 at compile time is lossy" {
- assertOrPanic(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
+ expect(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
}
comptime {
- assertOrPanic(f128(1 << 113) == 10384593717069655257060992658440192);
+ expect(f128(1 << 113) == 10384593717069655257060992658440192);
}
pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
@@ -415,15 +415,15 @@ pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
test "string literal used as comptime slice is memoized" {
const a = "link";
const b = "link";
- comptime assertOrPanic(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
- comptime assertOrPanic(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
+ comptime expect(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
+ comptime expect(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
}
test "comptime slice of undefined pointer of length 0" {
const slice1 = ([*]i32)(undefined)[0..0];
- assertOrPanic(slice1.len == 0);
+ expect(slice1.len == 0);
const slice2 = ([*]i32)(undefined)[100..100];
- assertOrPanic(slice2.len == 0);
+ expect(slice2.len == 0);
}
fn copyWithPartialInline(s: []u32, b: []u8) void {
@@ -445,16 +445,16 @@ test "binary math operator in partially inlined function" {
r.* = @intCast(u8, i + 1);
copyWithPartialInline(s[0..], b[0..]);
- assertOrPanic(s[0] == 0x1020304);
- assertOrPanic(s[1] == 0x5060708);
- assertOrPanic(s[2] == 0x90a0b0c);
- assertOrPanic(s[3] == 0xd0e0f10);
+ expect(s[0] == 0x1020304);
+ expect(s[1] == 0x5060708);
+ expect(s[2] == 0x90a0b0c);
+ expect(s[3] == 0xd0e0f10);
}
test "comptime function with the same args is memoized" {
comptime {
- assertOrPanic(MakeType(i32) == MakeType(i32));
- assertOrPanic(MakeType(i32) != MakeType(f64));
+ expect(MakeType(i32) == MakeType(i32));
+ expect(MakeType(i32) != MakeType(f64));
}
}
@@ -470,7 +470,7 @@ test "comptime function with mutable pointer is not memoized" {
const ptr = &x;
increment(ptr);
increment(ptr);
- assertOrPanic(x == 3);
+ expect(x == 3);
}
}
@@ -496,14 +496,14 @@ fn doesAlotT(comptime T: type, value: usize) T {
}
test "@setEvalBranchQuota at same scope as generic function call" {
- assertOrPanic(doesAlotT(u32, 2) == 2);
+ expect(doesAlotT(u32, 2) == 2);
}
test "comptime slice of slice preserves comptime var" {
comptime {
var buff: [10]u8 = undefined;
buff[0..][0..][0] = 1;
- assertOrPanic(buff[0..][0..][0] == 1);
+ expect(buff[0..][0..][0] == 1);
}
}
@@ -512,7 +512,7 @@ test "comptime slice of pointer preserves comptime var" {
var buff: [10]u8 = undefined;
var a = buff[0..].ptr;
a[0..1][0] = 1;
- assertOrPanic(buff[0..][0..][0] == 1);
+ expect(buff[0..][0..][0] == 1);
}
}
@@ -526,9 +526,9 @@ const SingleFieldStruct = struct {
test "const ptr to comptime mutable data is not memoized" {
comptime {
var foo = SingleFieldStruct{ .x = 1 };
- assertOrPanic(foo.read_x() == 1);
+ expect(foo.read_x() == 1);
foo.x = 2;
- assertOrPanic(foo.read_x() == 2);
+ expect(foo.read_x() == 2);
}
}
@@ -537,7 +537,7 @@ test "array concat of slices gives slice" {
var a: []const u8 = "aoeu";
var b: []const u8 = "asdf";
const c = a ++ b;
- assertOrPanic(std.mem.eql(u8, c, "aoeuasdf"));
+ expect(std.mem.eql(u8, c, "aoeuasdf"));
}
}
@@ -554,14 +554,14 @@ test "comptime shlWithOverflow" {
break :amt amt;
};
- assertOrPanic(ct_shifted == rt_shifted);
+ expect(ct_shifted == rt_shifted);
}
test "runtime 128 bit integer division" {
var a: u128 = 152313999999999991610955792383;
var b: u128 = 10000000000000000000;
var c = a / b;
- assertOrPanic(c == 15231399999);
+ expect(c == 15231399999);
}
pub const Info = struct {
@@ -574,20 +574,20 @@ test "comptime modification of const struct field" {
comptime {
var res = diamond_info;
res.version = 1;
- assertOrPanic(diamond_info.version == 0);
- assertOrPanic(res.version == 1);
+ expect(diamond_info.version == 0);
+ expect(res.version == 1);
}
}
test "pointer to type" {
comptime {
var T: type = i32;
- assertOrPanic(T == i32);
+ expect(T == i32);
var ptr = &T;
- assertOrPanic(@typeOf(ptr) == *type);
+ expect(@typeOf(ptr) == *type);
ptr.* = f32;
- assertOrPanic(T == f32);
- assertOrPanic(*T == *f32);
+ expect(T == f32);
+ expect(*T == *f32);
}
}
@@ -596,17 +596,17 @@ test "slice of type" {
var types_array = []type{ i32, f64, type };
for (types_array) |T, i| {
switch (i) {
- 0 => assertOrPanic(T == i32),
- 1 => assertOrPanic(T == f64),
- 2 => assertOrPanic(T == type),
+ 0 => expect(T == i32),
+ 1 => expect(T == f64),
+ 2 => expect(T == type),
else => unreachable,
}
}
for (types_array[0..]) |T, i| {
switch (i) {
- 0 => assertOrPanic(T == i32),
- 1 => assertOrPanic(T == f64),
- 2 => assertOrPanic(T == type),
+ 0 => expect(T == i32),
+ 1 => expect(T == f64),
+ 2 => expect(T == type),
else => unreachable,
}
}
@@ -623,7 +623,7 @@ fn wrap(comptime T: type) Wrapper {
test "function which returns struct with type field causes implicit comptime" {
const ty = wrap(i32).T;
- assertOrPanic(ty == i32);
+ expect(ty == i32);
}
test "call method with comptime pass-by-non-copying-value self parameter" {
@@ -637,12 +637,12 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
const s = S{ .a = 2 };
var b = s.b();
- assertOrPanic(b == 2);
+ expect(b == 2);
}
test "@tagName of @typeId" {
const str = @tagName(@typeId(u8));
- assertOrPanic(std.mem.eql(u8, str, "Int"));
+ expect(std.mem.eql(u8, str, "Int"));
}
test "setting backward branch quota just before a generic fn call" {
@@ -663,8 +663,8 @@ fn testVarInsideInlineLoop(args: ...) void {
comptime var i = 0;
inline while (i < args.len) : (i += 1) {
const x = args[i];
- if (i == 0) assertOrPanic(x);
- if (i == 1) assertOrPanic(x == 42);
+ if (i == 0) expect(x);
+ if (i == 1) expect(x == 42);
}
}
@@ -674,7 +674,7 @@ test "inline for with same type but different values" {
var a: T = undefined;
res += a.len;
}
- assertOrPanic(res == 5);
+ expect(res == 5);
}
test "refer to the type of a generic function" {
@@ -688,13 +688,13 @@ fn doNothingWithType(comptime T: type) void {}
test "zero extend from u0 to u1" {
var zero_u0: u0 = 0;
var zero_u1: u1 = zero_u0;
- assertOrPanic(zero_u1 == 0);
+ expect(zero_u1 == 0);
}
test "bit shift a u1" {
var x: u1 = 1;
var y = x << 0;
- assertOrPanic(y == 1);
+ expect(y == 1);
}
test "@bytesToslice on a packed struct" {
@@ -704,7 +704,7 @@ test "@bytesToslice on a packed struct" {
var b = [1]u8{9};
var f = @bytesToSlice(F, b);
- assertOrPanic(f[0].a == 9);
+ expect(f[0].a == 9);
}
test "comptime pointer cast array and then slice" {
@@ -716,8 +716,8 @@ test "comptime pointer cast array and then slice" {
const ptrB: [*]const u8 = &array;
const sliceB: []const u8 = ptrB[0..2];
- assertOrPanic(sliceA[1] == 2);
- assertOrPanic(sliceB[1] == 2);
+ expect(sliceA[1] == 2);
+ expect(sliceB[1] == 2);
}
test "slice bounds in comptime concatenation" {
@@ -726,47 +726,47 @@ test "slice bounds in comptime concatenation" {
break :blk b[8..9];
};
const str = "" ++ bs;
- assertOrPanic(str.len == 1);
- assertOrPanic(std.mem.eql(u8, str, "1"));
+ expect(str.len == 1);
+ expect(std.mem.eql(u8, str, "1"));
const str2 = bs ++ "";
- assertOrPanic(str2.len == 1);
- assertOrPanic(std.mem.eql(u8, str2, "1"));
+ expect(str2.len == 1);
+ expect(std.mem.eql(u8, str2, "1"));
}
test "comptime bitwise operators" {
comptime {
- assertOrPanic(3 & 1 == 1);
- assertOrPanic(3 & -1 == 3);
- assertOrPanic(-3 & -1 == -3);
- assertOrPanic(3 | -1 == -1);
- assertOrPanic(-3 | -1 == -1);
- assertOrPanic(3 ^ -1 == -4);
- assertOrPanic(-3 ^ -1 == 2);
- assertOrPanic(~i8(-1) == 0);
- assertOrPanic(~i128(-1) == 0);
- assertOrPanic(18446744073709551615 & 18446744073709551611 == 18446744073709551611);
- assertOrPanic(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);
- assertOrPanic(~u128(0) == 0xffffffffffffffffffffffffffffffff);
+ expect(3 & 1 == 1);
+ expect(3 & -1 == 3);
+ expect(-3 & -1 == -3);
+ expect(3 | -1 == -1);
+ expect(-3 | -1 == -1);
+ expect(3 ^ -1 == -4);
+ expect(-3 ^ -1 == 2);
+ expect(~i8(-1) == 0);
+ expect(~i128(-1) == 0);
+ expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611);
+ expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);
+ expect(~u128(0) == 0xffffffffffffffffffffffffffffffff);
}
}
test "*align(1) u16 is the same as *align(1:0:2) u16" {
comptime {
- assertOrPanic(*align(1:0:2) u16 == *align(1) u16);
+ expect(*align(1:0:2) u16 == *align(1) u16);
// TODO add parsing support for this syntax
- //assertOrPanic(*align(:0:2) u16 == *u16);
+ //expect(*align(:0:2) u16 == *u16);
}
}
test "array concatenation forces comptime" {
var a = oneItem(3) ++ oneItem(4);
- assertOrPanic(std.mem.eql(i32, a, []i32{ 3, 4 }));
+ expect(std.mem.eql(i32, a, []i32{ 3, 4 }));
}
test "array multiplication forces comptime" {
var a = oneItem(3) ** scalar(2);
- assertOrPanic(std.mem.eql(i32, a, []i32{ 3, 3 }));
+ expect(std.mem.eql(i32, a, []i32{ 3, 3 }));
}
fn oneItem(x: i32) [1]i32 {
diff --git a/test/stage1/behavior/field_parent_ptr.zig b/test/stage1/behavior/field_parent_ptr.zig
index ed2487c020..6026a49d12 100644
--- a/test/stage1/behavior/field_parent_ptr.zig
+++ b/test/stage1/behavior/field_parent_ptr.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "@fieldParentPtr non-first field" {
testParentFieldPtr(&foo.c);
@@ -25,17 +25,17 @@ const foo = Foo{
};
fn testParentFieldPtr(c: *const i32) void {
- assertOrPanic(c == &foo.c);
+ expect(c == &foo.c);
const base = @fieldParentPtr(Foo, "c", c);
- assertOrPanic(base == &foo);
- assertOrPanic(&base.c == c);
+ expect(base == &foo);
+ expect(&base.c == c);
}
fn testParentFieldPtrFirst(a: *const bool) void {
- assertOrPanic(a == &foo.a);
+ expect(a == &foo.a);
const base = @fieldParentPtr(Foo, "a", a);
- assertOrPanic(base == &foo);
- assertOrPanic(&base.a == a);
+ expect(base == &foo);
+ expect(&base.a == a);
}
diff --git a/test/stage1/behavior/fn.zig b/test/stage1/behavior/fn.zig
index 3011bc41d0..3f78c80290 100644
--- a/test/stage1/behavior/fn.zig
+++ b/test/stage1/behavior/fn.zig
@@ -1,7 +1,7 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "params" {
- assertOrPanic(testParamsAdd(22, 11) == 33);
+ expect(testParamsAdd(22, 11) == 33);
}
fn testParamsAdd(a: i32, b: i32) i32 {
return a + b;
@@ -21,32 +21,32 @@ test "void parameters" {
fn voidFun(a: i32, b: void, c: i32, d: void) void {
const v = b;
const vv: void = if (a == 1) v else {};
- assertOrPanic(a + c == 3);
+ expect(a + c == 3);
return vv;
}
test "mutable local variables" {
var zero: i32 = 0;
- assertOrPanic(zero == 0);
+ expect(zero == 0);
var i = i32(0);
while (i != 3) {
i += 1;
}
- assertOrPanic(i == 3);
+ expect(i == 3);
}
test "separate block scopes" {
{
const no_conflict: i32 = 5;
- assertOrPanic(no_conflict == 5);
+ expect(no_conflict == 5);
}
const c = x: {
const no_conflict = i32(10);
break :x no_conflict;
};
- assertOrPanic(c == 10);
+ expect(c == 10);
}
test "call function with empty string" {
@@ -59,7 +59,7 @@ fn @"weird function name"() i32 {
return 1234;
}
test "weird function name" {
- assertOrPanic(@"weird function name"() == 1234);
+ expect(@"weird function name"() == 1234);
}
test "implicit cast function unreachable return" {
@@ -80,7 +80,7 @@ test "function pointers" {
fn4,
};
for (fns) |f, i| {
- assertOrPanic(f() == @intCast(u32, i) + 5);
+ expect(f() == @intCast(u32, i) + 5);
}
}
fn fn1() u32 {
@@ -97,7 +97,7 @@ fn fn4() u32 {
}
test "inline function call" {
- assertOrPanic(@inlineCall(add, 3, 9) == 12);
+ expect(@inlineCall(add, 3, 9) == 12);
}
fn add(a: i32, b: i32) i32 {
@@ -110,7 +110,7 @@ test "number literal as an argument" {
}
fn numberLiteralArg(a: var) void {
- assertOrPanic(a == 3);
+ expect(a == 3);
}
test "assign inline fn to const variable" {
@@ -121,7 +121,7 @@ test "assign inline fn to const variable" {
inline fn inlineFn() void {}
test "pass by non-copying value" {
- assertOrPanic(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
+ expect(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
}
const Point = struct {
@@ -134,17 +134,17 @@ fn addPointCoords(pt: Point) i32 {
}
test "pass by non-copying value through var arg" {
- assertOrPanic(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
+ expect(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
}
fn addPointCoordsVar(pt: var) i32 {
- comptime assertOrPanic(@typeOf(pt) == Point);
+ comptime expect(@typeOf(pt) == Point);
return pt.x + pt.y;
}
test "pass by non-copying value as method" {
var pt = Point2{ .x = 1, .y = 2 };
- assertOrPanic(pt.addPointCoords() == 3);
+ expect(pt.addPointCoords() == 3);
}
const Point2 = struct {
@@ -158,7 +158,7 @@ const Point2 = struct {
test "pass by non-copying value as method, which is generic" {
var pt = Point3{ .x = 1, .y = 2 };
- assertOrPanic(pt.addPointCoords(i32) == 3);
+ expect(pt.addPointCoords(i32) == 3);
}
const Point3 = struct {
@@ -173,7 +173,7 @@ const Point3 = struct {
test "pass by non-copying value as method, at comptime" {
comptime {
var pt = Point2{ .x = 1, .y = 2 };
- assertOrPanic(pt.addPointCoords() == 3);
+ expect(pt.addPointCoords() == 3);
}
}
@@ -189,7 +189,7 @@ fn outer(y: u32) fn (u32) u32 {
test "return inner function which references comptime variable of outer function" {
var func = outer(10);
- assertOrPanic(func(3) == 7);
+ expect(func(3) == 7);
}
test "extern struct with stdcallcc fn pointer" {
@@ -203,6 +203,6 @@ test "extern struct with stdcallcc fn pointer" {
var s: S = undefined;
s.ptr = S.foo;
- assertOrPanic(s.ptr() == 1234);
+ expect(s.ptr() == 1234);
}
diff --git a/test/stage1/behavior/fn_in_struct_in_comptime.zig b/test/stage1/behavior/fn_in_struct_in_comptime.zig
index 0af076d40a..030693ac59 100644
--- a/test/stage1/behavior/fn_in_struct_in_comptime.zig
+++ b/test/stage1/behavior/fn_in_struct_in_comptime.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
fn get_foo() fn (*u8) usize {
comptime {
@@ -13,5 +13,5 @@ fn get_foo() fn (*u8) usize {
test "define a function in an anonymous struct in comptime" {
const foo = get_foo();
- assertOrPanic(foo(@intToPtr(*u8, 12345)) == 12345);
+ expect(foo(@intToPtr(*u8, 12345)) == 12345);
}
diff --git a/test/stage1/behavior/for.zig b/test/stage1/behavior/for.zig
index b6d1ef24c4..b10dd14fa4 100644
--- a/test/stage1/behavior/for.zig
+++ b/test/stage1/behavior/for.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const mem = std.mem;
test "continue in for loop" {
@@ -26,7 +26,7 @@ test "for loop with pointer elem var" {
var target: [source.len]u8 = undefined;
mem.copy(u8, target[0..], source);
mangleString(target[0..]);
- assertOrPanic(mem.eql(u8, target, "bcdefgh"));
+ expect(mem.eql(u8, target, "bcdefgh"));
}
fn mangleString(s: []u8) void {
for (s) |*c| {
@@ -68,7 +68,7 @@ test "basic for loop" {
buf_index += 1;
}
- assertOrPanic(mem.eql(u8, buffer[0..buf_index], expected_result));
+ expect(mem.eql(u8, buffer[0..buf_index], expected_result));
}
test "break from outer for loop" {
@@ -85,7 +85,7 @@ fn testBreakOuter() void {
break :outer;
}
}
- assertOrPanic(count == 1);
+ expect(count == 1);
}
test "continue outer for loop" {
@@ -102,5 +102,5 @@ fn testContinueOuter() void {
continue :outer;
}
}
- assertOrPanic(counter == array.len);
+ expect(counter == array.len);
}
diff --git a/test/stage1/behavior/generics.zig b/test/stage1/behavior/generics.zig
index a0928634a7..637f9b88ae 100644
--- a/test/stage1/behavior/generics.zig
+++ b/test/stage1/behavior/generics.zig
@@ -1,9 +1,9 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "simple generic fn" {
- assertOrPanic(max(i32, 3, -1) == 3);
- assertOrPanic(max(f32, 0.123, 0.456) == 0.456);
- assertOrPanic(add(2, 3) == 5);
+ expect(max(i32, 3, -1) == 3);
+ expect(max(f32, 0.123, 0.456) == 0.456);
+ expect(add(2, 3) == 5);
}
fn max(comptime T: type, a: T, b: T) T {
@@ -16,7 +16,7 @@ fn add(comptime a: i32, b: i32) i32 {
const the_max = max(u32, 1234, 5678);
test "compile time generic eval" {
- assertOrPanic(the_max == 5678);
+ expect(the_max == 5678);
}
fn gimmeTheBigOne(a: u32, b: u32) u32 {
@@ -32,19 +32,19 @@ fn sameButWithFloats(a: f64, b: f64) f64 {
}
test "fn with comptime args" {
- assertOrPanic(gimmeTheBigOne(1234, 5678) == 5678);
- assertOrPanic(shouldCallSameInstance(34, 12) == 34);
- assertOrPanic(sameButWithFloats(0.43, 0.49) == 0.49);
+ expect(gimmeTheBigOne(1234, 5678) == 5678);
+ expect(shouldCallSameInstance(34, 12) == 34);
+ expect(sameButWithFloats(0.43, 0.49) == 0.49);
}
test "var params" {
- assertOrPanic(max_i32(12, 34) == 34);
- assertOrPanic(max_f64(1.2, 3.4) == 3.4);
+ expect(max_i32(12, 34) == 34);
+ expect(max_f64(1.2, 3.4) == 3.4);
}
comptime {
- assertOrPanic(max_i32(12, 34) == 34);
- assertOrPanic(max_f64(1.2, 3.4) == 3.4);
+ expect(max_i32(12, 34) == 34);
+ expect(max_f64(1.2, 3.4) == 3.4);
}
fn max_var(a: var, b: var) @typeOf(a + b) {
@@ -76,8 +76,8 @@ test "function with return type type" {
var list2: List(i32) = undefined;
list.length = 10;
list2.length = 10;
- assertOrPanic(list.prealloc_items.len == 8);
- assertOrPanic(list2.prealloc_items.len == 8);
+ expect(list.prealloc_items.len == 8);
+ expect(list2.prealloc_items.len == 8);
}
test "generic struct" {
@@ -89,9 +89,9 @@ test "generic struct" {
.value = true,
.next = null,
};
- assertOrPanic(a1.value == 13);
- assertOrPanic(a1.value == a1.getVal());
- assertOrPanic(b1.getVal());
+ expect(a1.value == 13);
+ expect(a1.value == a1.getVal());
+ expect(b1.getVal());
}
fn GenNode(comptime T: type) type {
return struct {
@@ -104,7 +104,7 @@ fn GenNode(comptime T: type) type {
}
test "const decls in struct" {
- assertOrPanic(GenericDataThing(3).count_plus_one == 4);
+ expect(GenericDataThing(3).count_plus_one == 4);
}
fn GenericDataThing(comptime count: isize) type {
return struct {
@@ -113,15 +113,15 @@ fn GenericDataThing(comptime count: isize) type {
}
test "use generic param in generic param" {
- assertOrPanic(aGenericFn(i32, 3, 4) == 7);
+ expect(aGenericFn(i32, 3, 4) == 7);
}
fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
return a + b;
}
test "generic fn with implicit cast" {
- assertOrPanic(getFirstByte(u8, []u8{13}) == 13);
- assertOrPanic(getFirstByte(u16, []u16{
+ expect(getFirstByte(u8, []u8{13}) == 13);
+ expect(getFirstByte(u16, []u16{
0,
13,
}) == 0);
@@ -146,6 +146,6 @@ fn foo2(arg: var) bool {
}
test "array of generic fns" {
- assertOrPanic(foos[0](true));
- assertOrPanic(!foos[1](true));
+ expect(foos[0](true));
+ expect(!foos[1](true));
}
diff --git a/test/stage1/behavior/if.zig b/test/stage1/behavior/if.zig
index 58d1b8fd73..a61b9dcfb4 100644
--- a/test/stage1/behavior/if.zig
+++ b/test/stage1/behavior/if.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "if statements" {
shouldBeEqual(1, 1);
@@ -24,7 +24,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {
}
test "else if expression" {
- assertOrPanic(elseIfExpressionF(1) == 1);
+ expect(elseIfExpressionF(1) == 1);
}
fn elseIfExpressionF(c: u8) u8 {
if (c == 0) {
diff --git a/test/stage1/behavior/import.zig b/test/stage1/behavior/import.zig
index 736e4c219d..9a8c6848e2 100644
--- a/test/stage1/behavior/import.zig
+++ b/test/stage1/behavior/import.zig
@@ -1,10 +1,10 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const a_namespace = @import("import/a_namespace.zig");
test "call fn via namespace lookup" {
- assertOrPanic(a_namespace.foo() == 1234);
+ expect(a_namespace.foo() == 1234);
}
test "importing the same thing gives the same import" {
- assertOrPanic(@import("std") == @import("std"));
+ expect(@import("std") == @import("std"));
}
diff --git a/test/stage1/behavior/incomplete_struct_param_tld.zig b/test/stage1/behavior/incomplete_struct_param_tld.zig
index d062311b2e..77a3dfd221 100644
--- a/test/stage1/behavior/incomplete_struct_param_tld.zig
+++ b/test/stage1/behavior/incomplete_struct_param_tld.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const A = struct {
b: B,
@@ -26,5 +26,5 @@ test "incomplete struct param top level declaration" {
.c = C{ .x = 13 },
},
};
- assertOrPanic(foo(a) == 13);
+ expect(foo(a) == 13);
}
diff --git a/test/stage1/behavior/inttoptr.zig b/test/stage1/behavior/inttoptr.zig
index bf657fc86a..b1780f93d6 100644
--- a/test/stage1/behavior/inttoptr.zig
+++ b/test/stage1/behavior/inttoptr.zig
@@ -1,6 +1,6 @@
const builtin = @import("builtin");
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "casting random address to function pointer" {
randomAddressToFunction();
diff --git a/test/stage1/behavior/ir_block_deps.zig b/test/stage1/behavior/ir_block_deps.zig
index bc61e11df7..821079df79 100644
--- a/test/stage1/behavior/ir_block_deps.zig
+++ b/test/stage1/behavior/ir_block_deps.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
fn foo(id: u64) !i32 {
return switch (id) {
@@ -16,6 +16,6 @@ fn getErrInt() anyerror!i32 {
}
test "ir block deps" {
- assertOrPanic((foo(1) catch unreachable) == 0);
- assertOrPanic((foo(2) catch unreachable) == 0);
+ expect((foo(1) catch unreachable) == 0);
+ expect((foo(2) catch unreachable) == 0);
}
diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig
index 9d6a5a4997..0b88cc4497 100644
--- a/test/stage1/behavior/math.zig
+++ b/test/stage1/behavior/math.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const maxInt = std.math.maxInt;
const minInt = std.math.minInt;
@@ -8,57 +8,57 @@ test "division" {
comptime testDivision();
}
fn testDivision() void {
- assertOrPanic(div(u32, 13, 3) == 4);
- assertOrPanic(div(f16, 1.0, 2.0) == 0.5);
- assertOrPanic(div(f32, 1.0, 2.0) == 0.5);
+ expect(div(u32, 13, 3) == 4);
+ expect(div(f16, 1.0, 2.0) == 0.5);
+ expect(div(f32, 1.0, 2.0) == 0.5);
- assertOrPanic(divExact(u32, 55, 11) == 5);
- assertOrPanic(divExact(i32, -55, 11) == -5);
- assertOrPanic(divExact(f16, 55.0, 11.0) == 5.0);
- assertOrPanic(divExact(f16, -55.0, 11.0) == -5.0);
- assertOrPanic(divExact(f32, 55.0, 11.0) == 5.0);
- assertOrPanic(divExact(f32, -55.0, 11.0) == -5.0);
+ expect(divExact(u32, 55, 11) == 5);
+ expect(divExact(i32, -55, 11) == -5);
+ expect(divExact(f16, 55.0, 11.0) == 5.0);
+ expect(divExact(f16, -55.0, 11.0) == -5.0);
+ expect(divExact(f32, 55.0, 11.0) == 5.0);
+ expect(divExact(f32, -55.0, 11.0) == -5.0);
- assertOrPanic(divFloor(i32, 5, 3) == 1);
- assertOrPanic(divFloor(i32, -5, 3) == -2);
- assertOrPanic(divFloor(f16, 5.0, 3.0) == 1.0);
- assertOrPanic(divFloor(f16, -5.0, 3.0) == -2.0);
- assertOrPanic(divFloor(f32, 5.0, 3.0) == 1.0);
- assertOrPanic(divFloor(f32, -5.0, 3.0) == -2.0);
- assertOrPanic(divFloor(i32, -0x80000000, -2) == 0x40000000);
- assertOrPanic(divFloor(i32, 0, -0x80000000) == 0);
- assertOrPanic(divFloor(i32, -0x40000001, 0x40000000) == -2);
- assertOrPanic(divFloor(i32, -0x80000000, 1) == -0x80000000);
+ expect(divFloor(i32, 5, 3) == 1);
+ expect(divFloor(i32, -5, 3) == -2);
+ expect(divFloor(f16, 5.0, 3.0) == 1.0);
+ expect(divFloor(f16, -5.0, 3.0) == -2.0);
+ expect(divFloor(f32, 5.0, 3.0) == 1.0);
+ expect(divFloor(f32, -5.0, 3.0) == -2.0);
+ expect(divFloor(i32, -0x80000000, -2) == 0x40000000);
+ expect(divFloor(i32, 0, -0x80000000) == 0);
+ expect(divFloor(i32, -0x40000001, 0x40000000) == -2);
+ expect(divFloor(i32, -0x80000000, 1) == -0x80000000);
- assertOrPanic(divTrunc(i32, 5, 3) == 1);
- assertOrPanic(divTrunc(i32, -5, 3) == -1);
- assertOrPanic(divTrunc(f16, 5.0, 3.0) == 1.0);
- assertOrPanic(divTrunc(f16, -5.0, 3.0) == -1.0);
- assertOrPanic(divTrunc(f32, 5.0, 3.0) == 1.0);
- assertOrPanic(divTrunc(f32, -5.0, 3.0) == -1.0);
- assertOrPanic(divTrunc(f64, 5.0, 3.0) == 1.0);
- assertOrPanic(divTrunc(f64, -5.0, 3.0) == -1.0);
+ expect(divTrunc(i32, 5, 3) == 1);
+ expect(divTrunc(i32, -5, 3) == -1);
+ expect(divTrunc(f16, 5.0, 3.0) == 1.0);
+ expect(divTrunc(f16, -5.0, 3.0) == -1.0);
+ expect(divTrunc(f32, 5.0, 3.0) == 1.0);
+ expect(divTrunc(f32, -5.0, 3.0) == -1.0);
+ expect(divTrunc(f64, 5.0, 3.0) == 1.0);
+ expect(divTrunc(f64, -5.0, 3.0) == -1.0);
comptime {
- assertOrPanic(
+ expect(
1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600,
);
- assertOrPanic(
+ expect(
@rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600,
);
- assertOrPanic(
+ expect(
1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2,
);
- assertOrPanic(
+ expect(
@divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2,
);
- assertOrPanic(
+ expect(
@divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2,
);
- assertOrPanic(
+ expect(
@divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2,
);
- assertOrPanic(
+ expect(
4126227191251978491697987544882340798050766755606969681711 % 10 == 1,
);
}
@@ -78,9 +78,9 @@ fn divTrunc(comptime T: type, a: T, b: T) T {
test "@addWithOverflow" {
var result: u8 = undefined;
- assertOrPanic(@addWithOverflow(u8, 250, 100, &result));
- assertOrPanic(!@addWithOverflow(u8, 100, 150, &result));
- assertOrPanic(result == 250);
+ expect(@addWithOverflow(u8, 250, 100, &result));
+ expect(!@addWithOverflow(u8, 100, 150, &result));
+ expect(result == 250);
}
// TODO test mulWithOverflow
@@ -88,9 +88,9 @@ test "@addWithOverflow" {
test "@shlWithOverflow" {
var result: u16 = undefined;
- assertOrPanic(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
- assertOrPanic(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
- assertOrPanic(result == 0b1011111111111100);
+ expect(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
+ expect(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
+ expect(result == 0b1011111111111100);
}
test "@clz" {
@@ -99,11 +99,11 @@ test "@clz" {
}
fn testClz() void {
- assertOrPanic(clz(u8(0b00001010)) == 4);
- assertOrPanic(clz(u8(0b10001010)) == 0);
- assertOrPanic(clz(u8(0b00000000)) == 8);
- assertOrPanic(clz(u128(0xffffffffffffffff)) == 64);
- assertOrPanic(clz(u128(0x10000000000000000)) == 63);
+ expect(clz(u8(0b00001010)) == 4);
+ expect(clz(u8(0b10001010)) == 0);
+ expect(clz(u8(0b00000000)) == 8);
+ expect(clz(u128(0xffffffffffffffff)) == 64);
+ expect(clz(u128(0x10000000000000000)) == 63);
}
fn clz(x: var) usize {
@@ -116,9 +116,9 @@ test "@ctz" {
}
fn testCtz() void {
- assertOrPanic(ctz(u8(0b10100000)) == 5);
- assertOrPanic(ctz(u8(0b10001010)) == 1);
- assertOrPanic(ctz(u8(0b00000000)) == 8);
+ expect(ctz(u8(0b10100000)) == 5);
+ expect(ctz(u8(0b10001010)) == 1);
+ expect(ctz(u8(0b00000000)) == 8);
}
fn ctz(x: var) usize {
@@ -128,27 +128,27 @@ fn ctz(x: var) usize {
test "assignment operators" {
var i: u32 = 0;
i += 5;
- assertOrPanic(i == 5);
+ expect(i == 5);
i -= 2;
- assertOrPanic(i == 3);
+ expect(i == 3);
i *= 20;
- assertOrPanic(i == 60);
+ expect(i == 60);
i /= 3;
- assertOrPanic(i == 20);
+ expect(i == 20);
i %= 11;
- assertOrPanic(i == 9);
+ expect(i == 9);
i <<= 1;
- assertOrPanic(i == 18);
+ expect(i == 18);
i >>= 2;
- assertOrPanic(i == 4);
+ expect(i == 4);
i = 6;
i &= 5;
- assertOrPanic(i == 4);
+ expect(i == 4);
i ^= 6;
- assertOrPanic(i == 2);
+ expect(i == 2);
i = 6;
i |= 3;
- assertOrPanic(i == 7);
+ expect(i == 7);
}
test "three expr in a row" {
@@ -170,14 +170,14 @@ fn testThreeExprInARow(f: bool, t: bool) void {
assertFalse(i32(7) != --(i32(7)));
}
fn assertFalse(b: bool) void {
- assertOrPanic(!b);
+ expect(!b);
}
test "const number literal" {
const one = 1;
const eleven = ten + one;
- assertOrPanic(eleven == 11);
+ expect(eleven == 11);
}
const ten = 10;
@@ -187,9 +187,9 @@ test "unsigned wrapping" {
}
fn testUnsignedWrappingEval(x: u32) void {
const zero = x +% 1;
- assertOrPanic(zero == 0);
+ expect(zero == 0);
const orig = zero -% 1;
- assertOrPanic(orig == maxInt(u32));
+ expect(orig == maxInt(u32));
}
test "signed wrapping" {
@@ -198,9 +198,9 @@ test "signed wrapping" {
}
fn testSignedWrappingEval(x: i32) void {
const min_val = x +% 1;
- assertOrPanic(min_val == minInt(i32));
+ expect(min_val == minInt(i32));
const max_val = min_val -% 1;
- assertOrPanic(max_val == maxInt(i32));
+ expect(max_val == maxInt(i32));
}
test "negation wrapping" {
@@ -208,9 +208,9 @@ test "negation wrapping" {
comptime testNegationWrappingEval(minInt(i16));
}
fn testNegationWrappingEval(x: i16) void {
- assertOrPanic(x == -32768);
+ expect(x == -32768);
const neg = -%x;
- assertOrPanic(neg == -32768);
+ expect(neg == -32768);
}
test "unsigned 64-bit division" {
@@ -219,8 +219,8 @@ test "unsigned 64-bit division" {
}
fn test_u64_div() void {
const result = divWithResult(1152921504606846976, 34359738365);
- assertOrPanic(result.quotient == 33554432);
- assertOrPanic(result.remainder == 100663296);
+ expect(result.quotient == 33554432);
+ expect(result.remainder == 100663296);
}
fn divWithResult(a: u64, b: u64) DivResult {
return DivResult{
@@ -234,36 +234,36 @@ const DivResult = struct {
};
test "binary not" {
- assertOrPanic(comptime x: {
+ expect(comptime x: {
break :x ~u16(0b1010101010101010) == 0b0101010101010101;
});
- assertOrPanic(comptime x: {
+ expect(comptime x: {
break :x ~u64(2147483647) == 18446744071562067968;
});
testBinaryNot(0b1010101010101010);
}
fn testBinaryNot(x: u16) void {
- assertOrPanic(~x == 0b0101010101010101);
+ expect(~x == 0b0101010101010101);
}
test "small int addition" {
var x: @IntType(false, 2) = 0;
- assertOrPanic(x == 0);
+ expect(x == 0);
x += 1;
- assertOrPanic(x == 1);
+ expect(x == 1);
x += 1;
- assertOrPanic(x == 2);
+ expect(x == 2);
x += 1;
- assertOrPanic(x == 3);
+ expect(x == 3);
var result: @typeOf(x) = 3;
- assertOrPanic(@addWithOverflow(@typeOf(x), x, 1, &result));
+ expect(@addWithOverflow(@typeOf(x), x, 1, &result));
- assertOrPanic(result == 0);
+ expect(result == 0);
}
test "float equality" {
@@ -276,20 +276,20 @@ test "float equality" {
fn testFloatEqualityImpl(x: f64, y: f64) void {
const y2 = x + 1.0;
- assertOrPanic(y == y2);
+ expect(y == y2);
}
test "allow signed integer division/remainder when values are comptime known and positive or exact" {
- assertOrPanic(5 / 3 == 1);
- assertOrPanic(-5 / -3 == 1);
- assertOrPanic(-6 / 3 == -2);
+ expect(5 / 3 == 1);
+ expect(-5 / -3 == 1);
+ expect(-6 / 3 == -2);
- assertOrPanic(5 % 3 == 2);
- assertOrPanic(-6 % 3 == 0);
+ expect(5 % 3 == 2);
+ expect(-6 % 3 == 0);
}
test "hex float literal parsing" {
- comptime assertOrPanic(0x1.0 == 1.0);
+ comptime expect(0x1.0 == 1.0);
}
test "quad hex float literal parsing in range" {
@@ -304,7 +304,7 @@ test "quad hex float literal parsing accurate" {
// implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing.
const expected: u128 = 0x3fff1111222233334444555566667777;
- assertOrPanic(@bitCast(u128, a) == expected);
+ expect(@bitCast(u128, a) == expected);
}
test "hex float literal within range" {
@@ -319,7 +319,7 @@ test "truncating shift left" {
}
fn testShlTrunc(x: u16) void {
const shifted = x << 1;
- assertOrPanic(shifted == 65534);
+ expect(shifted == 65534);
}
test "truncating shift right" {
@@ -328,7 +328,7 @@ test "truncating shift right" {
}
fn testShrTrunc(x: u16) void {
const shifted = x >> 1;
- assertOrPanic(shifted == 32767);
+ expect(shifted == 32767);
}
test "exact shift left" {
@@ -337,7 +337,7 @@ test "exact shift left" {
}
fn testShlExact(x: u8) void {
const shifted = @shlExact(x, 2);
- assertOrPanic(shifted == 0b11010100);
+ expect(shifted == 0b11010100);
}
test "exact shift right" {
@@ -346,22 +346,22 @@ test "exact shift right" {
}
fn testShrExact(x: u8) void {
const shifted = @shrExact(x, 2);
- assertOrPanic(shifted == 0b00101101);
+ expect(shifted == 0b00101101);
}
test "comptime_int addition" {
comptime {
- assertOrPanic(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
- assertOrPanic(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
+ expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
+ expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
}
}
test "comptime_int multiplication" {
comptime {
- assertOrPanic(
+ expect(
45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,
);
- assertOrPanic(
+ expect(
594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016,
);
}
@@ -369,7 +369,7 @@ test "comptime_int multiplication" {
test "comptime_int shifting" {
comptime {
- assertOrPanic((u128(1) << 127) == 0x80000000000000000000000000000000);
+ expect((u128(1) << 127) == 0x80000000000000000000000000000000);
}
}
@@ -377,16 +377,16 @@ test "comptime_int multi-limb shift and mask" {
comptime {
var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
- assertOrPanic(u32(a & 0xffffffff) == 0xaaaaaaab);
+ expect(u32(a & 0xffffffff) == 0xaaaaaaab);
a >>= 32;
- assertOrPanic(u32(a & 0xffffffff) == 0xeeeeeeef);
+ expect(u32(a & 0xffffffff) == 0xeeeeeeef);
a >>= 32;
- assertOrPanic(u32(a & 0xffffffff) == 0xa0000001);
+ expect(u32(a & 0xffffffff) == 0xa0000001);
a >>= 32;
- assertOrPanic(u32(a & 0xffffffff) == 0xefffffff);
+ expect(u32(a & 0xffffffff) == 0xefffffff);
a >>= 32;
- assertOrPanic(a == 0);
+ expect(a == 0);
}
}
@@ -394,7 +394,7 @@ test "comptime_int multi-limb partial shift right" {
comptime {
var a = 0x1ffffffffeeeeeeee;
a >>= 16;
- assertOrPanic(a == 0x1ffffffffeeee);
+ expect(a == 0x1ffffffffeeee);
}
}
@@ -404,23 +404,23 @@ test "xor" {
}
fn test_xor() void {
- assertOrPanic(0xFF ^ 0x00 == 0xFF);
- assertOrPanic(0xF0 ^ 0x0F == 0xFF);
- assertOrPanic(0xFF ^ 0xF0 == 0x0F);
- assertOrPanic(0xFF ^ 0x0F == 0xF0);
- assertOrPanic(0xFF ^ 0xFF == 0x00);
+ expect(0xFF ^ 0x00 == 0xFF);
+ expect(0xF0 ^ 0x0F == 0xFF);
+ expect(0xFF ^ 0xF0 == 0x0F);
+ expect(0xFF ^ 0x0F == 0xF0);
+ expect(0xFF ^ 0xFF == 0x00);
}
test "comptime_int xor" {
comptime {
- assertOrPanic(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
- assertOrPanic(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
- assertOrPanic(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF);
- assertOrPanic(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000);
- assertOrPanic(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000);
- assertOrPanic(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
- assertOrPanic(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF);
- assertOrPanic(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000);
+ expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+ expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+ expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF);
+ expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000);
+ expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000);
+ expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
+ expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF);
+ expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000);
}
}
@@ -434,23 +434,23 @@ fn make_f128(x: f128) f128 {
}
fn test_f128() void {
- assertOrPanic(@sizeOf(f128) == 16);
- assertOrPanic(make_f128(1.0) == 1.0);
- assertOrPanic(make_f128(1.0) != 1.1);
- assertOrPanic(make_f128(1.0) > 0.9);
- assertOrPanic(make_f128(1.0) >= 0.9);
- assertOrPanic(make_f128(1.0) >= 1.0);
+ expect(@sizeOf(f128) == 16);
+ expect(make_f128(1.0) == 1.0);
+ expect(make_f128(1.0) != 1.1);
+ expect(make_f128(1.0) > 0.9);
+ expect(make_f128(1.0) >= 0.9);
+ expect(make_f128(1.0) >= 1.0);
should_not_be_zero(1.0);
}
fn should_not_be_zero(x: f128) void {
- assertOrPanic(x != 0.0);
+ expect(x != 0.0);
}
test "comptime float rem int" {
comptime {
var x = f32(1) % 2;
- assertOrPanic(x == 1.0);
+ expect(x == 1.0);
}
}
@@ -465,8 +465,8 @@ test "remainder division" {
}
fn remdiv(comptime T: type) void {
- assertOrPanic(T(1) == T(1) % T(2));
- assertOrPanic(T(1) == T(7) % T(3));
+ expect(T(1) == T(1) % T(2));
+ expect(T(1) == T(7) % T(3));
}
test "@sqrt" {
@@ -480,19 +480,19 @@ test "@sqrt" {
const x = 14.0;
const y = x * x;
const z = @sqrt(@typeOf(y), y);
- comptime assertOrPanic(z == x);
+ comptime expect(z == x);
}
fn testSqrt(comptime T: type, x: T) void {
- assertOrPanic(@sqrt(T, x * x) == x);
+ expect(@sqrt(T, x * x) == x);
}
test "comptime_int param and return" {
const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
- assertOrPanic(a == 137114567242441932203689521744947848950);
+ expect(a == 137114567242441932203689521744947848950);
const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768);
- assertOrPanic(b == 985095453608931032642182098849559179469148836107390954364380);
+ expect(b == 985095453608931032642182098849559179469148836107390954364380);
}
fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig
index 3cc8e5f31e..91cab78bc7 100644
--- a/test/stage1/behavior/misc.zig
+++ b/test/stage1/behavior/misc.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const mem = std.mem;
const cstr = std.cstr;
const builtin = @import("builtin");
@@ -26,38 +26,38 @@ test "call disabled extern fn" {
}
test "@IntType builtin" {
- assertOrPanic(@IntType(true, 8) == i8);
- assertOrPanic(@IntType(true, 16) == i16);
- assertOrPanic(@IntType(true, 32) == i32);
- assertOrPanic(@IntType(true, 64) == i64);
+ expect(@IntType(true, 8) == i8);
+ expect(@IntType(true, 16) == i16);
+ expect(@IntType(true, 32) == i32);
+ expect(@IntType(true, 64) == i64);
- assertOrPanic(@IntType(false, 8) == u8);
- assertOrPanic(@IntType(false, 16) == u16);
- assertOrPanic(@IntType(false, 32) == u32);
- assertOrPanic(@IntType(false, 64) == u64);
+ expect(@IntType(false, 8) == u8);
+ expect(@IntType(false, 16) == u16);
+ expect(@IntType(false, 32) == u32);
+ expect(@IntType(false, 64) == u64);
- assertOrPanic(i8.bit_count == 8);
- assertOrPanic(i16.bit_count == 16);
- assertOrPanic(i32.bit_count == 32);
- assertOrPanic(i64.bit_count == 64);
+ expect(i8.bit_count == 8);
+ expect(i16.bit_count == 16);
+ expect(i32.bit_count == 32);
+ expect(i64.bit_count == 64);
- assertOrPanic(i8.is_signed);
- assertOrPanic(i16.is_signed);
- assertOrPanic(i32.is_signed);
- assertOrPanic(i64.is_signed);
- assertOrPanic(isize.is_signed);
+ expect(i8.is_signed);
+ expect(i16.is_signed);
+ expect(i32.is_signed);
+ expect(i64.is_signed);
+ expect(isize.is_signed);
- assertOrPanic(!u8.is_signed);
- assertOrPanic(!u16.is_signed);
- assertOrPanic(!u32.is_signed);
- assertOrPanic(!u64.is_signed);
- assertOrPanic(!usize.is_signed);
+ expect(!u8.is_signed);
+ expect(!u16.is_signed);
+ expect(!u32.is_signed);
+ expect(!u64.is_signed);
+ expect(!usize.is_signed);
}
test "floating point primitive bit counts" {
- assertOrPanic(f16.bit_count == 16);
- assertOrPanic(f32.bit_count == 32);
- assertOrPanic(f64.bit_count == 64);
+ expect(f16.bit_count == 16);
+ expect(f32.bit_count == 32);
+ expect(f64.bit_count == 64);
}
test "short circuit" {
@@ -72,7 +72,7 @@ fn testShortCircuit(f: bool, t: bool) void {
var hit_4 = f;
if (t or x: {
- assertOrPanic(f);
+ expect(f);
break :x f;
}) {
hit_1 = t;
@@ -81,31 +81,31 @@ fn testShortCircuit(f: bool, t: bool) void {
hit_2 = t;
break :x f;
}) {
- assertOrPanic(f);
+ expect(f);
}
if (t and x: {
hit_3 = t;
break :x f;
}) {
- assertOrPanic(f);
+ expect(f);
}
if (f and x: {
- assertOrPanic(f);
+ expect(f);
break :x f;
}) {
- assertOrPanic(f);
+ expect(f);
} else {
hit_4 = t;
}
- assertOrPanic(hit_1);
- assertOrPanic(hit_2);
- assertOrPanic(hit_3);
- assertOrPanic(hit_4);
+ expect(hit_1);
+ expect(hit_2);
+ expect(hit_3);
+ expect(hit_4);
}
test "truncate" {
- assertOrPanic(testTruncate(0x10fd) == 0xfd);
+ expect(testTruncate(0x10fd) == 0xfd);
}
fn testTruncate(x: u32) u8 {
return @truncate(u8, x);
@@ -116,16 +116,16 @@ fn first4KeysOfHomeRow() []const u8 {
}
test "return string from function" {
- assertOrPanic(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
+ expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
}
const g1: i32 = 1233 + 1;
var g2: i32 = 0;
test "global variables" {
- assertOrPanic(g2 == 0);
+ expect(g2 == 0);
g2 = g1;
- assertOrPanic(g2 == 1234);
+ expect(g2 == 1234);
}
test "memcpy and memset intrinsics" {
@@ -142,7 +142,7 @@ test "builtin static eval" {
const x: i32 = comptime x: {
break :x 1 + 2 + 3;
};
- assertOrPanic(x == comptime 6);
+ expect(x == comptime 6);
}
test "slicing" {
@@ -163,7 +163,7 @@ test "slicing" {
test "constant equal function pointers" {
const alias = emptyFn;
- assertOrPanic(comptime x: {
+ expect(comptime x: {
break :x emptyFn == alias;
});
}
@@ -171,25 +171,25 @@ test "constant equal function pointers" {
fn emptyFn() void {}
test "hex escape" {
- assertOrPanic(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
+ expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
}
test "string concatenation" {
- assertOrPanic(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
+ expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
}
test "array mult operator" {
- assertOrPanic(mem.eql(u8, "ab" ** 5, "ababababab"));
+ expect(mem.eql(u8, "ab" ** 5, "ababababab"));
}
test "string escapes" {
- assertOrPanic(mem.eql(u8, "\"", "\x22"));
- assertOrPanic(mem.eql(u8, "\'", "\x27"));
- assertOrPanic(mem.eql(u8, "\n", "\x0a"));
- assertOrPanic(mem.eql(u8, "\r", "\x0d"));
- assertOrPanic(mem.eql(u8, "\t", "\x09"));
- assertOrPanic(mem.eql(u8, "\\", "\x5c"));
- assertOrPanic(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69"));
+ expect(mem.eql(u8, "\"", "\x22"));
+ expect(mem.eql(u8, "\'", "\x27"));
+ expect(mem.eql(u8, "\n", "\x0a"));
+ expect(mem.eql(u8, "\r", "\x0d"));
+ expect(mem.eql(u8, "\t", "\x09"));
+ expect(mem.eql(u8, "\\", "\x5c"));
+ expect(mem.eql(u8, "\u1234\u0069", "\xe1\x88\xb4\x69"));
}
test "multiline string" {
@@ -199,7 +199,7 @@ test "multiline string" {
\\three
;
const s2 = "one\ntwo)\nthree";
- assertOrPanic(mem.eql(u8, s1, s2));
+ expect(mem.eql(u8, s1, s2));
}
test "multiline C string" {
@@ -209,11 +209,11 @@ test "multiline C string" {
c\\three
;
const s2 = c"one\ntwo)\nthree";
- assertOrPanic(cstr.cmp(s1, s2) == 0);
+ expect(cstr.cmp(s1, s2) == 0);
}
test "type equality" {
- assertOrPanic(*const u8 != *u8);
+ expect(*const u8 != *u8);
}
const global_a: i32 = 1234;
@@ -221,7 +221,7 @@ const global_b: *const i32 = &global_a;
const global_c: *const f32 = @ptrCast(*const f32, global_b);
test "compile time global reinterpret" {
const d = @ptrCast(*const i32, global_c);
- assertOrPanic(d.* == 1234);
+ expect(d.* == 1234);
}
test "explicit cast maybe pointers" {
@@ -247,8 +247,8 @@ test "cast undefined" {
fn testCastUndefined(x: []const u8) void {}
test "cast small unsigned to larger signed" {
- assertOrPanic(castSmallUnsignedToLargerSigned1(200) == i16(200));
- assertOrPanic(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
+ expect(castSmallUnsignedToLargerSigned1(200) == i16(200));
+ expect(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
}
fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
return x;
@@ -258,7 +258,7 @@ fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
}
test "implicit cast after unreachable" {
- assertOrPanic(outer() == 1234);
+ expect(outer() == 1234);
}
fn inner() i32 {
return 1234;
@@ -273,13 +273,13 @@ test "pointer dereferencing" {
y.* += 1;
- assertOrPanic(x == 4);
- assertOrPanic(y.* == 4);
+ expect(x == 4);
+ expect(y.* == 4);
}
test "call result of if else expression" {
- assertOrPanic(mem.eql(u8, f2(true), "a"));
- assertOrPanic(mem.eql(u8, f2(false), "b"));
+ expect(mem.eql(u8, f2(true), "a"));
+ expect(mem.eql(u8, f2(false), "b"));
}
fn f2(x: bool) []const u8 {
return (if (x) fA else fB)();
@@ -321,8 +321,8 @@ const test3_bar = Test3Foo{ .Two = 13 };
fn test3_1(f: Test3Foo) void {
switch (f) {
Test3Foo.Three => |pt| {
- assertOrPanic(pt.x == 3);
- assertOrPanic(pt.y == 4);
+ expect(pt.x == 3);
+ expect(pt.y == 4);
},
else => unreachable,
}
@@ -330,14 +330,14 @@ fn test3_1(f: Test3Foo) void {
fn test3_2(f: Test3Foo) void {
switch (f) {
Test3Foo.Two => |x| {
- assertOrPanic(x == 13);
+ expect(x == 13);
},
else => unreachable,
}
}
test "character literals" {
- assertOrPanic('\'' == single_quote);
+ expect('\'' == single_quote);
}
const single_quote = '\'';
@@ -346,13 +346,13 @@ test "take address of parameter" {
}
fn testTakeAddressOfParameter(f: f32) void {
const f_ptr = &f;
- assertOrPanic(f_ptr.* == 12.34);
+ expect(f_ptr.* == 12.34);
}
test "pointer comparison" {
const a = ([]const u8)("a");
const b = &a;
- assertOrPanic(ptrEql(b, b));
+ expect(ptrEql(b, b));
}
fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
return a == b;
@@ -367,31 +367,31 @@ test "C string concatenation" {
{
var i: u32 = 0;
while (i < len_with_null) : (i += 1) {
- assertOrPanic(a[i] == b[i]);
+ expect(a[i] == b[i]);
}
}
- assertOrPanic(a[len] == 0);
- assertOrPanic(b[len] == 0);
+ expect(a[len] == 0);
+ expect(b[len] == 0);
}
test "cast slice to u8 slice" {
- assertOrPanic(@sizeOf(i32) == 4);
+ expect(@sizeOf(i32) == 4);
var big_thing_array = []i32{ 1, 2, 3, 4 };
const big_thing_slice: []i32 = big_thing_array[0..];
const bytes = @sliceToBytes(big_thing_slice);
- assertOrPanic(bytes.len == 4 * 4);
+ expect(bytes.len == 4 * 4);
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
- assertOrPanic(big_thing_slice[1] == 0);
+ expect(big_thing_slice[1] == 0);
const big_thing_again = @bytesToSlice(i32, bytes);
- assertOrPanic(big_thing_again[2] == 3);
+ expect(big_thing_again[2] == 3);
big_thing_again[2] = -1;
- assertOrPanic(bytes[8] == maxInt(u8));
- assertOrPanic(bytes[9] == maxInt(u8));
- assertOrPanic(bytes[10] == maxInt(u8));
- assertOrPanic(bytes[11] == maxInt(u8));
+ expect(bytes[8] == maxInt(u8));
+ expect(bytes[9] == maxInt(u8));
+ expect(bytes[10] == maxInt(u8));
+ expect(bytes[11] == maxInt(u8));
}
test "pointer to void return type" {
@@ -408,7 +408,7 @@ fn testPointerToVoidReturnType2() *const void {
test "non const ptr to aliased type" {
const int = i32;
- assertOrPanic(?*int == ?*i32);
+ expect(?*int == ?*i32);
}
test "array 2D const double ptr" {
@@ -421,8 +421,8 @@ test "array 2D const double ptr" {
fn testArray2DConstDoublePtr(ptr: *const f32) void {
const ptr2 = @ptrCast([*]const f32, ptr);
- assertOrPanic(ptr2[0] == 1.0);
- assertOrPanic(ptr2[1] == 2.0);
+ expect(ptr2[0] == 1.0);
+ expect(ptr2[1] == 2.0);
}
const Tid = builtin.TypeId;
@@ -444,32 +444,32 @@ const AUnion = union {
test "@typeId" {
comptime {
- assertOrPanic(@typeId(type) == Tid.Type);
- assertOrPanic(@typeId(void) == Tid.Void);
- assertOrPanic(@typeId(bool) == Tid.Bool);
- assertOrPanic(@typeId(noreturn) == Tid.NoReturn);
- assertOrPanic(@typeId(i8) == Tid.Int);
- assertOrPanic(@typeId(u8) == Tid.Int);
- assertOrPanic(@typeId(i64) == Tid.Int);
- assertOrPanic(@typeId(u64) == Tid.Int);
- assertOrPanic(@typeId(f32) == Tid.Float);
- assertOrPanic(@typeId(f64) == Tid.Float);
- assertOrPanic(@typeId(*f32) == Tid.Pointer);
- assertOrPanic(@typeId([2]u8) == Tid.Array);
- assertOrPanic(@typeId(AStruct) == Tid.Struct);
- assertOrPanic(@typeId(@typeOf(1)) == Tid.ComptimeInt);
- assertOrPanic(@typeId(@typeOf(1.0)) == Tid.ComptimeFloat);
- assertOrPanic(@typeId(@typeOf(undefined)) == Tid.Undefined);
- assertOrPanic(@typeId(@typeOf(null)) == Tid.Null);
- assertOrPanic(@typeId(?i32) == Tid.Optional);
- assertOrPanic(@typeId(anyerror!i32) == Tid.ErrorUnion);
- assertOrPanic(@typeId(anyerror) == Tid.ErrorSet);
- assertOrPanic(@typeId(AnEnum) == Tid.Enum);
- assertOrPanic(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
- assertOrPanic(@typeId(AUnionEnum) == Tid.Union);
- assertOrPanic(@typeId(AUnion) == Tid.Union);
- assertOrPanic(@typeId(fn () void) == Tid.Fn);
- assertOrPanic(@typeId(@typeOf(builtin)) == Tid.Namespace);
+ expect(@typeId(type) == Tid.Type);
+ expect(@typeId(void) == Tid.Void);
+ expect(@typeId(bool) == Tid.Bool);
+ expect(@typeId(noreturn) == Tid.NoReturn);
+ expect(@typeId(i8) == Tid.Int);
+ expect(@typeId(u8) == Tid.Int);
+ expect(@typeId(i64) == Tid.Int);
+ expect(@typeId(u64) == Tid.Int);
+ expect(@typeId(f32) == Tid.Float);
+ expect(@typeId(f64) == Tid.Float);
+ expect(@typeId(*f32) == Tid.Pointer);
+ expect(@typeId([2]u8) == Tid.Array);
+ expect(@typeId(AStruct) == Tid.Struct);
+ expect(@typeId(@typeOf(1)) == Tid.ComptimeInt);
+ expect(@typeId(@typeOf(1.0)) == Tid.ComptimeFloat);
+ expect(@typeId(@typeOf(undefined)) == Tid.Undefined);
+ expect(@typeId(@typeOf(null)) == Tid.Null);
+ expect(@typeId(?i32) == Tid.Optional);
+ expect(@typeId(anyerror!i32) == Tid.ErrorUnion);
+ expect(@typeId(anyerror) == Tid.ErrorSet);
+ expect(@typeId(AnEnum) == Tid.Enum);
+ expect(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
+ expect(@typeId(AUnionEnum) == Tid.Union);
+ expect(@typeId(AUnion) == Tid.Union);
+ expect(@typeId(fn () void) == Tid.Fn);
+ expect(@typeId(@typeOf(builtin)) == Tid.Namespace);
// TODO bound fn
// TODO arg tuple
// TODO opaque
@@ -485,13 +485,13 @@ test "@typeName" {
Unused,
};
comptime {
- assertOrPanic(mem.eql(u8, @typeName(i64), "i64"));
- assertOrPanic(mem.eql(u8, @typeName(*usize), "*usize"));
+ expect(mem.eql(u8, @typeName(i64), "i64"));
+ expect(mem.eql(u8, @typeName(*usize), "*usize"));
// https://github.com/ziglang/zig/issues/675
- assertOrPanic(mem.eql(u8, @typeName(TypeFromFn(u8)), "TypeFromFn(u8)"));
- assertOrPanic(mem.eql(u8, @typeName(Struct), "Struct"));
- assertOrPanic(mem.eql(u8, @typeName(Union), "Union"));
- assertOrPanic(mem.eql(u8, @typeName(Enum), "Enum"));
+ expect(mem.eql(u8, @typeName(TypeFromFn(u8)), "TypeFromFn(u8)"));
+ expect(mem.eql(u8, @typeName(Struct), "Struct"));
+ expect(mem.eql(u8, @typeName(Union), "Union"));
+ expect(mem.eql(u8, @typeName(Enum), "Enum"));
}
}
@@ -501,14 +501,14 @@ fn TypeFromFn(comptime T: type) type {
test "double implicit cast in same expression" {
var x = i32(u16(nine()));
- assertOrPanic(x == 9);
+ expect(x == 9);
}
fn nine() u8 {
return 9;
}
test "global variable initialized to global variable array element" {
- assertOrPanic(global_ptr == &gdt[0]);
+ expect(global_ptr == &gdt[0]);
}
const GDTEntry = struct {
field: i32,
@@ -529,9 +529,9 @@ export fn writeToVRam() void {
const OpaqueA = @OpaqueType();
const OpaqueB = @OpaqueType();
test "@OpaqueType" {
- assertOrPanic(*OpaqueA != *OpaqueB);
- assertOrPanic(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
- assertOrPanic(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
+ expect(*OpaqueA != *OpaqueB);
+ expect(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
+ expect(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
}
test "variable is allowed to be a pointer to an opaque type" {
@@ -571,7 +571,7 @@ fn fnThatClosesOverLocalConst() type {
test "function closes over local const" {
const x = fnThatClosesOverLocalConst().g();
- assertOrPanic(x == 1);
+ expect(x == 1);
}
test "cold function" {
@@ -608,21 +608,21 @@ export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion, c: Pack
test "slicing zero length array" {
const s1 = ""[0..];
const s2 = ([]u32{})[0..];
- assertOrPanic(s1.len == 0);
- assertOrPanic(s2.len == 0);
- assertOrPanic(mem.eql(u8, s1, ""));
- assertOrPanic(mem.eql(u32, s2, []u32{}));
+ expect(s1.len == 0);
+ expect(s2.len == 0);
+ expect(mem.eql(u8, s1, ""));
+ expect(mem.eql(u32, s2, []u32{}));
}
const addr1 = @ptrCast(*const u8, emptyFn);
test "comptime cast fn to ptr" {
const addr2 = @ptrCast(*const u8, emptyFn);
- comptime assertOrPanic(addr1 == addr2);
+ comptime expect(addr1 == addr2);
}
test "equality compare fn ptrs" {
var a = emptyFn;
- assertOrPanic(a == a);
+ expect(a == a);
}
test "self reference through fn ptr field" {
@@ -637,26 +637,26 @@ test "self reference through fn ptr field" {
};
var a: S.A = undefined;
a.f = S.foo;
- assertOrPanic(a.f(a) == 12);
+ expect(a.f(a) == 12);
}
test "volatile load and store" {
var number: i32 = 1234;
const ptr = (*volatile i32)(&number);
ptr.* += 1;
- assertOrPanic(ptr.* == 1235);
+ expect(ptr.* == 1235);
}
test "slice string literal has type []const u8" {
comptime {
- assertOrPanic(@typeOf("aoeu"[0..]) == []const u8);
+ expect(@typeOf("aoeu"[0..]) == []const u8);
const array = []i32{ 1, 2, 3, 4 };
- assertOrPanic(@typeOf(array[0..]) == []const i32);
+ expect(@typeOf(array[0..]) == []const i32);
}
}
test "pointer child field" {
- assertOrPanic((*u32).Child == u32);
+ expect((*u32).Child == u32);
}
test "struct inside function" {
@@ -675,11 +675,11 @@ fn testStructInFn() void {
block.kind += 1;
- assertOrPanic(block.kind == 1235);
+ expect(block.kind == 1235);
}
test "fn call returning scalar optional in equality expression" {
- assertOrPanic(getNull() == null);
+ expect(getNull() == null);
}
fn getNull() ?*i32 {
@@ -691,5 +691,5 @@ test "thread local variable" {
threadlocal var t: i32 = 1234;
};
S.t += 1;
- assertOrPanic(S.t == 1235);
+ expect(S.t == 1235);
}
diff --git a/test/stage1/behavior/namespace_depends_on_compile_var/index.zig b/test/stage1/behavior/namespace_depends_on_compile_var/index.zig
index fe3e0cc020..32feaced10 100644
--- a/test/stage1/behavior/namespace_depends_on_compile_var/index.zig
+++ b/test/stage1/behavior/namespace_depends_on_compile_var/index.zig
@@ -1,11 +1,11 @@
const builtin = @import("builtin");
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "namespace depends on compile var" {
if (some_namespace.a_bool) {
- assertOrPanic(some_namespace.a_bool);
+ expect(some_namespace.a_bool);
} else {
- assertOrPanic(!some_namespace.a_bool);
+ expect(!some_namespace.a_bool);
}
}
const some_namespace = switch (builtin.os) {
diff --git a/test/stage1/behavior/new_stack_call.zig b/test/stage1/behavior/new_stack_call.zig
index b9ae2d27cd..1e01a5a8a2 100644
--- a/test/stage1/behavior/new_stack_call.zig
+++ b/test/stage1/behavior/new_stack_call.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
var new_stack_bytes: [1024]u8 = undefined;
@@ -10,17 +10,17 @@ test "calling a function with a new stack" {
const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
_ = targetFunction(arg);
- assertOrPanic(arg == 1234);
- assertOrPanic(a < b);
+ expect(arg == 1234);
+ expect(a < b);
}
fn targetFunction(x: i32) usize {
- assertOrPanic(x == 1234);
+ expect(x == 1234);
var local_variable: i32 = 42;
const ptr = &local_variable;
ptr.* += 1;
- assertOrPanic(local_variable == 43);
+ expect(local_variable == 43);
return @ptrToInt(ptr);
}
diff --git a/test/stage1/behavior/null.zig b/test/stage1/behavior/null.zig
index e2f86a05ba..8c9b86b260 100644
--- a/test/stage1/behavior/null.zig
+++ b/test/stage1/behavior/null.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "optional type" {
const x: ?bool = true;
@@ -17,13 +17,13 @@ test "optional type" {
const z = next_x orelse 1234;
- assertOrPanic(z == 1234);
+ expect(z == 1234);
const final_x: ?i32 = 13;
const num = final_x orelse unreachable;
- assertOrPanic(num == 13);
+ expect(num == 13);
}
test "test maybe object and get a pointer to the inner value" {
@@ -33,7 +33,7 @@ test "test maybe object and get a pointer to the inner value" {
b.* = false;
}
- assertOrPanic(maybe_bool.? == false);
+ expect(maybe_bool.? == false);
}
test "rhs maybe unwrap return" {
@@ -47,9 +47,9 @@ test "maybe return" {
}
fn maybeReturnImpl() void {
- assertOrPanic(foo(1235).?);
+ expect(foo(1235).?);
if (foo(null) != null) unreachable;
- assertOrPanic(!foo(1234).?);
+ expect(!foo(1234).?);
}
fn foo(x: ?i32) ?bool {
@@ -58,7 +58,7 @@ fn foo(x: ?i32) ?bool {
}
test "if var maybe pointer" {
- assertOrPanic(shouldBeAPlus1(Particle{
+ expect(shouldBeAPlus1(Particle{
.a = 14,
.b = 1,
.c = 1,
@@ -84,10 +84,10 @@ const Particle = struct {
test "null literal outside function" {
const is_null = here_is_a_null_literal.context == null;
- assertOrPanic(is_null);
+ expect(is_null);
const is_non_null = here_is_a_null_literal.context != null;
- assertOrPanic(!is_non_null);
+ expect(!is_non_null);
}
const SillyStruct = struct {
context: ?i32,
@@ -98,8 +98,8 @@ test "test null runtime" {
testTestNullRuntime(null);
}
fn testTestNullRuntime(x: ?i32) void {
- assertOrPanic(x == null);
- assertOrPanic(!(x != null));
+ expect(x == null);
+ expect(!(x != null));
}
test "optional void" {
@@ -108,8 +108,8 @@ test "optional void" {
}
fn optionalVoidImpl() void {
- assertOrPanic(bar(null) == null);
- assertOrPanic(bar({}) != null);
+ expect(bar(null) == null);
+ expect(bar({}) != null);
}
fn bar(x: ?void) ?void {
@@ -133,7 +133,7 @@ test "unwrap optional which is field of global var" {
}
struct_with_optional.field = 1234;
if (struct_with_optional.field) |payload| {
- assertOrPanic(payload == 1234);
+ expect(payload == 1234);
} else {
unreachable;
}
@@ -141,13 +141,13 @@ test "unwrap optional which is field of global var" {
test "null with default unwrap" {
const x: i32 = null orelse 1;
- assertOrPanic(x == 1);
+ expect(x == 1);
}
test "optional types" {
comptime {
const opt_type_struct = StructWithOptionalType{ .t = u8 };
- assertOrPanic(opt_type_struct.t != null and opt_type_struct.t.? == u8);
+ expect(opt_type_struct.t != null and opt_type_struct.t.? == u8);
}
}
@@ -158,5 +158,5 @@ const StructWithOptionalType = struct {
test "optional pointer to 0 bit type null value at runtime" {
const EmptyStruct = struct {};
var x: ?*EmptyStruct = null;
- assertOrPanic(x == null);
+ expect(x == null);
}
diff --git a/test/stage1/behavior/optional.zig b/test/stage1/behavior/optional.zig
index 14692cb1ea..a65bed020c 100644
--- a/test/stage1/behavior/optional.zig
+++ b/test/stage1/behavior/optional.zig
@@ -1,11 +1,11 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
pub const EmptyStruct = struct {};
test "optional pointer to size zero struct" {
var e = EmptyStruct{};
var o: ?*EmptyStruct = &e;
- assertOrPanic(o != null);
+ expect(o != null);
}
test "equality compare nullable pointers" {
@@ -18,15 +18,15 @@ fn testNullPtrsEql() void {
var x: ?*i32 = null;
var y: ?*i32 = null;
- assertOrPanic(x == y);
+ expect(x == y);
y = &number;
- assertOrPanic(x != y);
- assertOrPanic(x != &number);
- assertOrPanic(&number != x);
+ expect(x != y);
+ expect(x != &number);
+ expect(&number != x);
x = &number;
- assertOrPanic(x == y);
- assertOrPanic(x == &number);
- assertOrPanic(&number == x);
+ expect(x == y);
+ expect(x == &number);
+ expect(&number == x);
}
test "address of unwrap optional" {
@@ -43,7 +43,7 @@ test "address of unwrap optional" {
};
S.global = S.Foo{ .a = 1234 };
const foo = S.getFoo() catch unreachable;
- assertOrPanic(foo.a == 1234);
+ expect(foo.a == 1234);
}
test "passing an optional integer as a parameter" {
@@ -57,15 +57,15 @@ test "passing an optional integer as a parameter" {
return x.? == 1234;
}
};
- assertOrPanic(S.entry());
- comptime assertOrPanic(S.entry());
+ expect(S.entry());
+ comptime expect(S.entry());
}
test "unwrap function call with optional pointer return value" {
const S = struct {
fn entry() void {
- assertOrPanic(foo().?.* == 1234);
- assertOrPanic(bar() == null);
+ expect(foo().?.* == 1234);
+ expect(bar() == null);
}
const global: i32 = 1234;
fn foo() ?*const i32 {
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 1142d89ab5..47b19700ee 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "dereference pointer" {
comptime testDerefPtr();
@@ -10,33 +10,33 @@ fn testDerefPtr() void {
var x: i32 = 1234;
var y = &x;
y.* += 1;
- assertOrPanic(x == 1235);
+ expect(x == 1235);
}
test "pointer arithmetic" {
var ptr = c"abcd";
- assertOrPanic(ptr[0] == 'a');
+ expect(ptr[0] == 'a');
ptr += 1;
- assertOrPanic(ptr[0] == 'b');
+ expect(ptr[0] == 'b');
ptr += 1;
- assertOrPanic(ptr[0] == 'c');
+ expect(ptr[0] == 'c');
ptr += 1;
- assertOrPanic(ptr[0] == 'd');
+ expect(ptr[0] == 'd');
ptr += 1;
- assertOrPanic(ptr[0] == 0);
+ expect(ptr[0] == 0);
ptr -= 1;
- assertOrPanic(ptr[0] == 'd');
+ expect(ptr[0] == 'd');
ptr -= 1;
- assertOrPanic(ptr[0] == 'c');
+ expect(ptr[0] == 'c');
ptr -= 1;
- assertOrPanic(ptr[0] == 'b');
+ expect(ptr[0] == 'b');
ptr -= 1;
- assertOrPanic(ptr[0] == 'a');
+ expect(ptr[0] == 'a');
}
test "double pointer parsing" {
- comptime assertOrPanic(PtrOf(PtrOf(i32)) == **i32);
+ comptime expect(PtrOf(PtrOf(i32)) == **i32);
}
fn PtrOf(comptime T: type) type {
diff --git a/test/stage1/behavior/popcount.zig b/test/stage1/behavior/popcount.zig
index f7f8bb523b..2b63284720 100644
--- a/test/stage1/behavior/popcount.zig
+++ b/test/stage1/behavior/popcount.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "@popCount" {
comptime testPopCount();
@@ -8,18 +8,18 @@ test "@popCount" {
fn testPopCount() void {
{
var x: u32 = 0xaa;
- assertOrPanic(@popCount(x) == 4);
+ expect(@popCount(x) == 4);
}
{
var x: u32 = 0xaaaaaaaa;
- assertOrPanic(@popCount(x) == 16);
+ expect(@popCount(x) == 16);
}
{
var x: i16 = -1;
- assertOrPanic(@popCount(x) == 16);
+ expect(@popCount(x) == 16);
}
comptime {
- assertOrPanic(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);
+ expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);
}
}
diff --git a/test/stage1/behavior/ptrcast.zig b/test/stage1/behavior/ptrcast.zig
index 54c3dda849..3787382aea 100644
--- a/test/stage1/behavior/ptrcast.zig
+++ b/test/stage1/behavior/ptrcast.zig
@@ -1,6 +1,6 @@
const builtin = @import("builtin");
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "reinterpret bytes as integer with nonzero offset" {
testReinterpretBytesAsInteger();
@@ -13,7 +13,7 @@ fn testReinterpretBytesAsInteger() void {
builtin.Endian.Little => 0xab785634,
builtin.Endian.Big => 0x345678ab,
};
- assertOrPanic(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);
+ expect(@ptrCast(*align(1) const u32, bytes[1..5].ptr).* == expected);
}
test "reinterpret bytes of an array into an extern struct" {
@@ -32,12 +32,12 @@ fn testReinterpretBytesAsExternStruct() void {
var ptr = @ptrCast(*const S, &bytes);
var val = ptr.c;
- assertOrPanic(val == 5);
+ expect(val == 5);
}
test "reinterpret struct field at comptime" {
const numLittle = comptime Bytes.init(0x12345678);
- assertOrPanic(std.mem.eql(u8, []u8{ 0x78, 0x56, 0x34, 0x12 }, numLittle.bytes));
+ expect(std.mem.eql(u8, []u8{ 0x78, 0x56, 0x34, 0x12 }, numLittle.bytes));
}
const Bytes = struct {
diff --git a/test/stage1/behavior/pub_enum/index.zig b/test/stage1/behavior/pub_enum/index.zig
index 181113f6bf..15e4114c2d 100644
--- a/test/stage1/behavior/pub_enum/index.zig
+++ b/test/stage1/behavior/pub_enum/index.zig
@@ -1,13 +1,13 @@
const other = @import("other.zig");
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "pub enum" {
pubEnumTest(other.APubEnum.Two);
}
fn pubEnumTest(foo: other.APubEnum) void {
- assertOrPanic(foo == other.APubEnum.Two);
+ expect(foo == other.APubEnum.Two);
}
test "cast with imported symbol" {
- assertOrPanic(other.size_t(42) == 42);
+ expect(other.size_t(42) == 42);
}
diff --git a/test/stage1/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig b/test/stage1/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig
index acbe6b2459..2c1cf06268 100644
--- a/test/stage1/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig
+++ b/test/stage1/behavior/ref_var_in_if_after_if_2nd_switch_prong.zig
@@ -1,14 +1,14 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
var ok: bool = false;
test "reference a variable in an if after an if in the 2nd switch prong" {
foo(true, Num.Two, false, "aoeu");
- assertOrPanic(!ok);
+ expect(!ok);
foo(false, Num.One, false, "aoeu");
- assertOrPanic(!ok);
+ expect(!ok);
foo(true, Num.One, false, "aoeu");
- assertOrPanic(ok);
+ expect(ok);
}
const Num = enum {
@@ -32,6 +32,6 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
}
fn a(x: []const u8) void {
- assertOrPanic(mem.eql(u8, x, "aoeu"));
+ expect(mem.eql(u8, x, "aoeu"));
ok = true;
}
diff --git a/test/stage1/behavior/reflection.zig b/test/stage1/behavior/reflection.zig
index f4c142e0f7..55efc85b97 100644
--- a/test/stage1/behavior/reflection.zig
+++ b/test/stage1/behavior/reflection.zig
@@ -1,25 +1,25 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
const reflection = @This();
test "reflection: array, pointer, optional, error union type child" {
comptime {
- assertOrPanic(([10]u8).Child == u8);
- assertOrPanic((*u8).Child == u8);
- assertOrPanic((anyerror!u8).Payload == u8);
- assertOrPanic((?u8).Child == u8);
+ expect(([10]u8).Child == u8);
+ expect((*u8).Child == u8);
+ expect((anyerror!u8).Payload == u8);
+ expect((?u8).Child == u8);
}
}
test "reflection: function return type, var args, and param types" {
comptime {
- assertOrPanic(@typeOf(dummy).ReturnType == i32);
- assertOrPanic(!@typeOf(dummy).is_var_args);
- assertOrPanic(@typeOf(dummy_varargs).is_var_args);
- assertOrPanic(@typeOf(dummy).arg_count == 3);
- assertOrPanic(@ArgType(@typeOf(dummy), 0) == bool);
- assertOrPanic(@ArgType(@typeOf(dummy), 1) == i32);
- assertOrPanic(@ArgType(@typeOf(dummy), 2) == f32);
+ expect(@typeOf(dummy).ReturnType == i32);
+ expect(!@typeOf(dummy).is_var_args);
+ expect(@typeOf(dummy_varargs).is_var_args);
+ expect(@typeOf(dummy).arg_count == 3);
+ expect(@ArgType(@typeOf(dummy), 0) == bool);
+ expect(@ArgType(@typeOf(dummy), 1) == i32);
+ expect(@ArgType(@typeOf(dummy), 2) == f32);
}
}
@@ -30,31 +30,31 @@ fn dummy_varargs(args: ...) void {}
test "reflection: struct member types and names" {
comptime {
- assertOrPanic(@memberCount(Foo) == 3);
+ expect(@memberCount(Foo) == 3);
- assertOrPanic(@memberType(Foo, 0) == i32);
- assertOrPanic(@memberType(Foo, 1) == bool);
- assertOrPanic(@memberType(Foo, 2) == void);
+ expect(@memberType(Foo, 0) == i32);
+ expect(@memberType(Foo, 1) == bool);
+ expect(@memberType(Foo, 2) == void);
- assertOrPanic(mem.eql(u8, @memberName(Foo, 0), "one"));
- assertOrPanic(mem.eql(u8, @memberName(Foo, 1), "two"));
- assertOrPanic(mem.eql(u8, @memberName(Foo, 2), "three"));
+ expect(mem.eql(u8, @memberName(Foo, 0), "one"));
+ expect(mem.eql(u8, @memberName(Foo, 1), "two"));
+ expect(mem.eql(u8, @memberName(Foo, 2), "three"));
}
}
test "reflection: enum member types and names" {
comptime {
- assertOrPanic(@memberCount(Bar) == 4);
+ expect(@memberCount(Bar) == 4);
- assertOrPanic(@memberType(Bar, 0) == void);
- assertOrPanic(@memberType(Bar, 1) == i32);
- assertOrPanic(@memberType(Bar, 2) == bool);
- assertOrPanic(@memberType(Bar, 3) == f64);
+ expect(@memberType(Bar, 0) == void);
+ expect(@memberType(Bar, 1) == i32);
+ expect(@memberType(Bar, 2) == bool);
+ expect(@memberType(Bar, 3) == f64);
- assertOrPanic(mem.eql(u8, @memberName(Bar, 0), "One"));
- assertOrPanic(mem.eql(u8, @memberName(Bar, 1), "Two"));
- assertOrPanic(mem.eql(u8, @memberName(Bar, 2), "Three"));
- assertOrPanic(mem.eql(u8, @memberName(Bar, 3), "Four"));
+ expect(mem.eql(u8, @memberName(Bar, 0), "One"));
+ expect(mem.eql(u8, @memberName(Bar, 1), "Two"));
+ expect(mem.eql(u8, @memberName(Bar, 2), "Three"));
+ expect(mem.eql(u8, @memberName(Bar, 3), "Four"));
}
}
@@ -65,18 +65,18 @@ test "reflection: @field" {
.three = void{},
};
- assertOrPanic(f.one == f.one);
- assertOrPanic(@field(f, "o" ++ "ne") == f.one);
- assertOrPanic(@field(f, "t" ++ "wo") == f.two);
- assertOrPanic(@field(f, "th" ++ "ree") == f.three);
- assertOrPanic(@field(Foo, "const" ++ "ant") == Foo.constant);
- assertOrPanic(@field(Bar, "O" ++ "ne") == Bar.One);
- assertOrPanic(@field(Bar, "T" ++ "wo") == Bar.Two);
- assertOrPanic(@field(Bar, "Th" ++ "ree") == Bar.Three);
- assertOrPanic(@field(Bar, "F" ++ "our") == Bar.Four);
- assertOrPanic(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
+ expect(f.one == f.one);
+ expect(@field(f, "o" ++ "ne") == f.one);
+ expect(@field(f, "t" ++ "wo") == f.two);
+ expect(@field(f, "th" ++ "ree") == f.three);
+ expect(@field(Foo, "const" ++ "ant") == Foo.constant);
+ expect(@field(Bar, "O" ++ "ne") == Bar.One);
+ expect(@field(Bar, "T" ++ "wo") == Bar.Two);
+ expect(@field(Bar, "Th" ++ "ree") == Bar.Three);
+ expect(@field(Bar, "F" ++ "our") == Bar.Four);
+ expect(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
@field(f, "o" ++ "ne") = 4;
- assertOrPanic(f.one == 4);
+ expect(f.one == 4);
}
const Foo = struct {
diff --git a/test/stage1/behavior/sizeof_and_typeof.zig b/test/stage1/behavior/sizeof_and_typeof.zig
index ddaea4c242..58a6c81759 100644
--- a/test/stage1/behavior/sizeof_and_typeof.zig
+++ b/test/stage1/behavior/sizeof_and_typeof.zig
@@ -1,9 +1,9 @@
const builtin = @import("builtin");
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "@sizeOf and @typeOf" {
const y: @typeOf(x) = 120;
- assertOrPanic(@sizeOf(@typeOf(y)) == 2);
+ expect(@sizeOf(@typeOf(y)) == 2);
}
const x: u16 = 13;
const z: @typeOf(x) = 19;
@@ -30,40 +30,40 @@ const P = packed struct {
test "@byteOffsetOf" {
// Packed structs have fixed memory layout
- assertOrPanic(@byteOffsetOf(P, "a") == 0);
- assertOrPanic(@byteOffsetOf(P, "b") == 1);
- assertOrPanic(@byteOffsetOf(P, "c") == 5);
- assertOrPanic(@byteOffsetOf(P, "d") == 6);
- assertOrPanic(@byteOffsetOf(P, "e") == 6);
- assertOrPanic(@byteOffsetOf(P, "f") == 7);
- assertOrPanic(@byteOffsetOf(P, "g") == 9);
+ expect(@byteOffsetOf(P, "a") == 0);
+ expect(@byteOffsetOf(P, "b") == 1);
+ expect(@byteOffsetOf(P, "c") == 5);
+ expect(@byteOffsetOf(P, "d") == 6);
+ expect(@byteOffsetOf(P, "e") == 6);
+ expect(@byteOffsetOf(P, "f") == 7);
+ expect(@byteOffsetOf(P, "g") == 9);
// Normal struct fields can be moved/padded
var a: A = undefined;
- assertOrPanic(@ptrToInt(&a.a) - @ptrToInt(&a) == @byteOffsetOf(A, "a"));
- assertOrPanic(@ptrToInt(&a.b) - @ptrToInt(&a) == @byteOffsetOf(A, "b"));
- assertOrPanic(@ptrToInt(&a.c) - @ptrToInt(&a) == @byteOffsetOf(A, "c"));
- assertOrPanic(@ptrToInt(&a.d) - @ptrToInt(&a) == @byteOffsetOf(A, "d"));
- assertOrPanic(@ptrToInt(&a.e) - @ptrToInt(&a) == @byteOffsetOf(A, "e"));
- assertOrPanic(@ptrToInt(&a.f) - @ptrToInt(&a) == @byteOffsetOf(A, "f"));
- assertOrPanic(@ptrToInt(&a.g) - @ptrToInt(&a) == @byteOffsetOf(A, "g"));
+ expect(@ptrToInt(&a.a) - @ptrToInt(&a) == @byteOffsetOf(A, "a"));
+ expect(@ptrToInt(&a.b) - @ptrToInt(&a) == @byteOffsetOf(A, "b"));
+ expect(@ptrToInt(&a.c) - @ptrToInt(&a) == @byteOffsetOf(A, "c"));
+ expect(@ptrToInt(&a.d) - @ptrToInt(&a) == @byteOffsetOf(A, "d"));
+ expect(@ptrToInt(&a.e) - @ptrToInt(&a) == @byteOffsetOf(A, "e"));
+ expect(@ptrToInt(&a.f) - @ptrToInt(&a) == @byteOffsetOf(A, "f"));
+ expect(@ptrToInt(&a.g) - @ptrToInt(&a) == @byteOffsetOf(A, "g"));
}
test "@bitOffsetOf" {
// Packed structs have fixed memory layout
- assertOrPanic(@bitOffsetOf(P, "a") == 0);
- assertOrPanic(@bitOffsetOf(P, "b") == 8);
- assertOrPanic(@bitOffsetOf(P, "c") == 40);
- assertOrPanic(@bitOffsetOf(P, "d") == 48);
- assertOrPanic(@bitOffsetOf(P, "e") == 51);
- assertOrPanic(@bitOffsetOf(P, "f") == 56);
- assertOrPanic(@bitOffsetOf(P, "g") == 72);
+ expect(@bitOffsetOf(P, "a") == 0);
+ expect(@bitOffsetOf(P, "b") == 8);
+ expect(@bitOffsetOf(P, "c") == 40);
+ expect(@bitOffsetOf(P, "d") == 48);
+ expect(@bitOffsetOf(P, "e") == 51);
+ expect(@bitOffsetOf(P, "f") == 56);
+ expect(@bitOffsetOf(P, "g") == 72);
- assertOrPanic(@byteOffsetOf(A, "a") * 8 == @bitOffsetOf(A, "a"));
- assertOrPanic(@byteOffsetOf(A, "b") * 8 == @bitOffsetOf(A, "b"));
- assertOrPanic(@byteOffsetOf(A, "c") * 8 == @bitOffsetOf(A, "c"));
- assertOrPanic(@byteOffsetOf(A, "d") * 8 == @bitOffsetOf(A, "d"));
- assertOrPanic(@byteOffsetOf(A, "e") * 8 == @bitOffsetOf(A, "e"));
- assertOrPanic(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
- assertOrPanic(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
+ expect(@byteOffsetOf(A, "a") * 8 == @bitOffsetOf(A, "a"));
+ expect(@byteOffsetOf(A, "b") * 8 == @bitOffsetOf(A, "b"));
+ expect(@byteOffsetOf(A, "c") * 8 == @bitOffsetOf(A, "c"));
+ expect(@byteOffsetOf(A, "d") * 8 == @bitOffsetOf(A, "d"));
+ expect(@byteOffsetOf(A, "e") * 8 == @bitOffsetOf(A, "e"));
+ expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
+ expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
}
diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig
index cc29e43485..13fa84d0fa 100644
--- a/test/stage1/behavior/slice.zig
+++ b/test/stage1/behavior/slice.zig
@@ -1,20 +1,20 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
const x = @intToPtr([*]i32, 0x1000)[0..0x500];
const y = x[0x100..];
test "compile time slice of pointer to hard coded address" {
- assertOrPanic(@ptrToInt(x.ptr) == 0x1000);
- assertOrPanic(x.len == 0x500);
+ expect(@ptrToInt(x.ptr) == 0x1000);
+ expect(x.len == 0x500);
- assertOrPanic(@ptrToInt(y.ptr) == 0x1100);
- assertOrPanic(y.len == 0x400);
+ expect(@ptrToInt(y.ptr) == 0x1100);
+ expect(y.len == 0x400);
}
test "slice child property" {
var array: [5]i32 = undefined;
var slice = array[0..];
- assertOrPanic(@typeOf(slice).Child == i32);
+ expect(@typeOf(slice).Child == i32);
}
test "runtime safety lets us slice from len..len" {
@@ -23,7 +23,7 @@ test "runtime safety lets us slice from len..len" {
2,
3,
};
- assertOrPanic(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
+ expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
}
fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
@@ -36,5 +36,5 @@ test "implicitly cast array of size 0 to slice" {
}
fn assertLenIsZero(msg: []const u8) void {
- assertOrPanic(msg.len == 0);
+ expect(msg.len == 0);
}
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index 92ae2baa15..a045f482a2 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const builtin = @import("builtin");
const maxInt = std.math.maxInt;
@@ -12,7 +12,7 @@ const empty_global_instance = StructWithNoFields{};
test "call struct static method" {
const result = StructWithNoFields.add(3, 4);
- assertOrPanic(result == 7);
+ expect(result == 7);
}
test "return empty struct instance" {
@@ -25,7 +25,7 @@ fn returnEmptyStructInstance() StructWithNoFields {
const should_be_11 = StructWithNoFields.add(5, 6);
test "invoke static method in global scope" {
- assertOrPanic(should_be_11 == 11);
+ expect(should_be_11 == 11);
}
test "void struct fields" {
@@ -34,8 +34,8 @@ test "void struct fields" {
.b = 1,
.c = void{},
};
- assertOrPanic(foo.b == 1);
- assertOrPanic(@sizeOf(VoidStructFieldsFoo) == 4);
+ expect(foo.b == 1);
+ expect(@sizeOf(VoidStructFieldsFoo) == 4);
}
const VoidStructFieldsFoo = struct {
a: void,
@@ -50,7 +50,7 @@ test "structs" {
foo.b = foo.a == 1;
testFoo(foo);
testMutation(&foo);
- assertOrPanic(foo.c == 100);
+ expect(foo.c == 100);
}
const StructFoo = struct {
a: i32,
@@ -58,7 +58,7 @@ const StructFoo = struct {
c: f32,
};
fn testFoo(foo: StructFoo) void {
- assertOrPanic(foo.b);
+ expect(foo.b);
}
fn testMutation(foo: *StructFoo) void {
foo.c = 100;
@@ -83,7 +83,7 @@ test "struct point to self" {
root.next = &node;
- assertOrPanic(node.next.next.next.val.x == 1);
+ expect(node.next.next.next.val.x == 1);
}
test "struct byval assign" {
@@ -92,18 +92,18 @@ test "struct byval assign" {
foo1.a = 1234;
foo2.a = 0;
- assertOrPanic(foo2.a == 0);
+ expect(foo2.a == 0);
foo2 = foo1;
- assertOrPanic(foo2.a == 1234);
+ expect(foo2.a == 1234);
}
fn structInitializer() void {
const val = Val{ .x = 42 };
- assertOrPanic(val.x == 42);
+ expect(val.x == 42);
}
test "fn call of struct field" {
- assertOrPanic(callStructField(Foo{ .ptr = aFunc }) == 13);
+ expect(callStructField(Foo{ .ptr = aFunc }) == 13);
}
const Foo = struct {
@@ -122,7 +122,7 @@ test "store member function in variable" {
const instance = MemberFnTestFoo{ .x = 1234 };
const memberFn = MemberFnTestFoo.member;
const result = memberFn(instance);
- assertOrPanic(result == 1234);
+ expect(result == 1234);
}
const MemberFnTestFoo = struct {
x: i32,
@@ -134,12 +134,12 @@ const MemberFnTestFoo = struct {
test "call member function directly" {
const instance = MemberFnTestFoo{ .x = 1234 };
const result = MemberFnTestFoo.member(instance);
- assertOrPanic(result == 1234);
+ expect(result == 1234);
}
test "member functions" {
const r = MemberFnRand{ .seed = 1234 };
- assertOrPanic(r.getSeed() == 1234);
+ expect(r.getSeed() == 1234);
}
const MemberFnRand = struct {
seed: u32,
@@ -150,7 +150,7 @@ const MemberFnRand = struct {
test "return struct byval from function" {
const bar = makeBar(1234, 5678);
- assertOrPanic(bar.y == 5678);
+ expect(bar.y == 5678);
}
const Bar = struct {
x: i32,
@@ -165,7 +165,7 @@ fn makeBar(x: i32, y: i32) Bar {
test "empty struct method call" {
const es = EmptyStruct{};
- assertOrPanic(es.method() == 1234);
+ expect(es.method() == 1234);
}
const EmptyStruct = struct {
fn method(es: *const EmptyStruct) i32 {
@@ -182,7 +182,7 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 {
}
test "pass slice of empty struct to fn" {
- assertOrPanic(testPassSliceOfEmptyStructToFn([]EmptyStruct2{EmptyStruct2{}}) == 1);
+ expect(testPassSliceOfEmptyStructToFn([]EmptyStruct2{EmptyStruct2{}}) == 1);
}
fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
return slice.len;
@@ -200,7 +200,7 @@ test "packed struct" {
};
foo.y += 1;
const four = foo.x + foo.y;
- assertOrPanic(four == 4);
+ expect(four == 4);
}
const BitField1 = packed struct {
@@ -217,17 +217,17 @@ const bit_field_1 = BitField1{
test "bit field access" {
var data = bit_field_1;
- assertOrPanic(getA(&data) == 1);
- assertOrPanic(getB(&data) == 2);
- assertOrPanic(getC(&data) == 3);
- comptime assertOrPanic(@sizeOf(BitField1) == 1);
+ expect(getA(&data) == 1);
+ expect(getB(&data) == 2);
+ expect(getC(&data) == 3);
+ comptime expect(@sizeOf(BitField1) == 1);
data.b += 1;
- assertOrPanic(data.b == 3);
+ expect(data.b == 3);
data.a += 1;
- assertOrPanic(data.a == 2);
- assertOrPanic(data.b == 3);
+ expect(data.a == 2);
+ expect(data.b == 3);
}
fn getA(data: *const BitField1) u3 {
@@ -254,8 +254,8 @@ const Foo96Bits = packed struct {
test "packed struct 24bits" {
comptime {
- assertOrPanic(@sizeOf(Foo24Bits) == 3);
- assertOrPanic(@sizeOf(Foo96Bits) == 12);
+ expect(@sizeOf(Foo24Bits) == 3);
+ expect(@sizeOf(Foo96Bits) == 12);
}
var value = Foo96Bits{
@@ -265,28 +265,28 @@ test "packed struct 24bits" {
.d = 0,
};
value.a += 1;
- assertOrPanic(value.a == 1);
- assertOrPanic(value.b == 0);
- assertOrPanic(value.c == 0);
- assertOrPanic(value.d == 0);
+ expect(value.a == 1);
+ expect(value.b == 0);
+ expect(value.c == 0);
+ expect(value.d == 0);
value.b += 1;
- assertOrPanic(value.a == 1);
- assertOrPanic(value.b == 1);
- assertOrPanic(value.c == 0);
- assertOrPanic(value.d == 0);
+ expect(value.a == 1);
+ expect(value.b == 1);
+ expect(value.c == 0);
+ expect(value.d == 0);
value.c += 1;
- assertOrPanic(value.a == 1);
- assertOrPanic(value.b == 1);
- assertOrPanic(value.c == 1);
- assertOrPanic(value.d == 0);
+ expect(value.a == 1);
+ expect(value.b == 1);
+ expect(value.c == 1);
+ expect(value.d == 0);
value.d += 1;
- assertOrPanic(value.a == 1);
- assertOrPanic(value.b == 1);
- assertOrPanic(value.c == 1);
- assertOrPanic(value.d == 1);
+ expect(value.a == 1);
+ expect(value.b == 1);
+ expect(value.c == 1);
+ expect(value.d == 1);
}
const FooArray24Bits = packed struct {
@@ -297,43 +297,43 @@ const FooArray24Bits = packed struct {
test "packed array 24bits" {
comptime {
- assertOrPanic(@sizeOf([9]Foo24Bits) == 9 * 3);
- assertOrPanic(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);
+ expect(@sizeOf([9]Foo24Bits) == 9 * 3);
+ expect(@sizeOf(FooArray24Bits) == 2 + 2 * 3 + 2);
}
var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);
bytes[bytes.len - 1] = 0xaa;
const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
- assertOrPanic(ptr.a == 0);
- assertOrPanic(ptr.b[0].field == 0);
- assertOrPanic(ptr.b[1].field == 0);
- assertOrPanic(ptr.c == 0);
+ expect(ptr.a == 0);
+ expect(ptr.b[0].field == 0);
+ expect(ptr.b[1].field == 0);
+ expect(ptr.c == 0);
ptr.a = maxInt(u16);
- assertOrPanic(ptr.a == maxInt(u16));
- assertOrPanic(ptr.b[0].field == 0);
- assertOrPanic(ptr.b[1].field == 0);
- assertOrPanic(ptr.c == 0);
+ expect(ptr.a == maxInt(u16));
+ expect(ptr.b[0].field == 0);
+ expect(ptr.b[1].field == 0);
+ expect(ptr.c == 0);
ptr.b[0].field = maxInt(u24);
- assertOrPanic(ptr.a == maxInt(u16));
- assertOrPanic(ptr.b[0].field == maxInt(u24));
- assertOrPanic(ptr.b[1].field == 0);
- assertOrPanic(ptr.c == 0);
+ expect(ptr.a == maxInt(u16));
+ expect(ptr.b[0].field == maxInt(u24));
+ expect(ptr.b[1].field == 0);
+ expect(ptr.c == 0);
ptr.b[1].field = maxInt(u24);
- assertOrPanic(ptr.a == maxInt(u16));
- assertOrPanic(ptr.b[0].field == maxInt(u24));
- assertOrPanic(ptr.b[1].field == maxInt(u24));
- assertOrPanic(ptr.c == 0);
+ expect(ptr.a == maxInt(u16));
+ expect(ptr.b[0].field == maxInt(u24));
+ expect(ptr.b[1].field == maxInt(u24));
+ expect(ptr.c == 0);
ptr.c = maxInt(u16);
- assertOrPanic(ptr.a == maxInt(u16));
- assertOrPanic(ptr.b[0].field == maxInt(u24));
- assertOrPanic(ptr.b[1].field == maxInt(u24));
- assertOrPanic(ptr.c == maxInt(u16));
+ expect(ptr.a == maxInt(u16));
+ expect(ptr.b[0].field == maxInt(u24));
+ expect(ptr.b[1].field == maxInt(u24));
+ expect(ptr.c == maxInt(u16));
- assertOrPanic(bytes[bytes.len - 1] == 0xaa);
+ expect(bytes[bytes.len - 1] == 0xaa);
}
const FooStructAligned = packed struct {
@@ -347,17 +347,17 @@ const FooArrayOfAligned = packed struct {
test "aligned array of packed struct" {
comptime {
- assertOrPanic(@sizeOf(FooStructAligned) == 2);
- assertOrPanic(@sizeOf(FooArrayOfAligned) == 2 * 2);
+ expect(@sizeOf(FooStructAligned) == 2);
+ expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
}
var bytes = []u8{0xbb} ** @sizeOf(FooArrayOfAligned);
const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];
- assertOrPanic(ptr.a[0].a == 0xbb);
- assertOrPanic(ptr.a[0].b == 0xbb);
- assertOrPanic(ptr.a[1].a == 0xbb);
- assertOrPanic(ptr.a[1].b == 0xbb);
+ expect(ptr.a[0].a == 0xbb);
+ expect(ptr.a[0].b == 0xbb);
+ expect(ptr.a[1].a == 0xbb);
+ expect(ptr.a[1].b == 0xbb);
}
test "runtime struct initialization of bitfield" {
@@ -370,10 +370,10 @@ test "runtime struct initialization of bitfield" {
.y = @intCast(u4, x2),
};
- assertOrPanic(s1.x == x1);
- assertOrPanic(s1.y == x1);
- assertOrPanic(s2.x == @intCast(u4, x2));
- assertOrPanic(s2.y == @intCast(u4, x2));
+ expect(s1.x == x1);
+ expect(s1.y == x1);
+ expect(s2.x == @intCast(u4, x2));
+ expect(s2.y == @intCast(u4, x2));
}
var x1 = u4(1);
@@ -400,18 +400,18 @@ test "native bit field understands endianness" {
@memcpy(bytes[0..].ptr, @ptrCast([*]u8, &all), 8);
var bitfields = @ptrCast(*Bitfields, bytes[0..].ptr).*;
- assertOrPanic(bitfields.f1 == 0x1111);
- assertOrPanic(bitfields.f2 == 0x2222);
- assertOrPanic(bitfields.f3 == 0x33);
- assertOrPanic(bitfields.f4 == 0x44);
- assertOrPanic(bitfields.f5 == 0x5);
- assertOrPanic(bitfields.f6 == 0x6);
- assertOrPanic(bitfields.f7 == 0x77);
+ expect(bitfields.f1 == 0x1111);
+ expect(bitfields.f2 == 0x2222);
+ expect(bitfields.f3 == 0x33);
+ expect(bitfields.f4 == 0x44);
+ expect(bitfields.f5 == 0x5);
+ expect(bitfields.f6 == 0x6);
+ expect(bitfields.f7 == 0x77);
}
test "align 1 field before self referential align 8 field as slice return type" {
const result = alloc(Expr);
- assertOrPanic(result.len == 0);
+ expect(result.len == 0);
}
const Expr = union(enum) {
@@ -434,10 +434,10 @@ test "call method with mutable reference to struct with no fields" {
};
var s = S{};
- assertOrPanic(S.doC(&s));
- assertOrPanic(s.doC());
- assertOrPanic(S.do(&s));
- assertOrPanic(s.do());
+ expect(S.doC(&s));
+ expect(s.doC());
+ expect(S.do(&s));
+ expect(s.do());
}
test "implicit cast packed struct field to const ptr" {
@@ -453,7 +453,7 @@ test "implicit cast packed struct field to const ptr" {
var lup: LevelUpMove = undefined;
lup.level = 12;
const res = LevelUpMove.toInt(lup.level);
- assertOrPanic(res == 12);
+ expect(res == 12);
}
test "pointer to packed struct member in a stack variable" {
@@ -464,7 +464,7 @@ test "pointer to packed struct member in a stack variable" {
var s = S{ .a = 2, .b = 0 };
var b_ptr = &s.b;
- assertOrPanic(s.b == 0);
+ expect(s.b == 0);
b_ptr.* = 2;
- assertOrPanic(s.b == 2);
+ expect(s.b == 2);
}
diff --git a/test/stage1/behavior/struct_contains_null_ptr_itself.zig b/test/stage1/behavior/struct_contains_null_ptr_itself.zig
index 4cc479f31c..991d742cec 100644
--- a/test/stage1/behavior/struct_contains_null_ptr_itself.zig
+++ b/test/stage1/behavior/struct_contains_null_ptr_itself.zig
@@ -1,9 +1,9 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "struct contains null pointer which contains original struct" {
var x: ?*NodeLineComment = null;
- assertOrPanic(x == null);
+ expect(x == null);
}
pub const Node = struct {
diff --git a/test/stage1/behavior/struct_contains_slice_of_itself.zig b/test/stage1/behavior/struct_contains_slice_of_itself.zig
index 15780a7c44..52c6579654 100644
--- a/test/stage1/behavior/struct_contains_slice_of_itself.zig
+++ b/test/stage1/behavior/struct_contains_slice_of_itself.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const Node = struct {
payload: i32,
@@ -39,12 +39,12 @@ test "struct contains slice of itself" {
.payload = 1234,
.children = nodes[0..],
};
- assertOrPanic(root.payload == 1234);
- assertOrPanic(root.children[0].payload == 1);
- assertOrPanic(root.children[1].payload == 2);
- assertOrPanic(root.children[2].payload == 3);
- assertOrPanic(root.children[2].children[0].payload == 31);
- assertOrPanic(root.children[2].children[1].payload == 32);
+ expect(root.payload == 1234);
+ expect(root.children[0].payload == 1);
+ expect(root.children[1].payload == 2);
+ expect(root.children[2].payload == 3);
+ expect(root.children[2].children[0].payload == 31);
+ expect(root.children[2].children[1].payload == 32);
}
test "struct contains aligned slice of itself" {
@@ -76,10 +76,10 @@ test "struct contains aligned slice of itself" {
.payload = 1234,
.children = nodes[0..],
};
- assertOrPanic(root.payload == 1234);
- assertOrPanic(root.children[0].payload == 1);
- assertOrPanic(root.children[1].payload == 2);
- assertOrPanic(root.children[2].payload == 3);
- assertOrPanic(root.children[2].children[0].payload == 31);
- assertOrPanic(root.children[2].children[1].payload == 32);
+ expect(root.payload == 1234);
+ expect(root.children[0].payload == 1);
+ expect(root.children[1].payload == 2);
+ expect(root.children[2].payload == 3);
+ expect(root.children[2].children[0].payload == 31);
+ expect(root.children[2].children[1].payload == 32);
}
diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig
index 4ac971397e..1059bf28f8 100644
--- a/test/stage1/behavior/switch.zig
+++ b/test/stage1/behavior/switch.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "switch with numbers" {
testSwitchWithNumbers(13);
@@ -10,14 +10,14 @@ fn testSwitchWithNumbers(x: u32) void {
13 => true,
else => false,
};
- assertOrPanic(result);
+ expect(result);
}
test "switch with all ranges" {
- assertOrPanic(testSwitchWithAllRanges(50, 3) == 1);
- assertOrPanic(testSwitchWithAllRanges(101, 0) == 2);
- assertOrPanic(testSwitchWithAllRanges(300, 5) == 3);
- assertOrPanic(testSwitchWithAllRanges(301, 6) == 6);
+ expect(testSwitchWithAllRanges(50, 3) == 1);
+ expect(testSwitchWithAllRanges(101, 0) == 2);
+ expect(testSwitchWithAllRanges(300, 5) == 3);
+ expect(testSwitchWithAllRanges(301, 6) == 6);
}
fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
@@ -40,7 +40,7 @@ test "implicit comptime switch" {
};
comptime {
- assertOrPanic(result + 1 == 14);
+ expect(result + 1 == 14);
}
}
@@ -71,7 +71,7 @@ fn nonConstSwitch(foo: SwitchStatmentFoo) void {
SwitchStatmentFoo.C => 3,
SwitchStatmentFoo.D => 4,
};
- assertOrPanic(val == 3);
+ expect(val == 3);
}
const SwitchStatmentFoo = enum {
A,
@@ -93,10 +93,10 @@ const SwitchProngWithVarEnum = union(enum) {
fn switchProngWithVarFn(a: SwitchProngWithVarEnum) void {
switch (a) {
SwitchProngWithVarEnum.One => |x| {
- assertOrPanic(x == 13);
+ expect(x == 13);
},
SwitchProngWithVarEnum.Two => |x| {
- assertOrPanic(x == 13.0);
+ expect(x == 13.0);
},
SwitchProngWithVarEnum.Meh => |x| {
const v: void = x;
@@ -116,7 +116,7 @@ fn testSwitchEnumPtrCapture() void {
else => unreachable,
}
switch (value) {
- SwitchProngWithVarEnum.One => |x| assertOrPanic(x == 1235),
+ SwitchProngWithVarEnum.One => |x| expect(x == 1235),
else => unreachable,
}
}
@@ -127,7 +127,7 @@ test "switch with multiple expressions" {
4, 5, 6 => 2,
else => i32(3),
};
- assertOrPanic(x == 2);
+ expect(x == 2);
}
fn returnsFive() i32 {
return 5;
@@ -149,12 +149,12 @@ fn returnsFalse() bool {
}
}
test "switch on const enum with var" {
- assertOrPanic(!returnsFalse());
+ expect(!returnsFalse());
}
test "switch on type" {
- assertOrPanic(trueIfBoolFalseOtherwise(bool));
- assertOrPanic(!trueIfBoolFalseOtherwise(i32));
+ expect(trueIfBoolFalseOtherwise(bool));
+ expect(!trueIfBoolFalseOtherwise(i32));
}
fn trueIfBoolFalseOtherwise(comptime T: type) bool {
@@ -170,16 +170,16 @@ test "switch handles all cases of number" {
}
fn testSwitchHandleAllCases() void {
- assertOrPanic(testSwitchHandleAllCasesExhaustive(0) == 3);
- assertOrPanic(testSwitchHandleAllCasesExhaustive(1) == 2);
- assertOrPanic(testSwitchHandleAllCasesExhaustive(2) == 1);
- assertOrPanic(testSwitchHandleAllCasesExhaustive(3) == 0);
+ expect(testSwitchHandleAllCasesExhaustive(0) == 3);
+ expect(testSwitchHandleAllCasesExhaustive(1) == 2);
+ expect(testSwitchHandleAllCasesExhaustive(2) == 1);
+ expect(testSwitchHandleAllCasesExhaustive(3) == 0);
- assertOrPanic(testSwitchHandleAllCasesRange(100) == 0);
- assertOrPanic(testSwitchHandleAllCasesRange(200) == 1);
- assertOrPanic(testSwitchHandleAllCasesRange(201) == 2);
- assertOrPanic(testSwitchHandleAllCasesRange(202) == 4);
- assertOrPanic(testSwitchHandleAllCasesRange(230) == 3);
+ expect(testSwitchHandleAllCasesRange(100) == 0);
+ expect(testSwitchHandleAllCasesRange(200) == 1);
+ expect(testSwitchHandleAllCasesRange(201) == 2);
+ expect(testSwitchHandleAllCasesRange(202) == 4);
+ expect(testSwitchHandleAllCasesRange(230) == 3);
}
fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
@@ -207,8 +207,8 @@ test "switch all prongs unreachable" {
}
fn testAllProngsUnreachable() void {
- assertOrPanic(switchWithUnreachable(1) == 2);
- assertOrPanic(switchWithUnreachable(2) == 10);
+ expect(switchWithUnreachable(1) == 2);
+ expect(switchWithUnreachable(2) == 10);
}
fn switchWithUnreachable(x: i32) i32 {
@@ -230,7 +230,7 @@ test "capture value of switch with all unreachable prongs" {
const x = return_a_number() catch |err| switch (err) {
else => unreachable,
};
- assertOrPanic(x == 1);
+ expect(x == 1);
}
test "switching on booleans" {
@@ -239,14 +239,14 @@ test "switching on booleans" {
}
fn testSwitchOnBools() void {
- assertOrPanic(testSwitchOnBoolsTrueAndFalse(true) == false);
- assertOrPanic(testSwitchOnBoolsTrueAndFalse(false) == true);
+ expect(testSwitchOnBoolsTrueAndFalse(true) == false);
+ expect(testSwitchOnBoolsTrueAndFalse(false) == true);
- assertOrPanic(testSwitchOnBoolsTrueWithElse(true) == false);
- assertOrPanic(testSwitchOnBoolsTrueWithElse(false) == true);
+ expect(testSwitchOnBoolsTrueWithElse(true) == false);
+ expect(testSwitchOnBoolsTrueWithElse(false) == true);
- assertOrPanic(testSwitchOnBoolsFalseWithElse(true) == false);
- assertOrPanic(testSwitchOnBoolsFalseWithElse(false) == true);
+ expect(testSwitchOnBoolsFalseWithElse(true) == false);
+ expect(testSwitchOnBoolsFalseWithElse(false) == true);
}
fn testSwitchOnBoolsTrueAndFalse(x: bool) bool {
diff --git a/test/stage1/behavior/switch_prong_err_enum.zig b/test/stage1/behavior/switch_prong_err_enum.zig
index 6ac1919f0d..3593eabb5a 100644
--- a/test/stage1/behavior/switch_prong_err_enum.zig
+++ b/test/stage1/behavior/switch_prong_err_enum.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
var read_count: u64 = 0;
@@ -22,9 +22,9 @@ fn doThing(form_id: u64) anyerror!FormValue {
test "switch prong returns error enum" {
switch (doThing(17) catch unreachable) {
FormValue.Address => |payload| {
- assertOrPanic(payload == 1);
+ expect(payload == 1);
},
else => unreachable,
}
- assertOrPanic(read_count == 1);
+ expect(read_count == 1);
}
diff --git a/test/stage1/behavior/switch_prong_implicit_cast.zig b/test/stage1/behavior/switch_prong_implicit_cast.zig
index 4ca031e2e1..da965915ca 100644
--- a/test/stage1/behavior/switch_prong_implicit_cast.zig
+++ b/test/stage1/behavior/switch_prong_implicit_cast.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const FormValue = union(enum) {
One: void,
@@ -18,5 +18,5 @@ test "switch prong implicit cast" {
FormValue.One => false,
FormValue.Two => |x| x,
};
- assertOrPanic(result);
+ expect(result);
}
diff --git a/test/stage1/behavior/this.zig b/test/stage1/behavior/this.zig
index 0e3a7a03ae..a0bee3a3ee 100644
--- a/test/stage1/behavior/this.zig
+++ b/test/stage1/behavior/this.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const module = @This();
@@ -20,7 +20,7 @@ fn add(x: i32, y: i32) i32 {
}
test "this refer to module call private fn" {
- assertOrPanic(module.add(1, 2) == 3);
+ expect(module.add(1, 2) == 3);
}
test "this refer to container" {
@@ -29,7 +29,7 @@ test "this refer to container" {
.y = 34,
};
pt.addOne();
- assertOrPanic(pt.x == 13);
- assertOrPanic(pt.y == 35);
+ expect(pt.x == 13);
+ expect(pt.y == 35);
}
diff --git a/test/stage1/behavior/truncate.zig b/test/stage1/behavior/truncate.zig
index b7904bc7fb..c195b64cbf 100644
--- a/test/stage1/behavior/truncate.zig
+++ b/test/stage1/behavior/truncate.zig
@@ -1,8 +1,8 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "truncate u0 to larger integer allowed and has comptime known result" {
var x: u0 = 0;
const y = @truncate(u8, x);
- comptime assertOrPanic(y == 0);
+ comptime expect(y == 0);
}
diff --git a/test/stage1/behavior/try.zig b/test/stage1/behavior/try.zig
index ed48875eb4..9c700f6260 100644
--- a/test/stage1/behavior/try.zig
+++ b/test/stage1/behavior/try.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "try on error union" {
tryOnErrorUnionImpl();
@@ -11,7 +11,7 @@ fn tryOnErrorUnionImpl() void {
error.CrappedOut => i32(2),
else => unreachable,
};
- assertOrPanic(x == 11);
+ expect(x == 11);
}
fn returnsTen() anyerror!i32 {
@@ -20,10 +20,10 @@ fn returnsTen() anyerror!i32 {
test "try without vars" {
const result1 = if (failIfTrue(true)) 1 else |_| i32(2);
- assertOrPanic(result1 == 2);
+ expect(result1 == 2);
const result2 = if (failIfTrue(false)) 1 else |_| i32(2);
- assertOrPanic(result2 == 1);
+ expect(result2 == 1);
}
fn failIfTrue(ok: bool) anyerror!void {
@@ -38,6 +38,6 @@ test "try then not executed with assignment" {
if (failIfTrue(true)) {
unreachable;
} else |err| {
- assertOrPanic(err == error.ItBroke);
+ expect(err == error.ItBroke);
}
}
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index f3bb17b282..ce0ad795b4 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
const TypeInfo = @import("builtin").TypeInfo;
const TypeId = @import("builtin").TypeId;
@@ -9,10 +9,10 @@ test "type info: tag type, void info" {
}
fn testBasic() void {
- assertOrPanic(@TagType(TypeInfo) == TypeId);
+ expect(@TagType(TypeInfo) == TypeId);
const void_info = @typeInfo(void);
- assertOrPanic(TypeId(void_info) == TypeId.Void);
- assertOrPanic(void_info.Void == {});
+ expect(TypeId(void_info) == TypeId.Void);
+ expect(void_info.Void == {});
}
test "type info: integer, floating point type info" {
@@ -22,13 +22,13 @@ test "type info: integer, floating point type info" {
fn testIntFloat() void {
const u8_info = @typeInfo(u8);
- assertOrPanic(TypeId(u8_info) == TypeId.Int);
- assertOrPanic(!u8_info.Int.is_signed);
- assertOrPanic(u8_info.Int.bits == 8);
+ expect(TypeId(u8_info) == TypeId.Int);
+ expect(!u8_info.Int.is_signed);
+ expect(u8_info.Int.bits == 8);
const f64_info = @typeInfo(f64);
- assertOrPanic(TypeId(f64_info) == TypeId.Float);
- assertOrPanic(f64_info.Float.bits == 64);
+ expect(TypeId(f64_info) == TypeId.Float);
+ expect(f64_info.Float.bits == 64);
}
test "type info: pointer type info" {
@@ -38,12 +38,12 @@ test "type info: pointer type info" {
fn testPointer() void {
const u32_ptr_info = @typeInfo(*u32);
- assertOrPanic(TypeId(u32_ptr_info) == TypeId.Pointer);
- assertOrPanic(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
- assertOrPanic(u32_ptr_info.Pointer.is_const == false);
- assertOrPanic(u32_ptr_info.Pointer.is_volatile == false);
- assertOrPanic(u32_ptr_info.Pointer.alignment == @alignOf(u32));
- assertOrPanic(u32_ptr_info.Pointer.child == u32);
+ expect(TypeId(u32_ptr_info) == TypeId.Pointer);
+ expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
+ expect(u32_ptr_info.Pointer.is_const == false);
+ expect(u32_ptr_info.Pointer.is_volatile == false);
+ expect(u32_ptr_info.Pointer.alignment == @alignOf(u32));
+ expect(u32_ptr_info.Pointer.child == u32);
}
test "type info: unknown length pointer type info" {
@@ -53,12 +53,12 @@ test "type info: unknown length pointer type info" {
fn testUnknownLenPtr() void {
const u32_ptr_info = @typeInfo([*]const volatile f64);
- assertOrPanic(TypeId(u32_ptr_info) == TypeId.Pointer);
- assertOrPanic(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
- assertOrPanic(u32_ptr_info.Pointer.is_const == true);
- assertOrPanic(u32_ptr_info.Pointer.is_volatile == true);
- assertOrPanic(u32_ptr_info.Pointer.alignment == @alignOf(f64));
- assertOrPanic(u32_ptr_info.Pointer.child == f64);
+ expect(TypeId(u32_ptr_info) == TypeId.Pointer);
+ expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
+ expect(u32_ptr_info.Pointer.is_const == true);
+ expect(u32_ptr_info.Pointer.is_volatile == true);
+ expect(u32_ptr_info.Pointer.alignment == @alignOf(f64));
+ expect(u32_ptr_info.Pointer.child == f64);
}
test "type info: slice type info" {
@@ -68,12 +68,12 @@ test "type info: slice type info" {
fn testSlice() void {
const u32_slice_info = @typeInfo([]u32);
- assertOrPanic(TypeId(u32_slice_info) == TypeId.Pointer);
- assertOrPanic(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
- assertOrPanic(u32_slice_info.Pointer.is_const == false);
- assertOrPanic(u32_slice_info.Pointer.is_volatile == false);
- assertOrPanic(u32_slice_info.Pointer.alignment == 4);
- assertOrPanic(u32_slice_info.Pointer.child == u32);
+ expect(TypeId(u32_slice_info) == TypeId.Pointer);
+ expect(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
+ expect(u32_slice_info.Pointer.is_const == false);
+ expect(u32_slice_info.Pointer.is_volatile == false);
+ expect(u32_slice_info.Pointer.alignment == 4);
+ expect(u32_slice_info.Pointer.child == u32);
}
test "type info: array type info" {
@@ -83,9 +83,9 @@ test "type info: array type info" {
fn testArray() void {
const arr_info = @typeInfo([42]bool);
- assertOrPanic(TypeId(arr_info) == TypeId.Array);
- assertOrPanic(arr_info.Array.len == 42);
- assertOrPanic(arr_info.Array.child == bool);
+ expect(TypeId(arr_info) == TypeId.Array);
+ expect(arr_info.Array.len == 42);
+ expect(arr_info.Array.child == bool);
}
test "type info: optional type info" {
@@ -95,8 +95,8 @@ test "type info: optional type info" {
fn testOptional() void {
const null_info = @typeInfo(?void);
- assertOrPanic(TypeId(null_info) == TypeId.Optional);
- assertOrPanic(null_info.Optional.child == void);
+ expect(TypeId(null_info) == TypeId.Optional);
+ expect(null_info.Optional.child == void);
}
test "type info: promise info" {
@@ -106,12 +106,12 @@ test "type info: promise info" {
fn testPromise() void {
const null_promise_info = @typeInfo(promise);
- assertOrPanic(TypeId(null_promise_info) == TypeId.Promise);
- assertOrPanic(null_promise_info.Promise.child == null);
+ expect(TypeId(null_promise_info) == TypeId.Promise);
+ expect(null_promise_info.Promise.child == null);
const promise_info = @typeInfo(promise->usize);
- assertOrPanic(TypeId(promise_info) == TypeId.Promise);
- assertOrPanic(promise_info.Promise.child.? == usize);
+ expect(TypeId(promise_info) == TypeId.Promise);
+ expect(promise_info.Promise.child.? == usize);
}
test "type info: error set, error union info" {
@@ -127,15 +127,15 @@ fn testErrorSet() void {
};
const error_set_info = @typeInfo(TestErrorSet);
- assertOrPanic(TypeId(error_set_info) == TypeId.ErrorSet);
- assertOrPanic(error_set_info.ErrorSet.errors.len == 3);
- assertOrPanic(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
- assertOrPanic(error_set_info.ErrorSet.errors[2].value == @errorToInt(TestErrorSet.Third));
+ expect(TypeId(error_set_info) == TypeId.ErrorSet);
+ expect(error_set_info.ErrorSet.errors.len == 3);
+ expect(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
+ expect(error_set_info.ErrorSet.errors[2].value == @errorToInt(TestErrorSet.Third));
const error_union_info = @typeInfo(TestErrorSet!usize);
- assertOrPanic(TypeId(error_union_info) == TypeId.ErrorUnion);
- assertOrPanic(error_union_info.ErrorUnion.error_set == TestErrorSet);
- assertOrPanic(error_union_info.ErrorUnion.payload == usize);
+ expect(TypeId(error_union_info) == TypeId.ErrorUnion);
+ expect(error_union_info.ErrorUnion.error_set == TestErrorSet);
+ expect(error_union_info.ErrorUnion.payload == usize);
}
test "type info: enum info" {
@@ -152,13 +152,13 @@ fn testEnum() void {
};
const os_info = @typeInfo(Os);
- assertOrPanic(TypeId(os_info) == TypeId.Enum);
- assertOrPanic(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
- assertOrPanic(os_info.Enum.fields.len == 4);
- assertOrPanic(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
- assertOrPanic(os_info.Enum.fields[3].value == 3);
- assertOrPanic(os_info.Enum.tag_type == u2);
- assertOrPanic(os_info.Enum.defs.len == 0);
+ expect(TypeId(os_info) == TypeId.Enum);
+ expect(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
+ expect(os_info.Enum.fields.len == 4);
+ expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
+ expect(os_info.Enum.fields[3].value == 3);
+ expect(os_info.Enum.tag_type == u2);
+ expect(os_info.Enum.defs.len == 0);
}
test "type info: union info" {
@@ -168,14 +168,14 @@ test "type info: union info" {
fn testUnion() void {
const typeinfo_info = @typeInfo(TypeInfo);
- assertOrPanic(TypeId(typeinfo_info) == TypeId.Union);
- assertOrPanic(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
- assertOrPanic(typeinfo_info.Union.tag_type.? == TypeId);
- assertOrPanic(typeinfo_info.Union.fields.len == 25);
- assertOrPanic(typeinfo_info.Union.fields[4].enum_field != null);
- assertOrPanic(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
- assertOrPanic(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
- assertOrPanic(typeinfo_info.Union.defs.len == 21);
+ expect(TypeId(typeinfo_info) == TypeId.Union);
+ expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
+ expect(typeinfo_info.Union.tag_type.? == TypeId);
+ expect(typeinfo_info.Union.fields.len == 25);
+ expect(typeinfo_info.Union.fields[4].enum_field != null);
+ expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
+ expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
+ expect(typeinfo_info.Union.defs.len == 21);
const TestNoTagUnion = union {
Foo: void,
@@ -183,22 +183,22 @@ fn testUnion() void {
};
const notag_union_info = @typeInfo(TestNoTagUnion);
- assertOrPanic(TypeId(notag_union_info) == TypeId.Union);
- assertOrPanic(notag_union_info.Union.tag_type == null);
- assertOrPanic(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
- assertOrPanic(notag_union_info.Union.fields.len == 2);
- assertOrPanic(notag_union_info.Union.fields[0].enum_field == null);
- assertOrPanic(notag_union_info.Union.fields[1].field_type == u32);
+ expect(TypeId(notag_union_info) == TypeId.Union);
+ expect(notag_union_info.Union.tag_type == null);
+ expect(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
+ expect(notag_union_info.Union.fields.len == 2);
+ expect(notag_union_info.Union.fields[0].enum_field == null);
+ expect(notag_union_info.Union.fields[1].field_type == u32);
const TestExternUnion = extern union {
foo: *c_void,
};
const extern_union_info = @typeInfo(TestExternUnion);
- assertOrPanic(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
- assertOrPanic(extern_union_info.Union.tag_type == null);
- assertOrPanic(extern_union_info.Union.fields[0].enum_field == null);
- assertOrPanic(extern_union_info.Union.fields[0].field_type == *c_void);
+ expect(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
+ expect(extern_union_info.Union.tag_type == null);
+ expect(extern_union_info.Union.fields[0].enum_field == null);
+ expect(extern_union_info.Union.fields[0].field_type == *c_void);
}
test "type info: struct info" {
@@ -208,17 +208,17 @@ test "type info: struct info" {
fn testStruct() void {
const struct_info = @typeInfo(TestStruct);
- assertOrPanic(TypeId(struct_info) == TypeId.Struct);
- assertOrPanic(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
- assertOrPanic(struct_info.Struct.fields.len == 3);
- assertOrPanic(struct_info.Struct.fields[1].offset == null);
- assertOrPanic(struct_info.Struct.fields[2].field_type == *TestStruct);
- assertOrPanic(struct_info.Struct.defs.len == 2);
- assertOrPanic(struct_info.Struct.defs[0].is_pub);
- assertOrPanic(!struct_info.Struct.defs[0].data.Fn.is_extern);
- assertOrPanic(struct_info.Struct.defs[0].data.Fn.lib_name == null);
- assertOrPanic(struct_info.Struct.defs[0].data.Fn.return_type == void);
- assertOrPanic(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);
+ expect(TypeId(struct_info) == TypeId.Struct);
+ expect(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
+ expect(struct_info.Struct.fields.len == 3);
+ expect(struct_info.Struct.fields[1].offset == null);
+ expect(struct_info.Struct.fields[2].field_type == *TestStruct);
+ expect(struct_info.Struct.defs.len == 2);
+ expect(struct_info.Struct.defs[0].is_pub);
+ expect(!struct_info.Struct.defs[0].data.Fn.is_extern);
+ expect(struct_info.Struct.defs[0].data.Fn.lib_name == null);
+ expect(struct_info.Struct.defs[0].data.Fn.return_type == void);
+ expect(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);
}
const TestStruct = packed struct {
@@ -238,18 +238,18 @@ test "type info: function type info" {
fn testFunction() void {
const fn_info = @typeInfo(@typeOf(foo));
- assertOrPanic(TypeId(fn_info) == TypeId.Fn);
- assertOrPanic(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
- assertOrPanic(fn_info.Fn.is_generic);
- assertOrPanic(fn_info.Fn.args.len == 2);
- assertOrPanic(fn_info.Fn.is_var_args);
- assertOrPanic(fn_info.Fn.return_type == null);
- assertOrPanic(fn_info.Fn.async_allocator_type == null);
+ expect(TypeId(fn_info) == TypeId.Fn);
+ expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
+ expect(fn_info.Fn.is_generic);
+ expect(fn_info.Fn.args.len == 2);
+ expect(fn_info.Fn.is_var_args);
+ expect(fn_info.Fn.return_type == null);
+ expect(fn_info.Fn.async_allocator_type == null);
const test_instance: TestStruct = undefined;
const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
- assertOrPanic(TypeId(bound_fn_info) == TypeId.BoundFn);
- assertOrPanic(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
+ expect(TypeId(bound_fn_info) == TypeId.BoundFn);
+ expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
}
fn foo(comptime a: usize, b: bool, args: ...) usize {
@@ -270,7 +270,7 @@ test "type info: vectors" {
fn testVector() void {
const vec_info = @typeInfo(@Vector(4, i32));
- assertOrPanic(TypeId(vec_info) == TypeId.Vector);
- assertOrPanic(vec_info.Vector.len == 4);
- assertOrPanic(vec_info.Vector.child == i32);
+ expect(TypeId(vec_info) == TypeId.Vector);
+ expect(vec_info.Vector.len == 4);
+ expect(vec_info.Vector.child == i32);
}
diff --git a/test/stage1/behavior/undefined.zig b/test/stage1/behavior/undefined.zig
index 333e217d49..4c233576cd 100644
--- a/test/stage1/behavior/undefined.zig
+++ b/test/stage1/behavior/undefined.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const mem = @import("std").mem;
fn initStaticArray() [10]i32 {
@@ -11,16 +11,16 @@ fn initStaticArray() [10]i32 {
}
const static_array = initStaticArray();
test "init static array to undefined" {
- assertOrPanic(static_array[0] == 1);
- assertOrPanic(static_array[4] == 2);
- assertOrPanic(static_array[7] == 3);
- assertOrPanic(static_array[9] == 4);
+ expect(static_array[0] == 1);
+ expect(static_array[4] == 2);
+ expect(static_array[7] == 3);
+ expect(static_array[9] == 4);
comptime {
- assertOrPanic(static_array[0] == 1);
- assertOrPanic(static_array[4] == 2);
- assertOrPanic(static_array[7] == 3);
- assertOrPanic(static_array[9] == 4);
+ expect(static_array[0] == 1);
+ expect(static_array[4] == 2);
+ expect(static_array[7] == 3);
+ expect(static_array[9] == 4);
}
}
@@ -40,12 +40,12 @@ test "assign undefined to struct" {
comptime {
var foo: Foo = undefined;
setFooX(&foo);
- assertOrPanic(foo.x == 2);
+ expect(foo.x == 2);
}
{
var foo: Foo = undefined;
setFooX(&foo);
- assertOrPanic(foo.x == 2);
+ expect(foo.x == 2);
}
}
@@ -53,17 +53,17 @@ test "assign undefined to struct with method" {
comptime {
var foo: Foo = undefined;
foo.setFooXMethod();
- assertOrPanic(foo.x == 3);
+ expect(foo.x == 3);
}
{
var foo: Foo = undefined;
foo.setFooXMethod();
- assertOrPanic(foo.x == 3);
+ expect(foo.x == 3);
}
}
test "type name of undefined" {
const x = undefined;
- assertOrPanic(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
+ expect(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
}
diff --git a/test/stage1/behavior/underscore.zig b/test/stage1/behavior/underscore.zig
index 7443319336..fd5aebc87e 100644
--- a/test/stage1/behavior/underscore.zig
+++ b/test/stage1/behavior/underscore.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "ignore lval with underscore" {
_ = false;
diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig
index c8e8feb11e..0a4e2cfb92 100644
--- a/test/stage1/behavior/union.zig
+++ b/test/stage1/behavior/union.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const Value = union(enum) {
Int: u64,
@@ -27,11 +27,11 @@ const array = []Value{
test "unions embedded in aggregate types" {
switch (array[1]) {
- Value.Array => |arr| assertOrPanic(arr[4] == 3),
+ Value.Array => |arr| expect(arr[4] == 3),
else => unreachable,
}
switch ((err catch unreachable).val1) {
- Value.Int => |x| assertOrPanic(x == 1234),
+ Value.Int => |x| expect(x == 1234),
else => unreachable,
}
}
@@ -43,18 +43,18 @@ const Foo = union {
test "basic unions" {
var foo = Foo{ .int = 1 };
- assertOrPanic(foo.int == 1);
+ expect(foo.int == 1);
foo = Foo{ .float = 12.34 };
- assertOrPanic(foo.float == 12.34);
+ expect(foo.float == 12.34);
}
test "comptime union field access" {
comptime {
var foo = Foo{ .int = 0 };
- assertOrPanic(foo.int == 0);
+ expect(foo.int == 0);
foo = Foo{ .float = 42.42 };
- assertOrPanic(foo.float == 42.42);
+ expect(foo.float == 42.42);
}
}
@@ -62,10 +62,10 @@ test "init union with runtime value" {
var foo: Foo = undefined;
setFloat(&foo, 12.34);
- assertOrPanic(foo.float == 12.34);
+ expect(foo.float == 12.34);
setInt(&foo, 42);
- assertOrPanic(foo.int == 42);
+ expect(foo.int == 42);
}
fn setFloat(foo: *Foo, x: f64) void {
@@ -83,9 +83,9 @@ const FooExtern = extern union {
test "basic extern unions" {
var foo = FooExtern{ .int = 1 };
- assertOrPanic(foo.int == 1);
+ expect(foo.int == 1);
foo.float = 12.34;
- assertOrPanic(foo.float == 12.34);
+ expect(foo.float == 12.34);
}
const Letter = enum {
@@ -105,11 +105,11 @@ test "union with specified enum tag" {
}
fn doTest() void {
- assertOrPanic(bar(Payload{ .A = 1234 }) == -10);
+ expect(bar(Payload{ .A = 1234 }) == -10);
}
fn bar(value: Payload) i32 {
- assertOrPanic(Letter(value) == Letter.A);
+ expect(Letter(value) == Letter.A);
return switch (value) {
Payload.A => |x| return x - 1244,
Payload.B => |x| if (x == 12.34) i32(20) else 21,
@@ -125,8 +125,8 @@ const MultipleChoice = union(enum(u32)) {
};
test "simple union(enum(u32))" {
var x = MultipleChoice.C;
- assertOrPanic(x == MultipleChoice.C);
- assertOrPanic(@enumToInt(@TagType(MultipleChoice)(x)) == 60);
+ expect(x == MultipleChoice.C);
+ expect(@enumToInt(@TagType(MultipleChoice)(x)) == 60);
}
const MultipleChoice2 = union(enum(u32)) {
@@ -142,14 +142,14 @@ const MultipleChoice2 = union(enum(u32)) {
};
test "union(enum(u32)) with specified and unspecified tag values" {
- comptime assertOrPanic(@TagType(@TagType(MultipleChoice2)) == u32);
+ comptime expect(@TagType(@TagType(MultipleChoice2)) == u32);
testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
}
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
- assertOrPanic(@enumToInt(@TagType(MultipleChoice2)(x)) == 60);
- assertOrPanic(1123 == switch (x) {
+ expect(@enumToInt(@TagType(MultipleChoice2)(x)) == 60);
+ expect(1123 == switch (x) {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
MultipleChoice2.C => |v| i32(1000) + v,
@@ -167,7 +167,7 @@ const ExternPtrOrInt = extern union {
int: u64,
};
test "extern union size" {
- comptime assertOrPanic(@sizeOf(ExternPtrOrInt) == 8);
+ comptime expect(@sizeOf(ExternPtrOrInt) == 8);
}
const PackedPtrOrInt = packed union {
@@ -175,14 +175,14 @@ const PackedPtrOrInt = packed union {
int: u64,
};
test "extern union size" {
- comptime assertOrPanic(@sizeOf(PackedPtrOrInt) == 8);
+ comptime expect(@sizeOf(PackedPtrOrInt) == 8);
}
const ZeroBits = union {
OnlyField: void,
};
test "union with only 1 field which is void should be zero bits" {
- comptime assertOrPanic(@sizeOf(ZeroBits) == 0);
+ comptime expect(@sizeOf(ZeroBits) == 0);
}
const TheTag = enum {
@@ -196,9 +196,9 @@ const TheUnion = union(TheTag) {
C: i32,
};
test "union field access gives the enum values" {
- assertOrPanic(TheUnion.A == TheTag.A);
- assertOrPanic(TheUnion.B == TheTag.B);
- assertOrPanic(TheUnion.C == TheTag.C);
+ expect(TheUnion.A == TheTag.A);
+ expect(TheUnion.B == TheTag.B);
+ expect(TheUnion.C == TheTag.C);
}
test "cast union to tag type of union" {
@@ -207,12 +207,12 @@ test "cast union to tag type of union" {
}
fn testCastUnionToTagType(x: TheUnion) void {
- assertOrPanic(TheTag(x) == TheTag.B);
+ expect(TheTag(x) == TheTag.B);
}
test "cast tag type of union to union" {
var x: Value2 = Letter2.B;
- assertOrPanic(Letter2(x) == Letter2.B);
+ expect(Letter2(x) == Letter2.B);
}
const Letter2 = enum {
A,
@@ -227,11 +227,11 @@ const Value2 = union(Letter2) {
test "implicit cast union to its tag type" {
var x: Value2 = Letter2.B;
- assertOrPanic(x == Letter2.B);
+ expect(x == Letter2.B);
giveMeLetterB(x);
}
fn giveMeLetterB(x: Letter2) void {
- assertOrPanic(x == Value2.B);
+ expect(x == Value2.B);
}
pub const PackThis = union(enum) {
@@ -244,7 +244,7 @@ test "constant packed union" {
}
fn testConstPackedUnion(expected_tokens: []const PackThis) void {
- assertOrPanic(expected_tokens[0].StringLiteral == 1);
+ expect(expected_tokens[0].StringLiteral == 1);
}
test "switch on union with only 1 field" {
@@ -256,7 +256,7 @@ test "switch on union with only 1 field" {
z = PartialInstWithPayload{ .Compiled = 1234 };
switch (z) {
PartialInstWithPayload.Compiled => |x| {
- assertOrPanic(x == 1234);
+ expect(x == 1234);
return;
},
}
@@ -282,11 +282,11 @@ test "access a member of tagged union with conflicting enum tag name" {
const B = void;
};
- comptime assertOrPanic(Bar.A == u8);
+ comptime expect(Bar.A == u8);
}
test "tagged union initialization with runtime void" {
- assertOrPanic(testTaggedUnionInit({}));
+ expect(testTaggedUnionInit({}));
}
const TaggedUnionWithAVoid = union(enum) {
@@ -324,9 +324,9 @@ test "union with only 1 field casted to its enum type" {
var e = Expr{ .Literal = Literal{ .Bool = true } };
const Tag = @TagType(Expr);
- comptime assertOrPanic(@TagType(Tag) == comptime_int);
+ comptime expect(@TagType(Tag) == comptime_int);
var t = Tag(e);
- assertOrPanic(t == Expr.Literal);
+ expect(t == Expr.Literal);
}
test "union with only 1 field casted to its enum type which has enum value specified" {
@@ -344,9 +344,9 @@ test "union with only 1 field casted to its enum type which has enum value speci
};
var e = Expr{ .Literal = Literal{ .Bool = true } };
- comptime assertOrPanic(@TagType(Tag) == comptime_int);
+ comptime expect(@TagType(Tag) == comptime_int);
var t = Tag(e);
- assertOrPanic(t == Expr.Literal);
- assertOrPanic(@enumToInt(t) == 33);
- comptime assertOrPanic(@enumToInt(t) == 33);
+ expect(t == Expr.Literal);
+ expect(@enumToInt(t) == 33);
+ comptime expect(@enumToInt(t) == 33);
}
diff --git a/test/stage1/behavior/var_args.zig b/test/stage1/behavior/var_args.zig
index 1f782a3bb3..cc93b57f06 100644
--- a/test/stage1/behavior/var_args.zig
+++ b/test/stage1/behavior/var_args.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
fn add(args: ...) i32 {
var sum = i32(0);
@@ -12,9 +12,9 @@ fn add(args: ...) i32 {
}
test "add arbitrary args" {
- assertOrPanic(add(i32(1), i32(2), i32(3), i32(4)) == 10);
- assertOrPanic(add(i32(1234)) == 1234);
- assertOrPanic(add() == 0);
+ expect(add(i32(1), i32(2), i32(3), i32(4)) == 10);
+ expect(add(i32(1234)) == 1234);
+ expect(add() == 0);
}
fn readFirstVarArg(args: ...) void {
@@ -26,9 +26,9 @@ test "send void arg to var args" {
}
test "pass args directly" {
- assertOrPanic(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10);
- assertOrPanic(addSomeStuff(i32(1234)) == 1234);
- assertOrPanic(addSomeStuff() == 0);
+ expect(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10);
+ expect(addSomeStuff(i32(1234)) == 1234);
+ expect(addSomeStuff() == 0);
}
fn addSomeStuff(args: ...) i32 {
@@ -36,24 +36,24 @@ fn addSomeStuff(args: ...) i32 {
}
test "runtime parameter before var args" {
- assertOrPanic(extraFn(10) == 0);
- assertOrPanic(extraFn(10, false) == 1);
- assertOrPanic(extraFn(10, false, true) == 2);
+ expect(extraFn(10) == 0);
+ expect(extraFn(10, false) == 1);
+ expect(extraFn(10, false, true) == 2);
// TODO issue #313
//comptime {
- // assertOrPanic(extraFn(10) == 0);
- // assertOrPanic(extraFn(10, false) == 1);
- // assertOrPanic(extraFn(10, false, true) == 2);
+ // expect(extraFn(10) == 0);
+ // expect(extraFn(10, false) == 1);
+ // expect(extraFn(10, false, true) == 2);
//}
}
fn extraFn(extra: u32, args: ...) usize {
if (args.len >= 1) {
- assertOrPanic(args[0] == false);
+ expect(args[0] == false);
}
if (args.len >= 2) {
- assertOrPanic(args[1] == true);
+ expect(args[1] == true);
}
return args.len;
}
@@ -71,8 +71,8 @@ fn foo2(args: ...) bool {
}
test "array of var args functions" {
- assertOrPanic(foos[0]());
- assertOrPanic(!foos[1]());
+ expect(foos[0]());
+ expect(!foos[1]());
}
test "pass zero length array to var args param" {
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index c97ee0e3d6..7cead12b65 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -1,15 +1,15 @@
const std = @import("std");
const mem = std.mem;
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
test "vector wrap operators" {
const S = struct {
fn doTheTest() void {
const v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
const x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
- assertOrPanic(mem.eql(i32, ([4]i32)(v +% x), [4]i32{ 11, 22, 33, 44 }));
- assertOrPanic(mem.eql(i32, ([4]i32)(v -% x), [4]i32{ 9, 18, 27, 36 }));
- assertOrPanic(mem.eql(i32, ([4]i32)(v *% x), [4]i32{ 10, 40, 90, 160 }));
+ expect(mem.eql(i32, ([4]i32)(v +% x), [4]i32{ 11, 22, 33, 44 }));
+ expect(mem.eql(i32, ([4]i32)(v -% x), [4]i32{ 9, 18, 27, 36 }));
+ expect(mem.eql(i32, ([4]i32)(v *% x), [4]i32{ 10, 40, 90, 160 }));
}
};
S.doTheTest();
diff --git a/test/stage1/behavior/void.zig b/test/stage1/behavior/void.zig
index 431d3f4eb1..9722791946 100644
--- a/test/stage1/behavior/void.zig
+++ b/test/stage1/behavior/void.zig
@@ -1,4 +1,4 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
const Foo = struct {
a: void,
@@ -13,14 +13,14 @@ test "compare void with void compile time known" {
.b = 1,
.c = {},
};
- assertOrPanic(foo.a == {});
+ expect(foo.a == {});
}
}
test "iterate over a void slice" {
var j: usize = 0;
for (times(10)) |_, i| {
- assertOrPanic(i == j);
+ expect(i == j);
j += 1;
}
}
@@ -31,5 +31,5 @@ fn times(n: usize) []const void {
test "void optional" {
var x: ?void = {};
- assertOrPanic(x != null);
+ expect(x != null);
}
diff --git a/test/stage1/behavior/while.zig b/test/stage1/behavior/while.zig
index 579b4e4db8..29ad90ed17 100644
--- a/test/stage1/behavior/while.zig
+++ b/test/stage1/behavior/while.zig
@@ -1,12 +1,12 @@
-const assertOrPanic = @import("std").debug.assertOrPanic;
+const expect = @import("std").testing.expect;
test "while loop" {
var i: i32 = 0;
while (i < 4) {
i += 1;
}
- assertOrPanic(i == 4);
- assertOrPanic(whileLoop1() == 1);
+ expect(i == 4);
+ expect(whileLoop1() == 1);
}
fn whileLoop1() i32 {
return whileLoop2();
@@ -18,7 +18,7 @@ fn whileLoop2() i32 {
}
test "static eval while" {
- assertOrPanic(static_eval_while_number == 1);
+ expect(static_eval_while_number == 1);
}
const static_eval_while_number = staticWhileLoop1();
fn staticWhileLoop1() i32 {
@@ -32,7 +32,7 @@ fn staticWhileLoop2() i32 {
test "continue and break" {
runContinueAndBreakTest();
- assertOrPanic(continue_and_break_counter == 8);
+ expect(continue_and_break_counter == 8);
}
var continue_and_break_counter: i32 = 0;
fn runContinueAndBreakTest() void {
@@ -45,7 +45,7 @@ fn runContinueAndBreakTest() void {
}
break;
}
- assertOrPanic(i == 4);
+ expect(i == 4);
}
test "return with implicit cast from while loop" {
@@ -66,7 +66,7 @@ test "while with continue expression" {
sum += i;
}
}
- assertOrPanic(sum == 40);
+ expect(sum == 40);
}
test "while with else" {
@@ -78,8 +78,8 @@ test "while with else" {
} else {
got_else += 1;
}
- assertOrPanic(sum == 10);
- assertOrPanic(got_else == 1);
+ expect(sum == 10);
+ expect(got_else == 1);
}
test "while with optional as condition" {
@@ -88,7 +88,7 @@ test "while with optional as condition" {
while (getNumberOrNull()) |value| {
sum += value;
}
- assertOrPanic(sum == 45);
+ expect(sum == 45);
}
test "while with optional as condition with else" {
@@ -97,12 +97,12 @@ test "while with optional as condition with else" {
var got_else: i32 = 0;
while (getNumberOrNull()) |value| {
sum += value;
- assertOrPanic(got_else == 0);
+ expect(got_else == 0);
} else {
got_else += 1;
}
- assertOrPanic(sum == 45);
- assertOrPanic(got_else == 1);
+ expect(sum == 45);
+ expect(got_else == 1);
}
test "while with error union condition" {
@@ -112,11 +112,11 @@ test "while with error union condition" {
while (getNumberOrErr()) |value| {
sum += value;
} else |err| {
- assertOrPanic(err == error.OutOfNumbers);
+ expect(err == error.OutOfNumbers);
got_else += 1;
}
- assertOrPanic(sum == 45);
- assertOrPanic(got_else == 1);
+ expect(sum == 45);
+ expect(got_else == 1);
}
var numbers_left: i32 = undefined;
@@ -138,7 +138,7 @@ test "while on optional with else result follow else prong" {
break value;
} else
i32(2);
- assertOrPanic(result == 2);
+ expect(result == 2);
}
test "while on optional with else result follow break prong" {
@@ -146,7 +146,7 @@ test "while on optional with else result follow break prong" {
break value;
} else
i32(2);
- assertOrPanic(result == 10);
+ expect(result == 10);
}
test "while on error union with else result follow else prong" {
@@ -154,7 +154,7 @@ test "while on error union with else result follow else prong" {
break value;
} else |err|
i32(2);
- assertOrPanic(result == 2);
+ expect(result == 2);
}
test "while on error union with else result follow break prong" {
@@ -162,7 +162,7 @@ test "while on error union with else result follow break prong" {
break value;
} else |err|
i32(2);
- assertOrPanic(result == 10);
+ expect(result == 10);
}
test "while on bool with else result follow else prong" {
@@ -170,7 +170,7 @@ test "while on bool with else result follow else prong" {
break i32(10);
} else
i32(2);
- assertOrPanic(result == 2);
+ expect(result == 2);
}
test "while on bool with else result follow break prong" {
@@ -178,7 +178,7 @@ test "while on bool with else result follow break prong" {
break i32(10);
} else
i32(2);
- assertOrPanic(result == 10);
+ expect(result == 10);
}
test "break from outer while loop" {
diff --git a/test/stage1/behavior/widening.zig b/test/stage1/behavior/widening.zig
index 7577868aff..f7c238ee8d 100644
--- a/test/stage1/behavior/widening.zig
+++ b/test/stage1/behavior/widening.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
const mem = std.mem;
test "integer widening" {
@@ -9,13 +9,13 @@ test "integer widening" {
var d: u64 = c;
var e: u64 = d;
var f: u128 = e;
- assertOrPanic(f == a);
+ expect(f == a);
}
test "implicit unsigned integer to signed integer" {
var a: u8 = 250;
var b: i16 = a;
- assertOrPanic(b == 250);
+ expect(b == 250);
}
test "float widening" {
@@ -23,6 +23,6 @@ test "float widening" {
var b: f32 = a;
var c: f64 = b;
var d: f128 = c;
- assertOrPanic(d == a);
+ expect(d == a);
}
diff --git a/test/stage1/c_abi/main.zig b/test/stage1/c_abi/main.zig
index 196311a283..4805fc9896 100644
--- a/test/stage1/c_abi/main.zig
+++ b/test/stage1/c_abi/main.zig
@@ -1,5 +1,5 @@
const std = @import("std");
-const assertOrPanic = std.debug.assertOrPanic;
+const expect = std.testing.expect;
extern fn run_c_tests() void;
@@ -33,28 +33,28 @@ test "C ABI integers" {
}
export fn zig_u8(x: u8) void {
- assertOrPanic(x == 0xff);
+ expect(x == 0xff);
}
export fn zig_u16(x: u16) void {
- assertOrPanic(x == 0xfffe);
+ expect(x == 0xfffe);
}
export fn zig_u32(x: u32) void {
- assertOrPanic(x == 0xfffffffd);
+ expect(x == 0xfffffffd);
}
export fn zig_u64(x: u64) void {
- assertOrPanic(x == 0xfffffffffffffffc);
+ expect(x == 0xfffffffffffffffc);
}
export fn zig_i8(x: i8) void {
- assertOrPanic(x == -1);
+ expect(x == -1);
}
export fn zig_i16(x: i16) void {
- assertOrPanic(x == -2);
+ expect(x == -2);
}
export fn zig_i32(x: i32) void {
- assertOrPanic(x == -3);
+ expect(x == -3);
}
export fn zig_i64(x: i64) void {
- assertOrPanic(x == -4);
+ expect(x == -4);
}
extern fn c_f32(f32) void;
@@ -66,10 +66,10 @@ test "C ABI floats" {
}
export fn zig_f32(x: f32) void {
- assertOrPanic(x == 12.34);
+ expect(x == 12.34);
}
export fn zig_f64(x: f64) void {
- assertOrPanic(x == 56.78);
+ expect(x == 56.78);
}
extern fn c_ptr(*c_void) void;
@@ -79,7 +79,7 @@ test "C ABI pointer" {
}
export fn zig_ptr(x: *c_void) void {
- assertOrPanic(@ptrToInt(x) == 0xdeadbeef);
+ expect(@ptrToInt(x) == 0xdeadbeef);
}
extern fn c_bool(bool) void;
@@ -89,7 +89,7 @@ test "C ABI bool" {
}
export fn zig_bool(x: bool) void {
- assertOrPanic(x);
+ expect(x);
}
extern fn c_array([10]u8) void;
@@ -100,7 +100,7 @@ test "C ABI array" {
}
export fn zig_array(x: [10]u8) void {
- assertOrPanic(std.mem.eql(u8, x, "1234567890"));
+ expect(std.mem.eql(u8, x, "1234567890"));
}
const BigStruct = extern struct {
@@ -124,11 +124,11 @@ test "C ABI big struct" {
}
export fn zig_big_struct(x: BigStruct) void {
- assertOrPanic(x.a == 1);
- assertOrPanic(x.b == 2);
- assertOrPanic(x.c == 3);
- assertOrPanic(x.d == 4);
- assertOrPanic(x.e == 5);
+ expect(x.a == 1);
+ expect(x.b == 2);
+ expect(x.c == 3);
+ expect(x.d == 4);
+ expect(x.e == 5);
}
const BigUnion = extern union {
@@ -150,11 +150,11 @@ test "C ABI big union" {
}
export fn zig_big_union(x: BigUnion) void {
- assertOrPanic(x.a.a == 1);
- assertOrPanic(x.a.b == 2);
- assertOrPanic(x.a.c == 3);
- assertOrPanic(x.a.d == 4);
- assertOrPanic(x.a.e == 5);
+ expect(x.a.a == 1);
+ expect(x.a.b == 2);
+ expect(x.a.c == 3);
+ expect(x.a.d == 4);
+ expect(x.a.e == 5);
}
const SmallStructInts = extern struct {
@@ -176,10 +176,10 @@ test "C ABI small struct of ints" {
}
export fn zig_small_struct_ints(x: SmallStructInts) void {
- assertOrPanic(x.a == 1);
- assertOrPanic(x.b == 2);
- assertOrPanic(x.c == 3);
- assertOrPanic(x.d == 4);
+ expect(x.a == 1);
+ expect(x.b == 2);
+ expect(x.c == 3);
+ expect(x.d == 4);
}
const SplitStructInt = extern struct {
@@ -199,9 +199,9 @@ test "C ABI split struct of ints" {
}
export fn zig_split_struct_ints(x: SplitStructInt) void {
- assertOrPanic(x.a == 1234);
- assertOrPanic(x.b == 100);
- assertOrPanic(x.c == 1337);
+ expect(x.a == 1234);
+ expect(x.b == 100);
+ expect(x.c == 1337);
}
extern fn c_big_struct_both(BigStruct) BigStruct;
@@ -215,19 +215,19 @@ test "C ABI sret and byval together" {
.e = 5,
};
var y = c_big_struct_both(s);
- assertOrPanic(y.a == 10);
- assertOrPanic(y.b == 11);
- assertOrPanic(y.c == 12);
- assertOrPanic(y.d == 13);
- assertOrPanic(y.e == 14);
+ expect(y.a == 10);
+ expect(y.b == 11);
+ expect(y.c == 12);
+ expect(y.d == 13);
+ expect(y.e == 14);
}
export fn zig_big_struct_both(x: BigStruct) BigStruct {
- assertOrPanic(x.a == 30);
- assertOrPanic(x.b == 31);
- assertOrPanic(x.c == 32);
- assertOrPanic(x.d == 33);
- assertOrPanic(x.e == 34);
+ expect(x.a == 30);
+ expect(x.b == 31);
+ expect(x.c == 32);
+ expect(x.d == 33);
+ expect(x.e == 34);
var s = BigStruct{
.a = 20,
.b = 21,
diff --git a/test/standalone/brace_expansion/main.zig b/test/standalone/brace_expansion/main.zig
index 52863d5fa4..f5bcd59ecf 100644
--- a/test/standalone/brace_expansion/main.zig
+++ b/test/standalone/brace_expansion/main.zig
@@ -3,6 +3,7 @@ const io = std.io;
const mem = std.mem;
const debug = std.debug;
const assert = debug.assert;
+const testing = std.testing;
const Buffer = std.Buffer;
const ArrayList = std.ArrayList;
const maxInt = std.math.maxInt;
@@ -220,11 +221,7 @@ fn expectError(test_input: []const u8, expected_err: anyerror) void {
var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;
defer output_buf.deinit();
- if (expandString(test_input, &output_buf)) {
- unreachable;
- } else |err| {
- assert(expected_err == err);
- }
+ testing.expectError(expected_err, expandString(test_input, &output_buf));
}
test "valid inputs" {
@@ -256,5 +253,5 @@ fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {
expandString(test_input, &result) catch unreachable;
- assert(mem.eql(u8, result.toSlice(), expected_result));
+ testing.expectEqualSlices(u8, expected_result, result.toSlice());
}
diff --git a/test/standalone/issue_794/main.zig b/test/standalone/issue_794/main.zig
index 356a106418..191bdc9b4f 100644
--- a/test/standalone/issue_794/main.zig
+++ b/test/standalone/issue_794/main.zig
@@ -1,7 +1,7 @@
const c = @cImport(@cInclude("foo.h"));
const std = @import("std");
-const assert = std.debug.assert;
+const testing = std.testing;
test "c import" {
- comptime assert(c.NUMBER == 1234);
+ comptime testing.expect(c.NUMBER == 1234);
}
From 46ddd5f5f4db7977010f78129fade7dfa5b9d8d3 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Feb 2019 19:23:46 -0500
Subject: [PATCH 154/218] fix compiler assertion failure when returning value
from test
closes #1935
---
src/ir.cpp | 11 +++++++----
test/compile_errors.zig | 7 +++++++
test/tests.zig | 16 +++++++++++++++-
3 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index efda2b321b..d87486bbdd 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -11510,10 +11510,13 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
return ir_unreach_error(ira);
IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type);
- if (type_is_invalid(casted_value->value.type) && ira->explicit_return_type_source_node != nullptr) {
- ErrorMsg *msg = ira->codegen->errors.last();
- add_error_note(ira->codegen, msg, ira->explicit_return_type_source_node,
- buf_sprintf("return type declared here"));
+ if (type_is_invalid(casted_value->value.type)) {
+ AstNode *source_node = ira->explicit_return_type_source_node;
+ if (source_node != nullptr) {
+ ErrorMsg *msg = ira->codegen->errors.last();
+ add_error_note(ira->codegen, msg, source_node,
+ buf_sprintf("return type declared here"));
+ }
return ir_unreach_error(ira);
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index acd1eada06..de01a5ac45 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,13 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "return invalid type from test",
+ \\test "example" { return 1; }
+ ,
+ ".tmp_source.zig:1:25: error: integer value 1 cannot be implicitly casted to type 'void'",
+ );
+
cases.add(
"threadlocal qualifier on const",
\\threadlocal const x: i32 = 1234;
diff --git a/test/tests.zig b/test/tests.zig
index 670c410509..800ddc1ccd 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -538,6 +538,7 @@ pub const CompileErrorContext = struct {
expected_errors: ArrayList([]const u8),
link_libc: bool,
is_exe: bool,
+ is_test: bool,
const SourceFile = struct {
filename: []const u8,
@@ -596,7 +597,13 @@ pub const CompileErrorContext = struct {
var zig_args = ArrayList([]const u8).init(b.allocator);
zig_args.append(b.zig_exe) catch unreachable;
- zig_args.append(if (self.case.is_exe) "build-exe" else "build-obj") catch unreachable;
+ if (self.case.is_exe) {
+ try zig_args.append("build-exe");
+ } else if (self.case.is_test) {
+ try zig_args.append("test");
+ } else {
+ try zig_args.append("build-obj");
+ }
zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
zig_args.append("--name") catch unreachable;
@@ -699,6 +706,7 @@ pub const CompileErrorContext = struct {
.expected_errors = ArrayList([]const u8).init(self.b.allocator),
.link_libc = false,
.is_exe = false,
+ .is_test = false,
};
tc.addSourceFile(".tmp_source.zig", source);
@@ -726,6 +734,12 @@ pub const CompileErrorContext = struct {
self.addCase(tc);
}
+ pub fn addTest(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ const tc = self.create(name, source, expected_lines);
+ tc.is_test = true;
+ self.addCase(tc);
+ }
+
pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
const b = self.b;
From d6f2af378abe7467657f6fbf8133b995e5f55142 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 8 Feb 2019 19:37:59 -0500
Subject: [PATCH 155/218] fix docs
broken by c2db077574be8
---
doc/docgen.zig | 2 +-
doc/langref.html.in | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 7aaf5ebdc7..1bd0805bb9 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -620,7 +620,7 @@ const TermState = enum {
test "term color" {
const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
const result = try termColor(std.debug.global_allocator, input_bytes);
- testing.expectEqualSlices(u8, "AgreenB", result));
+ testing.expectEqualSlices(u8, "AgreenB", result);
}
fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
diff --git a/doc/langref.html.in b/doc/langref.html.in
index e3ba0e3956..2cd35c2f4e 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -4627,7 +4627,7 @@ test "fibonacci" {
What if we fix the base case, but put the wrong value in the {#syntax#}assert{#endsyntax#} line?
- {#code_begin|test_err|encountered @panic at compile-time#}
+ {#code_begin|test_err|unable to evaluate constant expression#}
const assert = @import("std").debug.assert;
fn fibonacci(index: i32) i32 {
From 052800e9529a3c2b403b7f43ffba4c981935d0a6 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 00:19:06 -0500
Subject: [PATCH 156/218] zig fmt: support threadlocal
---
std/zig/ast.zig | 6 +++++
std/zig/parse.zig | 54 +++++++++++++++++++++++++++++++++++++++++
std/zig/parser_test.zig | 8 ++++++
std/zig/render.zig | 3 +++
std/zig/tokenizer.zig | 2 ++
5 files changed, 73 insertions(+)
diff --git a/std/zig/ast.zig b/std/zig/ast.zig
index f6ac4ed98c..ea32634566 100644
--- a/std/zig/ast.zig
+++ b/std/zig/ast.zig
@@ -110,6 +110,7 @@ pub const Tree = struct {
pub const Error = union(enum) {
InvalidToken: InvalidToken,
ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
+ ExpectedVarDecl: ExpectedVarDecl,
ExpectedAggregateKw: ExpectedAggregateKw,
UnattachedDocComment: UnattachedDocComment,
ExpectedEqOrSemi: ExpectedEqOrSemi,
@@ -133,6 +134,7 @@ pub const Error = union(enum) {
// TODO https://github.com/ziglang/zig/issues/683
@TagType(Error).InvalidToken => |*x| return x.render(tokens, stream),
@TagType(Error).ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
+ @TagType(Error).ExpectedVarDecl => |*x| return x.render(tokens, stream),
@TagType(Error).ExpectedAggregateKw => |*x| return x.render(tokens, stream),
@TagType(Error).UnattachedDocComment => |*x| return x.render(tokens, stream),
@TagType(Error).ExpectedEqOrSemi => |*x| return x.render(tokens, stream),
@@ -158,6 +160,7 @@ pub const Error = union(enum) {
// TODO https://github.com/ziglang/zig/issues/683
@TagType(Error).InvalidToken => |x| return x.token,
@TagType(Error).ExpectedVarDeclOrFn => |x| return x.token,
+ @TagType(Error).ExpectedVarDecl => |x| return x.token,
@TagType(Error).ExpectedAggregateKw => |x| return x.token,
@TagType(Error).UnattachedDocComment => |x| return x.token,
@TagType(Error).ExpectedEqOrSemi => |x| return x.token,
@@ -180,6 +183,7 @@ pub const Error = union(enum) {
pub const InvalidToken = SingleTokenError("Invalid token {}");
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found {}");
+ pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found {}");
pub const ExpectedAggregateKw = SingleTokenError("Expected " ++ @tagName(Token.Id.Keyword_struct) ++ ", " ++ @tagName(Token.Id.Keyword_union) ++ ", or " ++ @tagName(Token.Id.Keyword_enum) ++ ", found {}");
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found {}");
pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found {}");
@@ -496,6 +500,7 @@ pub const Node = struct {
base: Node,
doc_comments: ?*DocComment,
visib_token: ?TokenIndex,
+ thread_local_token: ?TokenIndex,
name_token: TokenIndex,
eq_token: TokenIndex,
mut_token: TokenIndex,
@@ -536,6 +541,7 @@ pub const Node = struct {
pub fn firstToken(self: *const VarDecl) TokenIndex {
if (self.visib_token) |visib_token| return visib_token;
+ if (self.thread_local_token) |thread_local_token| return thread_local_token;
if (self.comptime_token) |comptime_token| return comptime_token;
if (self.extern_export_token) |extern_export_token| return extern_export_token;
assert(self.lib_name == null);
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index 783464c620..ae3e00eb4b 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -229,6 +229,32 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
}) catch unreachable;
continue;
},
+ State.ThreadLocal => |ctx| {
+ const token = nextToken(&tok_it, &tree);
+ const token_index = token.index;
+ const token_ptr = token.ptr;
+ switch (token_ptr.id) {
+ Token.Id.Keyword_var, Token.Id.Keyword_const => {
+ try stack.append(State{
+ .VarDecl = VarDeclCtx{
+ .comments = ctx.comments,
+ .visib_token = ctx.visib_token,
+ .thread_local_token = ctx.thread_local_token,
+ .lib_name = ctx.lib_name,
+ .comptime_token = ctx.comptime_token,
+ .extern_export_token = ctx.extern_export_token,
+ .mut_token = token_index,
+ .list = ctx.list,
+ },
+ });
+ continue;
+ },
+ else => {
+ ((try tree.errors.addOne())).* = Error{ .ExpectedVarDecl = Error.ExpectedVarDecl{ .token = token_index } };
+ return tree;
+ },
+ }
+ },
State.TopLevelDecl => |ctx| {
const token = nextToken(&tok_it, &tree);
const token_index = token.index;
@@ -260,6 +286,28 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
try stack.append(State{ .Expression = OptionalCtx{ .Required = &node.expr } });
continue;
},
+ Token.Id.Keyword_threadlocal => {
+ if (ctx.extern_export_inline_token) |annotated_token| {
+ if (annotated_token.ptr.id == Token.Id.Keyword_inline) {
+ ((try tree.errors.addOne())).* = Error{ .InvalidToken = Error.InvalidToken{ .token = annotated_token.index } };
+ return tree;
+ }
+ }
+
+ try stack.append(State{
+ .ThreadLocal = VarDeclCtx{
+ .comments = ctx.comments,
+ .visib_token = ctx.visib_token,
+ .thread_local_token = token_index,
+ .lib_name = ctx.lib_name,
+ .comptime_token = null,
+ .extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,
+ .mut_token = undefined,
+ .list = ctx.decls,
+ },
+ });
+ continue;
+ },
Token.Id.Keyword_var, Token.Id.Keyword_const => {
if (ctx.extern_export_inline_token) |annotated_token| {
if (annotated_token.ptr.id == Token.Id.Keyword_inline) {
@@ -272,6 +320,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.VarDecl = VarDeclCtx{
.comments = ctx.comments,
.visib_token = ctx.visib_token,
+ .thread_local_token = null,
.lib_name = ctx.lib_name,
.comptime_token = null,
.extern_export_token = if (ctx.extern_export_inline_token) |at| at.index else null,
@@ -611,6 +660,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.base = ast.Node{ .id = ast.Node.Id.VarDecl },
.doc_comments = ctx.comments,
.visib_token = ctx.visib_token,
+ .thread_local_token = ctx.thread_local_token,
.mut_token = ctx.mut_token,
.comptime_token = ctx.comptime_token,
.extern_export_token = ctx.extern_export_token,
@@ -1094,6 +1144,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.VarDecl = VarDeclCtx{
.comments = null,
.visib_token = null,
+ .thread_local_token = null,
.comptime_token = null,
.extern_export_token = null,
.lib_name = null,
@@ -1150,6 +1201,7 @@ pub fn parse(allocator: *mem.Allocator, source: []const u8) !ast.Tree {
.VarDecl = VarDeclCtx{
.comments = null,
.visib_token = null,
+ .thread_local_token = null,
.comptime_token = ctx.comptime_token,
.extern_export_token = null,
.lib_name = null,
@@ -2937,6 +2989,7 @@ const TopLevelDeclCtx = struct {
const VarDeclCtx = struct {
mut_token: TokenIndex,
visib_token: ?TokenIndex,
+ thread_local_token: ?TokenIndex,
comptime_token: ?TokenIndex,
extern_export_token: ?TokenIndex,
lib_name: ?*ast.Node,
@@ -3081,6 +3134,7 @@ const State = union(enum) {
ContainerInitArg: *ast.Node.ContainerDecl,
ContainerDecl: *ast.Node.ContainerDecl,
+ ThreadLocal: VarDeclCtx,
VarDecl: VarDeclCtx,
VarDeclAlign: *ast.Node.VarDecl,
VarDeclSection: *ast.Node.VarDecl,
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 7ad842e4b6..93d5ce3437 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -1,3 +1,10 @@
+test "zig fmt: threadlocal" {
+ try testCanonical(
+ \\threadlocal var x: i32 = 1234;
+ \\
+ );
+}
+
test "zig fmt: linksection" {
try testCanonical(
\\export var aoeu: u64 linksection(".text.derp") = 1234;
@@ -5,6 +12,7 @@ test "zig fmt: linksection" {
\\
);
}
+
test "zig fmt: shebang line" {
try testCanonical(
\\#!/usr/bin/env zig
diff --git a/std/zig/render.zig b/std/zig/render.zig
index e55a0beb93..66aba75e1b 100644
--- a/std/zig/render.zig
+++ b/std/zig/render.zig
@@ -1706,6 +1706,9 @@ fn renderVarDecl(
try renderToken(tree, stream, comptime_token, indent, start_col, Space.Space); // comptime
}
+ if (var_decl.thread_local_token) |thread_local_token| {
+ try renderToken(tree, stream, thread_local_token, indent, start_col, Space.Space); // threadlocal
+ }
try renderToken(tree, stream, var_decl.mut_token, indent, start_col, Space.Space); // var
const name_space = if (var_decl.type_node == null and (var_decl.align_node != null or
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index e71babe4e8..08ffa28fce 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -53,6 +53,7 @@ pub const Token = struct {
Keyword{ .bytes = "switch", .id = Id.Keyword_switch },
Keyword{ .bytes = "test", .id = Id.Keyword_test },
Keyword{ .bytes = "this", .id = Id.Keyword_this },
+ Keyword{ .bytes = "threadlocal", .id = Id.Keyword_threadlocal },
Keyword{ .bytes = "true", .id = Id.Keyword_true },
Keyword{ .bytes = "try", .id = Id.Keyword_try },
Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
@@ -182,6 +183,7 @@ pub const Token = struct {
Keyword_switch,
Keyword_test,
Keyword_this,
+ Keyword_threadlocal,
Keyword_true,
Keyword_try,
Keyword_undefined,
From a8a63feba7e40a998b1e1d8d36169e5f1be0d4e1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 00:28:12 -0500
Subject: [PATCH 157/218] docgen: update for threadlocal keyword
---
doc/docgen.zig | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 1bd0805bb9..45f6dc2684 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -770,6 +770,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
std.zig.Token.Id.Keyword_suspend,
std.zig.Token.Id.Keyword_switch,
std.zig.Token.Id.Keyword_test,
+ std.zig.Token.Id.Keyword_threadlocal,
std.zig.Token.Id.Keyword_try,
std.zig.Token.Id.Keyword_union,
std.zig.Token.Id.Keyword_unreachable,
From 0a7bdc00771dbad1dfe5eb93a7cade89059d227a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 14:44:33 -0500
Subject: [PATCH 158/218] implement vector addition with safety checking
this would work if @llvm.sadd.with.overflow supported
vectors, which it does in trunk. but it does not support
them in llvm 7 or even in llvm 8 release branch.
so the next commit after this will have to do a different
strategy, but when llvm 9 comes out it may be worth coming
back to this one.
---
src/all_types.hpp | 3 +
src/analyze.cpp | 6 +-
src/codegen.cpp | 154 ++++++++++++++++++++++++++--------------------
3 files changed, 95 insertions(+), 68 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 842c9ae904..908c0e327c 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1538,6 +1538,8 @@ enum ZigLLVMFnId {
ZigLLVMFnIdBitReverse,
};
+// There are a bunch of places in code that rely on these values being in
+// exactly this order.
enum AddSubMul {
AddSubMulAdd = 0,
AddSubMulSub = 1,
@@ -1563,6 +1565,7 @@ struct ZigLLVMFnKey {
struct {
AddSubMul add_sub_mul;
uint32_t bit_count;
+ uint32_t vector_len; // 0 means not a vector
bool is_signed;
} overflow_arithmetic;
struct {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 83a576554a..0c493ebda1 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -6361,7 +6361,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
case ZigLLVMFnIdOverflowArithmetic:
return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +
((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +
- ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820);
+ ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820) +
+ x.data.overflow_arithmetic.vector_len * 1435156945;
}
zig_unreachable();
}
@@ -6387,7 +6388,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
case ZigLLVMFnIdOverflowArithmetic:
return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) &&
(a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) &&
- (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed);
+ (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed) &&
+ (a.data.overflow_arithmetic.vector_len == b.data.overflow_arithmetic.vector_len);
}
zig_unreachable();
}
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 3bfd7cdfc5..e45280b0d1 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -715,38 +715,59 @@ static void clear_debug_source_node(CodeGen *g) {
ZigLLVMClearCurrentDebugLocation(g->builder);
}
-static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, ZigType *type_entry,
+static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, ZigType *operand_type,
const char *signed_name, const char *unsigned_name)
{
+ ZigType *int_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
char fn_name[64];
- assert(type_entry->id == ZigTypeIdInt);
- const char *signed_str = type_entry->data.integral.is_signed ? signed_name : unsigned_name;
- sprintf(fn_name, "llvm.%s.with.overflow.i%" PRIu32, signed_str, type_entry->data.integral.bit_count);
+ assert(int_type->id == ZigTypeIdInt);
+ const char *signed_str = int_type->data.integral.is_signed ? signed_name : unsigned_name;
- LLVMTypeRef return_elem_types[] = {
- type_entry->type_ref,
- LLVMInt1Type(),
- };
LLVMTypeRef param_types[] = {
- type_entry->type_ref,
- type_entry->type_ref,
+ operand_type->type_ref,
+ operand_type->type_ref,
};
- LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false);
- LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false);
- LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type);
- assert(LLVMGetIntrinsicID(fn_val));
- return fn_val;
+
+ if (operand_type->id == ZigTypeIdVector) {
+ sprintf(fn_name, "llvm.%s.with.overflow.v%" PRIu32 "i%" PRIu32, signed_str,
+ operand_type->data.vector.len, int_type->data.integral.bit_count);
+
+ LLVMTypeRef return_elem_types[] = {
+ operand_type->type_ref,
+ LLVMVectorType(LLVMInt1Type(), operand_type->data.vector.len),
+ };
+ LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false);
+ LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false);
+ LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type);
+ assert(LLVMGetIntrinsicID(fn_val));
+ return fn_val;
+ } else {
+ sprintf(fn_name, "llvm.%s.with.overflow.i%" PRIu32, signed_str, int_type->data.integral.bit_count);
+
+ LLVMTypeRef return_elem_types[] = {
+ operand_type->type_ref,
+ LLVMInt1Type(),
+ };
+ LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false);
+ LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false);
+ LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type);
+ assert(LLVMGetIntrinsicID(fn_val));
+ return fn_val;
+ }
}
-static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *type_entry, AddSubMul add_sub_mul) {
- assert(type_entry->id == ZigTypeIdInt);
+static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *operand_type, AddSubMul add_sub_mul) {
+ ZigType *int_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
+ assert(int_type->id == ZigTypeIdInt);
ZigLLVMFnKey key = {};
key.id = ZigLLVMFnIdOverflowArithmetic;
- key.data.overflow_arithmetic.is_signed = type_entry->data.integral.is_signed;
+ key.data.overflow_arithmetic.is_signed = int_type->data.integral.is_signed;
key.data.overflow_arithmetic.add_sub_mul = add_sub_mul;
- key.data.overflow_arithmetic.bit_count = (uint32_t)type_entry->data.integral.bit_count;
+ key.data.overflow_arithmetic.bit_count = (uint32_t)int_type->data.integral.bit_count;
+ key.data.overflow_arithmetic.vector_len = (operand_type->id == ZigTypeIdVector) ?
+ operand_type->data.vector.len : 0;
auto existing_entry = g->llvm_fn_table.maybe_get(key);
if (existing_entry)
@@ -755,13 +776,13 @@ static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *type_entry, AddSubM
LLVMValueRef fn_val;
switch (add_sub_mul) {
case AddSubMulAdd:
- fn_val = get_arithmetic_overflow_fn(g, type_entry, "sadd", "uadd");
+ fn_val = get_arithmetic_overflow_fn(g, operand_type, "sadd", "uadd");
break;
case AddSubMulSub:
- fn_val = get_arithmetic_overflow_fn(g, type_entry, "ssub", "usub");
+ fn_val = get_arithmetic_overflow_fn(g, operand_type, "ssub", "usub");
break;
case AddSubMulMul:
- fn_val = get_arithmetic_overflow_fn(g, type_entry, "smul", "umul");
+ fn_val = get_arithmetic_overflow_fn(g, operand_type, "smul", "umul");
break;
}
@@ -1752,17 +1773,28 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
}
}
-static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *type_entry, AddSubMul op,
+static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul op,
LLVMValueRef val1, LLVMValueRef val2)
{
- LLVMValueRef fn_val = get_int_overflow_fn(g, type_entry, op);
+ LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op);
LLVMValueRef params[] = {
val1,
val2,
};
LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
- LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
+
+ LLVMValueRef overflow_bit;
+ if (operand_type->id == ZigTypeIdVector) {
+ LLVMValueRef overflow_vector = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
+ LLVMTypeRef bigger_int_type_ref = LLVMIntType(operand_type->data.vector.len);
+ LLVMValueRef bitcasted_overflow = LLVMBuildBitCast(g->builder, overflow_vector, bigger_int_type_ref, "");
+ LLVMValueRef zero = LLVMConstNull(bigger_int_type_ref);
+ overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, bitcasted_overflow, zero, "");
+ } else {
+ overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
+ }
+
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail");
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk");
LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
@@ -2608,7 +2640,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
(op_id == IrBinOpAdd || op_id == IrBinOpSub) &&
op1->value.type->data.pointer.ptr_len == PtrLenUnknown)
);
- ZigType *type_entry = op1->value.type;
+ ZigType *operand_type = op1->value.type;
+ ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
bool want_runtime_safety = bin_op_instruction->safety_check_on &&
ir_want_runtime_safety(g, &bin_op_instruction->base);
@@ -2634,17 +2667,17 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpCmpGreaterThan:
case IrBinOpCmpLessOrEq:
case IrBinOpCmpGreaterOrEq:
- if (type_entry->id == ZigTypeIdFloat) {
+ if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id);
return LLVMBuildFCmp(g->builder, pred, op1_value, op2_value, "");
- } else if (type_entry->id == ZigTypeIdInt) {
- LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, type_entry->data.integral.is_signed);
+ } else if (scalar_type->id == ZigTypeIdInt) {
+ LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, scalar_type->data.integral.is_signed);
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
- } else if (type_entry->id == ZigTypeIdEnum ||
- type_entry->id == ZigTypeIdErrorSet ||
- type_entry->id == ZigTypeIdBool ||
- get_codegen_ptr_type(type_entry) != nullptr)
+ } else if (scalar_type->id == ZigTypeIdEnum ||
+ scalar_type->id == ZigTypeIdErrorSet ||
+ scalar_type->id == ZigTypeIdBool ||
+ get_codegen_ptr_type(scalar_type) != nullptr)
{
LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false);
return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, "");
@@ -2665,23 +2698,16 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
static const BuildBinOpFunc signed_op[3] = { LLVMBuildNSWAdd, LLVMBuildNSWSub, LLVMBuildNSWMul };
static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, LLVMBuildNUWMul };
- bool is_vector = type_entry->id == ZigTypeIdVector;
bool is_wrapping = (op_id == IrBinOpSubWrap || op_id == IrBinOpAddWrap || op_id == IrBinOpMultWrap);
AddSubMul add_sub_mul =
op_id == IrBinOpAdd || op_id == IrBinOpAddWrap ? AddSubMulAdd :
op_id == IrBinOpSub || op_id == IrBinOpSubWrap ? AddSubMulSub :
AddSubMulMul;
- // The code that is generated for vectors and scalars are the same,
- // so we can just set type_entry to the vectors elem_type an avoid
- // a lot of repeated code.
- if (is_vector)
- type_entry = type_entry->data.vector.elem_type;
-
- if (type_entry->id == ZigTypeIdPointer) {
- assert(type_entry->data.pointer.ptr_len == PtrLenUnknown);
+ if (scalar_type->id == ZigTypeIdPointer) {
+ assert(scalar_type->data.pointer.ptr_len == PtrLenUnknown);
LLVMValueRef subscript_value;
- if (is_vector)
+ if (operand_type->id == ZigTypeIdVector)
zig_panic("TODO: Implement vector operations on pointers.");
switch (add_sub_mul) {
@@ -2697,17 +2723,15 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
// TODO runtime safety
return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, "");
- } else if (type_entry->id == ZigTypeIdFloat) {
+ } else if (scalar_type->id == ZigTypeIdFloat) {
ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base));
return float_op[add_sub_mul](g->builder, op1_value, op2_value, "");
- } else if (type_entry->id == ZigTypeIdInt) {
+ } else if (scalar_type->id == ZigTypeIdInt) {
if (is_wrapping) {
return wrap_op[add_sub_mul](g->builder, op1_value, op2_value, "");
} else if (want_runtime_safety) {
- if (is_vector)
- zig_panic("TODO: Implement runtime safety vector operations.");
- return gen_overflow_op(g, type_entry, add_sub_mul, op1_value, op2_value);
- } else if (type_entry->data.integral.is_signed) {
+ return gen_overflow_op(g, operand_type, add_sub_mul, op1_value, op2_value);
+ } else if (scalar_type->data.integral.is_signed) {
return signed_op[add_sub_mul](g->builder, op1_value, op2_value, "");
} else {
return unsigned_op[add_sub_mul](g->builder, op1_value, op2_value, "");
@@ -2725,15 +2749,14 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpBitShiftLeftLossy:
case IrBinOpBitShiftLeftExact:
{
- assert(type_entry->id == ZigTypeIdInt);
- LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type,
- type_entry, op2_value);
+ assert(scalar_type->id == ZigTypeIdInt);
+ LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type, scalar_type, op2_value);
bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);
if (is_sloppy) {
return LLVMBuildShl(g->builder, op1_value, op2_casted, "");
} else if (want_runtime_safety) {
- return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);
- } else if (type_entry->data.integral.is_signed) {
+ return gen_overflow_shl_op(g, scalar_type, op1_value, op2_casted);
+ } else if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");
} else {
return ZigLLVMBuildNUWShl(g->builder, op1_value, op2_casted, "");
@@ -2742,19 +2765,18 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpBitShiftRightLossy:
case IrBinOpBitShiftRightExact:
{
- assert(type_entry->id == ZigTypeIdInt);
- LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type,
- type_entry, op2_value);
+ assert(scalar_type->id == ZigTypeIdInt);
+ LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value.type, scalar_type, op2_value);
bool is_sloppy = (op_id == IrBinOpBitShiftRightLossy);
if (is_sloppy) {
- if (type_entry->data.integral.is_signed) {
+ if (scalar_type->data.integral.is_signed) {
return LLVMBuildAShr(g->builder, op1_value, op2_casted, "");
} else {
return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");
}
} else if (want_runtime_safety) {
- return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);
- } else if (type_entry->data.integral.is_signed) {
+ return gen_overflow_shr_op(g, scalar_type, op1_value, op2_casted);
+ } else if (scalar_type->data.integral.is_signed) {
return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");
} else {
return ZigLLVMBuildLShrExact(g->builder, op1_value, op2_casted, "");
@@ -2762,22 +2784,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
}
case IrBinOpDivUnspecified:
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, DivKindFloat);
+ op1_value, op2_value, scalar_type, DivKindFloat);
case IrBinOpDivExact:
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, DivKindExact);
+ op1_value, op2_value, scalar_type, DivKindExact);
case IrBinOpDivTrunc:
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, DivKindTrunc);
+ op1_value, op2_value, scalar_type, DivKindTrunc);
case IrBinOpDivFloor:
return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, DivKindFloor);
+ op1_value, op2_value, scalar_type, DivKindFloor);
case IrBinOpRemRem:
return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, RemKindRem);
+ op1_value, op2_value, scalar_type, RemKindRem);
case IrBinOpRemMod:
return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
- op1_value, op2_value, type_entry, RemKindMod);
+ op1_value, op2_value, scalar_type, RemKindMod);
}
zig_unreachable();
}
From 373e21bb564a27c4292812bdfd1673711c2e0fe4 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 15:23:29 -0500
Subject: [PATCH 159/218] implement vector math safety with ext and trunc
---
src/codegen.cpp | 55 +++++++++++++++++++++--------------
test/runtime_safety.zig | 14 +++++++++
test/stage1/behavior/math.zig | 17 +++++++++++
3 files changed, 64 insertions(+), 22 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index e45280b0d1..4868576b49 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1773,25 +1773,46 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, Z
}
}
+typedef LLVMValueRef (*BuildBinOpFunc)(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, const char *);
+// These are lookup table using the AddSubMul enum as the lookup.
+// If AddSubMul ever changes, then these tables will be out of
+// date.
+static const BuildBinOpFunc float_op[3] = { LLVMBuildFAdd, LLVMBuildFSub, LLVMBuildFMul };
+static const BuildBinOpFunc wrap_op[3] = { LLVMBuildAdd, LLVMBuildSub, LLVMBuildMul };
+static const BuildBinOpFunc signed_op[3] = { LLVMBuildNSWAdd, LLVMBuildNSWSub, LLVMBuildNSWMul };
+static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, LLVMBuildNUWMul };
+
static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul op,
LLVMValueRef val1, LLVMValueRef val2)
{
- LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op);
- LLVMValueRef params[] = {
- val1,
- val2,
- };
- LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
- LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
-
LLVMValueRef overflow_bit;
+ LLVMValueRef result;
+
if (operand_type->id == ZigTypeIdVector) {
- LLVMValueRef overflow_vector = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
- LLVMTypeRef bigger_int_type_ref = LLVMIntType(operand_type->data.vector.len);
- LLVMValueRef bitcasted_overflow = LLVMBuildBitCast(g->builder, overflow_vector, bigger_int_type_ref, "");
- LLVMValueRef zero = LLVMConstNull(bigger_int_type_ref);
+ ZigType *int_type = operand_type->data.vector.elem_type;
+ assert(int_type->id == ZigTypeIdInt);
+ LLVMTypeRef one_more_bit_int = LLVMIntType(int_type->data.integral.bit_count + 1);
+ LLVMTypeRef one_more_bit_int_vector = LLVMVectorType(one_more_bit_int, operand_type->data.vector.len);
+ const auto buildExtFn = int_type->data.integral.is_signed ? LLVMBuildSExt : LLVMBuildZExt;
+ LLVMValueRef extended1 = buildExtFn(g->builder, val1, one_more_bit_int_vector, "");
+ LLVMValueRef extended2 = buildExtFn(g->builder, val2, one_more_bit_int_vector, "");
+ LLVMValueRef extended_result = wrap_op[op](g->builder, extended1, extended2, "");
+ result = LLVMBuildTrunc(g->builder, extended_result, operand_type->type_ref, "");
+
+ LLVMValueRef re_extended_result = buildExtFn(g->builder, result, one_more_bit_int_vector, "");
+ LLVMValueRef overflow_vector = LLVMBuildICmp(g->builder, LLVMIntNE, extended_result, re_extended_result, "");
+ LLVMTypeRef bitcast_int_type = LLVMIntType(operand_type->data.vector.len);
+ LLVMValueRef bitcasted_overflow = LLVMBuildBitCast(g->builder, overflow_vector, bitcast_int_type, "");
+ LLVMValueRef zero = LLVMConstNull(bitcast_int_type);
overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, bitcasted_overflow, zero, "");
} else {
+ LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op);
+ LLVMValueRef params[] = {
+ val1,
+ val2,
+ };
+ LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, "");
+ result = LLVMBuildExtractValue(g->builder, result_struct, 0, "");
overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, "");
}
@@ -2623,8 +2644,6 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast
}
-typedef LLVMValueRef (*BuildBinOpFunc)(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, const char *);
-
static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
IrInstructionBinOp *bin_op_instruction)
{
@@ -2690,14 +2709,6 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
case IrBinOpAddWrap:
case IrBinOpSub:
case IrBinOpSubWrap: {
- // These are lookup table using the AddSubMul enum as the lookup.
- // If AddSubMul ever changes, then these tables will be out of
- // date.
- static const BuildBinOpFunc float_op[3] = { LLVMBuildFAdd, LLVMBuildFSub, LLVMBuildFMul };
- static const BuildBinOpFunc wrap_op[3] = { LLVMBuildAdd, LLVMBuildSub, LLVMBuildMul };
- static const BuildBinOpFunc signed_op[3] = { LLVMBuildNSWAdd, LLVMBuildNSWSub, LLVMBuildNSWMul };
- static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, LLVMBuildNUWMul };
-
bool is_wrapping = (op_id == IrBinOpSubWrap || op_id == IrBinOpAddWrap || op_id == IrBinOpMultWrap);
AddSubMul add_sub_mul =
op_id == IrBinOpAdd || op_id == IrBinOpAddWrap ? AddSubMulAdd :
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 7de43b45f4..821328b7a6 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -94,6 +94,20 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}
);
+ cases.addRuntimeSafety("vector integer addition overflow",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ var a: @Vector(4, i32) = []i32{ 1, 2, 2147483643, 4 };
+ \\ var b: @Vector(4, i32) = []i32{ 5, 6, 7, 8 };
+ \\ const x = add(a, b);
+ \\}
+ \\fn add(a: @Vector(4, i32), b: @Vector(4, i32)) @Vector(4, i32) {
+ \\ return a + b;
+ \\}
+ );
+
cases.addRuntimeSafety("integer subtraction overflow",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig
index 0b88cc4497..36e81e11ed 100644
--- a/test/stage1/behavior/math.zig
+++ b/test/stage1/behavior/math.zig
@@ -1,5 +1,7 @@
const std = @import("std");
const expect = std.testing.expect;
+const expectEqual = std.testing.expectEqual;
+const expectEqualSlices = std.testing.expectEqualSlices;
const maxInt = std.math.maxInt;
const minInt = std.math.minInt;
@@ -498,3 +500,18 @@ test "comptime_int param and return" {
fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
return a + b;
}
+
+test "vector integer addition" {
+ const S = struct {
+ fn doTheTest() void {
+ var a: @Vector(4, i32) = []i32{ 1, 2, 3, 4 };
+ var b: @Vector(4, i32) = []i32{ 5, 6, 7, 8 };
+ var result = a + b;
+ var result_array: [4]i32 = result;
+ const expected = []i32{ 6, 8, 10, 12 };
+ expectEqualSlices(i32, &expected, &result_array);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From 34eb9f18acc2370973adcc7be0d010d62300e9a9 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 20:41:26 -0500
Subject: [PATCH 160/218] fix not updating debug info type of optional error
sets
There's an unfortunate footgun in the current design of error sets.
The debug info type for every error set is the same as the debug info
type of the global error set, which is essentially an enum forward
declaration. The problem is that when we "replace" the forward
declaration with the final value, once we know all the possible errors,
we have to update the pointers of every error set.
So the footgun is that if you ever copy the debug info type of the
global error set, you have to add the address of the pointer to a list
of pointers that need to be updated once we "replace" the forward
declaration. I activated the footgun when I introduced the optimization
that `?anyerror` types are the same size as `anyerror` types (using 0 as
the null value), because I introduced a pointer copy of the global error
set debug info type, but forgot to add it to the list.
I'm sure that there is a better way to code this, which does not have
the footgun, but this commit contains only a fix, not a reworking of the
logic.
closes #1937
---
src/analyze.cpp | 3 +++
test/stage1/behavior/error.zig | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 0c493ebda1..970d1cc382 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -594,6 +594,9 @@ ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
// function types are technically pointers
entry->type_ref = child_type->type_ref;
entry->di_type = child_type->di_type;
+ if (entry->di_type == g->builtin_types.entry_global_error_set->di_type) {
+ g->error_di_types.append(&entry->di_type);
+ }
} else {
assert(child_type->di_type);
// create a struct with a boolean whether this is the null value
diff --git a/test/stage1/behavior/error.zig b/test/stage1/behavior/error.zig
index 265ddd9d6c..7d9dae7bdd 100644
--- a/test/stage1/behavior/error.zig
+++ b/test/stage1/behavior/error.zig
@@ -330,3 +330,8 @@ test "optional error set is the same size as error set" {
expect(S.returnsOptErrSet() == null);
comptime expect(S.returnsOptErrSet() == null);
}
+
+test "debug info for optional error set" {
+ const SomeError = error{Hello};
+ var a_local_variable: ?SomeError = null;
+}
From 31be1ddf09fafae270d9946a3f09aa25816dd153 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 20:57:45 -0500
Subject: [PATCH 161/218] docs: add threadlocal keyword to grammar
---
doc/langref.html.in | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 2cd35c2f4e..dfea8e1e04 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -7870,7 +7870,7 @@ TopLevelComptime <- KEYWORD_comptime BlockExpr
TopLevelDecl
<- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
- / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
+ / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
/ KEYWORD_use Expr SEMICOLON
FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
@@ -8330,6 +8330,7 @@ KEYWORD_struct <- 'struct' end_of_word
KEYWORD_suspend <- 'suspend' end_of_word
KEYWORD_switch <- 'switch' end_of_word
KEYWORD_test <- 'test' end_of_word
+KEYWORD_threadlocal <- 'threadlocal' end_of_word
KEYWORD_true <- 'true' end_of_word
KEYWORD_try <- 'try' end_of_word
KEYWORD_undefined <- 'undefined' end_of_word
@@ -8350,7 +8351,7 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_anyerror / KEYWORD_asm
/ KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub
/ KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
/ KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
- / KEYWORD_switch / KEYWORD_test / KEYWORD_true / KEYWORD_try
+ / KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
/ KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable
/ KEYWORD_use / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
{#header_close#}
From caf672c49586f1af5e3d41ae200aded991b8b0f7 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 9 Feb 2019 21:10:59 -0500
Subject: [PATCH 162/218] `@truncate`: comptime 0 when target type is 0 bits
also if the dest type is a comptime_int, then treat it
as an implicit cast.
also compile error for attempting to truncate undefined
closes #1568
---
doc/langref.html.in | 11 +++++++----
src/ir.cpp | 24 ++++++++++++++++--------
test/compile_errors.zig | 11 ++++++++++-
test/stage1/behavior/truncate.zig | 23 +++++++++++++++++++++++
4 files changed, 56 insertions(+), 13 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index dfea8e1e04..779eb6a31b 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6381,14 +6381,14 @@ fn List(comptime T: type) type {
{#header_close#}
{#header_open|@truncate#}
- {#syntax#}@truncate(comptime T: type, integer) T{#endsyntax#}
+ {#syntax#}@truncate(comptime T: type, integer: var) T{#endsyntax#}
This function truncates bits from an integer type, resulting in a smaller
integer type.
- The following produces a crash in debug mode and undefined behavior in
- release mode:
+ The following produces a crash in {#link|Debug#} mode and {#link|Undefined Behavior#} in
+ {#link|ReleaseFast#} mode:
{#syntax#}const a: u16 = 0xabcd;
const b: u8 = u8(a);{#endsyntax#}
@@ -6402,7 +6402,10 @@ const b: u8 = @truncate(u8, a);
This function always truncates the significant bits of the integer, regardless
of endianness on the target platform.
-
+
+ If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
+ then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.
+
{#header_close#}
{#header_open|@typeId#}
diff --git a/src/ir.cpp b/src/ir.cpp
index d87486bbdd..5d4013b4b9 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -18491,7 +18491,22 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
}
- if (src_type->data.integral.bit_count == 0) {
+ if (dest_type->id == ZigTypeIdComptimeInt) {
+ return ir_implicit_cast(ira, target, dest_type);
+ }
+
+ if (instr_is_comptime(target)) {
+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
+ if (val == nullptr)
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
+ bigint_truncate(&result->value.data.x_bigint, &val->data.x_bigint,
+ dest_type->data.integral.bit_count, dest_type->data.integral.is_signed);
+ return result;
+ }
+
+ if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) {
IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
bigint_init_unsigned(&result->value.data.x_bigint, 0);
return result;
@@ -18507,13 +18522,6 @@ static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruct
return ira->codegen->invalid_instruction;
}
- if (target->value.special == ConstValSpecialStatic) {
- IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
- bigint_truncate(&result->value.data.x_bigint, &target->value.data.x_bigint,
- dest_type->data.integral.bit_count, dest_type->data.integral.is_signed);
- return result;
- }
-
IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, dest_type_value, target);
new_instruction->value.type = dest_type;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index de01a5ac45..b47cdf2ed1 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,15 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "@truncate undefined value",
+ \\export fn entry() void {
+ \\ var z = @truncate(u8, u16(undefined));
+ \\}
+ ,
+ ".tmp_source.zig:2:30: error: use of undefined value",
+ );
+
cases.addTest(
"return invalid type from test",
\\test "example" { return 1; }
@@ -3335,7 +3344,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"truncate sign mismatch",
\\fn f() i8 {
- \\ const x: u32 = 10;
+ \\ var x: u32 = 10;
\\ return @truncate(i8, x);
\\}
\\
diff --git a/test/stage1/behavior/truncate.zig b/test/stage1/behavior/truncate.zig
index c195b64cbf..568346369f 100644
--- a/test/stage1/behavior/truncate.zig
+++ b/test/stage1/behavior/truncate.zig
@@ -6,3 +6,26 @@ test "truncate u0 to larger integer allowed and has comptime known result" {
const y = @truncate(u8, x);
comptime expect(y == 0);
}
+
+test "truncate.u0.literal" {
+ var z = @truncate(u0, 0);
+ expect(z == 0);
+}
+
+test "truncate.u0.const" {
+ const c0: usize = 0;
+ var z = @truncate(u0, c0);
+ expect(z == 0);
+}
+
+test "truncate.u0.var" {
+ var d: u8 = 2;
+ var z = @truncate(u0, d);
+ expect(z == 0);
+}
+
+test "truncate sign mismatch but comptime known so it works anyway" {
+ const x: u32 = 10;
+ var result = @truncate(i8, x);
+ expect(result == 10);
+}
From b8cbe3872e702ab8ec388e75cb711330a45825b0 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Feb 2019 00:14:30 -0500
Subject: [PATCH 163/218] added C pointer type and implicit int-to-ptr for this
type
See #1059
---
src/all_types.hpp | 1 +
src/analyze.cpp | 14 +-
src/ir.cpp | 262 ++++++++++++++++++++----------
src/parser.cpp | 8 +
src/tokenizer.cpp | 19 ++-
src/tokenizer.hpp | 1 +
test/stage1/behavior/pointers.zig | 6 +
7 files changed, 223 insertions(+), 88 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 908c0e327c..fd66b77ad2 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1038,6 +1038,7 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
enum PtrLen {
PtrLenUnknown,
PtrLenSingle,
+ PtrLenC,
};
struct ZigTypePointer {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 970d1cc382..e561050e0d 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -417,6 +417,18 @@ ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
return entry;
}
+static const char *ptr_len_to_star_str(PtrLen ptr_len) {
+ switch (ptr_len) {
+ case PtrLenSingle:
+ return "*";
+ case PtrLenUnknown:
+ return "[*]";
+ case PtrLenC:
+ return "[*c]";
+ }
+ zig_unreachable();
+}
+
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
uint32_t bit_offset_in_host, uint32_t host_int_bytes)
@@ -466,7 +478,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
ZigType *entry = new_type_table_entry(ZigTypeIdPointer);
- const char *star_str = ptr_len == PtrLenSingle ? "*" : "[*]";
+ const char *star_str = ptr_len_to_star_str(ptr_len);
const char *const_str = is_const ? "const " : "";
const char *volatile_str = is_volatile ? "volatile " : "";
buf_resize(&entry->name, 0);
diff --git a/src/ir.cpp b/src/ir.cpp
index 5d4013b4b9..76277f541b 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -169,6 +169,10 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry);
+static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
+ ZigType *ptr_type);
+static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
+ ZigType *dest_type);
static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
assert(get_src_ptr_type(const_val->type) != nullptr);
@@ -5019,10 +5023,23 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *
return ir_build_ref(irb, scope, value->source_node, value, false, false);
}
+static PtrLen star_token_to_ptr_len(TokenId token_id) {
+ switch (token_id) {
+ case TokenIdStar:
+ case TokenIdStarStar:
+ return PtrLenSingle;
+ case TokenIdBracketStarBracket:
+ return PtrLenUnknown;
+ case TokenIdBracketStarCBracket:
+ return PtrLenC;
+ default:
+ zig_unreachable();
+ }
+}
+
static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypePointerType);
- PtrLen ptr_len = (node->data.pointer_type.star_token->id == TokenIdStar ||
- node->data.pointer_type.star_token->id == TokenIdStarStar) ? PtrLenSingle : PtrLenUnknown;
+ PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id);
bool is_const = node->data.pointer_type.is_const;
bool is_volatile = node->data.pointer_type.is_volatile;
AstNode *expr_node = node->data.pointer_type.op_expr;
@@ -8538,6 +8555,20 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
}
}
}
+ if (other_type->id == ZigTypeIdPointer && other_type->data.pointer.ptr_len == PtrLenC && const_val_is_int) {
+ if (!bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, true) &&
+ !bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, false))
+ {
+ Buf *val_buf = buf_alloc();
+ bigint_append_buf(val_buf, &const_val->data.x_bigint, 10);
+
+ ir_add_error(ira, instruction,
+ buf_sprintf("integer value %s outside of pointer address range",
+ buf_ptr(val_buf)));
+ return false;
+ }
+ return true;
+ }
const char *num_lit_str;
Buf *val_buf = buf_alloc();
@@ -10811,6 +10842,37 @@ static IrInstruction *ir_analyze_vector_to_array(IrAnalyze *ira, IrInstruction *
return ir_build_vector_to_array(ira, source_instr, vector, array_type);
}
+static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *integer, ZigType *dest_type)
+{
+ IrInstruction *unsigned_integer;
+ if (instr_is_comptime(integer)) {
+ unsigned_integer = integer;
+ } else {
+ assert(integer->value.type->id == ZigTypeIdInt);
+
+ if (integer->value.type->data.integral.bit_count >
+ ira->codegen->builtin_types.entry_usize->data.integral.bit_count)
+ {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("integer type too big for implicit @intToPtr to type '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (integer->value.type->data.integral.is_signed) {
+ ZigType *unsigned_int_type = get_int_type(ira->codegen, false,
+ integer->value.type->data.integral.bit_count);
+ unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type);
+ if (type_is_invalid(unsigned_integer->value.type))
+ return ira->codegen->invalid_instruction;
+ } else {
+ unsigned_integer = integer;
+ }
+ }
+
+ return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type);
+}
+
static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
ZigType *wanted_type, IrInstruction *value)
{
@@ -11217,6 +11279,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
}
+ // casting to C pointers
+ if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC) {
+ // cast from integer to C pointer
+ if (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt) {
+ return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
+ }
+ }
+
// cast from undefined to anything
if (actual_type->id == ZigTypeIdUndefined) {
return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
@@ -20674,17 +20744,38 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
zig_unreachable();
}
-static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
- Error err;
- IrInstruction *dest_type_value = instruction->dest_type->child;
- ZigType *dest_type = ir_resolve_type(ira, dest_type_value);
- if (type_is_invalid(dest_type))
- return ira->codegen->invalid_instruction;
+static bool type_can_bit_cast(ZigType *t) {
+ switch (t->id) {
+ case ZigTypeIdInvalid:
+ zig_unreachable();
+ case ZigTypeIdMetaType:
+ case ZigTypeIdOpaque:
+ case ZigTypeIdBoundFn:
+ case ZigTypeIdArgTuple:
+ case ZigTypeIdNamespace:
+ case ZigTypeIdUnreachable:
+ case ZigTypeIdComptimeFloat:
+ case ZigTypeIdComptimeInt:
+ case ZigTypeIdUndefined:
+ case ZigTypeIdNull:
+ case ZigTypeIdPointer:
+ return false;
+ default:
+ // TODO list these types out explicitly, there are probably some other invalid ones here
+ return true;
+ }
+}
+
+static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
+ ZigType *dest_type)
+{
+ Error err;
- IrInstruction *value = instruction->value->child;
ZigType *src_type = value->value.type;
- if (type_is_invalid(src_type))
- return ira->codegen->invalid_instruction;
+ assert(get_codegen_ptr_type(src_type) == nullptr);
+ assert(type_can_bit_cast(src_type));
+ assert(get_codegen_ptr_type(dest_type) == nullptr);
+ assert(type_can_bit_cast(dest_type));
if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
@@ -20692,60 +20783,11 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
- if (get_codegen_ptr_type(src_type) != nullptr) {
- ir_add_error(ira, value,
- buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name)));
- return ira->codegen->invalid_instruction;
- }
-
- switch (src_type->id) {
- case ZigTypeIdInvalid:
- case ZigTypeIdMetaType:
- case ZigTypeIdOpaque:
- case ZigTypeIdBoundFn:
- case ZigTypeIdArgTuple:
- case ZigTypeIdNamespace:
- case ZigTypeIdUnreachable:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- ir_add_error(ira, dest_type_value,
- buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
- return ira->codegen->invalid_instruction;
- default:
- break;
- }
-
- if (get_codegen_ptr_type(dest_type) != nullptr) {
- ir_add_error(ira, dest_type_value,
- buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
- return ira->codegen->invalid_instruction;
- }
-
- switch (dest_type->id) {
- case ZigTypeIdInvalid:
- case ZigTypeIdMetaType:
- case ZigTypeIdOpaque:
- case ZigTypeIdBoundFn:
- case ZigTypeIdArgTuple:
- case ZigTypeIdNamespace:
- case ZigTypeIdUnreachable:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdUndefined:
- case ZigTypeIdNull:
- ir_add_error(ira, dest_type_value,
- buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
- return ira->codegen->invalid_instruction;
- default:
- break;
- }
uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
uint64_t src_size_bytes = type_size(ira->codegen, src_type);
if (dest_size_bytes != src_size_bytes) {
- ir_add_error(ira, &instruction->base,
+ ir_add_error(ira, source_instr,
buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64,
buf_ptr(&dest_type->name), dest_size_bytes,
buf_ptr(&src_type->name), src_size_bytes));
@@ -20755,7 +20797,7 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type);
uint64_t src_size_bits = type_size_bits(ira->codegen, src_type);
if (dest_size_bits != src_size_bits) {
- ir_add_error(ira, &instruction->base,
+ ir_add_error(ira, source_instr,
buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits",
buf_ptr(&dest_type->name), dest_size_bits,
buf_ptr(&src_type->name), src_size_bits));
@@ -20767,20 +20809,86 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
if (!val)
return ira->codegen->invalid_instruction;
- IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
+ IrInstruction *result = ir_const(ira, source_instr, dest_type);
uint8_t *buf = allocate_nonzero(src_size_bytes);
buf_write_value_bytes(ira->codegen, buf, val);
- if ((err = buf_read_value_bytes(ira, ira->codegen, instruction->base.source_node, buf, &result->value)))
+ if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, &result->value)))
return ira->codegen->invalid_instruction;
return result;
}
- IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, nullptr, value);
+ IrInstruction *result = ir_build_bit_cast(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, nullptr, value);
result->value.type = dest_type;
return result;
}
+static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) {
+ IrInstruction *dest_type_value = instruction->dest_type->child;
+ ZigType *dest_type = ir_resolve_type(ira, dest_type_value);
+ if (type_is_invalid(dest_type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *value = instruction->value->child;
+ ZigType *src_type = value->value.type;
+ if (type_is_invalid(src_type))
+ return ira->codegen->invalid_instruction;
+
+ if (get_codegen_ptr_type(src_type) != nullptr) {
+ ir_add_error(ira, value,
+ buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (!type_can_bit_cast(src_type)) {
+ ir_add_error(ira, dest_type_value,
+ buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (get_codegen_ptr_type(dest_type) != nullptr) {
+ ir_add_error(ira, dest_type_value,
+ buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if (!type_can_bit_cast(dest_type)) {
+ ir_add_error(ira, dest_type_value,
+ buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ return ir_analyze_bit_cast(ira, &instruction->base, value, dest_type);
+}
+
+static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
+ ZigType *ptr_type)
+{
+ assert(get_src_ptr_type(ptr_type) != nullptr);
+ assert(type_has_bits(ptr_type));
+
+ IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize);
+ if (type_is_invalid(casted_int->value.type))
+ return ira->codegen->invalid_instruction;
+
+ if (instr_is_comptime(casted_int)) {
+ ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *result = ir_const(ira, source_instr, ptr_type);
+ result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
+ result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar;
+ result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint);
+ return result;
+ }
+
+ IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, source_instr->scope,
+ source_instr->source_node, nullptr, casted_int);
+ result->value.type = ptr_type;
+ return result;
+}
+
static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) {
Error err;
IrInstruction *dest_type_value = instruction->dest_type->child;
@@ -20802,30 +20910,12 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
}
+
IrInstruction *target = instruction->target->child;
if (type_is_invalid(target->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize);
- if (type_is_invalid(casted_int->value.type))
- return ira->codegen->invalid_instruction;
-
- if (instr_is_comptime(casted_int)) {
- ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad);
- if (!val)
- return ira->codegen->invalid_instruction;
-
- IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
- result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
- result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar;
- result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint);
- return result;
- }
-
- IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, nullptr, casted_int);
- result->value.type = dest_type;
- return result;
+ return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type);
}
static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
diff --git a/src/parser.cpp b/src/parser.cpp
index 1c1af87c51..160a7268b0 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -2779,6 +2779,7 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) {
// <- ASTERISK
// / ASTERISK2
// / LBRACKET ASTERISK RBRACKET
+// / LBRACKET ASTERISK C RBRACKET
static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
Token *asterisk = eat_token_if(pc, TokenIdStar);
if (asterisk != nullptr) {
@@ -2804,6 +2805,13 @@ static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
return res;
}
+ Token *cptr = eat_token_if(pc, TokenIdBracketStarCBracket);
+ if (cptr != nullptr) {
+ AstNode *res = ast_create_node(pc, NodeTypePointerType, cptr);
+ res->data.pointer_type.star_token = cptr;
+ return res;
+ }
+
return nullptr;
}
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 3acd605748..9ff6ed3bbe 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -221,6 +221,7 @@ enum TokenizeState {
TokenizeStateError,
TokenizeStateLBracket,
TokenizeStateLBracketStar,
+ TokenizeStateLBracketStarC,
};
@@ -846,7 +847,6 @@ void tokenize(Buf *buf, Tokenization *out) {
switch (c) {
case '*':
t.state = TokenizeStateLBracketStar;
- set_token_id(&t, t.cur_tok, TokenIdBracketStarBracket);
break;
default:
// reinterpret as just an lbracket
@@ -857,6 +857,21 @@ void tokenize(Buf *buf, Tokenization *out) {
}
break;
case TokenizeStateLBracketStar:
+ switch (c) {
+ case 'c':
+ t.state = TokenizeStateLBracketStarC;
+ set_token_id(&t, t.cur_tok, TokenIdBracketStarCBracket);
+ break;
+ case ']':
+ set_token_id(&t, t.cur_tok, TokenIdBracketStarBracket);
+ end_token(&t);
+ t.state = TokenizeStateStart;
+ break;
+ default:
+ invalid_char_error(&t, c);
+ }
+ break;
+ case TokenizeStateLBracketStarC:
switch (c) {
case ']':
end_token(&t);
@@ -1491,6 +1506,7 @@ void tokenize(Buf *buf, Tokenization *out) {
case TokenizeStateLineStringContinue:
case TokenizeStateLineStringContinueC:
case TokenizeStateLBracketStar:
+ case TokenizeStateLBracketStarC:
tokenize_error(&t, "unexpected EOF");
break;
case TokenizeStateLineComment:
@@ -1528,6 +1544,7 @@ const char * token_name(TokenId id) {
case TokenIdBitShiftRightEq: return ">>=";
case TokenIdBitXorEq: return "^=";
case TokenIdBracketStarBracket: return "[*]";
+ case TokenIdBracketStarCBracket: return "[*c]";
case TokenIdCharLiteral: return "CharLiteral";
case TokenIdCmpEq: return "==";
case TokenIdCmpGreaterOrEq: return ">=";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 17f36699b3..62117b5779 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -29,6 +29,7 @@ enum TokenId {
TokenIdBitShiftRightEq,
TokenIdBitXorEq,
TokenIdBracketStarBracket,
+ TokenIdBracketStarCBracket,
TokenIdCharLiteral,
TokenIdCmpEq,
TokenIdCmpGreaterOrEq,
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 47b19700ee..6969e151df 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -42,3 +42,9 @@ test "double pointer parsing" {
fn PtrOf(comptime T: type) type {
return *T;
}
+
+test "assigning integer to C pointer" {
+ var x: i32 = 0;
+ var ptr: [*c]u8 = 0;
+ var ptr2: [*c]u8 = x;
+}
From 73e8e46257ac8f34e941a357a860d19e0d38dbac Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Feb 2019 01:11:30 -0500
Subject: [PATCH 164/218] casting between C pointers and normal pointers
See #1059
---
src/ir.cpp | 41 +++++++++++++++++++------------
test/stage1/behavior/pointers.zig | 8 ++++++
2 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 76277f541b..30350d75de 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -2462,7 +2462,7 @@ static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *
ir_ref_instruction(type_value, irb->current_basic_block);
- return &instruction->base;
+ return &instruction->base;
}
static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node,
@@ -6739,7 +6739,7 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode
atomic_state_field_name);
// set the is_canceled bit
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
+ IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr,
AtomicRmwOp_or, AtomicOrderSeqCst);
@@ -6817,7 +6817,7 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
atomic_state_field_name);
// clear the is_suspended bit
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
+ IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr,
AtomicRmwOp_and, AtomicOrderSeqCst);
@@ -6933,7 +6933,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle);
IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false);
- IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
+ IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr,
AtomicRmwOp_or, AtomicOrderSeqCst);
@@ -6976,7 +6976,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block);
- IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
+ IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr,
AtomicRmwOp_or, AtomicOrderSeqCst);
IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false);
@@ -7008,7 +7008,7 @@ static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *n
ir_set_cursor_at_end_and_append_block(irb, cleanup_block);
IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false);
- IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
+ IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node,
usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr,
AtomicRmwOp_or, AtomicOrderSeqCst);
IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false);
@@ -11279,12 +11279,21 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type);
}
- // casting to C pointers
- if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC) {
- // cast from integer to C pointer
- if (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt) {
- return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
- }
+ // casting between C pointers and normal pointers
+ if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer &&
+ (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) &&
+ types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
+ actual_type->data.pointer.child_type, source_node,
+ !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);
+ }
+
+ // cast from integer to C pointer
+ if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC &&
+ (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt))
+ {
+ return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
}
// cast from undefined to anything
@@ -16436,7 +16445,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);
if (pointee_val == nullptr)
return ira->codegen->invalid_instruction;
-
+
if (pointee_val->special == ConstValSpecialRuntime)
pointee_val = nullptr;
}
@@ -17186,7 +17195,7 @@ static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
static TypeStructField *validate_byte_offset(IrAnalyze *ira,
IrInstruction *type_value,
IrInstruction *field_name_value,
- size_t *byte_offset)
+ size_t *byte_offset)
{
ZigType *container_type = ir_resolve_type(ira, type_value);
if (type_is_invalid(container_type))
@@ -17360,7 +17369,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
// Loop through the definitions and generate info.
decl_it = decls_scope->decl_table.entry_iterator();
- curr_entry = nullptr;
+ curr_entry = nullptr;
int definition_index = 0;
while ((curr_entry = decl_it.next()) != nullptr) {
// Skip comptime blocks and test functions.
@@ -20312,7 +20321,7 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
} else {
seenFalse += 1;
}
-
+
if ((seenTrue > 1) || (seenFalse > 1)) {
ir_add_error(ira, value, buf_sprintf("duplicate switch value"));
return ira->codegen->invalid_instruction;
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 6969e151df..79832bc316 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -48,3 +48,11 @@ test "assigning integer to C pointer" {
var ptr: [*c]u8 = 0;
var ptr2: [*c]u8 = x;
}
+
+test "implicit cast single item pointer to C pointer and back" {
+ var y: u8 = 11;
+ var x: [*c]u8 = &y;
+ var z: *u8 = x;
+ z.* += 1;
+ expect(y == 12);
+}
From 2f9fedabf0805a47aba5c348e5369c1c28f6cf21 Mon Sep 17 00:00:00 2001
From: Jimmi HC
Date: Sun, 10 Feb 2019 12:43:49 +0100
Subject: [PATCH 165/218] testing.expectEqual use expected type as the type of
actual This allows for impl casts
---
std/testing.zig | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/std/testing.zig b/std/testing.zig
index ade6e8b0dd..bece76ee5c 100644
--- a/std/testing.zig
+++ b/std/testing.zig
@@ -24,11 +24,7 @@ pub fn expectError(expected_error: anyerror, actual_error_union: var) void {
/// equal, prints diagnostics to stderr to show exactly how they are not equal,
/// then aborts.
/// The types must match exactly.
-pub fn expectEqual(expected: var, actual: var) void {
- if (@typeOf(actual) != @typeOf(expected)) {
- @compileError("type mismatch. expected " ++ @typeName(@typeOf(expected)) ++ ", found " ++ @typeName(@typeOf(actual)));
- }
-
+pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
switch (@typeInfo(@typeOf(actual))) {
TypeId.NoReturn,
TypeId.BoundFn,
From 8e68d43ad373e643797209d59e6f10aa12b4c038 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Feb 2019 10:58:00 -0500
Subject: [PATCH 166/218] avoid needlessly creating global constants
This deletes some legacy cruft, and produces leaner object files.
Example:
```
var x: i32 = 1234;
export fn entry() i32 {
return x;
}
```
This produces:
```
@x = internal unnamed_addr global i32 1234, align 4
@0 = internal unnamed_addr constant i32* @x, align 8
```
and @0 is never even used. After this commit, @0 is not produced.
This fixes a bug: Zig was creating invalid LLVM IR when one of these
globals that shouldn't exist takes the address of a thread local
variable. In LLVM 8.0.0rc2, it would produce a linker error. But
probably after my bug report is solved it will be caught by the IR
verifier.
https://bugs.llvm.org/show_bug.cgi?id=40652
---
src/codegen.cpp | 47 ++++++++++++++++-------------------------------
1 file changed, 16 insertions(+), 31 deletions(-)
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 4868576b49..192c0f0519 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -5762,81 +5762,71 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
zig_unreachable();
case ConstPtrSpecialRef:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *pointee = const_val->data.x_ptr.data.ref.pointee;
render_const_val(g, pointee, "");
render_const_val_global(g, pointee, "");
- ConstExprValue *other_val = pointee;
- const_val->global_refs->llvm_value = LLVMConstBitCast(other_val->global_refs->llvm_global, const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
+ const_val->global_refs->llvm_value = LLVMConstBitCast(pointee->global_refs->llvm_global, const_val->type->type_ref);
return const_val->global_refs->llvm_value;
}
case ConstPtrSpecialBaseArray:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val;
- size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
assert(array_const_val->type->id == ZigTypeIdArray);
- if (array_const_val->type->zero_bits) {
+ if (!type_has_bits(array_const_val->type)) {
// make this a null pointer
ZigType *usize = g->builtin_types.entry_usize;
const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
- LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val,
- elem_index);
+ size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index;
+ LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
const_val->global_refs->llvm_value = ptr_val;
- render_const_val_global(g, const_val, "");
return ptr_val;
}
case ConstPtrSpecialBaseStruct:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val;
assert(struct_const_val->type->id == ZigTypeIdStruct);
- if (struct_const_val->type->zero_bits) {
+ if (!type_has_bits(struct_const_val->type)) {
// make this a null pointer
ZigType *usize = g->builtin_types.entry_usize;
const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;
- size_t gen_field_index =
- struct_const_val->type->data.structure.fields[src_field_index].gen_index;
+ size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index].gen_index;
LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,
gen_field_index);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
const_val->global_refs->llvm_value = ptr_val;
- render_const_val_global(g, const_val, "");
return ptr_val;
}
case ConstPtrSpecialBaseErrorUnionCode:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val;
assert(err_union_const_val->type->id == ZigTypeIdErrorUnion);
- if (err_union_const_val->type->zero_bits) {
+ if (!type_has_bits(err_union_const_val->type)) {
// make this a null pointer
ZigType *usize = g->builtin_types.entry_usize;
const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_code_recursive(g, err_union_const_val);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
const_val->global_refs->llvm_value = ptr_val;
- render_const_val_global(g, const_val, "");
return ptr_val;
}
case ConstPtrSpecialBaseErrorUnionPayload:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val;
assert(err_union_const_val->type->id == ZigTypeIdErrorUnion);
if (err_union_const_val->type->zero_bits) {
@@ -5844,18 +5834,16 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
ZigType *usize = g->builtin_types.entry_usize;
const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_payload_recursive(g, err_union_const_val);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
const_val->global_refs->llvm_value = ptr_val;
- render_const_val_global(g, const_val, "");
return ptr_val;
}
case ConstPtrSpecialBaseOptionalPayload:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
ConstExprValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val;
assert(optional_const_val->type->id == ZigTypeIdOptional);
if (optional_const_val->type->zero_bits) {
@@ -5863,23 +5851,20 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
ZigType *usize = g->builtin_types.entry_usize;
const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->type_ref),
const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
return const_val->global_refs->llvm_value;
}
LLVMValueRef uncasted_ptr_val = gen_const_ptr_optional_payload_recursive(g, optional_const_val);
LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, const_val->type->type_ref);
const_val->global_refs->llvm_value = ptr_val;
- render_const_val_global(g, const_val, "");
return ptr_val;
}
case ConstPtrSpecialHardCodedAddr:
{
- render_const_val_global(g, const_val, name);
+ assert(const_val->global_refs != nullptr);
uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr;
ZigType *usize = g->builtin_types.entry_usize;
- const_val->global_refs->llvm_value = LLVMConstIntToPtr(LLVMConstInt(usize->type_ref, addr_value, false),
- const_val->type->type_ref);
- render_const_val_global(g, const_val, "");
+ const_val->global_refs->llvm_value = LLVMConstIntToPtr(
+ LLVMConstInt(usize->type_ref, addr_value, false), const_val->type->type_ref);
return const_val->global_refs->llvm_value;
}
case ConstPtrSpecialFunction:
From 661fc79fba242f2ad72ede06d4e23e635a1b1452 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 10 Feb 2019 12:02:38 -0500
Subject: [PATCH 167/218] langref: update grammar with c pointers
See #1059
---
doc/langref.html.in | 7 +++++--
src/parser.cpp | 4 ++--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 779eb6a31b..82ec13c9bb 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -8164,7 +8164,8 @@ ArrayTypeStart <- LBRACKET Expr? RBRACKET
PtrTypeStart
<- ASTERISK
/ ASTERISK2
- / LBRACKET ASTERISK RBRACKET
+ / PTRUNKNOWN
+ / PTRC
# ContainerDecl specific
ContainerDeclAuto <- ContainerDeclType LBRACE ContainerMembers RBRACE
@@ -8262,7 +8263,7 @@ LARROW2 <- '<<' ![=] skip
LARROW2EQUAL <- '<<=' skip
LARROWEQUAL <- '<=' skip
LBRACE <- '{' skip
-LBRACKET <- '[' skip
+LBRACKET <- '[' ![*] skip
LPAREN <- '(' skip
MINUS <- '-' ![%=>] skip
MINUSEQUAL <- '-=' skip
@@ -8279,6 +8280,8 @@ PLUS2 <- '++' skip
PLUSEQUAL <- '+=' skip
PLUSPERCENT <- '+%' ![=] skip
PLUSPERCENTEQUAL <- '+%=' skip
+PTRC <- '[*c]' skip
+PTRUNKNOWN <- '[*]' skip
QUESTIONMARK <- '?' skip
RARROW <- '>' ![>=] skip
RARROW2 <- '>>' ![=] skip
diff --git a/src/parser.cpp b/src/parser.cpp
index 160a7268b0..3a6ce04647 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -2778,8 +2778,8 @@ static AstNode *ast_parse_array_type_start(ParseContext *pc) {
// PtrTypeStart
// <- ASTERISK
// / ASTERISK2
-// / LBRACKET ASTERISK RBRACKET
-// / LBRACKET ASTERISK C RBRACKET
+// / PTRUNKNOWN
+// / PTRC
static AstNode *ast_parse_ptr_type_start(ParseContext *pc) {
Token *asterisk = eat_token_if(pc, TokenIdStar);
if (asterisk != nullptr) {
From 43df49cb35349e48b63356eef4a990c2233ec88f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 12:59:33 -0500
Subject: [PATCH 168/218] README: move i386-macosx to Tier 4
See #1930
---
README.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index e9756b404d..8b64d75c11 100644
--- a/README.md
+++ b/README.md
@@ -84,13 +84,16 @@ clarity.
* LLVM may have the target as an experimental target, which means that you
need to use Zig-provided binaries for the target to be available, or
build LLVM from source with special configure flags.
+ * This target may be considered deprecated by an official party,
+ [such as macosx/i386](https://support.apple.com/en-us/HT208436) in which
+ case this target will remain forever stuck in Tier 4.
#### Support Table
| | freestanding | linux | macosx | windows | freebsd | UEFI | other |
|--------|--------------|--------|--------|---------|---------|--------|--------|
|x86_64 | Tier 2 | Tier 1 | Tier 1 | Tier 1 | Tier 2 | Tier 2 | Tier 3 |
-|i386 | Tier 2 | Tier 2 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 |
+|i386 | Tier 2 | Tier 2 | Tier 4 | Tier 2 | Tier 3 | Tier 3 | Tier 3 |
|arm | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
|arm64 | Tier 2 | Tier 2 | Tier 3 | Tier 3 | Tier 3 | Tier 3 | Tier 3 |
|bpf | Tier 3 | Tier 3 | N/A | N/A | Tier 3 | Tier 3 | Tier 3 |
From 4a1b910e03f931b7d8d3cb8c810b084e6e152e18 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 14:07:19 -0500
Subject: [PATCH 169/218] zig fmt: support C pointers
See #1059
---
std/zig/parse.zig | 7 ++++++-
std/zig/parser_test.zig | 7 +++++++
std/zig/tokenizer.zig | 23 ++++++++++++++++++++++-
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/std/zig/parse.zig b/std/zig/parse.zig
index ae3e00eb4b..867dd11592 100644
--- a/std/zig/parse.zig
+++ b/std/zig/parse.zig
@@ -3525,7 +3525,12 @@ fn tokenIdToPrefixOp(id: Token.Id) ?ast.Node.PrefixOp.Op {
Token.Id.Minus => ast.Node.PrefixOp.Op{ .Negation = void{} },
Token.Id.MinusPercent => ast.Node.PrefixOp.Op{ .NegationWrap = void{} },
Token.Id.Ampersand => ast.Node.PrefixOp.Op{ .AddressOf = void{} },
- Token.Id.Asterisk, Token.Id.AsteriskAsterisk, Token.Id.BracketStarBracket => ast.Node.PrefixOp.Op{
+
+ Token.Id.Asterisk,
+ Token.Id.AsteriskAsterisk,
+ Token.Id.BracketStarBracket,
+ Token.Id.BracketStarCBracket,
+ => ast.Node.PrefixOp.Op{
.PtrType = ast.Node.PrefixOp.PtrInfo{
.align_info = null,
.const_token = null,
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 93d5ce3437..5b7b7aa2a9 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -1,3 +1,10 @@
+test "zig fmt: C pointers" {
+ try testCanonical(
+ \\const Ptr = [*c]i32;
+ \\
+ );
+}
+
test "zig fmt: threadlocal" {
try testCanonical(
\\threadlocal var x: i32 = 1234;
diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig
index 08ffa28fce..877e4e8db3 100644
--- a/std/zig/tokenizer.zig
+++ b/std/zig/tokenizer.zig
@@ -141,6 +141,7 @@ pub const Token = struct {
LineComment,
DocComment,
BracketStarBracket,
+ BracketStarCBracket,
ShebangLine,
Keyword_align,
Keyword_and,
@@ -279,6 +280,7 @@ pub const Tokenizer = struct {
SawAtSign,
LBracket,
LBracketStar,
+ LBracketStarC,
};
pub fn next(self: *Tokenizer) Token {
@@ -456,6 +458,9 @@ pub const Tokenizer = struct {
},
State.LBracketStar => switch (c) {
+ 'c' => {
+ state = State.LBracketStarC;
+ },
']' => {
result.id = Token.Id.BracketStarBracket;
self.index += 1;
@@ -467,6 +472,18 @@ pub const Tokenizer = struct {
},
},
+ State.LBracketStarC => switch (c) {
+ ']' => {
+ result.id = Token.Id.BracketStarCBracket;
+ self.index += 1;
+ break;
+ },
+ else => {
+ result.id = Token.Id.Invalid;
+ break;
+ },
+ },
+
State.Ampersand => switch (c) {
'=' => {
result.id = Token.Id.AmpersandEqual;
@@ -1035,6 +1052,7 @@ pub const Tokenizer = struct {
State.CharLiteralEnd,
State.StringLiteralBackslash,
State.LBracketStar,
+ State.LBracketStarC,
=> {
result.id = Token.Id.Invalid;
},
@@ -1169,12 +1187,15 @@ test "tokenizer" {
testTokenize("test", []Token.Id{Token.Id.Keyword_test});
}
-test "tokenizer - unknown length pointer" {
+test "tokenizer - unknown length pointer and then c pointer" {
testTokenize(
\\[*]u8
+ \\[*c]u8
, []Token.Id{
Token.Id.BracketStarBracket,
Token.Id.Identifier,
+ Token.Id.BracketStarCBracket,
+ Token.Id.Identifier,
});
}
From d9e01be97386f008e4a4b4281658f25b50ff80f1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 14:56:59 -0500
Subject: [PATCH 170/218] translate-c: use C pointer type everywhere
See #1059
---
src/analyze.cpp | 9 +++++++
src/analyze.hpp | 1 +
src/ast_render.cpp | 27 +++++++++----------
src/ast_render.hpp | 3 ---
src/translate_c.cpp | 50 ++++++++++++-----------------------
test/translate_c.zig | 62 ++++++++++++++++++++++----------------------
6 files changed, 72 insertions(+), 80 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index e561050e0d..691579200e 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -6872,3 +6872,12 @@ Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_no
return ErrorNone;
}
+
+const char *container_string(ContainerKind kind) {
+ switch (kind) {
+ case ContainerKindEnum: return "enum";
+ case ContainerKindStruct: return "struct";
+ case ContainerKindUnion: return "union";
+ }
+ zig_unreachable();
+}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 9773782510..1e4f2f2ce7 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -215,6 +215,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty);
bool type_is_c_abi_int(CodeGen *g, ZigType *ty);
bool want_first_arg_sret(CodeGen *g, FnTypeId *fn_type_id);
+const char *container_string(ContainerKind kind);
uint32_t get_host_int_bytes(CodeGen *g, ZigType *struct_type, TypeStructField *field);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 34a7faa2a5..7b57841205 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -136,13 +136,19 @@ static const char *thread_local_string(Token *tok) {
return (tok == nullptr) ? "" : "threadlocal ";
}
-const char *container_string(ContainerKind kind) {
- switch (kind) {
- case ContainerKindEnum: return "enum";
- case ContainerKindStruct: return "struct";
- case ContainerKindUnion: return "union";
+static const char *token_to_ptr_len_str(Token *tok) {
+ assert(tok != nullptr);
+ switch (tok->id) {
+ case TokenIdStar:
+ case TokenIdStarStar:
+ return "*";
+ case TokenIdBracketStarBracket:
+ return "[*]";
+ case TokenIdBracketStarCBracket:
+ return "[*c]";
+ default:
+ zig_unreachable();
}
- zig_unreachable();
}
static const char *node_type_str(NodeType node_type) {
@@ -644,13 +650,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
case NodeTypePointerType:
{
if (!grouped) fprintf(ar->f, "(");
- const char *star = "[*]";
- if (node->data.pointer_type.star_token != nullptr &&
- (node->data.pointer_type.star_token->id == TokenIdStar || node->data.pointer_type.star_token->id == TokenIdStarStar))
- {
- star = "*";
- }
- fprintf(ar->f, "%s", star);
+ const char *ptr_len_str = token_to_ptr_len_str(node->data.pointer_type.star_token);
+ fprintf(ar->f, "%s", ptr_len_str);
if (node->data.pointer_type.align_expr != nullptr) {
fprintf(ar->f, "align(");
render_node_grouped(ar, node->data.pointer_type.align_expr);
diff --git a/src/ast_render.hpp b/src/ast_render.hpp
index d37002d8c7..1652156eee 100644
--- a/src/ast_render.hpp
+++ b/src/ast_render.hpp
@@ -17,7 +17,4 @@ void ast_print(FILE *f, AstNode *node, int indent);
void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
-const char *container_string(ContainerKind kind);
-
#endif
-
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 02fa3b24be..b06a28d12d 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -291,11 +291,22 @@ static AstNode *maybe_suppress_result(Context *c, ResultUsed result_used, AstNod
node);
}
+static TokenId ptr_len_to_token_id(PtrLen ptr_len) {
+ switch (ptr_len) {
+ case PtrLenSingle:
+ return TokenIdStar;
+ case PtrLenUnknown:
+ return TokenIdBracketStarBracket;
+ case PtrLenC:
+ return TokenIdBracketStarCBracket;
+ }
+ zig_unreachable();
+}
+
static AstNode *trans_create_node_ptr_type(Context *c, bool is_const, bool is_volatile, AstNode *child_node, PtrLen ptr_len) {
AstNode *node = trans_create_node(c, NodeTypePointerType);
node->data.pointer_type.star_token = allocate(1);
- node->data.pointer_type.star_token->id = (ptr_len == PtrLenSingle) ? TokenIdStar: TokenIdBracketStarBracket;
- node->data.pointer_type.is_const = is_const;
+ node->data.pointer_type.star_token->id = ptr_len_to_token_id(ptr_len);
node->data.pointer_type.is_const = is_const;
node->data.pointer_type.is_volatile = is_volatile;
node->data.pointer_type.op_expr = child_node;
@@ -752,30 +763,6 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
}
}
-static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &source_loc) {
- switch (ty->getTypeClass()) {
- case Type::Builtin: {
- const BuiltinType *builtin_ty = static_cast(ty);
- return builtin_ty->getKind() == BuiltinType::Void;
- }
- case Type::Record: {
- const RecordType *record_ty = static_cast(ty);
- return record_ty->getDecl()->getDefinition() == nullptr;
- }
- case Type::Elaborated: {
- const ElaboratedType *elaborated_ty = static_cast(ty);
- return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
- }
- case Type::Typedef: {
- const TypedefType *typedef_ty = static_cast(ty);
- const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
- return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
- }
- default:
- return false;
- }
-}
-
static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
case Type::Builtin:
@@ -925,11 +912,8 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
}
- PtrLen ptr_len = type_is_opaque(c, child_qt.getTypePtr(), source_loc) ? PtrLenSingle : PtrLenUnknown;
-
- AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
- child_qt.isVolatileQualified(), child_node, ptr_len);
- return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
+ return trans_create_node_ptr_type(c, child_qt.isConstQualified(),
+ child_qt.isVolatileQualified(), child_node, PtrLenC);
}
case Type::Typedef:
{
@@ -1113,7 +1097,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return nullptr;
}
AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
- child_qt.isVolatileQualified(), child_type_node, PtrLenUnknown);
+ child_qt.isVolatileQualified(), child_type_node, PtrLenC);
return pointer_node;
}
case Type::BlockPointer:
@@ -4568,7 +4552,7 @@ static AstNode *parse_ctok_suffix_op_expr(Context *c, CTokenize *ctok, size_t *t
} else if (first_tok->id == CTokIdAsterisk) {
*tok_i += 1;
- node = trans_create_node_ptr_type(c, false, false, node, PtrLenUnknown);
+ node = trans_create_node_ptr_type(c, false, false, node, PtrLenC);
} else {
return node;
}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 13f2a964d0..746fa60b18 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -117,11 +117,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
,
\\pub const struct_Foo = extern struct {
- \\ a: ?[*]Foo,
+ \\ a: [*c]Foo,
\\};
\\pub const Foo = struct_Foo;
\\pub const struct_Bar = extern struct {
- \\ a: ?[*]Foo,
+ \\ a: [*c]Foo,
\\};
);
@@ -202,7 +202,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("restrict -> noalias",
\\void foo(void *restrict bar, void *restrict);
,
- \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
+ \\pub extern fn foo(noalias bar: [*c]c_void, noalias arg1: [*c]c_void) void;
);
cases.add("simple struct",
@@ -213,7 +213,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\const struct_Foo = extern struct {
\\ x: c_int,
- \\ y: ?[*]u8,
+ \\ y: [*c]u8,
\\};
,
\\pub const Foo = struct_Foo;
@@ -244,7 +244,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const BarB = enum_Bar.B;
,
- \\pub extern fn func(a: ?[*]struct_Foo, b: ?[*](?[*]enum_Bar)) void;
+ \\pub extern fn func(a: [*c]struct_Foo, b: [*c]([*c]enum_Bar)) void;
,
\\pub const Foo = struct_Foo;
,
@@ -254,7 +254,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("constant size array",
\\void func(int array[20]);
,
- \\pub extern fn func(array: ?[*]c_int) void;
+ \\pub extern fn func(array: [*c]c_int) void;
);
cases.add("self referential struct with function pointer",
@@ -263,7 +263,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
,
\\pub const struct_Foo = extern struct {
- \\ derp: ?extern fn(?[*]struct_Foo) void,
+ \\ derp: ?extern fn([*c]struct_Foo) void,
\\};
,
\\pub const Foo = struct_Foo;
@@ -275,7 +275,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const struct_Foo = @OpaqueType();
,
- \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
+ \\pub extern fn some_func(foo: [*c]struct_Foo, x: c_int) [*c]struct_Foo;
,
\\pub const Foo = struct_Foo;
);
@@ -322,11 +322,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\};
,
\\pub const struct_Bar = extern struct {
- \\ next: ?[*]struct_Foo,
+ \\ next: [*c]struct_Foo,
\\};
,
\\pub const struct_Foo = extern struct {
- \\ next: ?[*]struct_Bar,
+ \\ next: [*c]struct_Bar,
\\};
);
@@ -336,7 +336,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const Foo = c_void;
,
- \\pub extern fn fun(a: ?*Foo) Foo;
+ \\pub extern fn fun(a: [*c]Foo) Foo;
);
cases.add("generate inline func for #define global extern fn",
@@ -608,7 +608,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 6;
\\}
,
- \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
+ \\pub export fn and_or_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ if ((a != 0) and (b != 0)) return 0;
\\ if ((b != 0) and (c != null)) return 1;
\\ if ((a != 0) and (c != null)) return 2;
@@ -710,7 +710,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub const struct_Foo = extern struct {
\\ field: c_int,
\\};
- \\pub export fn read_field(foo: ?[*]struct_Foo) c_int {
+ \\pub export fn read_field(foo: [*c]struct_Foo) c_int {
\\ return foo.?.field;
\\}
);
@@ -756,8 +756,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return x;
\\}
,
- \\pub export fn foo(x: ?[*]c_ushort) ?*c_void {
- \\ return @ptrCast(?*c_void, x);
+ \\pub export fn foo(x: [*c]c_ushort) [*c]c_void {
+ \\ return @ptrCast([*c]c_void, x);
\\}
);
@@ -777,7 +777,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 0;
\\}
,
- \\pub export fn foo() ?[*]c_int {
+ \\pub export fn foo() [*c]c_int {
\\ return null;
\\}
);
@@ -1086,7 +1086,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ *x = 1;
\\}
,
- \\pub export fn foo(x: ?[*]c_int) void {
+ \\pub export fn foo(x: [*c]c_int) void {
\\ x.?.* = 1;
\\}
);
@@ -1114,7 +1114,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub fn foo() c_int {
\\ var x: c_int = 1234;
- \\ var ptr: ?[*]c_int = &x;
+ \\ var ptr: [*c]c_int = &x;
\\ return ptr.?.*;
\\}
);
@@ -1124,7 +1124,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return "bar";
\\}
,
- \\pub fn foo() ?[*]const u8 {
+ \\pub fn foo() [*c]const u8 {
\\ return c"bar";
\\}
);
@@ -1253,8 +1253,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return (float *)a;
\\}
,
- \\fn ptrcast(a: ?[*]c_int) ?[*]f32 {
- \\ return @ptrCast(?[*]f32, a);
+ \\fn ptrcast(a: [*c]c_int) [*c]f32 {
+ \\ return @ptrCast([*c]f32, a);
\\}
);
@@ -1276,7 +1276,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return !c;
\\}
,
- \\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int {
+ \\pub fn foo(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ return !(a == 0);
\\ return !(a != 0);
\\ return !(b != 0);
@@ -1297,7 +1297,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("const ptr initializer",
\\static const char *v0 = "0.0.0";
,
- \\pub var v0: ?[*]const u8 = c"0.0.0";
+ \\pub var v0: [*c]const u8 = c"0.0.0";
);
cases.add("static incomplete array inside function",
@@ -1306,17 +1306,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub fn foo() void {
- \\ const v2: [*]const u8 = c"2.2.2";
+ \\ const v2: [*c]const u8 = c"2.2.2";
\\}
);
cases.add("macro pointer cast",
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
,
- \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*]NRF_GPIO_Type)(NRF_GPIO_BASE);
+ \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*c]NRF_GPIO_Type)(NRF_GPIO_BASE);
);
- cases.add("if on none bool",
+ cases.add("if on non-bool",
\\enum SomeEnum { A, B, C };
\\int if_none_bool(int a, float b, void *c, enum SomeEnum d) {
\\ if (a) return 0;
@@ -1334,7 +1334,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B,
\\ C,
\\};
- \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
+ \\pub fn if_none_bool(a: c_int, b: f32, c: [*c]c_void, d: enum_SomeEnum) c_int {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != null) return 2;
@@ -1343,7 +1343,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
);
- cases.add("while on none bool",
+ cases.add("while on non-bool",
\\int while_none_bool(int a, float b, void *c) {
\\ while (a) return 0;
\\ while (b) return 1;
@@ -1351,7 +1351,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
+ \\pub fn while_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
@@ -1359,7 +1359,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
);
- cases.add("for on none bool",
+ cases.add("for on non-bool",
\\int for_none_bool(int a, float b, void *c) {
\\ for (;a;) return 0;
\\ for (;b;) return 1;
@@ -1367,7 +1367,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
+ \\pub fn for_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
From 342bca7f4627454435e9f6c2d12b099f95a2fd47 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 15:31:09 -0500
Subject: [PATCH 171/218] C pointer comparison and arithmetic
See #1059
---
src/analyze.cpp | 2 +-
src/codegen.cpp | 4 +--
src/ir.cpp | 46 +++++++++++++++++++++++++++----
src/translate_c.cpp | 8 ++++--
test/stage1/behavior/pointers.zig | 20 ++++++++++++++
test/translate_c.zig | 18 ++++++------
6 files changed, 78 insertions(+), 20 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 691579200e..af6200cc82 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -434,7 +434,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
uint32_t bit_offset_in_host, uint32_t host_int_bytes)
{
assert(!type_is_invalid(child_type));
- assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
+ assert(ptr_len != PtrLenUnknown || child_type->id != ZigTypeIdOpaque);
if (byte_alignment != 0) {
uint32_t abi_alignment = get_abi_alignment(g, child_type);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 4868576b49..605ea59b06 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2657,7 +2657,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
(op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) ||
(op1->value.type->id == ZigTypeIdPointer &&
(op_id == IrBinOpAdd || op_id == IrBinOpSub) &&
- op1->value.type->data.pointer.ptr_len == PtrLenUnknown)
+ op1->value.type->data.pointer.ptr_len != PtrLenSingle)
);
ZigType *operand_type = op1->value.type;
ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type;
@@ -2716,7 +2716,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
AddSubMulMul;
if (scalar_type->id == ZigTypeIdPointer) {
- assert(scalar_type->data.pointer.ptr_len == PtrLenUnknown);
+ assert(scalar_type->data.pointer.ptr_len != PtrLenSingle);
LLVMValueRef subscript_value;
if (operand_type->id == ZigTypeIdVector)
zig_panic("TODO: Implement vector operations on pointers.");
diff --git a/src/ir.cpp b/src/ir.cpp
index 30350d75de..bc37ac9b54 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8943,7 +8943,9 @@ static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *
*errors = reallocate(*errors, old_errors_count, *errors_count);
}
-static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, IrInstruction **instructions, size_t instruction_count) {
+static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type,
+ IrInstruction **instructions, size_t instruction_count)
+{
Error err;
assert(instruction_count >= 1);
IrInstruction *prev_inst = instructions[0];
@@ -9260,6 +9262,19 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
continue;
}
+ if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC &&
+ (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt))
+ {
+ continue;
+ }
+
+ if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC &&
+ (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt))
+ {
+ prev_inst = cur_inst;
+ continue;
+ }
+
if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) {
continue;
}
@@ -11852,7 +11867,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
case ZigTypeIdBool:
case ZigTypeIdMetaType:
case ZigTypeIdVoid:
- case ZigTypeIdPointer:
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdOpaque:
@@ -11864,6 +11878,10 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
operator_allowed = is_equality_cmp;
break;
+ case ZigTypeIdPointer:
+ operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len != PtrLenSingle);
+ break;
+
case ZigTypeIdUnreachable:
case ZigTypeIdArray:
case ZigTypeIdStruct:
@@ -12324,6 +12342,26 @@ static bool ok_float_op(IrBinOp op) {
zig_unreachable();
}
+static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) {
+ if (lhs_type->id != ZigTypeIdPointer)
+ return false;
+ switch (op) {
+ case IrBinOpAdd:
+ case IrBinOpSub:
+ break;
+ default:
+ return false;
+ }
+ switch (lhs_type->data.pointer.ptr_len) {
+ case PtrLenSingle:
+ return false;
+ case PtrLenUnknown:
+ case PtrLenC:
+ break;
+ }
+ return true;
+}
+
static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {
IrInstruction *op1 = instruction->op1->child;
if (type_is_invalid(op1->value.type))
@@ -12336,9 +12374,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
IrBinOp op_id = instruction->op_id;
// look for pointer math
- if (op1->value.type->id == ZigTypeIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenUnknown &&
- (op_id == IrBinOpAdd || op_id == IrBinOpSub))
- {
+ if (is_pointer_arithmetic_allowed(op1->value.type, op_id)) {
IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize);
if (casted_op2 == ira->codegen->invalid_instruction)
return ira->codegen->invalid_instruction;
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index b06a28d12d..63f04dae6c 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -1677,7 +1677,7 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im
return node;
}
case CK_NullToPointer:
- return trans_create_node(c, NodeTypeNullLiteral);
+ return trans_create_node_unsigned(c, 0);
case CK_Dependent:
emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent");
return nullptr;
@@ -2409,7 +2409,8 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
case BuiltinType::Float16:
return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
case BuiltinType::NullPtr:
- return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
+ return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
+ trans_create_node_unsigned(c, 0));
case BuiltinType::Void:
case BuiltinType::Half:
@@ -2494,7 +2495,8 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
break;
}
case Type::Pointer:
- return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node(c, NodeTypeNullLiteral));
+ return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
+ trans_create_node_unsigned(c, 0));
case Type::Typedef:
{
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 79832bc316..63e4c314b1 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -56,3 +56,23 @@ test "implicit cast single item pointer to C pointer and back" {
z.* += 1;
expect(y == 12);
}
+
+test "C pointer comparison and arithmetic" {
+ var one: usize = 1;
+ var ptr1: [*c]u8 = 0;
+ var ptr2 = ptr1 + 10;
+ expect(ptr1 == 0);
+ expect(ptr1 >= 0);
+ expect(ptr1 <= 0);
+ expect(ptr1 < 1);
+ expect(ptr1 < one);
+ expect(1 > ptr1);
+ expect(one > ptr1);
+ expect(ptr1 < ptr2);
+ expect(ptr2 > ptr1);
+ expect(ptr2 >= 10);
+ expect(ptr2 == 10);
+ expect(ptr2 <= 10);
+ ptr2 -= 10;
+ expect(ptr1 == ptr2);
+}
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 746fa60b18..b87b962edc 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -610,11 +610,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub export fn and_or_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ if ((a != 0) and (b != 0)) return 0;
- \\ if ((b != 0) and (c != null)) return 1;
- \\ if ((a != 0) and (c != null)) return 2;
+ \\ if ((b != 0) and (c != 0)) return 1;
+ \\ if ((a != 0) and (c != 0)) return 2;
\\ if ((a != 0) or (b != 0)) return 3;
- \\ if ((b != 0) or (c != null)) return 4;
- \\ if ((a != 0) or (c != null)) return 5;
+ \\ if ((b != 0) or (c != 0)) return 4;
+ \\ if ((a != 0) or (c != 0)) return 5;
\\ return 6;
\\}
);
@@ -778,7 +778,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
,
\\pub export fn foo() [*c]c_int {
- \\ return null;
+ \\ return 0;
\\}
);
@@ -1280,7 +1280,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return !(a == 0);
\\ return !(a != 0);
\\ return !(b != 0);
- \\ return !(c != null);
+ \\ return !(c != 0);
\\}
);
@@ -1337,7 +1337,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn if_none_bool(a: c_int, b: f32, c: [*c]c_void, d: enum_SomeEnum) c_int {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
- \\ if (c != null) return 2;
+ \\ if (c != 0) return 2;
\\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;
\\ return 4;
\\}
@@ -1354,7 +1354,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn while_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
- \\ while (c != null) return 2;
+ \\ while (c != 0) return 2;
\\ return 3;
\\}
);
@@ -1370,7 +1370,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn for_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
- \\ while (c != null) return 2;
+ \\ while (c != 0) return 2;
\\ return 3;
\\}
);
From 90b8cd4a45bcb2ca131b6ed6466f799aaa162d13 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 16:07:40 -0500
Subject: [PATCH 172/218] add C pointer type to @typeInfo
See #1059
---
src-self-hosted/type.zig | 2 ++
src/codegen.cpp | 1 +
src/ir.cpp | 14 +++++++++++++-
std/fmt/index.zig | 3 +++
std/meta/index.zig | 9 ++++++---
std/testing.zig | 3 +--
test/stage1/behavior/type_info.zig | 15 +++++++++++++++
7 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig
index 8a05594b30..790b51b7be 100644
--- a/src-self-hosted/type.zig
+++ b/src-self-hosted/type.zig
@@ -794,6 +794,7 @@ pub const Type = struct {
Size.One => "*",
Size.Many => "[*]",
Size.Slice => "[]",
+ Size.C => "[*c]",
};
const mut_str = switch (self.key.mut) {
Mut.Const => "const ",
@@ -1088,6 +1089,7 @@ fn hashAny(x: var, comptime seed: u64) u32 {
builtin.TypeInfo.Pointer.Size.One => return hashAny(@ptrToInt(x), seed),
builtin.TypeInfo.Pointer.Size.Many => @compileError("implement hash function"),
builtin.TypeInfo.Pointer.Size.Slice => @compileError("implement hash function"),
+ builtin.TypeInfo.Pointer.Size.C => unreachable,
}
},
builtin.TypeId.Enum => return hashAny(@enumToInt(x), seed),
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 605ea59b06..142e8174f5 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -7309,6 +7309,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" One,\n"
" Many,\n"
" Slice,\n"
+ " C,\n"
" };\n"
" };\n"
"\n"
diff --git a/src/ir.cpp b/src/ir.cpp
index bc37ac9b54..36ea50ed52 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -17584,6 +17584,18 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
return ErrorNone;
}
+static uint32_t ptr_len_to_size_enum_index(PtrLen ptr_len) {
+ switch (ptr_len) {
+ case PtrLenSingle:
+ return 0;
+ case PtrLenUnknown:
+ return 1;
+ case PtrLenC:
+ return 3;
+ }
+ zig_unreachable();
+}
+
static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) {
Error err;
ZigType *attrs_type;
@@ -17593,7 +17605,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
size_enum_index = 2;
} else if (ptr_type_entry->id == ZigTypeIdPointer) {
attrs_type = ptr_type_entry;
- size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1;
+ size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len);
} else {
zig_unreachable();
}
diff --git a/std/fmt/index.zig b/std/fmt/index.zig
index 05b028112f..b09fe21032 100644
--- a/std/fmt/index.zig
+++ b/std/fmt/index.zig
@@ -236,6 +236,9 @@ pub fn formatType(
const casted_value = ([]const u8)(value);
return output(context, casted_value);
},
+ builtin.TypeInfo.Pointer.Size.C => {
+ return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
+ },
},
builtin.TypeId.Array => |info| {
if (info.child == u8) {
diff --git a/std/meta/index.zig b/std/meta/index.zig
index 3f8ea762a6..652e2d39ec 100644
--- a/std/meta/index.zig
+++ b/std/meta/index.zig
@@ -463,13 +463,16 @@ pub fn eql(a: var, b: @typeOf(a)) bool {
builtin.TypeId.Pointer => {
const info = @typeInfo(T).Pointer;
switch (info.size) {
- builtin.TypeInfo.Pointer.Size.One, builtin.TypeInfo.Pointer.Size.Many => return a == b,
+ builtin.TypeInfo.Pointer.Size.One,
+ builtin.TypeInfo.Pointer.Size.Many,
+ builtin.TypeInfo.Pointer.Size.C,
+ => return a == b,
builtin.TypeInfo.Pointer.Size.Slice => return a.ptr == b.ptr and a.len == b.len,
}
},
builtin.TypeId.Optional => {
- if(a == null and b == null) return true;
- if(a == null or b == null) return false;
+ if (a == null and b == null) return true;
+ if (a == null or b == null) return false;
return eql(a.?, b.?);
},
else => return a == b,
diff --git a/std/testing.zig b/std/testing.zig
index ade6e8b0dd..f3ce69659d 100644
--- a/std/testing.zig
+++ b/std/testing.zig
@@ -69,7 +69,7 @@ pub fn expectEqual(expected: var, actual: var) void {
}
},
- builtin.TypeInfo.Pointer.Size.Slice => {
+ builtin.TypeInfo.Pointer.Size.Slice => {
if (actual.ptr != expected.ptr) {
std.debug.panic("expected slice ptr {}, found {}", expected.ptr, actual.ptr);
}
@@ -122,7 +122,6 @@ pub fn expectEqual(expected: var, actual: var) void {
}
}
},
-
}
}
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index ce0ad795b4..dc185cc960 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -61,6 +61,21 @@ fn testUnknownLenPtr() void {
expect(u32_ptr_info.Pointer.child == f64);
}
+test "type info: C pointer type info" {
+ testCPtr();
+ comptime testCPtr();
+}
+
+fn testCPtr() void {
+ const ptr_info = @typeInfo([*c]align(4) const i8);
+ expect(TypeId(ptr_info) == TypeId.Pointer);
+ expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);
+ expect(ptr_info.Pointer.is_const);
+ expect(!ptr_info.Pointer.is_volatile);
+ expect(ptr_info.Pointer.alignment == 4);
+ expect(ptr_info.Pointer.child == i8);
+}
+
test "type info: slice type info" {
testSlice();
comptime testSlice();
From 57a7ab0d330416f15c0288004b67101c1c3e9629 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 19:12:01 -0500
Subject: [PATCH 173/218] comptime support for pointer arithmetic with hard
coded addresses
---
src/ir.cpp | 109 +++++++++++++++++++++++-------
test/stage1/behavior/pointers.zig | 40 ++++++-----
2 files changed, 109 insertions(+), 40 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 36ea50ed52..5ec397b0b2 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -11682,28 +11682,34 @@ static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp
}
static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) {
- if (op_id == IrBinOpCmpEq) {
- return cmp == CmpEQ;
- } else if (op_id == IrBinOpCmpNotEq) {
- return cmp != CmpEQ;
- } else if (op_id == IrBinOpCmpLessThan) {
- return cmp == CmpLT;
- } else if (op_id == IrBinOpCmpGreaterThan) {
- return cmp == CmpGT;
- } else if (op_id == IrBinOpCmpLessOrEq) {
- return cmp != CmpGT;
- } else if (op_id == IrBinOpCmpGreaterOrEq) {
- return cmp != CmpLT;
- } else {
- zig_unreachable();
+ switch (op_id) {
+ case IrBinOpCmpEq:
+ return cmp == CmpEQ;
+ case IrBinOpCmpNotEq:
+ return cmp != CmpEQ;
+ case IrBinOpCmpLessThan:
+ return cmp == CmpLT;
+ case IrBinOpCmpGreaterThan:
+ return cmp == CmpGT;
+ case IrBinOpCmpLessOrEq:
+ return cmp != CmpGT;
+ case IrBinOpCmpGreaterOrEq:
+ return cmp != CmpLT;
+ default:
+ zig_unreachable();
}
}
static bool optional_value_is_null(ConstExprValue *val) {
assert(val->special == ConstValSpecialStatic);
if (get_codegen_ptr_type(val->type) != nullptr) {
- return val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
- val->data.x_ptr.data.hard_coded_addr.addr == 0;
+ if (val->data.x_ptr.special == ConstPtrSpecialNull) {
+ return true;
+ } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
+ return val->data.x_ptr.data.hard_coded_addr.addr == 0;
+ } else {
+ return false;
+ }
} else if (is_opt_err_set(val->type)) {
return val->data.x_err_set == nullptr;
} else {
@@ -11879,7 +11885,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
break;
case ZigTypeIdPointer:
- operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len != PtrLenSingle);
+ operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len == PtrLenC);
break;
case ZigTypeIdUnreachable:
@@ -11929,15 +11935,38 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
if (op2_val == nullptr)
return ira->codegen->invalid_instruction;
- bool answer;
if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) {
Cmp cmp_result = float_cmp(op1_val, op2_val);
- answer = resolve_cmp_op_id(op_id, cmp_result);
+ bool answer = resolve_cmp_op_id(op_id, cmp_result);
+ return ir_const_bool(ira, &bin_op_instruction->base, answer);
} else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) {
Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
- answer = resolve_cmp_op_id(op_id, cmp_result);
+ bool answer = resolve_cmp_op_id(op_id, cmp_result);
+ return ir_const_bool(ira, &bin_op_instruction->base, answer);
+ } else if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) {
+ if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr ||
+ op1_val->data.x_ptr.special == ConstPtrSpecialNull) &&
+ (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr ||
+ op2_val->data.x_ptr.special == ConstPtrSpecialNull))
+ {
+ uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ?
+ 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr;
+ uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ?
+ 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr;
+ Cmp cmp_result;
+ if (op1_addr > op2_addr) {
+ cmp_result = CmpGT;
+ } else if (op1_addr < op2_addr) {
+ cmp_result = CmpLT;
+ } else {
+ cmp_result = CmpEQ;
+ }
+ bool answer = resolve_cmp_op_id(op_id, cmp_result);
+ return ir_const_bool(ira, &bin_op_instruction->base, answer);
+ }
} else {
bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val);
+ bool answer;
if (op_id == IrBinOpCmpEq) {
answer = are_equal;
} else if (op_id == IrBinOpCmpNotEq) {
@@ -11945,9 +11974,8 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
} else {
zig_unreachable();
}
+ return ir_const_bool(ira, &bin_op_instruction->base, answer);
}
-
- return ir_const_bool(ira, &bin_op_instruction->base, answer);
}
// some comparisons with unsigned numbers can be evaluated
@@ -12363,6 +12391,8 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) {
}
static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) {
+ Error err;
+
IrInstruction *op1 = instruction->op1->child;
if (type_is_invalid(op1->value.type))
return ira->codegen->invalid_instruction;
@@ -12376,9 +12406,42 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
// look for pointer math
if (is_pointer_arithmetic_allowed(op1->value.type, op_id)) {
IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize);
- if (casted_op2 == ira->codegen->invalid_instruction)
+ if (type_is_invalid(casted_op2->value.type))
return ira->codegen->invalid_instruction;
+ if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) {
+ IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type);
+ result->value.special = ConstValSpecialUndef;
+ return result;
+ }
+ if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic &&
+ (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr ||
+ op1->value.data.x_ptr.special == ConstPtrSpecialNull))
+ {
+ uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ?
+ 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr;
+ uint64_t elem_offset;
+ if (!ir_resolve_usize(ira, casted_op2, &elem_offset))
+ return ira->codegen->invalid_instruction;
+ ZigType *elem_type = op1->value.type->data.pointer.child_type;
+ if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown)))
+ return ira->codegen->invalid_instruction;
+ uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset;
+ uint64_t new_addr;
+ if (op_id == IrBinOpAdd) {
+ new_addr = start_addr + byte_offset;
+ } else if (op_id == IrBinOpSub) {
+ new_addr = start_addr - byte_offset;
+ } else {
+ zig_unreachable();
+ }
+ IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type);
+ result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
+ result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar;
+ result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr;
+ return result;
+ }
+
IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, op_id, op1, casted_op2, true);
result->value.type = op1->value.type;
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 63e4c314b1..4375a6971f 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -58,21 +58,27 @@ test "implicit cast single item pointer to C pointer and back" {
}
test "C pointer comparison and arithmetic" {
- var one: usize = 1;
- var ptr1: [*c]u8 = 0;
- var ptr2 = ptr1 + 10;
- expect(ptr1 == 0);
- expect(ptr1 >= 0);
- expect(ptr1 <= 0);
- expect(ptr1 < 1);
- expect(ptr1 < one);
- expect(1 > ptr1);
- expect(one > ptr1);
- expect(ptr1 < ptr2);
- expect(ptr2 > ptr1);
- expect(ptr2 >= 10);
- expect(ptr2 == 10);
- expect(ptr2 <= 10);
- ptr2 -= 10;
- expect(ptr1 == ptr2);
+ const S = struct {
+ fn doTheTest() void {
+ var one: usize = 1;
+ var ptr1: [*c]u32 = 0;
+ var ptr2 = ptr1 + 10;
+ expect(ptr1 == 0);
+ expect(ptr1 >= 0);
+ expect(ptr1 <= 0);
+ expect(ptr1 < 1);
+ expect(ptr1 < one);
+ expect(1 > ptr1);
+ expect(one > ptr1);
+ expect(ptr1 < ptr2);
+ expect(ptr2 > ptr1);
+ expect(ptr2 >= 40);
+ expect(ptr2 == 40);
+ expect(ptr2 <= 40);
+ ptr2 -= 10;
+ expect(ptr1 == ptr2);
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
}
From 069fc1a26990b3946cf788b4ebe5edefca5a3bfd Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Mon, 11 Feb 2019 19:21:59 -0500
Subject: [PATCH 174/218] peer type resolution with C pointers
See #1059
---
src/ir.cpp | 18 ++++++++++++++++++
test/stage1/behavior/pointers.zig | 15 +++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index 5ec397b0b2..91c8503234 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -9275,6 +9275,24 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
continue;
}
+ if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) {
+ if (prev_type->data.pointer.ptr_len == PtrLenC &&
+ types_match_const_cast_only(ira, prev_type->data.pointer.child_type,
+ cur_type->data.pointer.child_type, source_node,
+ !prev_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ continue;
+ }
+ if (cur_type->data.pointer.ptr_len == PtrLenC &&
+ types_match_const_cast_only(ira, cur_type->data.pointer.child_type,
+ prev_type->data.pointer.child_type, source_node,
+ !cur_type->data.pointer.is_const).id == ConstCastResultIdOk)
+ {
+ prev_inst = cur_inst;
+ continue;
+ }
+ }
+
if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) {
continue;
}
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 4375a6971f..3f62bd1cec 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -82,3 +82,18 @@ test "C pointer comparison and arithmetic" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "peer type resolution with C pointers" {
+ var ptr_one: *u8 = undefined;
+ var ptr_many: [*]u8 = undefined;
+ var ptr_c: [*c]u8 = undefined;
+ var t = true;
+ var x1 = if (t) ptr_one else ptr_c;
+ var x2 = if (t) ptr_many else ptr_c;
+ var x3 = if (t) ptr_c else ptr_one;
+ var x4 = if (t) ptr_c else ptr_many;
+ expect(@typeOf(x1) == [*c]u8);
+ expect(@typeOf(x2) == [*c]u8);
+ expect(@typeOf(x3) == [*c]u8);
+ expect(@typeOf(x4) == [*c]u8);
+}
From 0abe6d668eb52aefa59c75a8d8f782f2372f8600 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Feb 2019 00:39:08 -0500
Subject: [PATCH 175/218] C pointers: delete dead code in
ir_num_lit_fits_in_other_type
---
src/ir.cpp | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 91c8503234..1f0edc910d 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8555,20 +8555,6 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
}
}
}
- if (other_type->id == ZigTypeIdPointer && other_type->data.pointer.ptr_len == PtrLenC && const_val_is_int) {
- if (!bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, true) &&
- !bigint_fits_in_bits(&const_val->data.x_bigint, ira->codegen->pointer_size_bytes * 8, false))
- {
- Buf *val_buf = buf_alloc();
- bigint_append_buf(val_buf, &const_val->data.x_bigint, 10);
-
- ir_add_error(ira, instruction,
- buf_sprintf("integer value %s outside of pointer address range",
- buf_ptr(val_buf)));
- return false;
- }
- return true;
- }
const char *num_lit_str;
Buf *val_buf = buf_alloc();
From 285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Feb 2019 00:51:06 -0500
Subject: [PATCH 176/218] disallow C pointers to non-C-ABI-compatible element
types
See #1059
---
src/analyze.cpp | 2 +-
src/analyze.hpp | 2 +-
src/ir.cpp | 4 ++++
test/compile_errors.zig | 10 ++++++++++
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index af6200cc82..ab2afba561 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1469,7 +1469,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {
zig_unreachable();
}
-static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
+bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
switch (type_entry->id) {
case ZigTypeIdInvalid:
zig_unreachable();
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 1e4f2f2ce7..c8141b02ff 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -44,7 +44,7 @@ void find_libc_include_path(CodeGen *g);
void find_libc_lib_path(CodeGen *g);
bool type_has_bits(ZigType *type_entry);
-
+bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
diff --git a/src/ir.cpp b/src/ir.cpp
index 1f0edc910d..64e08ef7ea 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21145,6 +21145,10 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
} else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) {
ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque"));
return ira->codegen->invalid_instruction;
+ } else if (instruction->ptr_len == PtrLenC && !type_allowed_in_extern(ira->codegen, child_type)) {
+ ir_add_error(ira, &instruction->base,
+ buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name)));
+ return ira->codegen->invalid_instruction;
}
uint32_t align_bytes;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index b47cdf2ed1..63850bb888 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,16 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "C pointer pointing to non C ABI compatible type",
+ \\const Foo = struct {};
+ \\export fn entry() [*c]Foo {
+ \\ return undefined;
+ \\}
+ ,
+ ".tmp_source.zig:2:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
+ );
+
cases.addTest(
"@truncate undefined value",
\\export fn entry() void {
From 6f05e8d1be083a429673e717e8b3c736c7ddb8d2 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Feb 2019 01:38:11 -0500
Subject: [PATCH 177/218] implicit casting between C pointer and optional non-C
pointer
See #1059
---
src/ir.cpp | 34 +++++++++++++++++++------------
test/stage1/behavior/pointers.zig | 10 +++++++++
2 files changed, 31 insertions(+), 13 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 64e08ef7ea..00d82c9224 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8669,33 +8669,41 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
}
// pointer const
- if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) {
- ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type,
- actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const);
+ ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type);
+ ZigType *actual_ptr_type = get_src_ptr_type(actual_type);
+ bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC;
+ bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC;
+ if ((wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) ||
+ (wanted_ptr_type != nullptr && actual_is_c_ptr) ||
+ (actual_ptr_type != nullptr && wanted_is_c_ptr))
+ {
+ ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
+ actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
if (child.id == ConstCastResultIdInvalid)
return child;
if (child.id != ConstCastResultIdOk) {
result.id = ConstCastResultIdPointerChild;
result.data.pointer_mismatch = allocate_nonzero(1);
result.data.pointer_mismatch->child = child;
- result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type;
- result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type;
+ result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type;
+ result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
return result;
}
- if ((err = type_resolve(g, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
result.id = ConstCastResultIdInvalid;
return result;
}
- if ((err = type_resolve(g, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
+ if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
result.id = ConstCastResultIdInvalid;
return result;
}
- if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) &&
- (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) &&
- (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) &&
- actual_type->data.pointer.bit_offset_in_host == wanted_type->data.pointer.bit_offset_in_host &&
- actual_type->data.pointer.host_int_bytes == wanted_type->data.pointer.host_int_bytes &&
- get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type))
+ bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
+ if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) &&
+ (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
+ (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
+ actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
+ actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes &&
+ get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type))
{
return result;
}
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 3f62bd1cec..8d87fe2a20 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -97,3 +97,13 @@ test "peer type resolution with C pointers" {
expect(@typeOf(x3) == [*c]u8);
expect(@typeOf(x4) == [*c]u8);
}
+
+test "implicit casting between C pointer and optional non-C pointer" {
+ var slice: []const u8 = "aoeu";
+ const opt_many_ptr: ?[*]const u8 = slice.ptr;
+ var ptr_opt_many_ptr = &opt_many_ptr;
+ var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr;
+ expect(c_ptr.*.* == 'a');
+ ptr_opt_many_ptr = c_ptr;
+ expect(ptr_opt_many_ptr.*.?[1] == 'o');
+}
From 270933b1e997c91a9c2d28b6896d625c0ae1b163 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Feb 2019 10:25:21 -0500
Subject: [PATCH 178/218] compile error test for casting integer to c pointer
when the int has more bits than pointers
See #1059
---
src/ir.cpp | 4 +++-
test/compile_errors.zig | 14 ++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 00d82c9224..50b5661e12 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10882,7 +10882,9 @@ static IrInstruction *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInstruction *sou
ira->codegen->builtin_types.entry_usize->data.integral.bit_count)
{
ir_add_error(ira, source_instr,
- buf_sprintf("integer type too big for implicit @intToPtr to type '%s'", buf_ptr(&dest_type->name)));
+ buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'",
+ buf_ptr(&integer->value.type->name),
+ buf_ptr(&dest_type->name)));
return ira->codegen->invalid_instruction;
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 63850bb888..8f8e2a0bdf 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,20 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "implicit casting too big integers to C pointers",
+ \\export fn a() void {
+ \\ var ptr: [*c]u8 = (1 << 64) + 1;
+ \\}
+ \\export fn b() void {
+ \\ var x: @IntType(false, 65) = 0x1234;
+ \\ var ptr: [*c]u8 = x;
+ \\}
+ ,
+ ".tmp_source.zig:2:33: error: integer value 71615590737044764481 cannot be implicitly casted to type 'usize'",
+ ".tmp_source.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",
+ );
+
cases.addTest(
"C pointer pointing to non C ABI compatible type",
\\const Foo = struct {};
From 5699ab5e77f8d13cac1e34775e6e51358119965c Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 12 Feb 2019 18:20:00 -0500
Subject: [PATCH 179/218] C pointers: errors for nested pointer casting
regarding null
See #1059
---
src/all_types.hpp | 12 +++--
src/analyze.cpp | 45 +++++++++++-----
src/ir.cpp | 99 ++++++++++++++++++++++++----------
test/compile_errors.zig | 114 ++++++++++++++++++++++++----------------
4 files changed, 181 insertions(+), 89 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index fd66b77ad2..230dba9a42 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -691,15 +691,17 @@ struct AstNodePointerType {
AstNode *align_expr;
BigInt *bit_offset_start;
BigInt *host_int_bytes;
+ AstNode *op_expr;
+ Token *allow_zero_token;
bool is_const;
bool is_volatile;
- AstNode *op_expr;
};
struct AstNodeArrayType {
AstNode *size;
AstNode *child_type;
AstNode *align_expr;
+ Token *allow_zero_token;
bool is_const;
bool is_volatile;
};
@@ -1050,6 +1052,7 @@ struct ZigTypePointer {
uint32_t host_int_bytes; // size of host integer. 0 means no host integer; this field is aligned
bool is_const;
bool is_volatile;
+ bool allow_zero;
};
struct ZigTypeInt {
@@ -1499,11 +1502,12 @@ struct TypeId {
struct {
ZigType *child_type;
PtrLen ptr_len;
- bool is_const;
- bool is_volatile;
uint32_t alignment;
uint32_t bit_offset_in_host;
uint32_t host_int_bytes;
+ bool is_const;
+ bool is_volatile;
+ bool allow_zero;
} pointer;
struct {
ZigType *child_type;
@@ -2592,6 +2596,7 @@ struct IrInstructionPtrType {
PtrLen ptr_len;
bool is_const;
bool is_volatile;
+ bool allow_zero;
};
struct IrInstructionPromiseType {
@@ -2607,6 +2612,7 @@ struct IrInstructionSliceType {
IrInstruction *child_type;
bool is_const;
bool is_volatile;
+ bool allow_zero;
};
struct IrInstructionAsm {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index ab2afba561..900def52d4 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -433,6 +433,9 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
uint32_t bit_offset_in_host, uint32_t host_int_bytes)
{
+ // TODO when implementing https://github.com/ziglang/zig/issues/1953
+ // move this to a parameter
+ bool allow_zero = (ptr_len == PtrLenC);
assert(!type_is_invalid(child_type));
assert(ptr_len != PtrLenUnknown || child_type->id != ZigTypeIdOpaque);
@@ -452,7 +455,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
TypeId type_id = {};
ZigType **parent_pointer = nullptr;
- if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle) {
+ if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle || allow_zero) {
type_id.id = ZigTypeIdPointer;
type_id.data.pointer.child_type = child_type;
type_id.data.pointer.is_const = is_const;
@@ -461,6 +464,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
type_id.data.pointer.bit_offset_in_host = bit_offset_in_host;
type_id.data.pointer.host_int_bytes = host_int_bytes;
type_id.data.pointer.ptr_len = ptr_len;
+ type_id.data.pointer.allow_zero = allow_zero;
auto existing_entry = g->type_table.maybe_get(type_id);
if (existing_entry)
@@ -481,18 +485,28 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
const char *star_str = ptr_len_to_star_str(ptr_len);
const char *const_str = is_const ? "const " : "";
const char *volatile_str = is_volatile ? "volatile " : "";
+ const char *allow_zero_str;
+ if (ptr_len == PtrLenC) {
+ assert(allow_zero);
+ allow_zero_str = "";
+ } else {
+ allow_zero_str = allow_zero ? "allowzero " : "";
+ }
buf_resize(&entry->name, 0);
if (host_int_bytes == 0 && byte_alignment == 0) {
- buf_appendf(&entry->name, "%s%s%s%s", star_str, const_str, volatile_str, buf_ptr(&child_type->name));
+ buf_appendf(&entry->name, "%s%s%s%s%s",
+ star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
} else if (host_int_bytes == 0) {
- buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s", star_str, byte_alignment,
- const_str, volatile_str, buf_ptr(&child_type->name));
+ buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
+ const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
} else if (byte_alignment == 0) {
- buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str,
- bit_offset_in_host, host_int_bytes, const_str, volatile_str, buf_ptr(&child_type->name));
+ buf_appendf(&entry->name, "%salign(:%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str,
+ bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
+ buf_ptr(&child_type->name));
} else {
- buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str, byte_alignment,
- bit_offset_in_host, host_int_bytes, const_str, volatile_str, buf_ptr(&child_type->name));
+ buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
+ bit_offset_in_host, host_int_bytes, const_str, volatile_str, allow_zero_str,
+ buf_ptr(&child_type->name));
}
assert(child_type->id != ZigTypeIdInvalid);
@@ -500,7 +514,9 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
entry->zero_bits = !type_has_bits(child_type);
if (!entry->zero_bits) {
- if (is_const || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle || bit_offset_in_host != 0) {
+ if (is_const || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
+ bit_offset_in_host != 0 || allow_zero)
+ {
ZigType *peer_type = get_pointer_to_type_extra(g, child_type, false, false,
PtrLenSingle, 0, 0, host_int_bytes);
entry->type_ref = peer_type->type_ref;
@@ -534,6 +550,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
entry->data.pointer.explicit_alignment = byte_alignment;
entry->data.pointer.bit_offset_in_host = bit_offset_in_host;
entry->data.pointer.host_int_bytes = host_int_bytes;
+ entry->data.pointer.allow_zero = allow_zero;
if (parent_pointer) {
*parent_pointer = entry;
@@ -850,7 +867,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
ZigType *child_type = ptr_type->data.pointer.child_type;
if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile ||
- ptr_type->data.pointer.explicit_alignment != 0)
+ ptr_type->data.pointer.explicit_alignment != 0 || ptr_type->data.pointer.allow_zero)
{
ZigType *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false,
PtrLenUnknown, 0, 0, 0);
@@ -873,7 +890,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;
assert(child_ptr_type->id == ZigTypeIdPointer);
if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
- child_ptr_type->data.pointer.explicit_alignment != 0)
+ child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
{
ZigType *grand_child_type = child_ptr_type->data.pointer.child_type;
ZigType *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false,
@@ -4053,7 +4070,9 @@ ZigType *get_src_ptr_type(ZigType *type) {
if (type->id == ZigTypeIdFn) return type;
if (type->id == ZigTypeIdPromise) return type;
if (type->id == ZigTypeIdOptional) {
- if (type->data.maybe.child_type->id == ZigTypeIdPointer) return type->data.maybe.child_type;
+ if (type->data.maybe.child_type->id == ZigTypeIdPointer) {
+ return type->data.maybe.child_type->data.pointer.allow_zero ? nullptr : type->data.maybe.child_type;
+ }
if (type->data.maybe.child_type->id == ZigTypeIdFn) return type->data.maybe.child_type;
if (type->data.maybe.child_type->id == ZigTypeIdPromise) return type->data.maybe.child_type;
}
@@ -6289,6 +6308,7 @@ uint32_t type_id_hash(TypeId x) {
((x.data.pointer.ptr_len == PtrLenSingle) ? (uint32_t)1120226602 : (uint32_t)3200913342) +
(x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) +
(x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) +
+ (x.data.pointer.allow_zero ? (uint32_t)3324284834 : (uint32_t)3584904923) +
(((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) +
(((uint32_t)x.data.pointer.bit_offset_in_host) ^ (uint32_t)2639019452) +
(((uint32_t)x.data.pointer.host_int_bytes) ^ (uint32_t)529908881);
@@ -6339,6 +6359,7 @@ bool type_id_eql(TypeId a, TypeId b) {
a.data.pointer.ptr_len == b.data.pointer.ptr_len &&
a.data.pointer.is_const == b.data.pointer.is_const &&
a.data.pointer.is_volatile == b.data.pointer.is_volatile &&
+ a.data.pointer.allow_zero == b.data.pointer.allow_zero &&
a.data.pointer.alignment == b.data.pointer.alignment &&
a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;
diff --git a/src/ir.cpp b/src/ir.cpp
index 50b5661e12..19bec193d5 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -61,7 +61,7 @@ enum ConstCastResultId {
ConstCastResultIdType,
ConstCastResultIdUnresolvedInferredErrSet,
ConstCastResultIdAsyncAllocatorType,
- ConstCastResultIdNullWrapPtr
+ ConstCastResultIdBadAllowsZero,
};
struct ConstCastOnly;
@@ -83,6 +83,7 @@ struct ConstCastErrUnionErrSetMismatch;
struct ConstCastErrUnionPayloadMismatch;
struct ConstCastErrSetMismatch;
struct ConstCastTypeMismatch;
+struct ConstCastBadAllowsZero;
struct ConstCastOnly {
ConstCastResultId id;
@@ -99,6 +100,7 @@ struct ConstCastOnly {
ConstCastOnly *null_wrap_ptr_child;
ConstCastArg fn_arg;
ConstCastArgNoAlias arg_no_alias;
+ ConstCastBadAllowsZero *bad_allows_zero;
} data;
};
@@ -141,6 +143,12 @@ struct ConstCastErrSetMismatch {
ZigList missing_errors;
};
+struct ConstCastBadAllowsZero {
+ ZigType *wanted_type;
+ ZigType *actual_type;
+};
+
+
enum UndefAllowed {
UndefOk,
UndefBad,
@@ -8636,6 +8644,14 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp
return err_set_type;
}
+static bool ptr_allows_addr_zero(ZigType *ptr_type) {
+ if (ptr_type->id == ZigTypeIdPointer) {
+ return ptr_type->data.pointer.allow_zero;
+ } else if (ptr_type->id == ZigTypeIdOptional) {
+ return true;
+ }
+ return false;
+}
static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type,
ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable)
@@ -8649,34 +8665,35 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
if (wanted_type == actual_type)
return result;
- // *T and [*]T may const-cast-only to ?*U and ?[*]U, respectively
- // but not if we want a mutable pointer
- // and not if the actual pointer has zero bits
- if (!wanted_is_mutable && wanted_type->id == ZigTypeIdOptional &&
- wanted_type->data.maybe.child_type->id == ZigTypeIdPointer &&
- actual_type->id == ZigTypeIdPointer && type_has_bits(actual_type))
- {
- ConstCastOnly child = types_match_const_cast_only(ira,
- wanted_type->data.maybe.child_type, actual_type, source_node, wanted_is_mutable);
- if (child.id == ConstCastResultIdInvalid)
- return child;
- if (child.id != ConstCastResultIdOk) {
- result.id = ConstCastResultIdNullWrapPtr;
- result.data.null_wrap_ptr_child = allocate_nonzero(1);
- *result.data.null_wrap_ptr_child = child;
- }
- return result;
- }
-
- // pointer const
+ // If pointers have the same representation in memory, they can be "const-casted".
+ // `const` attribute can be gained
+ // `volatile` attribute can be gained
+ // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer)
+ // but only if !wanted_is_mutable
+ // alignment can be decreased
+ // bit offset attributes must match exactly
+ // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one
ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type);
ZigType *actual_ptr_type = get_src_ptr_type(actual_type);
+ bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type);
+ bool actual_allows_zero = ptr_allows_addr_zero(actual_type);
bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC;
bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC;
- if ((wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) ||
- (wanted_ptr_type != nullptr && actual_is_c_ptr) ||
- (actual_ptr_type != nullptr && wanted_is_c_ptr))
- {
+ bool wanted_opt_or_ptr = wanted_ptr_type != nullptr &&
+ (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional);
+ bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
+ (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
+ if (wanted_opt_or_ptr && actual_opt_or_ptr) {
+ bool ok_allows_zero = (wanted_allows_zero &&
+ (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
+ (!wanted_allows_zero && !actual_allows_zero);
+ if (!ok_allows_zero) {
+ result.id = ConstCastResultIdBadAllowsZero;
+ result.data.bad_allows_zero = allocate_nonzero(1);
+ result.data.bad_allows_zero->wanted_type = wanted_type;
+ result.data.bad_allows_zero->actual_type = actual_type;
+ return result;
+ }
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
if (child.id == ConstCastResultIdInvalid)
@@ -8699,6 +8716,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
}
bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr) &&
+ type_has_bits(wanted_type) == type_has_bits(actual_type) &&
(!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
(!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
@@ -9922,7 +9940,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
if (undef_allowed == UndefOk) {
return &value->value;
} else {
- ir_add_error(ira, value, buf_sprintf("use of undefined value"));
+ ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior"));
return nullptr;
}
}
@@ -10828,6 +10846,26 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg);
break;
}
+ case ConstCastResultIdBadAllowsZero: {
+ bool wanted_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->wanted_type);
+ bool actual_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->actual_type);
+ ZigType *wanted_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->wanted_type);
+ ZigType *actual_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->actual_type);
+ ZigType *wanted_elem_type = wanted_ptr_type->data.pointer.child_type;
+ ZigType *actual_elem_type = actual_ptr_type->data.pointer.child_type;
+ if (actual_allows_zero && !wanted_allows_zero) {
+ add_error_note(ira->codegen, parent_msg, source_node,
+ buf_sprintf("'%s' could have null values which are illegal in type '%s'",
+ buf_ptr(&actual_elem_type->name),
+ buf_ptr(&wanted_elem_type->name)));
+ } else {
+ add_error_note(ira->codegen, parent_msg, source_node,
+ buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
+ buf_ptr(&cast_result->data.bad_allows_zero->wanted_type->name),
+ buf_ptr(&cast_result->data.bad_allows_zero->actual_type->name)));
+ }
+ break;
+ }
case ConstCastResultIdFnAlign: // TODO
case ConstCastResultIdFnCC: // TODO
case ConstCastResultIdFnVarArgs: // TODO
@@ -10838,7 +10876,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
case ConstCastResultIdFnArgNoAlias: // TODO
case ConstCastResultIdUnresolvedInferredErrSet: // TODO
case ConstCastResultIdAsyncAllocatorType: // TODO
- case ConstCastResultIdNullWrapPtr: // TODO
break;
}
}
@@ -20589,12 +20626,14 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
// We have a check for zero bits later so we use get_src_ptr_type to
// validate src_type and dest_type.
- if (get_src_ptr_type(src_type) == nullptr) {
+ ZigType *src_ptr_type = get_src_ptr_type(src_type);
+ if (src_ptr_type == nullptr) {
ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name)));
return ira->codegen->invalid_instruction;
}
- if (get_src_ptr_type(dest_type) == nullptr) {
+ ZigType *dest_ptr_type = get_src_ptr_type(dest_type);
+ if (dest_ptr_type == nullptr) {
ir_add_error(ira, dest_type_src,
buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_instruction;
@@ -20606,6 +20645,8 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
}
if (instr_is_comptime(ptr)) {
+ // Undefined is OK here; @ptrCast is defined to reinterpret the bit pattern
+ // of the pointer as the new pointer type.
ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
if (!val)
return ira->codegen->invalid_instruction;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 8f8e2a0bdf..c51a65cadf 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,30 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "implicit casting C pointers which would mess up null semantics",
+ \\export fn entry() void {
+ \\ var slice: []const u8 = "aoeu";
+ \\ const opt_many_ptr: [*]const u8 = slice.ptr;
+ \\ var ptr_opt_many_ptr = &opt_many_ptr;
+ \\ var c_ptr: [*c]const [*c]const u8 = ptr_opt_many_ptr;
+ \\ ptr_opt_many_ptr = c_ptr;
+ \\}
+ \\export fn entry2() void {
+ \\ var buf: [4]u8 = "aoeu";
+ \\ var slice: []u8 = &buf;
+ \\ var opt_many_ptr: [*]u8 = slice.ptr;
+ \\ var ptr_opt_many_ptr = &opt_many_ptr;
+ \\ var c_ptr: [*c]const [*c]u8 = ptr_opt_many_ptr;
+ \\}
+ ,
+ ".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
+ ".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
+ ".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
+ ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",
+ ".tmp_source.zig:13:35: note: mutable '[*c]u8' allows illegal null values stored to type '[*]u8'",
+ );
+
cases.addTest(
"implicit casting too big integers to C pointers",
\\export fn a() void {
@@ -31,7 +55,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var z = @truncate(u8, u16(undefined));
\\}
,
- ".tmp_source.zig:2:30: error: use of undefined value",
+ ".tmp_source.zig:2:30: error: use of undefined value here causes undefined behavior",
);
cases.addTest(
@@ -392,7 +416,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ f(i32);
\\}
,
- ".tmp_source.zig:4:5: error: use of undefined value",
+ ".tmp_source.zig:4:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -792,7 +816,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ command.exec();
\\}
,
- ".tmp_source.zig:6:12: error: use of undefined value",
+ ".tmp_source.zig:6:12: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -805,7 +829,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ command.exec();
\\}
,
- ".tmp_source.zig:6:12: error: use of undefined value",
+ ".tmp_source.zig:6:12: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2776,7 +2800,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
,
- ".tmp_source.zig:1:15: error: use of undefined value",
+ ".tmp_source.zig:1:15: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2786,7 +2810,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a / a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2796,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a /= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2806,7 +2830,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a % a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2816,7 +2840,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a %= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2826,7 +2850,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a + a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2836,7 +2860,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a += a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2846,7 +2870,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a +% a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2856,7 +2880,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a +%= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2866,7 +2890,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a - a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2876,7 +2900,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a -= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2886,7 +2910,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a -% a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2896,7 +2920,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a -%= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2906,7 +2930,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a * a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2916,7 +2940,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a *= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2926,7 +2950,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a *% a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2936,7 +2960,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a *%= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2946,7 +2970,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a << 2;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2956,7 +2980,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a <<= 2;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2966,7 +2990,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a >> 2;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2976,7 +3000,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a >>= 2;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2986,7 +3010,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a & a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -2996,7 +3020,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a &= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3006,7 +3030,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a | a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3016,7 +3040,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a |= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3026,7 +3050,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a ^ a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3036,7 +3060,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ a ^= a;
\\}
,
- ".tmp_source.zig:3:5: error: use of undefined value",
+ ".tmp_source.zig:3:5: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3046,7 +3070,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a == a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3056,7 +3080,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a != a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3066,7 +3090,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a > a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3076,7 +3100,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a >= a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3086,7 +3110,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a < a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3096,7 +3120,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a <= a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3106,7 +3130,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a and a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3116,7 +3140,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a or a;
\\}
,
- ".tmp_source.zig:3:9: error: use of undefined value",
+ ".tmp_source.zig:3:9: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3126,7 +3150,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = -a;
\\}
,
- ".tmp_source.zig:3:10: error: use of undefined value",
+ ".tmp_source.zig:3:10: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3136,7 +3160,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = -%a;
\\}
,
- ".tmp_source.zig:3:11: error: use of undefined value",
+ ".tmp_source.zig:3:11: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3146,7 +3170,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = ~a;
\\}
,
- ".tmp_source.zig:3:10: error: use of undefined value",
+ ".tmp_source.zig:3:10: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3156,7 +3180,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = !a;
\\}
,
- ".tmp_source.zig:3:10: error: use of undefined value",
+ ".tmp_source.zig:3:10: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3166,7 +3190,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a orelse false;
\\}
,
- ".tmp_source.zig:3:11: error: use of undefined value",
+ ".tmp_source.zig:3:11: error: use of undefined value here causes undefined behavior",
);
cases.add(
@@ -3176,7 +3200,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = a catch |err| false;
\\}
,
- ".tmp_source.zig:3:11: error: use of undefined value",
+ ".tmp_source.zig:3:11: error: use of undefined value here causes undefined behavior",
);
cases.add(
From 0b3db784f1cf21dd35fc14dfee29ab6fd867c0ed Mon Sep 17 00:00:00 2001
From: Matthew McAllister
Date: Sun, 3 Feb 2019 01:15:51 -0800
Subject: [PATCH 180/218] Enable compileLog to display slices
---
src/analyze.cpp | 53 +++++++++++++++++++++++++++++++++++--------------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 970d1cc382..b3b4c36cf1 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -6010,16 +6010,20 @@ static void render_const_val_err_set(CodeGen *g, Buf *buf, ConstExprValue *const
}
}
-static void render_const_val_array(CodeGen *g, Buf *buf, ConstExprValue *const_val, size_t len) {
- switch (const_val->data.x_array.special) {
+static void render_const_val_array(CodeGen *g, Buf *buf, Buf *type_name, ConstExprValue *const_val, uint64_t start, uint64_t len) {
+ ConstArrayValue *array = &const_val->data.x_array;
+ switch (array->special) {
case ConstArraySpecialUndef:
buf_append_str(buf, "undefined");
return;
case ConstArraySpecialBuf: {
- Buf *array_buf = const_val->data.x_array.data.s_buf;
+ Buf *array_buf = array->data.s_buf;
+ const char *base = &buf_ptr(array_buf)[start];
+ assert(start + len <= buf_len(array_buf));
+
buf_append_char(buf, '"');
- for (size_t i = 0; i < buf_len(array_buf); i += 1) {
- uint8_t c = buf_ptr(array_buf)[i];
+ for (size_t i = 0; i < len; i += 1) {
+ uint8_t c = base[i];
if (c == '"') {
buf_append_str(buf, "\\\"");
} else {
@@ -6030,12 +6034,13 @@ static void render_const_val_array(CodeGen *g, Buf *buf, ConstExprValue *const_v
return;
}
case ConstArraySpecialNone: {
- buf_appendf(buf, "%s{", buf_ptr(&const_val->type->name));
+ ConstExprValue *base = &array->data.s_none.elements[start];
+ assert(start + len <= const_val->type->data.array.len);
+
+ buf_appendf(buf, "%s{", buf_ptr(type_name));
for (uint64_t i = 0; i < len; i += 1) {
- if (i != 0)
- buf_appendf(buf, ",");
- ConstExprValue *child_value = &const_val->data.x_array.data.s_none.elements[i];
- render_const_value(g, buf, child_value);
+ if (i != 0) buf_appendf(buf, ",");
+ render_const_value(g, buf, &base[i]);
}
buf_appendf(buf, "}");
return;
@@ -6124,10 +6129,16 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
}
case ZigTypeIdPointer:
return render_const_val_ptr(g, buf, const_val, type_entry);
- case ZigTypeIdVector:
- return render_const_val_array(g, buf, const_val, type_entry->data.vector.len);
- case ZigTypeIdArray:
- return render_const_val_array(g, buf, const_val, type_entry->data.array.len);
+ case ZigTypeIdArray: {
+ uint64_t len = type_entry->data.array.len;
+ render_const_val_array(g, buf, &type_entry->name, const_val, 0, len);
+ return;
+ }
+ case ZigTypeIdVector: {
+ uint32_t len = type_entry->data.vector.len;
+ render_const_val_array(g, buf, &type_entry->name, const_val, 0, len);
+ return;
+ }
case ZigTypeIdNull:
{
buf_appendf(buf, "null");
@@ -6169,7 +6180,19 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
}
case ZigTypeIdStruct:
{
- buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name));
+ if (is_slice(type_entry)) {
+ ConstPtrValue *ptr = &const_val->data.x_struct.fields[slice_ptr_index].data.x_ptr;
+ assert(ptr->special == ConstPtrSpecialBaseArray);
+ ConstExprValue *array = ptr->data.base_array.array_val;
+ size_t start = ptr->data.base_array.elem_index;
+
+ ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index];
+ size_t len = bigint_as_unsigned(&len_val->data.x_bigint);
+
+ render_const_val_array(g, buf, &type_entry->name, array, start, len);
+ } else {
+ buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name));
+ }
return;
}
case ZigTypeIdEnum:
From be861a85c8a1adc1f82c523136e6d6b18992c372 Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Wed, 13 Feb 2019 23:24:52 +1300
Subject: [PATCH 181/218] compiler-rt: Add __addtf3, __subtf3 and __truncdfhf2
Allows addition/subtraction of f128 and narrowing casts to f16 from
larger float types.
---
CMakeLists.txt | 1 +
std/special/compiler_rt/addXf3.zig | 191 ++++++++++++++++++++
std/special/compiler_rt/addXf3_test.zig | 85 +++++++++
std/special/compiler_rt/index.zig | 4 +
std/special/compiler_rt/truncXfYf2.zig | 4 +
std/special/compiler_rt/truncXfYf2_test.zig | 68 +++++++
6 files changed, 353 insertions(+)
create mode 100644 std/special/compiler_rt/addXf3.zig
create mode 100644 std/special/compiler_rt/addXf3_test.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed79f99901..41fa44374e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -608,6 +608,7 @@ set(ZIG_STD_FILES
"special/bootstrap_lib.zig"
"special/build_runner.zig"
"special/builtin.zig"
+ "special/compiler_rt/addXf3.zig"
"special/compiler_rt/aulldiv.zig"
"special/compiler_rt/aullrem.zig"
"special/compiler_rt/comparetf2.zig"
diff --git a/std/special/compiler_rt/addXf3.zig b/std/special/compiler_rt/addXf3.zig
new file mode 100644
index 0000000000..5f7f73c44f
--- /dev/null
+++ b/std/special/compiler_rt/addXf3.zig
@@ -0,0 +1,191 @@
+// Ported from:
+//
+// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/lib/builtins/fp_add_impl.inc
+
+const std = @import("std");
+const builtin = @import("builtin");
+const compiler_rt = @import("index.zig");
+
+pub extern fn __addtf3(a: f128, b: f128) f128 {
+ return addXf3(f128, a, b);
+}
+
+pub extern fn __subtf3(a: f128, b: f128) f128 {
+ const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127));
+ return addXf3(f128, a, neg_b);
+}
+
+inline fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
+ const Z = @IntType(false, T.bit_count);
+ const significandBits = std.math.floatMantissaBits(T);
+ const implicitBit = Z(1) << significandBits;
+
+ const shift = @clz(significand.*) - @clz(implicitBit);
+ significand.* <<= @intCast(u7, shift);
+ return 1 - shift;
+}
+
+inline fn addXf3(comptime T: type, a: T, b: T) T {
+ const Z = @IntType(false, T.bit_count);
+
+ const typeWidth = T.bit_count;
+ const significandBits = std.math.floatMantissaBits(T);
+ const exponentBits = std.math.floatExponentBits(T);
+
+ const signBit = (Z(1) << (significandBits + exponentBits));
+ const maxExponent = ((1 << exponentBits) - 1);
+ const exponentBias = (maxExponent >> 1);
+
+ const implicitBit = (Z(1) << significandBits);
+ const quietBit = implicitBit >> 1;
+ const significandMask = implicitBit - 1;
+
+ const absMask = signBit - 1;
+ const exponentMask = absMask ^ significandMask;
+ const qnanRep = exponentMask | quietBit;
+
+ var aRep = @bitCast(Z, a);
+ var bRep = @bitCast(Z, b);
+ const aAbs = aRep & absMask;
+ const bAbs = bRep & absMask;
+
+ const negative = (aRep & signBit) != 0;
+ const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
+ const significand = (aAbs & significandMask) | implicitBit;
+
+ const infRep = @bitCast(Z, std.math.inf(T));
+
+ // Detect if a or b is zero, infinity, or NaN.
+ if (aAbs - Z(1) >= infRep - Z(1) or
+ bAbs - Z(1) >= infRep - Z(1))
+ {
+ // NaN + anything = qNaN
+ if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);
+ // anything + NaN = qNaN
+ if (bAbs > infRep) return @bitCast(T, @bitCast(Z, b) | quietBit);
+
+ if (aAbs == infRep) {
+ // +/-infinity + -/+infinity = qNaN
+ if ((@bitCast(Z, a) ^ @bitCast(Z, b)) == signBit) {
+ return @bitCast(T, qnanRep);
+ }
+ // +/-infinity + anything remaining = +/- infinity
+ else {
+ return a;
+ }
+ }
+
+ // anything remaining + +/-infinity = +/-infinity
+ if (bAbs == infRep) return b;
+
+ // zero + anything = anything
+ if (aAbs == 0) {
+ // but we need to get the sign right for zero + zero
+ if (bAbs == 0) {
+ return @bitCast(T, @bitCast(Z, a) & @bitCast(Z, b));
+ } else {
+ return b;
+ }
+ }
+
+ // anything + zero = anything
+ if (bAbs == 0) return a;
+ }
+
+ // Swap a and b if necessary so that a has the larger absolute value.
+ if (bAbs > aAbs) {
+ const temp = aRep;
+ aRep = bRep;
+ bRep = temp;
+ }
+
+ // Extract the exponent and significand from the (possibly swapped) a and b.
+ var aExponent = @intCast(i32, (aRep >> significandBits) & maxExponent);
+ var bExponent = @intCast(i32, (bRep >> significandBits) & maxExponent);
+ var aSignificand = aRep & significandMask;
+ var bSignificand = bRep & significandMask;
+
+ // Normalize any denormals, and adjust the exponent accordingly.
+ if (aExponent == 0) aExponent = normalize(T, &aSignificand);
+ if (bExponent == 0) bExponent = normalize(T, &bSignificand);
+
+ // The sign of the result is the sign of the larger operand, a. If they
+ // have opposite signs, we are performing a subtraction; otherwise addition.
+ const resultSign = aRep & signBit;
+ const subtraction = (aRep ^ bRep) & signBit != 0;
+
+ // Shift the significands to give us round, guard and sticky, and or in the
+ // implicit significand bit. (If we fell through from the denormal path it
+ // was already set by normalize( ), but setting it twice won't hurt
+ // anything.)
+ aSignificand = (aSignificand | implicitBit) << 3;
+ bSignificand = (bSignificand | implicitBit) << 3;
+
+ // Shift the significand of b by the difference in exponents, with a sticky
+ // bottom bit to get rounding correct.
+ const @"align" = @intCast(Z, aExponent - bExponent);
+ if (@"align" != 0) {
+ if (@"align" < typeWidth) {
+ const sticky = if (bSignificand << @intCast(u7, typeWidth - @"align") != 0) Z(1) else 0;
+ bSignificand = (bSignificand >> @truncate(u7, @"align")) | sticky;
+ } else {
+ bSignificand = 1; // sticky; b is known to be non-zero.
+ }
+ }
+ if (subtraction) {
+ aSignificand -= bSignificand;
+ // If a == -b, return +zero.
+ if (aSignificand == 0) return @bitCast(T, Z(0));
+
+ // If partial cancellation occured, we need to left-shift the result
+ // and adjust the exponent:
+ if (aSignificand < implicitBit << 3) {
+ const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3));
+ aSignificand <<= @intCast(u7, shift);
+ aExponent -= shift;
+ }
+ } else { // addition
+ aSignificand += bSignificand;
+
+ // If the addition carried up, we need to right-shift the result and
+ // adjust the exponent:
+ if (aSignificand & (implicitBit << 4) != 0) {
+ const sticky = aSignificand & 1;
+ aSignificand = aSignificand >> 1 | sticky;
+ aExponent += 1;
+ }
+ }
+
+ // If we have overflowed the type, return +/- infinity:
+ if (aExponent >= maxExponent) return @bitCast(T, infRep | resultSign);
+
+ if (aExponent <= 0) {
+ // Result is denormal before rounding; the exponent is zero and we
+ // need to shift the significand.
+ const shift = @intCast(Z, 1 - aExponent);
+ const sticky = if (aSignificand << @intCast(u7, typeWidth - shift) != 0) Z(1) else 0;
+ aSignificand = aSignificand >> @intCast(u7, shift | sticky);
+ aExponent = 0;
+ }
+
+ // Low three bits are round, guard, and sticky.
+ const roundGuardSticky = aSignificand & 0x7;
+
+ // Shift the significand into place, and mask off the implicit bit.
+ var result = (aSignificand >> 3) & significandMask;
+
+ // Insert the exponent and sign.
+ result |= @intCast(Z, aExponent) << significandBits;
+ result |= resultSign;
+
+ // Final rounding. The result may overflow to infinity, but that is the
+ // correct result in that case.
+ if (roundGuardSticky > 0x4) result += 1;
+ if (roundGuardSticky == 0x4) result += result & 1;
+
+ return @bitCast(T, result);
+}
+
+test "import addXf3" {
+ _ = @import("addXf3_test.zig");
+}
diff --git a/std/special/compiler_rt/addXf3_test.zig b/std/special/compiler_rt/addXf3_test.zig
new file mode 100644
index 0000000000..f374a67433
--- /dev/null
+++ b/std/special/compiler_rt/addXf3_test.zig
@@ -0,0 +1,85 @@
+// Ported from:
+//
+// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/test/builtins/Unit/addtf3_test.c
+// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/test/builtins/Unit/subtf3_test.c
+
+const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);
+const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);
+
+const __addtf3 = @import("addXf3.zig").__addtf3;
+
+fn test__addtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
+ const x = __addtf3(a, b);
+
+ const rep = @bitCast(u128, x);
+ const hi = @intCast(u64, rep >> 64);
+ const lo = @truncate(u64, rep);
+
+ if (hi == expected_hi and lo == expected_lo) {
+ return;
+ }
+ // test other possible NaN representation (signal NaN)
+ else if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
+ if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
+ ((hi & 0xffffffffffff) > 0 or lo > 0))
+ {
+ return;
+ }
+ }
+
+ @panic("__addtf3 test failure");
+}
+
+test "addtf3" {
+ test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+
+ // NaN + any = NaN
+ test__addtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+
+ // inf + inf = inf
+ test__addtf3(inf128, inf128, 0x7fff000000000000, 0x0);
+
+ // inf + any = inf
+ test__addtf3(inf128, 0x1.2335653452436234723489432abcdefp+5, 0x7fff000000000000, 0x0);
+
+ // any + any
+ test__addtf3(0x1.23456734245345543849abcdefp+5, 0x1.edcba52449872455634654321fp-1, 0x40042afc95c8b579, 0x61e58dd6c51eb77c);
+}
+
+const __subtf3 = @import("addXf3.zig").__subtf3;
+
+fn test__subtf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
+ const x = __subtf3(a, b);
+
+ const rep = @bitCast(u128, x);
+ const hi = @intCast(u64, rep >> 64);
+ const lo = @truncate(u64, rep);
+
+ if (hi == expected_hi and lo == expected_lo) {
+ return;
+ }
+ // test other possible NaN representation (signal NaN)
+ else if (expected_hi == 0x7fff800000000000 and expected_lo == 0x0) {
+ if ((hi & 0x7fff000000000000) == 0x7fff000000000000 and
+ ((hi & 0xffffffffffff) > 0 or lo > 0))
+ {
+ return;
+ }
+ }
+
+ @panic("__subtf3 test failure");
+}
+
+test "subtf3" {
+ // qNaN - any = qNaN
+ test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+
+ // NaN + any = NaN
+ test__subtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
+
+ // inf - any = inf
+ test__subtf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
+
+ // any + any
+ test__subtf3(0x1.234567829a3bcdef5678ade36734p+5, 0x1.ee9d7c52354a6936ab8d7654321fp-1, 0x40041b8af1915166, 0xa44a7bca780a166c);
+}
diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig
index 3df94db589..6715df1805 100644
--- a/std/special/compiler_rt/index.zig
+++ b/std/special/compiler_rt/index.zig
@@ -21,6 +21,9 @@ comptime {
@export("__unordtf2", @import("comparetf2.zig").__unordtf2, linkage);
+ @export("__addtf3", @import("addXf3.zig").__addtf3, linkage);
+ @export("__subtf3", @import("addXf3.zig").__subtf3, linkage);
+
@export("__floattitf", @import("floattitf.zig").__floattitf, linkage);
@export("__floattidf", @import("floattidf.zig").__floattidf, linkage);
@export("__floattisf", @import("floattisf.zig").__floattisf, linkage);
@@ -37,6 +40,7 @@ comptime {
@export("__extendhfsf2", @import("extendXfYf2.zig").__extendhfsf2, linkage);
@export("__truncsfhf2", @import("truncXfYf2.zig").__truncsfhf2, linkage);
+ @export("__truncdfhf2", @import("truncXfYf2.zig").__truncdfhf2, linkage);
@export("__trunctfdf2", @import("truncXfYf2.zig").__trunctfdf2, linkage);
@export("__trunctfsf2", @import("truncXfYf2.zig").__trunctfsf2, linkage);
diff --git a/std/special/compiler_rt/truncXfYf2.zig b/std/special/compiler_rt/truncXfYf2.zig
index 5cb2f61568..b385090a93 100644
--- a/std/special/compiler_rt/truncXfYf2.zig
+++ b/std/special/compiler_rt/truncXfYf2.zig
@@ -4,6 +4,10 @@ pub extern fn __truncsfhf2(a: f32) u16 {
return @bitCast(u16, truncXfYf2(f16, f32, a));
}
+pub extern fn __truncdfhf2(a: f64) u16 {
+ return @bitCast(u16, truncXfYf2(f16, f64, a));
+}
+
pub extern fn __trunctfsf2(a: f128) f32 {
return truncXfYf2(f32, f128, a);
}
diff --git a/std/special/compiler_rt/truncXfYf2_test.zig b/std/special/compiler_rt/truncXfYf2_test.zig
index c4bf2db733..429372c3f1 100644
--- a/std/special/compiler_rt/truncXfYf2_test.zig
+++ b/std/special/compiler_rt/truncXfYf2_test.zig
@@ -63,6 +63,74 @@ test "truncsfhf2" {
test__truncsfhf2(0x33000000, 0x0000); // 0x1.0p-25 -> zero
}
+const __truncdfhf2 = @import("truncXfYf2.zig").__truncdfhf2;
+
+fn test__truncdfhf2(a: f64, expected: u16) void {
+ const rep = @bitCast(u16, __truncdfhf2(a));
+
+ if (rep == expected) {
+ return;
+ }
+ // test other possible NaN representation(signal NaN)
+ else if (expected == 0x7e00) {
+ if ((rep & 0x7c00) == 0x7c00 and (rep & 0x3ff) > 0) {
+ return;
+ }
+ }
+
+ @panic("__truncdfhf2 test failure");
+}
+
+fn test__truncdfhf2_raw(a: u64, expected: u16) void {
+ const actual = __truncdfhf2(@bitCast(f64, a));
+
+ if (actual == expected) {
+ return;
+ }
+
+ @panic("__truncdfhf2 test failure");
+}
+
+test "truncdfhf2" {
+ test__truncdfhf2_raw(0x7ff8000000000000, 0x7e00); // qNaN
+ test__truncdfhf2_raw(0x7ff0000000008000, 0x7e00); // NaN
+
+ test__truncdfhf2_raw(0x7ff0000000000000, 0x7c00); //inf
+ test__truncdfhf2_raw(0xfff0000000000000, 0xfc00); // -inf
+
+ test__truncdfhf2(0.0, 0x0); // zero
+ test__truncdfhf2_raw(0x80000000 << 32, 0x8000); // -zero
+
+ test__truncdfhf2(3.1415926535, 0x4248);
+ test__truncdfhf2(-3.1415926535, 0xc248);
+
+ test__truncdfhf2(0x1.987124876876324p+1000, 0x7c00);
+ test__truncdfhf2(0x1.987124876876324p+12, 0x6e62);
+ test__truncdfhf2(0x1.0p+0, 0x3c00);
+ test__truncdfhf2(0x1.0p-14, 0x0400);
+
+ // denormal
+ test__truncdfhf2(0x1.0p-20, 0x0010);
+ test__truncdfhf2(0x1.0p-24, 0x0001);
+ test__truncdfhf2(-0x1.0p-24, 0x8001);
+ test__truncdfhf2(0x1.5p-25, 0x0001);
+
+ // and back to zero
+ test__truncdfhf2(0x1.0p-25, 0x0000);
+ test__truncdfhf2(-0x1.0p-25, 0x8000);
+
+ // max (precise)
+ test__truncdfhf2(65504.0, 0x7bff);
+
+ // max (rounded)
+ test__truncdfhf2(65519.0, 0x7bff);
+
+ // max (to +inf)
+ test__truncdfhf2(65520.0, 0x7c00);
+ test__truncdfhf2(-65520.0, 0xfc00);
+ test__truncdfhf2(65536.0, 0x7c00);
+}
+
const __trunctfsf2 = @import("truncXfYf2.zig").__trunctfsf2;
fn test__trunctfsf2(a: f128, expected: u32) void {
From cf007e37b95db9faebf34c4c8f9b73aa20eb0672 Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Wed, 13 Feb 2019 23:27:23 +1300
Subject: [PATCH 182/218] Add f128 support for fabs, isinf, isnan, inf and nan
functions
---
std/math/fabs.zig | 19 +++++++++++++++++++
std/math/index.zig | 12 +++++++++++-
std/math/inf.zig | 7 ++++---
std/math/isinf.zig | 22 ++++++++++++++++++++++
std/math/isnan.zig | 6 ++++++
std/math/nan.zig | 7 ++++---
6 files changed, 66 insertions(+), 7 deletions(-)
diff --git a/std/math/fabs.zig b/std/math/fabs.zig
index 9fad5644c3..a605f4f33f 100644
--- a/std/math/fabs.zig
+++ b/std/math/fabs.zig
@@ -14,6 +14,7 @@ pub fn fabs(x: var) @typeOf(x) {
f16 => fabs16(x),
f32 => fabs32(x),
f64 => fabs64(x),
+ f128 => fabs128(x),
else => @compileError("fabs not implemented for " ++ @typeName(T)),
};
}
@@ -36,10 +37,17 @@ fn fabs64(x: f64) f64 {
return @bitCast(f64, u);
}
+fn fabs128(x: f128) f128 {
+ var u = @bitCast(u128, x);
+ u &= maxInt(u128) >> 1;
+ return @bitCast(f128, u);
+}
+
test "math.fabs" {
expect(fabs(f16(1.0)) == fabs16(1.0));
expect(fabs(f32(1.0)) == fabs32(1.0));
expect(fabs(f64(1.0)) == fabs64(1.0));
+ expect(fabs(f128(1.0)) == fabs128(1.0));
}
test "math.fabs16" {
@@ -57,6 +65,11 @@ test "math.fabs64" {
expect(fabs64(-1.0) == 1.0);
}
+test "math.fabs128" {
+ expect(fabs128(1.0) == 1.0);
+ expect(fabs128(-1.0) == 1.0);
+}
+
test "math.fabs16.special" {
expect(math.isPositiveInf(fabs(math.inf(f16))));
expect(math.isPositiveInf(fabs(-math.inf(f16))));
@@ -74,3 +87,9 @@ test "math.fabs64.special" {
expect(math.isPositiveInf(fabs(-math.inf(f64))));
expect(math.isNan(fabs(math.nan(f64))));
}
+
+test "math.fabs128.special" {
+ expect(math.isPositiveInf(fabs(math.inf(f128))));
+ expect(math.isPositiveInf(fabs(-math.inf(f128))));
+ expect(math.isNan(fabs(math.nan(f128))));
+}
diff --git a/std/math/index.zig b/std/math/index.zig
index ccfac03038..20648139b8 100644
--- a/std/math/index.zig
+++ b/std/math/index.zig
@@ -51,6 +51,12 @@ pub const nan_f64 = @bitCast(f64, nan_u64);
pub const inf_u64 = u64(0x7FF << 52);
pub const inf_f64 = @bitCast(f64, inf_u64);
+pub const nan_u128 = u128(0x7fff0000000000000000000000000001);
+pub const nan_f128 = @bitCast(f128, nan_u128);
+
+pub const inf_u128 = u128(0x7fff0000000000000000000000000000);
+pub const inf_f128 = @bitCast(f128, inf_u128);
+
pub const nan = @import("nan.zig").nan;
pub const snan = @import("nan.zig").snan;
pub const inf = @import("inf.zig").inf;
@@ -379,7 +385,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
return u0;
}
const is_signed = from < 0;
- const largest_positive_integer = max(if (from<0) (-from)-1 else from, to); // two's complement
+ const largest_positive_integer = max(if (from < 0) (-from) - 1 else from, to); // two's complement
const base = log2(largest_positive_integer);
const upper = (1 << base) - 1;
var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
@@ -752,6 +758,7 @@ test "minInt and maxInt" {
testing.expect(maxInt(u16) == 65535);
testing.expect(maxInt(u32) == 4294967295);
testing.expect(maxInt(u64) == 18446744073709551615);
+ testing.expect(maxInt(u128) == 340282366920938463463374607431768211455);
testing.expect(maxInt(i0) == 0);
testing.expect(maxInt(i1) == 0);
@@ -760,6 +767,7 @@ test "minInt and maxInt" {
testing.expect(maxInt(i32) == 2147483647);
testing.expect(maxInt(i63) == 4611686018427387903);
testing.expect(maxInt(i64) == 9223372036854775807);
+ testing.expect(maxInt(i128) == 170141183460469231731687303715884105727);
testing.expect(minInt(u0) == 0);
testing.expect(minInt(u1) == 0);
@@ -768,6 +776,7 @@ test "minInt and maxInt" {
testing.expect(minInt(u32) == 0);
testing.expect(minInt(u63) == 0);
testing.expect(minInt(u64) == 0);
+ testing.expect(minInt(u128) == 0);
testing.expect(minInt(i0) == 0);
testing.expect(minInt(i1) == -1);
@@ -776,6 +785,7 @@ test "minInt and maxInt" {
testing.expect(minInt(i32) == -2147483648);
testing.expect(minInt(i63) == -4611686018427387904);
testing.expect(minInt(i64) == -9223372036854775808);
+ testing.expect(minInt(i128) == -170141183460469231731687303715884105728);
}
test "max value type" {
diff --git a/std/math/inf.zig b/std/math/inf.zig
index 62f5ef7c0d..fb7a3489c5 100644
--- a/std/math/inf.zig
+++ b/std/math/inf.zig
@@ -3,9 +3,10 @@ const math = std.math;
pub fn inf(comptime T: type) T {
return switch (T) {
- f16 => @bitCast(f16, math.inf_u16),
- f32 => @bitCast(f32, math.inf_u32),
- f64 => @bitCast(f64, math.inf_u64),
+ f16 => math.inf_f16,
+ f32 => math.inf_f32,
+ f64 => math.inf_f64,
+ f128 => math.inf_f128,
else => @compileError("inf not implemented for " ++ @typeName(T)),
};
}
diff --git a/std/math/isinf.zig b/std/math/isinf.zig
index e34e9c5971..b1e3f7795e 100644
--- a/std/math/isinf.zig
+++ b/std/math/isinf.zig
@@ -18,6 +18,10 @@ pub fn isInf(x: var) bool {
const bits = @bitCast(u64, x);
return bits & (maxInt(u64) >> 1) == (0x7FF << 52);
},
+ f128 => {
+ const bits = @bitCast(u128, x);
+ return bits & (maxInt(u128) >> 1) == (0x7FFF << 112);
+ },
else => {
@compileError("isInf not implemented for " ++ @typeName(T));
},
@@ -36,6 +40,9 @@ pub fn isPositiveInf(x: var) bool {
f64 => {
return @bitCast(u64, x) == 0x7FF << 52;
},
+ f128 => {
+ return @bitCast(u128, x) == 0x7FFF << 112;
+ },
else => {
@compileError("isPositiveInf not implemented for " ++ @typeName(T));
},
@@ -54,6 +61,9 @@ pub fn isNegativeInf(x: var) bool {
f64 => {
return @bitCast(u64, x) == 0xFFF << 52;
},
+ f128 => {
+ return @bitCast(u128, x) == 0xFFFF << 112;
+ },
else => {
@compileError("isNegativeInf not implemented for " ++ @typeName(T));
},
@@ -67,12 +77,16 @@ test "math.isInf" {
expect(!isInf(f32(-0.0)));
expect(!isInf(f64(0.0)));
expect(!isInf(f64(-0.0)));
+ expect(!isInf(f128(0.0)));
+ expect(!isInf(f128(-0.0)));
expect(isInf(math.inf(f16)));
expect(isInf(-math.inf(f16)));
expect(isInf(math.inf(f32)));
expect(isInf(-math.inf(f32)));
expect(isInf(math.inf(f64)));
expect(isInf(-math.inf(f64)));
+ expect(isInf(math.inf(f128)));
+ expect(isInf(-math.inf(f128)));
}
test "math.isPositiveInf" {
@@ -82,12 +96,16 @@ test "math.isPositiveInf" {
expect(!isPositiveInf(f32(-0.0)));
expect(!isPositiveInf(f64(0.0)));
expect(!isPositiveInf(f64(-0.0)));
+ expect(!isPositiveInf(f128(0.0)));
+ expect(!isPositiveInf(f128(-0.0)));
expect(isPositiveInf(math.inf(f16)));
expect(!isPositiveInf(-math.inf(f16)));
expect(isPositiveInf(math.inf(f32)));
expect(!isPositiveInf(-math.inf(f32)));
expect(isPositiveInf(math.inf(f64)));
expect(!isPositiveInf(-math.inf(f64)));
+ expect(isPositiveInf(math.inf(f128)));
+ expect(!isPositiveInf(-math.inf(f128)));
}
test "math.isNegativeInf" {
@@ -97,10 +115,14 @@ test "math.isNegativeInf" {
expect(!isNegativeInf(f32(-0.0)));
expect(!isNegativeInf(f64(0.0)));
expect(!isNegativeInf(f64(-0.0)));
+ expect(!isNegativeInf(f128(0.0)));
+ expect(!isNegativeInf(f128(-0.0)));
expect(!isNegativeInf(math.inf(f16)));
expect(isNegativeInf(-math.inf(f16)));
expect(!isNegativeInf(math.inf(f32)));
expect(isNegativeInf(-math.inf(f32)));
expect(!isNegativeInf(math.inf(f64)));
expect(isNegativeInf(-math.inf(f64)));
+ expect(!isNegativeInf(math.inf(f128)));
+ expect(isNegativeInf(-math.inf(f128)));
}
diff --git a/std/math/isnan.zig b/std/math/isnan.zig
index 641da9e620..e8b03a1e34 100644
--- a/std/math/isnan.zig
+++ b/std/math/isnan.zig
@@ -18,6 +18,10 @@ pub fn isNan(x: var) bool {
const bits = @bitCast(u64, x);
return (bits & (maxInt(u64) >> 1)) > (u64(0x7FF) << 52);
},
+ f128 => {
+ const bits = @bitCast(u128, x);
+ return (bits & (maxInt(u128) >> 1)) > (u128(0x7FFF) << 112);
+ },
else => {
@compileError("isNan not implemented for " ++ @typeName(T));
},
@@ -34,7 +38,9 @@ test "math.isNan" {
expect(isNan(math.nan(f16)));
expect(isNan(math.nan(f32)));
expect(isNan(math.nan(f64)));
+ expect(isNan(math.nan(f128)));
expect(!isNan(f16(1.0)));
expect(!isNan(f32(1.0)));
expect(!isNan(f64(1.0)));
+ expect(!isNan(f128(1.0)));
}
diff --git a/std/math/nan.zig b/std/math/nan.zig
index 2cbcbee81b..d3ad43da23 100644
--- a/std/math/nan.zig
+++ b/std/math/nan.zig
@@ -2,9 +2,10 @@ const math = @import("index.zig");
pub fn nan(comptime T: type) T {
return switch (T) {
- f16 => @bitCast(f16, math.nan_u16),
- f32 => @bitCast(f32, math.nan_u32),
- f64 => @bitCast(f64, math.nan_u64),
+ f16 => math.nan_f16,
+ f32 => math.nan_f32,
+ f64 => math.nan_f64,
+ f128 => math.nan_f128,
else => @compileError("nan not implemented for " ++ @typeName(T)),
};
}
From c221b29c9d3c269326b3d901ce5a8b5f50263feb Mon Sep 17 00:00:00 2001
From: Jimmi Holst Christensen
Date: Wed, 13 Feb 2019 11:31:13 +0100
Subject: [PATCH 183/218] We already support vector on floats, so let's test it
---
test/stage1/behavior/vector.zig | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index 7cead12b65..5e3e446109 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -15,3 +15,17 @@ test "vector wrap operators" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "vector float operators" {
+ const S = struct {
+ fn doTheTest() void {
+ const v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 };
+ const x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 };
+ expect(mem.eql(f32, ([4]f32)(v + x), [4]f32{ 11, 22, 33, 44 }));
+ expect(mem.eql(f32, ([4]f32)(v - x), [4]f32{ 9, 18, 27, 36 }));
+ expect(mem.eql(f32, ([4]f32)(v * x), [4]f32{ 10, 40, 90, 160 }));
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From 53297a1bd09d4a4499117c1868d8448f007b12d9 Mon Sep 17 00:00:00 2001
From: Jimmi Holst Christensen
Date: Wed, 13 Feb 2019 11:40:32 +0100
Subject: [PATCH 184/218] We already support vector bit operators, so let's
test it
---
test/stage1/behavior/vector.zig | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/test/stage1/behavior/vector.zig b/test/stage1/behavior/vector.zig
index 5e3e446109..b0d2871454 100644
--- a/test/stage1/behavior/vector.zig
+++ b/test/stage1/behavior/vector.zig
@@ -29,3 +29,17 @@ test "vector float operators" {
S.doTheTest();
comptime S.doTheTest();
}
+
+test "vector bit operators" {
+ const S = struct {
+ fn doTheTest() void {
+ const v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
+ const x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
+ expect(mem.eql(u8, ([4]u8)(v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
+ expect(mem.eql(u8, ([4]u8)(v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
+ expect(mem.eql(u8, ([4]u8)(v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From c34ce6878e5834a123be862d45bd26fd9a843eef Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Thu, 14 Feb 2019 00:06:32 +1300
Subject: [PATCH 185/218] Add parseFloat to std.fmt
This is not intended to be the long-term implementation as it doesn't
provide various properties that we eventually will want (e.g.
round-tripping, denormal support). It also uses f64 internally so the
wider f128 will be inaccurate.
---
CMakeLists.txt | 1 +
std/fmt/index.zig | 8 +-
std/fmt/parse_float.zig | 425 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 433 insertions(+), 1 deletion(-)
create mode 100644 std/fmt/parse_float.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 41fa44374e..8e80c65dbd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -482,6 +482,7 @@ set(ZIG_STD_FILES
"fmt/errol/index.zig"
"fmt/errol/lookup.zig"
"fmt/index.zig"
+ "fmt/parse_float.zig"
"hash/adler.zig"
"hash/crc.zig"
"hash/fnv.zig"
diff --git a/std/fmt/index.zig b/std/fmt/index.zig
index 05b028112f..efb1c41f92 100644
--- a/std/fmt/index.zig
+++ b/std/fmt/index.zig
@@ -828,7 +828,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) ParseUnsigned
return x;
}
-test "parseUnsigned" {
+test "fmt.parseUnsigned" {
testing.expect((try parseUnsigned(u16, "050124", 10)) == 50124);
testing.expect((try parseUnsigned(u16, "65535", 10)) == 65535);
testing.expectError(error.Overflow, parseUnsigned(u16, "65536", 10));
@@ -855,6 +855,12 @@ test "parseUnsigned" {
testing.expectError(error.Overflow, parseUnsigned(u2, "4", 16));
}
+pub const parseFloat = @import("parse_float.zig").parseFloat;
+
+test "fmt.parseFloat" {
+ _ = @import("parse_float.zig");
+}
+
pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
const value = switch (c) {
'0'...'9' => c - '0',
diff --git a/std/fmt/parse_float.zig b/std/fmt/parse_float.zig
new file mode 100644
index 0000000000..b83cdbbbb2
--- /dev/null
+++ b/std/fmt/parse_float.zig
@@ -0,0 +1,425 @@
+// Adapted from https://github.com/grzegorz-kraszewski/stringtofloat.
+
+// MIT License
+//
+// Copyright (c) 2016 Grzegorz Kraszewski
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//
+
+// Be aware that this implementation has the following limitations:
+//
+// - Is not round-trip accurate for all values
+// - Only supports round-to-zero
+// - Does not handle denormals
+
+const std = @import("../index.zig");
+
+const max_digits = 25;
+
+const f64_plus_zero: u64 = 0x0000000000000000;
+const f64_minus_zero: u64 = 0x8000000000000000;
+const f64_plus_infinity: u64 = 0x7FF0000000000000;
+const f64_minus_infinity: u64 = 0xFFF0000000000000;
+
+const Z96 = struct {
+ d0: u32,
+ d1: u32,
+ d2: u32,
+
+ // d = s >> 1
+ inline fn shiftRight1(d: *Z96, s: Z96) void {
+ d.d0 = (s.d0 >> 1) | ((s.d1 & 1) << 31);
+ d.d1 = (s.d1 >> 1) | ((s.d2 & 1) << 31);
+ d.d2 = s.d2 >> 1;
+ }
+
+ // d = s << 1
+ inline fn shiftLeft1(d: *Z96, s: Z96) void {
+ d.d2 = (s.d2 << 1) | ((s.d1 & (1 << 31)) >> 31);
+ d.d1 = (s.d1 << 1) | ((s.d0 & (1 << 31)) >> 31);
+ d.d0 = s.d0 << 1;
+ }
+
+ // d += s
+ inline fn add(d: *Z96, s: Z96) void {
+ var w = u64(d.d0) + u64(s.d0);
+ d.d0 = @truncate(u32, w);
+
+ w >>= 32;
+ w += u64(d.d1) + u64(s.d1);
+ d.d1 = @truncate(u32, w);
+
+ w >>= 32;
+ w += u64(d.d2) + u64(s.d2);
+ d.d2 = @truncate(u32, w);
+ }
+
+ // d -= s
+ inline fn sub(d: *Z96, s: Z96) void {
+ var w = u64(d.d0) -% u64(s.d0);
+ d.d0 = @truncate(u32, w);
+
+ w >>= 32;
+ w += u64(d.d1) -% u64(s.d1);
+ d.d1 = @truncate(u32, w);
+
+ w >>= 32;
+ w += u64(d.d2) -% u64(s.d2);
+ d.d2 = @truncate(u32, w);
+ }
+
+ fn dump(d: Z96) void {
+ std.debug.warn("{} {} {}\n", d.d0, d.d1, d.d2);
+ }
+};
+
+const FloatRepr = struct {
+ negative: bool,
+ exponent: i32,
+ mantissa: u64,
+};
+
+fn convertRepr(comptime T: type, n: FloatRepr) T {
+ const mask28: u32 = 0xf << 28;
+
+ var s: Z96 = undefined;
+ var q: Z96 = undefined;
+ var r: Z96 = undefined;
+
+ s.d0 = @truncate(u32, n.mantissa);
+ s.d1 = @truncate(u32, n.mantissa >> 32);
+ s.d2 = 0;
+
+ var binary_exponent: u64 = 92;
+ var exp = n.exponent;
+
+ while (exp > 0) : (exp -= 1) {
+ q.shiftLeft1(s); // q = p << 1
+ r.shiftLeft1(q); // r = p << 2
+ s.shiftLeft1(r); // p = p << 3
+ q.add(s); // p = (p << 3) + (p << 1)
+
+ exp -= 1;
+
+ while (s.d2 & mask28 != 0) {
+ q.shiftRight1(s);
+ binary_exponent += 1;
+ s = q;
+ }
+ }
+
+ while (exp < 0) {
+ while (s.d2 & (1 << 31) == 0) {
+ q.shiftLeft1(s);
+ binary_exponent -= 1;
+ s = q;
+ }
+
+ q.d2 = s.d2 / 10;
+ r.d1 = s.d2 % 10;
+ r.d2 = (s.d1 >> 8) | (r.d1 << 24);
+ q.d1 = r.d2 / 10;
+ r.d1 = r.d2 % 10;
+ r.d2 = ((s.d1 & 0xff) << 16) | (s.d0 >> 16) | (r.d1 << 24);
+ r.d0 = r.d2 / 10;
+ r.d1 = r.d2 % 10;
+ q.d1 = (q.d1 << 8) | ((r.d0 & 0x00ff0000) >> 16);
+ q.d0 = r.d0 << 16;
+ r.d2 = (s.d0 *% 0xffff) | (r.d1 << 16);
+ q.d0 |= r.d2 / 10;
+ s = q;
+
+ exp += 1;
+ }
+
+ if (s.d0 != 0 or s.d1 != 0 or s.d2 != 0) {
+ while (s.d2 & mask28 == 0) {
+ q.shiftLeft1(s);
+ binary_exponent -= 1;
+ s = q;
+ }
+ }
+
+ binary_exponent += 1023;
+
+ const repr: u64 = blk: {
+ if (binary_exponent > 2046) {
+ break :blk if (n.negative) f64_minus_infinity else f64_plus_infinity;
+ } else if (binary_exponent < 1) {
+ break :blk if (n.negative) f64_minus_zero else f64_plus_zero;
+ } else if (s.d2 != 0) {
+ const binexs2 = u64(binary_exponent) << 52;
+ const rr = (u64(s.d2 & ~mask28) << 24) | ((u64(s.d1) + 128) >> 8) | binexs2;
+ break :blk if (n.negative) rr | (1 << 63) else rr;
+ } else {
+ break :blk 0;
+ }
+ };
+
+ const f = @bitCast(f64, repr);
+ return @floatCast(T, f);
+}
+
+const State = enum {
+ SkipLeadingWhitespace,
+ MaybeSign,
+ LeadingMantissaZeros,
+ LeadingFractionalZeros,
+ MantissaIntegral,
+ MantissaFractional,
+ ExponentSign,
+ LeadingExponentZeros,
+ Exponent,
+ Stop,
+};
+
+const ParseResult = enum {
+ Ok,
+ PlusZero,
+ MinusZero,
+ PlusInf,
+ MinusInf,
+};
+
+inline fn isDigit(c: u8) bool {
+ return c >= '0' and c <= '9';
+}
+
+inline fn isSpace(c: u8) bool {
+ return (c >= 0x09 and c <= 0x13) or c == 0x20;
+}
+
+fn parseRepr(s: []const u8, n: *FloatRepr) ParseResult {
+ var digit_index: usize = 0;
+ var negative = false;
+ var negative_exp = false;
+ var exponent: i32 = 0;
+
+ var state = State.SkipLeadingWhitespace;
+
+ var i: usize = 0;
+ loop: while (state != State.Stop and i < s.len) {
+ const c = s[i];
+
+ switch (state) {
+ State.SkipLeadingWhitespace => {
+ if (isSpace(c)) {
+ i += 1;
+ } else {
+ state = State.MaybeSign;
+ }
+ },
+
+ State.MaybeSign => {
+ state = State.LeadingMantissaZeros;
+
+ if (c == '+') {
+ i += 1;
+ } else if (c == '-') {
+ n.negative = true;
+ i += 1;
+ } else if (isDigit(c) or c == '.') {
+ // continue
+ } else {
+ state = State.Stop;
+ }
+ },
+
+ State.LeadingMantissaZeros => {
+ if (c == '0') {
+ i += 1;
+ } else if (c == '.') {
+ i += 1;
+ state = State.LeadingFractionalZeros;
+ } else {
+ state = State.MantissaIntegral;
+ }
+ },
+
+ State.LeadingFractionalZeros => {
+ if (c == '0') {
+ i += 1;
+ if (n.exponent > std.math.minInt(i32)) {
+ n.exponent -= 1;
+ }
+ } else {
+ state = State.MantissaFractional;
+ }
+ },
+
+ State.MantissaIntegral => {
+ if (isDigit(c)) {
+ if (digit_index < max_digits) {
+ n.mantissa *%= 10;
+ n.mantissa += s[i] - '0';
+ digit_index += 1;
+ } else if (n.exponent < std.math.maxInt(i32)) {
+ n.exponent += 1;
+ }
+
+ i += 1;
+ } else if (c == '.') {
+ i += 1;
+ state = State.MantissaFractional;
+ } else {
+ state = State.MantissaFractional;
+ }
+ },
+
+ State.MantissaFractional => {
+ if (isDigit(c)) {
+ if (digit_index < max_digits) {
+ n.mantissa *%= 10;
+ n.mantissa += c - '0';
+ n.exponent -%= 1;
+ digit_index += 1;
+ }
+
+ i += 1;
+ } else if (c == 'e' or c == 'E') {
+ i += 1;
+ state = State.ExponentSign;
+ } else {
+ state = State.ExponentSign;
+ }
+ },
+
+ State.ExponentSign => {
+ if (c == '+') {
+ i += 1;
+ } else if (c == '-') {
+ negative_exp = true;
+ i += 1;
+ }
+
+ state = State.LeadingExponentZeros;
+ },
+
+ State.LeadingExponentZeros => {
+ if (c == '0') {
+ i += 1;
+ } else {
+ state = State.Exponent;
+ }
+ },
+
+ State.Exponent => {
+ if (isDigit(c)) {
+ if (exponent < std.math.maxInt(i32)) {
+ exponent *= 10;
+ exponent += @intCast(i32, c - '0');
+ }
+
+ i += 1;
+ } else {
+ state = State.Stop;
+ }
+ },
+
+ State.Stop => break :loop,
+ }
+ }
+
+ if (negative_exp) exponent = -exponent;
+ n.exponent += exponent;
+
+ if (n.mantissa == 0) {
+ return if (n.negative) ParseResult.MinusZero else ParseResult.PlusZero;
+ } else if (n.exponent > 309) {
+ return if (n.negative) ParseResult.MinusInf else ParseResult.PlusInf;
+ } else if (n.exponent < -328) {
+ return if (n.negative) ParseResult.MinusZero else ParseResult.PlusZero;
+ }
+
+ return ParseResult.Ok;
+}
+
+inline fn isLower(c: u8) bool {
+ return c -% 'a' < 26;
+}
+
+inline fn toUpper(c: u8) u8 {
+ return if (isLower(c)) (c & 0x5f) else c;
+}
+
+fn caseInEql(a: []const u8, b: []const u8) bool {
+ if (a.len != b.len) return false;
+
+ for (a) |_, i| {
+ if (toUpper(a[i]) != toUpper(b[i])) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+pub fn parseFloat(comptime T: type, s: []const u8) T {
+ var r = FloatRepr{
+ .negative = false,
+ .exponent = 0,
+ .mantissa = 0,
+ };
+
+ if (caseInEql(s, "nan")) {
+ return std.math.nan(T);
+ } else if (caseInEql(s, "inf") or caseInEql(s, "+inf")) {
+ return std.math.inf(T);
+ } else if (caseInEql(s, "-inf")) {
+ return -std.math.inf(T);
+ }
+
+ return switch (parseRepr(s, &r)) {
+ ParseResult.Ok => convertRepr(T, r),
+ ParseResult.PlusZero => 0.0,
+ ParseResult.MinusZero => -T(0.0),
+ ParseResult.PlusInf => std.math.inf(T),
+ ParseResult.MinusInf => -std.math.inf(T),
+ };
+}
+
+test "fmt.parseFloat" {
+ const assert = std.debug.assert;
+ const approxEq = std.math.approxEq;
+ const epsilon = 1e-7;
+
+ inline for ([]type{ f32, f64, f128 }) |T| {
+ const Z = @IntType(false, T.bit_count);
+
+ assert(parseFloat(T, "0") == 0.0);
+ assert(parseFloat(T, "+0") == 0.0);
+ assert(parseFloat(T, "-0") == 0.0);
+
+ assert(approxEq(T, parseFloat(T, "3.141"), 3.141, epsilon));
+ assert(approxEq(T, parseFloat(T, "-3.141"), -3.141, epsilon));
+
+ assert(parseFloat(T, "1e-700") == 0);
+ assert(parseFloat(T, "1e+700") == std.math.inf(T));
+
+ assert(@bitCast(Z, parseFloat(T, "nAn")) == @bitCast(Z, std.math.nan(T)));
+ assert(parseFloat(T, "inF") == std.math.inf(T));
+ assert(parseFloat(T, "-INF") == -std.math.inf(T));
+
+ if (T != f16) {
+ assert(approxEq(T, parseFloat(T, "123142.1"), 123142.1, epsilon));
+ assert(approxEq(T, parseFloat(T, "-123142.1124"), T(-123142.1124), epsilon));
+ }
+ }
+}
From de7c55145aeb6687040254dedaef66eedf5328dd Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Thu, 14 Feb 2019 00:12:00 +1300
Subject: [PATCH 186/218] Add parseFloat support to json.zig
---
std/json.zig | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/std/json.zig b/std/json.zig
index d8f28560e5..5a28d9ab41 100644
--- a/std/json.zig
+++ b/std/json.zig
@@ -1345,7 +1345,7 @@ pub const Parser = struct {
return if (token.number_is_integer)
Value{ .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }
else
- @panic("TODO: fmt.parseFloat not yet implemented");
+ Value{ .Float = std.fmt.parseFloat(f64, token.slice(input, i)) };
}
};
@@ -1366,7 +1366,8 @@ test "json.parser.dynamic" {
\\ },
\\ "Animated" : false,
\\ "IDs": [116, 943, 234, 38793],
- \\ "ArrayOfObject": [{"n": "m"}]
+ \\ "ArrayOfObject": [{"n": "m"}],
+ \\ "double": 1.3412
\\ }
\\}
;
@@ -1395,4 +1396,7 @@ test "json.parser.dynamic" {
const obj0 = array_of_object.Array.at(0).Object.get("n").?.value;
testing.expect(mem.eql(u8, obj0.String, "m"));
+
+ const double = image.Object.get("double").?.value;
+ testing.expect(double.Float == 1.3412);
}
From 2911eb34ded4709429a9767e08675ae862907a5f Mon Sep 17 00:00:00 2001
From: Jimmi Holst Christensen
Date: Wed, 13 Feb 2019 12:19:08 +0100
Subject: [PATCH 187/218] Added error for nesting vectors
---
test/compile_errors.zig | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index b47cdf2ed1..b895e2c2d1 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -5430,4 +5430,14 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
".tmp_source.zig:7:30: error: unable to evaluate constant expression",
);
+
+ cases.addTest(
+ "nested vectors",
+ \\export fn entry() void {
+ \\ const V = @Vector(4, @Vector(4, u8));
+ \\ var v: V = undefined;
+ \\}
+ ,
+ ".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid",
+ );
}
From d4d2718bca9e23ceec029bb505c0ea1b91c875b6 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 00:40:39 -0500
Subject: [PATCH 188/218] comptime detection of casting null to pointer
See #1059
---
src/ir.cpp | 17 ++++++++++++++---
test/compile_errors.zig | 20 ++++++++++++++++++++
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 19bec193d5..f064adb128 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -20645,12 +20645,23 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
}
if (instr_is_comptime(ptr)) {
- // Undefined is OK here; @ptrCast is defined to reinterpret the bit pattern
- // of the pointer as the new pointer type.
- ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
+ bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);
+ UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;
+ ConstExprValue *val = ir_resolve_const(ira, ptr, is_undef_allowed);
if (!val)
return ira->codegen->invalid_instruction;
+ if (val->special == ConstValSpecialStatic) {
+ bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull ||
+ (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
+ val->data.x_ptr.data.hard_coded_addr.addr == 0);
+ if (is_addr_zero && !dest_allows_addr_zero) {
+ ir_add_error(ira, source_instr,
+ buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+ }
+
IrInstruction *result = ir_const(ira, source_instr, dest_type);
copy_const_val(&result->value, val, false);
result->value.type = dest_type;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index c51a65cadf..71ee4901ff 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,26 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "implicit casting null c pointer to zig pointer",
+ \\comptime {
+ \\ var c_ptr: [*c]u8 = 0;
+ \\ var zig_ptr: *u8 = c_ptr;
+ \\}
+ ,
+ ".tmp_source.zig:3:24: error: null pointer casted to type '*u8'",
+ );
+
+ cases.addTest(
+ "implicit casting undefined c pointer to zig pointer",
+ \\comptime {
+ \\ var c_ptr: [*c]u8 = undefined;
+ \\ var zig_ptr: *u8 = c_ptr;
+ \\}
+ ,
+ ".tmp_source.zig:3:24: error: use of undefined value here causes undefined behavior",
+ );
+
cases.addTest(
"implicit casting C pointers which would mess up null semantics",
\\export fn entry() void {
From 59de24817e8538434f35a20a401f40c2f0231a9a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 01:09:33 -0500
Subject: [PATCH 189/218] runtime safety check for casting null to pointer
see #1059
---
src/all_types.hpp | 3 +++
src/analyze.cpp | 9 +++++++
src/analyze.hpp | 1 +
src/codegen.cpp | 19 ++++++++++++++-
src/ir.cpp | 52 ++++++++++++++++++++---------------------
test/runtime_safety.zig | 10 ++++++++
6 files changed, 67 insertions(+), 27 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 230dba9a42..bafe316c3d 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1488,6 +1488,7 @@ enum PanicMsgId {
PanicMsgIdBadUnionField,
PanicMsgIdBadEnumValue,
PanicMsgIdFloatToInt,
+ PanicMsgIdPtrCastNull,
PanicMsgIdCount,
};
@@ -3001,12 +3002,14 @@ struct IrInstructionPtrCastSrc {
IrInstruction *dest_type;
IrInstruction *ptr;
+ bool safety_check_on;
};
struct IrInstructionPtrCastGen {
IrInstruction base;
IrInstruction *ptr;
+ bool safety_check_on;
};
struct IrInstructionBitCast {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 900def52d4..6a8090a843 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -6902,3 +6902,12 @@ const char *container_string(ContainerKind kind) {
}
zig_unreachable();
}
+
+bool ptr_allows_addr_zero(ZigType *ptr_type) {
+ if (ptr_type->id == ZigTypeIdPointer) {
+ return ptr_type->data.pointer.allow_zero;
+ } else if (ptr_type->id == ZigTypeIdOptional) {
+ return true;
+ }
+ return false;
+}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index c8141b02ff..50e841baa1 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -45,6 +45,7 @@ void find_libc_lib_path(CodeGen *g);
bool type_has_bits(ZigType *type_entry);
bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
+bool ptr_allows_addr_zero(ZigType *ptr_type);
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 142e8174f5..dbb13ca885 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -950,6 +950,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("invalid enum value");
case PanicMsgIdFloatToInt:
return buf_create_from_str("integer part of floating point value out of bounds");
+ case PanicMsgIdPtrCastNull:
+ return buf_create_from_str("cast causes pointer to be null");
}
zig_unreachable();
}
@@ -3028,7 +3030,22 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
return nullptr;
}
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
- return LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
+ LLVMValueRef result_ptr = LLVMBuildBitCast(g->builder, ptr, wanted_type->type_ref, "");
+ bool want_safety_check = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
+ if (!want_safety_check || ptr_allows_addr_zero(wanted_type))
+ return result_ptr;
+
+ LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(result_ptr));
+ LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntNE, result_ptr, zero, "");
+ LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrCastFail");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrCastOk");
+ LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, fail_block);
+ gen_safety_crash(g, PanicMsgIdPtrCastNull);
+
+ LLVMPositionBuilderAtEnd(g->builder, ok_block);
+ return result_ptr;
}
static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
diff --git a/src/ir.cpp b/src/ir.cpp
index f064adb128..dfbc36e02c 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -172,7 +172,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
ConstExprValue *out_val, ConstExprValue *ptr_val);
static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
- ZigType *dest_type, IrInstruction *dest_type_src);
+ ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on);
static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed);
static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs);
static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align);
@@ -2202,12 +2202,13 @@ static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNo
}
static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction *dest_type, IrInstruction *ptr)
+ IrInstruction *dest_type, IrInstruction *ptr, bool safety_check_on)
{
IrInstructionPtrCastSrc *instruction = ir_build_instruction(
irb, scope, source_node);
instruction->dest_type = dest_type;
instruction->ptr = ptr;
+ instruction->safety_check_on = safety_check_on;
ir_ref_instruction(dest_type, irb->current_basic_block);
ir_ref_instruction(ptr, irb->current_basic_block);
@@ -2216,12 +2217,13 @@ static IrInstruction *ir_build_ptr_cast_src(IrBuilder *irb, Scope *scope, AstNod
}
static IrInstruction *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction,
- ZigType *ptr_type, IrInstruction *ptr)
+ ZigType *ptr_type, IrInstruction *ptr, bool safety_check_on)
{
IrInstructionPtrCastGen *instruction = ir_build_instruction(
&ira->new_irb, source_instruction->scope, source_instruction->source_node);
instruction->base.value.type = ptr_type;
instruction->ptr = ptr;
+ instruction->safety_check_on = safety_check_on;
ir_ref_instruction(ptr, ira->new_irb.current_basic_block);
@@ -4505,7 +4507,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
- IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value);
+ IrInstruction *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true);
return ir_lval_wrap(irb, scope, ptr_cast, lval);
}
case BuiltinFnIdBitCast:
@@ -6740,7 +6742,8 @@ static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode
IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010
// TODO relies on Zig not re-ordering fields
- IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst);
+ IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst,
+ false);
IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
@@ -6818,7 +6821,8 @@ static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode
get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void));
// TODO relies on Zig not re-ordering fields
- IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst);
+ IrInstruction *casted_target_inst = ir_build_ptr_cast_src(irb, scope, node, promise_T_type_val, target_inst,
+ false);
IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst);
Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr,
@@ -7363,7 +7367,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
u8_ptr_type = ir_build_const_type(irb, coro_scope, node,
get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false));
- IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, coro_promise_ptr);
+ IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type,
+ coro_promise_ptr, false);
coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr);
coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false);
IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node);
@@ -7387,7 +7392,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
ir_build_return(irb, coro_scope, node, undef);
ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
- IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr);
+ IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr,
+ false);
irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr);
Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME);
@@ -7465,9 +7471,10 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
false, false, PtrLenUnknown, 0, 0, 0));
IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr);
- IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, result_ptr);
- IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len,
- irb->exec->coro_result_field_ptr);
+ IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len,
+ result_ptr, false);
+ IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast_src(irb, scope, node,
+ u8_ptr_type_unknown_len, irb->exec->coro_result_field_ptr, false);
IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node,
fn_entry->type_entry->data.fn.fn_type_id.return_type);
IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst);
@@ -7517,7 +7524,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
false, false, PtrLenUnknown, 0, 0, 0));
- IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe);
+ IrInstruction *coro_mem_ptr = ir_build_ptr_cast_src(irb, scope, node, u8_ptr_type_unknown_len,
+ coro_mem_ptr_maybe, false);
IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
@@ -8644,15 +8652,6 @@ static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigTyp
return err_set_type;
}
-static bool ptr_allows_addr_zero(ZigType *ptr_type) {
- if (ptr_type->id == ZigTypeIdPointer) {
- return ptr_type->data.pointer.allow_zero;
- } else if (ptr_type->id == ZigTypeIdOptional) {
- return true;
- }
- return false;
-}
-
static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type,
ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable)
{
@@ -11310,7 +11309,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->data.pointer.host_int_bytes == dest_ptr_type->data.pointer.host_int_bytes &&
get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type))
{
- return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);
+ return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true);
}
}
@@ -11352,7 +11351,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
actual_type->data.pointer.child_type, source_node,
!wanted_type->data.pointer.is_const).id == ConstCastResultIdOk)
{
- return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr);
+ return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr, true);
}
// cast from integer to C pointer
@@ -20616,7 +20615,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
}
static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr,
- ZigType *dest_type, IrInstruction *dest_type_src)
+ ZigType *dest_type, IrInstruction *dest_type_src, bool safety_check_on)
{
Error err;
@@ -20685,7 +20684,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
return ira->codegen->invalid_instruction;
}
- IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr);
+ IrInstruction *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
if (type_has_bits(dest_type) && !type_has_bits(src_type)) {
ErrorMsg *msg = ir_add_error(ira, source_instr,
@@ -20722,7 +20721,8 @@ static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstruct
if (type_is_invalid(src_type))
return ira->codegen->invalid_instruction;
- return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value);
+ return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value,
+ instruction->safety_check_on);
}
static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ConstExprValue *val, size_t len) {
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 821328b7a6..12cac64b3a 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -1,6 +1,16 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompareOutputContext) void {
+ cases.addRuntimeSafety("pointer casting null to non-optional pointer",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ var c_ptr: [*c]u8 = 0;
+ \\ var zig_ptr: *u8 = c_ptr;
+ \\}
+ );
+
cases.addRuntimeSafety("@intToEnum - no matching tag value",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
From a4e32d9fb143dbfb622a5097ea4a1e4bcad03463 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 09:46:08 -0500
Subject: [PATCH 190/218] ci: freebsd: remove '.git' from URL as per upstream
suggestion
https://todo.sr.ht/~sircmpwn/dispatch.sr.ht/24#comment-1465
---
.builds/freebsd.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.builds/freebsd.yml b/.builds/freebsd.yml
index 934b8a4f4a..5e94a83a3a 100644
--- a/.builds/freebsd.yml
+++ b/.builds/freebsd.yml
@@ -4,7 +4,7 @@ packages:
- ninja
- llvm70
sources:
- - https://github.com/ziglang/zig.git
+ - https://github.com/ziglang/zig
tasks:
- build: |
cd zig && mkdir build && cd build
From c58b80203443dcbf8b737ebdaa1f17fb20c77711 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 10:51:59 -0500
Subject: [PATCH 191/218] remove the "top of the comptime stack" compile error
It's still best practice to put `@setEvalBranchQuota` at the top of
the comptime stack, but as Jimmi notes in #1949, when a function
can be called at comptime and also can be the top of the comptime stack,
this compile error is fundamentally unsound.
So now it's gone.
closes #1949
---
src/ir.cpp | 6 ------
test/compile_errors.zig | 14 --------------
2 files changed, 20 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 5d4013b4b9..03dea10b10 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -18172,12 +18172,6 @@ static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira,
static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
IrInstructionSetEvalBranchQuota *instruction)
{
- if (ira->new_irb.exec->parent_exec != nullptr && !ira->new_irb.exec->is_generic_instantiation) {
- ir_add_error(ira, &instruction->base,
- buf_sprintf("@setEvalBranchQuota must be called from the top of the comptime stack"));
- return ira->codegen->invalid_instruction;
- }
-
uint64_t new_quota;
if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota))
return ira->codegen->invalid_instruction;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index b895e2c2d1..6a2ded1844 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -4554,20 +4554,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",
);
- cases.add(
- "@setEvalBranchQuota in non-root comptime execution context",
- \\comptime {
- \\ foo();
- \\}
- \\fn foo() void {
- \\ @setEvalBranchQuota(1001);
- \\}
- ,
- ".tmp_source.zig:5:5: error: @setEvalBranchQuota must be called from the top of the comptime stack",
- ".tmp_source.zig:2:8: note: called from here",
- ".tmp_source.zig:1:10: note: called from here",
- );
-
cases.add(
"wrong pointer implicitly casted to pointer to @OpaqueType()",
\\const Derp = @OpaqueType();
From e03c770145b5dc7b428d53b3cac97c2733fb84d8 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 12:28:50 -0500
Subject: [PATCH 192/218] compile error tests for implicit C pointer casting
See #1059
---
src/ir.cpp | 38 ++++++++++++++++++--------------------
test/compile_errors.zig | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index dfbc36e02c..89528db185 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8683,16 +8683,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
(actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
if (wanted_opt_or_ptr && actual_opt_or_ptr) {
- bool ok_allows_zero = (wanted_allows_zero &&
- (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
- (!wanted_allows_zero && !actual_allows_zero);
- if (!ok_allows_zero) {
- result.id = ConstCastResultIdBadAllowsZero;
- result.data.bad_allows_zero = allocate_nonzero(1);
- result.data.bad_allows_zero->wanted_type = wanted_type;
- result.data.bad_allows_zero->actual_type = actual_type;
- return result;
- }
ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
if (child.id == ConstCastResultIdInvalid)
@@ -8705,6 +8695,16 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type;
return result;
}
+ bool ok_allows_zero = (wanted_allows_zero &&
+ (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
+ (!wanted_allows_zero && !actual_allows_zero);
+ if (!ok_allows_zero) {
+ result.id = ConstCastResultIdBadAllowsZero;
+ result.data.bad_allows_zero = allocate_nonzero(1);
+ result.data.bad_allows_zero->wanted_type = wanted_type;
+ result.data.bad_allows_zero->actual_type = actual_type;
+ return result;
+ }
if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
result.id = ConstCastResultIdInvalid;
return result;
@@ -10846,22 +10846,20 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
break;
}
case ConstCastResultIdBadAllowsZero: {
- bool wanted_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->wanted_type);
- bool actual_allows_zero = ptr_allows_addr_zero(cast_result->data.bad_allows_zero->actual_type);
- ZigType *wanted_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->wanted_type);
- ZigType *actual_ptr_type = get_src_ptr_type(cast_result->data.bad_allows_zero->actual_type);
- ZigType *wanted_elem_type = wanted_ptr_type->data.pointer.child_type;
- ZigType *actual_elem_type = actual_ptr_type->data.pointer.child_type;
+ ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type;
+ ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type;
+ bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type);
+ bool actual_allows_zero = ptr_allows_addr_zero(actual_type);
if (actual_allows_zero && !wanted_allows_zero) {
add_error_note(ira->codegen, parent_msg, source_node,
buf_sprintf("'%s' could have null values which are illegal in type '%s'",
- buf_ptr(&actual_elem_type->name),
- buf_ptr(&wanted_elem_type->name)));
+ buf_ptr(&actual_type->name),
+ buf_ptr(&wanted_type->name)));
} else {
add_error_note(ira->codegen, parent_msg, source_node,
buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'",
- buf_ptr(&cast_result->data.bad_allows_zero->wanted_type->name),
- buf_ptr(&cast_result->data.bad_allows_zero->actual_type->name)));
+ buf_ptr(&wanted_type->name),
+ buf_ptr(&actual_type->name)));
}
break;
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 71ee4901ff..630386aa4f 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,42 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "implicit cast between C pointer and Zig pointer - bad const/align/child",
+ \\export fn a() void {
+ \\ var x: [*c]u8 = undefined;
+ \\ var y: *align(4) u8 = x;
+ \\}
+ \\export fn b() void {
+ \\ var x: [*c]const u8 = undefined;
+ \\ var y: *u8 = x;
+ \\}
+ \\export fn c() void {
+ \\ var x: [*c]u8 = undefined;
+ \\ var y: *u32 = x;
+ \\}
+ \\export fn d() void {
+ \\ var y: *align(1) u32 = undefined;
+ \\ var x: [*c]u32 = y;
+ \\}
+ \\export fn e() void {
+ \\ var y: *const u8 = undefined;
+ \\ var x: [*c]u8 = y;
+ \\}
+ \\export fn f() void {
+ \\ var y: *u8 = undefined;
+ \\ var x: [*c]u32 = y;
+ \\}
+ ,
+ ".tmp_source.zig:3:27: error: cast increases pointer alignment",
+ ".tmp_source.zig:7:18: error: cast discards const qualifier",
+ ".tmp_source.zig:11:19: error: expected type '*u32', found '[*c]u8'",
+ ".tmp_source.zig:11:19: note: pointer type child 'u8' cannot cast into pointer type child 'u32'",
+ ".tmp_source.zig:15:22: error: cast increases pointer alignment",
+ ".tmp_source.zig:19:21: error: cast discards const qualifier",
+ ".tmp_source.zig:23:22: error: expected type '[*c]u32', found '*u8'",
+ );
+
cases.addTest(
"implicit casting null c pointer to zig pointer",
\\comptime {
@@ -39,6 +75,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
+ ".tmp_source.zig:6:24: note: pointer type child '[*c]const u8' cannot cast into pointer type child '[*]const u8'",
".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",
From 52c03de5c2495b369ae730ff203e5342e4f33a36 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 13:07:51 -0500
Subject: [PATCH 193/218] add missing compile error for OpaqueType inside
structs/unions
closes #1862
---
src/analyze.cpp | 14 ++++++++++++++
test/compile_errors.zig | 21 +++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 6a8090a843..90ce3d3371 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -2679,6 +2679,13 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
buf_sprintf("enums, not structs, support field assignment"));
}
+ if (field_type->id == ZigTypeIdOpaque) {
+ add_node_error(g, field_node->data.struct_field.type,
+ buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in structs"));
+ struct_type->data.structure.resolve_status = ResolveStatusInvalid;
+ continue;
+ }
+
switch (type_requires_comptime(g, field_type)) {
case ReqCompTimeYes:
struct_type->data.structure.requires_comptime = true;
@@ -2963,6 +2970,13 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
}
union_field->type_entry = field_type;
+ if (field_type->id == ZigTypeIdOpaque) {
+ add_node_error(g, field_node->data.struct_field.type,
+ buf_sprintf("opaque types have unknown size and therefore cannot be directly embedded in unions"));
+ union_type->data.unionation.is_invalid = true;
+ continue;
+ }
+
switch (type_requires_comptime(g, field_type)) {
case ReqCompTimeInvalid:
union_type->data.unionation.is_invalid = true;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 630386aa4f..ac8d413d2c 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,27 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "directly embedding opaque type in struct and union",
+ \\const O = @OpaqueType();
+ \\const Foo = struct {
+ \\ o: O,
+ \\};
+ \\const Bar = union {
+ \\ One: i32,
+ \\ Two: O,
+ \\};
+ \\export fn a() void {
+ \\ var foo: Foo = undefined;
+ \\}
+ \\export fn b() void {
+ \\ var bar: Bar = undefined;
+ \\}
+ ,
+ ".tmp_source.zig:3:8: error: opaque types have unknown size and therefore cannot be directly embedded in structs",
+ ".tmp_source.zig:7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions",
+ );
+
cases.addTest(
"implicit cast between C pointer and Zig pointer - bad const/align/child",
\\export fn a() void {
From 6769183a9d5f5ec69747f46d4d13c0f8709b2f46 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 15:48:28 -0500
Subject: [PATCH 194/218] fix implicit cast error unions with non-optional to
optional pointer
and update self hosted compiler for C pointers
See #1059
---
doc/docgen.zig | 1 +
src-self-hosted/codegen.zig | 42 +++----
src-self-hosted/compilation.zig | 22 ++--
src-self-hosted/ir.zig | 20 ++--
src-self-hosted/llvm.zig | 181 +++++++++++++++++++++---------
src-self-hosted/scope.zig | 2 +-
src-self-hosted/target.zig | 4 +-
src-self-hosted/type.zig | 42 +++----
src-self-hosted/value.zig | 16 +--
src/ir.cpp | 2 +-
std/hash_map.zig | 2 +
test/compile_errors.zig | 8 +-
test/stage1/behavior/pointers.zig | 17 +++
13 files changed, 228 insertions(+), 131 deletions(-)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 45f6dc2684..082f308a57 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -916,6 +916,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
std.zig.Token.Id.AngleBracketAngleBracketRightEqual,
std.zig.Token.Id.Tilde,
std.zig.Token.Id.BracketStarBracket,
+ std.zig.Token.Id.BracketStarCBracket,
=> try writeEscaped(out, src[token.start..token.end]),
std.zig.Token.Id.Invalid => return parseError(
diff --git a/src-self-hosted/codegen.zig b/src-self-hosted/codegen.zig
index 45cfa98942..1c671b61e2 100644
--- a/src-self-hosted/codegen.zig
+++ b/src-self-hosted/codegen.zig
@@ -137,10 +137,10 @@ pub async fn renderToLlvm(comp: *Compilation, fn_val: *Value.Fn, code: *ir.Code)
pub const ObjectFile = struct {
comp: *Compilation,
- module: llvm.ModuleRef,
- builder: llvm.BuilderRef,
+ module: *llvm.Module,
+ builder: *llvm.Builder,
dibuilder: *llvm.DIBuilder,
- context: llvm.ContextRef,
+ context: *llvm.Context,
lock: event.Lock,
arena: *std.mem.Allocator,
@@ -323,7 +323,7 @@ pub fn renderToLlvmModule(ofile: *ObjectFile, fn_val: *Value.Fn, code: *ir.Code)
fn addLLVMAttr(
ofile: *ObjectFile,
- val: llvm.ValueRef,
+ val: *llvm.Value,
attr_index: llvm.AttributeIndex,
attr_name: []const u8,
) !void {
@@ -335,7 +335,7 @@ fn addLLVMAttr(
fn addLLVMAttrStr(
ofile: *ObjectFile,
- val: llvm.ValueRef,
+ val: *llvm.Value,
attr_index: llvm.AttributeIndex,
attr_name: []const u8,
attr_val: []const u8,
@@ -351,7 +351,7 @@ fn addLLVMAttrStr(
}
fn addLLVMAttrInt(
- val: llvm.ValueRef,
+ val: *llvm.Value,
attr_index: llvm.AttributeIndex,
attr_name: []const u8,
attr_val: u64,
@@ -362,25 +362,25 @@ fn addLLVMAttrInt(
llvm.AddAttributeAtIndex(val, attr_index, llvm_attr);
}
-fn addLLVMFnAttr(ofile: *ObjectFile, fn_val: llvm.ValueRef, attr_name: []const u8) !void {
+fn addLLVMFnAttr(ofile: *ObjectFile, fn_val: *llvm.Value, attr_name: []const u8) !void {
return addLLVMAttr(ofile, fn_val, maxInt(llvm.AttributeIndex), attr_name);
}
-fn addLLVMFnAttrStr(ofile: *ObjectFile, fn_val: llvm.ValueRef, attr_name: []const u8, attr_val: []const u8) !void {
+fn addLLVMFnAttrStr(ofile: *ObjectFile, fn_val: *llvm.Value, attr_name: []const u8, attr_val: []const u8) !void {
return addLLVMAttrStr(ofile, fn_val, maxInt(llvm.AttributeIndex), attr_name, attr_val);
}
-fn addLLVMFnAttrInt(ofile: *ObjectFile, fn_val: llvm.ValueRef, attr_name: []const u8, attr_val: u64) !void {
+fn addLLVMFnAttrInt(ofile: *ObjectFile, fn_val: *llvm.Value, attr_name: []const u8, attr_val: u64) !void {
return addLLVMAttrInt(ofile, fn_val, maxInt(llvm.AttributeIndex), attr_name, attr_val);
}
fn renderLoadUntyped(
ofile: *ObjectFile,
- ptr: llvm.ValueRef,
+ ptr: *llvm.Value,
alignment: Type.Pointer.Align,
vol: Type.Pointer.Vol,
name: [*]const u8,
-) !llvm.ValueRef {
+) !*llvm.Value {
const result = llvm.BuildLoad(ofile.builder, ptr, name) orelse return error.OutOfMemory;
switch (vol) {
Type.Pointer.Vol.Non => {},
@@ -390,11 +390,11 @@ fn renderLoadUntyped(
return result;
}
-fn renderLoad(ofile: *ObjectFile, ptr: llvm.ValueRef, ptr_type: *Type.Pointer, name: [*]const u8) !llvm.ValueRef {
+fn renderLoad(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer, name: [*]const u8) !*llvm.Value {
return renderLoadUntyped(ofile, ptr, ptr_type.key.alignment, ptr_type.key.vol, name);
}
-pub fn getHandleValue(ofile: *ObjectFile, ptr: llvm.ValueRef, ptr_type: *Type.Pointer) !?llvm.ValueRef {
+pub fn getHandleValue(ofile: *ObjectFile, ptr: *llvm.Value, ptr_type: *Type.Pointer) !?*llvm.Value {
const child_type = ptr_type.key.child_type;
if (!child_type.hasBits()) {
return null;
@@ -407,11 +407,11 @@ pub fn getHandleValue(ofile: *ObjectFile, ptr: llvm.ValueRef, ptr_type: *Type.Po
pub fn renderStoreUntyped(
ofile: *ObjectFile,
- value: llvm.ValueRef,
- ptr: llvm.ValueRef,
+ value: *llvm.Value,
+ ptr: *llvm.Value,
alignment: Type.Pointer.Align,
vol: Type.Pointer.Vol,
-) !llvm.ValueRef {
+) !*llvm.Value {
const result = llvm.BuildStore(ofile.builder, value, ptr) orelse return error.OutOfMemory;
switch (vol) {
Type.Pointer.Vol.Non => {},
@@ -423,10 +423,10 @@ pub fn renderStoreUntyped(
pub fn renderStore(
ofile: *ObjectFile,
- value: llvm.ValueRef,
- ptr: llvm.ValueRef,
+ value: *llvm.Value,
+ ptr: *llvm.Value,
ptr_type: *Type.Pointer,
-) !llvm.ValueRef {
+) !*llvm.Value {
return renderStoreUntyped(ofile, value, ptr, ptr_type.key.alignment, ptr_type.key.vol);
}
@@ -435,7 +435,7 @@ pub fn renderAlloca(
var_type: *Type,
name: []const u8,
alignment: Type.Pointer.Align,
-) !llvm.ValueRef {
+) !*llvm.Value {
const llvm_var_type = try var_type.getLlvmType(ofile.arena, ofile.context);
const name_with_null = try std.cstr.addNullByte(ofile.arena, name);
const result = llvm.BuildAlloca(ofile.builder, llvm_var_type, name_with_null.ptr) orelse return error.OutOfMemory;
@@ -443,7 +443,7 @@ pub fn renderAlloca(
return result;
}
-pub fn resolveAlign(ofile: *ObjectFile, alignment: Type.Pointer.Align, llvm_type: llvm.TypeRef) u32 {
+pub fn resolveAlign(ofile: *ObjectFile, alignment: Type.Pointer.Align, llvm_type: *llvm.Type) u32 {
return switch (alignment) {
Type.Pointer.Align.Abi => return llvm.ABIAlignmentOfType(ofile.comp.target_data_ref, llvm_type),
Type.Pointer.Align.Override => |a| a,
diff --git a/src-self-hosted/compilation.zig b/src-self-hosted/compilation.zig
index e55d8ccda6..de956f1525 100644
--- a/src-self-hosted/compilation.zig
+++ b/src-self-hosted/compilation.zig
@@ -37,7 +37,7 @@ const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
/// Data that is local to the event loop.
pub const ZigCompiler = struct {
loop: *event.Loop,
- llvm_handle_pool: std.atomic.Stack(llvm.ContextRef),
+ llvm_handle_pool: std.atomic.Stack(*llvm.Context),
lld_lock: event.Lock,
/// TODO pool these so that it doesn't have to lock
@@ -60,7 +60,7 @@ pub const ZigCompiler = struct {
return ZigCompiler{
.loop = loop,
.lld_lock = event.Lock.init(loop),
- .llvm_handle_pool = std.atomic.Stack(llvm.ContextRef).init(),
+ .llvm_handle_pool = std.atomic.Stack(*llvm.Context).init(),
.prng = event.Locked(std.rand.DefaultPrng).init(loop, std.rand.DefaultPrng.init(seed)),
.native_libc = event.Future(LibCInstallation).init(loop),
};
@@ -70,7 +70,7 @@ pub const ZigCompiler = struct {
fn deinit(self: *ZigCompiler) void {
self.lld_lock.deinit();
while (self.llvm_handle_pool.pop()) |node| {
- c.LLVMContextDispose(node.data);
+ llvm.ContextDispose(node.data);
self.loop.allocator.destroy(node);
}
}
@@ -80,11 +80,11 @@ pub const ZigCompiler = struct {
pub fn getAnyLlvmContext(self: *ZigCompiler) !LlvmHandle {
if (self.llvm_handle_pool.pop()) |node| return LlvmHandle{ .node = node };
- const context_ref = c.LLVMContextCreate() orelse return error.OutOfMemory;
- errdefer c.LLVMContextDispose(context_ref);
+ const context_ref = llvm.ContextCreate() orelse return error.OutOfMemory;
+ errdefer llvm.ContextDispose(context_ref);
- const node = try self.loop.allocator.create(std.atomic.Stack(llvm.ContextRef).Node);
- node.* = std.atomic.Stack(llvm.ContextRef).Node{
+ const node = try self.loop.allocator.create(std.atomic.Stack(*llvm.Context).Node);
+ node.* = std.atomic.Stack(*llvm.Context).Node{
.next = undefined,
.data = context_ref,
};
@@ -114,7 +114,7 @@ pub const ZigCompiler = struct {
};
pub const LlvmHandle = struct {
- node: *std.atomic.Stack(llvm.ContextRef).Node,
+ node: *std.atomic.Stack(*llvm.Context).Node,
pub fn release(self: LlvmHandle, zig_compiler: *ZigCompiler) void {
zig_compiler.llvm_handle_pool.push(self.node);
@@ -128,7 +128,7 @@ pub const Compilation = struct {
llvm_triple: Buffer,
root_src_path: ?[]const u8,
target: Target,
- llvm_target: llvm.TargetRef,
+ llvm_target: *llvm.Target,
build_mode: builtin.Mode,
zig_lib_dir: []const u8,
zig_std_dir: []const u8,
@@ -212,8 +212,8 @@ pub const Compilation = struct {
false_value: *Value.Bool,
noreturn_value: *Value.NoReturn,
- target_machine: llvm.TargetMachineRef,
- target_data_ref: llvm.TargetDataRef,
+ target_machine: *llvm.TargetMachine,
+ target_data_ref: *llvm.TargetData,
target_layout_str: [*]u8,
target_ptr_bits: u32,
diff --git a/src-self-hosted/ir.zig b/src-self-hosted/ir.zig
index 0362bb4ef8..dc1b0dc943 100644
--- a/src-self-hosted/ir.zig
+++ b/src-self-hosted/ir.zig
@@ -67,7 +67,7 @@ pub const Inst = struct {
parent: ?*Inst,
/// populated durign codegen
- llvm_value: ?llvm.ValueRef,
+ llvm_value: ?*llvm.Value,
pub fn cast(base: *Inst, comptime T: type) ?*T {
if (base.id == comptime typeToId(T)) {
@@ -129,7 +129,7 @@ pub const Inst = struct {
}
}
- pub fn render(base: *Inst, ofile: *ObjectFile, fn_val: *Value.Fn) (error{OutOfMemory}!?llvm.ValueRef) {
+ pub fn render(base: *Inst, ofile: *ObjectFile, fn_val: *Value.Fn) (error{OutOfMemory}!?*llvm.Value) {
switch (base.id) {
Id.Return => return @fieldParentPtr(Return, "base", base).render(ofile, fn_val),
Id.Const => return @fieldParentPtr(Const, "base", base).render(ofile, fn_val),
@@ -313,10 +313,10 @@ pub const Inst = struct {
return new_inst;
}
- pub fn render(self: *Call, ofile: *ObjectFile, fn_val: *Value.Fn) !?llvm.ValueRef {
+ pub fn render(self: *Call, ofile: *ObjectFile, fn_val: *Value.Fn) !?*llvm.Value {
const fn_ref = self.params.fn_ref.llvm_value.?;
- const args = try ofile.arena.alloc(llvm.ValueRef, self.params.args.len);
+ const args = try ofile.arena.alloc(*llvm.Value, self.params.args.len);
for (self.params.args) |arg, i| {
args[i] = arg.llvm_value.?;
}
@@ -360,7 +360,7 @@ pub const Inst = struct {
return new_inst;
}
- pub fn render(self: *Const, ofile: *ObjectFile, fn_val: *Value.Fn) !?llvm.ValueRef {
+ pub fn render(self: *Const, ofile: *ObjectFile, fn_val: *Value.Fn) !?*llvm.Value {
return self.base.val.KnownValue.getLlvmConst(ofile);
}
};
@@ -392,7 +392,7 @@ pub const Inst = struct {
return ira.irb.build(Return, self.base.scope, self.base.span, Params{ .return_value = casted_value });
}
- pub fn render(self: *Return, ofile: *ObjectFile, fn_val: *Value.Fn) !?llvm.ValueRef {
+ pub fn render(self: *Return, ofile: *ObjectFile, fn_val: *Value.Fn) !?*llvm.Value {
const value = self.params.return_value.llvm_value;
const return_type = self.params.return_value.getKnownType();
@@ -540,7 +540,7 @@ pub const Inst = struct {
}
}
- pub fn render(self: *VarPtr, ofile: *ObjectFile, fn_val: *Value.Fn) llvm.ValueRef {
+ pub fn render(self: *VarPtr, ofile: *ObjectFile, fn_val: *Value.Fn) *llvm.Value {
switch (self.params.var_scope.data) {
Scope.Var.Data.Const => unreachable, // turned into Inst.Const in analyze pass
Scope.Var.Data.Param => |param| return param.llvm_value,
@@ -596,7 +596,7 @@ pub const Inst = struct {
return new_inst;
}
- pub fn render(self: *LoadPtr, ofile: *ObjectFile, fn_val: *Value.Fn) !?llvm.ValueRef {
+ pub fn render(self: *LoadPtr, ofile: *ObjectFile, fn_val: *Value.Fn) !?*llvm.Value {
const child_type = self.base.getKnownType();
if (!child_type.hasBits()) {
return null;
@@ -935,8 +935,8 @@ pub const BasicBlock = struct {
ref_instruction: ?*Inst,
/// for codegen
- llvm_block: llvm.BasicBlockRef,
- llvm_exit_block: llvm.BasicBlockRef,
+ llvm_block: *llvm.BasicBlock,
+ llvm_exit_block: *llvm.BasicBlock,
/// the basic block that is derived from this one in analysis
child: ?*BasicBlock,
diff --git a/src-self-hosted/llvm.zig b/src-self-hosted/llvm.zig
index 778d3fae07..704e83c3c6 100644
--- a/src-self-hosted/llvm.zig
+++ b/src-self-hosted/llvm.zig
@@ -11,45 +11,31 @@ const assert = @import("std").debug.assert;
pub const AttributeIndex = c_uint;
pub const Bool = c_int;
-pub const BuilderRef = removeNullability(c.LLVMBuilderRef);
-pub const ContextRef = removeNullability(c.LLVMContextRef);
-pub const ModuleRef = removeNullability(c.LLVMModuleRef);
-pub const ValueRef = removeNullability(c.LLVMValueRef);
-pub const TypeRef = removeNullability(c.LLVMTypeRef);
-pub const BasicBlockRef = removeNullability(c.LLVMBasicBlockRef);
-pub const AttributeRef = removeNullability(c.LLVMAttributeRef);
-pub const TargetRef = removeNullability(c.LLVMTargetRef);
-pub const TargetMachineRef = removeNullability(c.LLVMTargetMachineRef);
-pub const TargetDataRef = removeNullability(c.LLVMTargetDataRef);
+pub const Builder = c.LLVMBuilderRef.Child;
+pub const Context = c.LLVMContextRef.Child;
+pub const Module = c.LLVMModuleRef.Child;
+pub const Value = c.LLVMValueRef.Child;
+pub const Type = c.LLVMTypeRef.Child;
+pub const BasicBlock = c.LLVMBasicBlockRef.Child;
+pub const Attribute = c.LLVMAttributeRef.Child;
+pub const Target = c.LLVMTargetRef.Child;
+pub const TargetMachine = c.LLVMTargetMachineRef.Child;
+pub const TargetData = c.LLVMTargetDataRef.Child;
pub const DIBuilder = c.ZigLLVMDIBuilder;
+pub const DIFile = c.ZigLLVMDIFile;
+pub const DICompileUnit = c.ZigLLVMDICompileUnit;
pub const ABIAlignmentOfType = c.LLVMABIAlignmentOfType;
pub const AddAttributeAtIndex = c.LLVMAddAttributeAtIndex;
-pub const AddFunction = c.LLVMAddFunction;
-pub const AddGlobal = c.LLVMAddGlobal;
pub const AddModuleCodeViewFlag = c.ZigLLVMAddModuleCodeViewFlag;
pub const AddModuleDebugInfoFlag = c.ZigLLVMAddModuleDebugInfoFlag;
-pub const ArrayType = c.LLVMArrayType;
-pub const BuildLoad = c.LLVMBuildLoad;
pub const ClearCurrentDebugLocation = c.ZigLLVMClearCurrentDebugLocation;
pub const ConstAllOnes = c.LLVMConstAllOnes;
pub const ConstArray = c.LLVMConstArray;
pub const ConstBitCast = c.LLVMConstBitCast;
-pub const ConstInt = c.LLVMConstInt;
pub const ConstIntOfArbitraryPrecision = c.LLVMConstIntOfArbitraryPrecision;
pub const ConstNeg = c.LLVMConstNeg;
-pub const ConstNull = c.LLVMConstNull;
-pub const ConstStringInContext = c.LLVMConstStringInContext;
pub const ConstStructInContext = c.LLVMConstStructInContext;
-pub const CopyStringRepOfTargetData = c.LLVMCopyStringRepOfTargetData;
-pub const CreateBuilderInContext = c.LLVMCreateBuilderInContext;
-pub const CreateCompileUnit = c.ZigLLVMCreateCompileUnit;
-pub const CreateDIBuilder = c.ZigLLVMCreateDIBuilder;
-pub const CreateEnumAttribute = c.LLVMCreateEnumAttribute;
-pub const CreateFile = c.ZigLLVMCreateFile;
-pub const CreateStringAttribute = c.LLVMCreateStringAttribute;
-pub const CreateTargetDataLayout = c.LLVMCreateTargetDataLayout;
-pub const CreateTargetMachine = c.LLVMCreateTargetMachine;
pub const DIBuilderFinalize = c.ZigLLVMDIBuilderFinalize;
pub const DisposeBuilder = c.LLVMDisposeBuilder;
pub const DisposeDIBuilder = c.ZigLLVMDisposeDIBuilder;
@@ -62,9 +48,7 @@ pub const DumpModule = c.LLVMDumpModule;
pub const FP128TypeInContext = c.LLVMFP128TypeInContext;
pub const FloatTypeInContext = c.LLVMFloatTypeInContext;
pub const GetEnumAttributeKindForName = c.LLVMGetEnumAttributeKindForName;
-pub const GetHostCPUName = c.ZigLLVMGetHostCPUName;
pub const GetMDKindIDInContext = c.LLVMGetMDKindIDInContext;
-pub const GetNativeFeatures = c.ZigLLVMGetNativeFeatures;
pub const GetUndef = c.LLVMGetUndef;
pub const HalfTypeInContext = c.LLVMHalfTypeInContext;
pub const InitializeAllAsmParsers = c.LLVMInitializeAllAsmParsers;
@@ -81,14 +65,11 @@ pub const Int64TypeInContext = c.LLVMInt64TypeInContext;
pub const Int8TypeInContext = c.LLVMInt8TypeInContext;
pub const IntPtrTypeForASInContext = c.LLVMIntPtrTypeForASInContext;
pub const IntPtrTypeInContext = c.LLVMIntPtrTypeInContext;
-pub const IntTypeInContext = c.LLVMIntTypeInContext;
pub const LabelTypeInContext = c.LLVMLabelTypeInContext;
pub const MDNodeInContext = c.LLVMMDNodeInContext;
pub const MDStringInContext = c.LLVMMDStringInContext;
pub const MetadataTypeInContext = c.LLVMMetadataTypeInContext;
-pub const ModuleCreateWithNameInContext = c.LLVMModuleCreateWithNameInContext;
pub const PPCFP128TypeInContext = c.LLVMPPCFP128TypeInContext;
-pub const PointerType = c.LLVMPointerType;
pub const SetAlignment = c.LLVMSetAlignment;
pub const SetDataLayout = c.LLVMSetDataLayout;
pub const SetGlobalConstant = c.LLVMSetGlobalConstant;
@@ -99,50 +80,146 @@ pub const SetUnnamedAddr = c.LLVMSetUnnamedAddr;
pub const SetVolatile = c.LLVMSetVolatile;
pub const StructTypeInContext = c.LLVMStructTypeInContext;
pub const TokenTypeInContext = c.LLVMTokenTypeInContext;
-pub const VoidTypeInContext = c.LLVMVoidTypeInContext;
pub const X86FP80TypeInContext = c.LLVMX86FP80TypeInContext;
pub const X86MMXTypeInContext = c.LLVMX86MMXTypeInContext;
+pub const AddGlobal = LLVMAddGlobal;
+extern fn LLVMAddGlobal(M: *Module, Ty: *Type, Name: [*]const u8) ?*Value;
+
+pub const ConstStringInContext = LLVMConstStringInContext;
+extern fn LLVMConstStringInContext(C: *Context, Str: [*]const u8, Length: c_uint, DontNullTerminate: Bool) ?*Value;
+
+pub const ConstInt = LLVMConstInt;
+extern fn LLVMConstInt(IntTy: *Type, N: c_ulonglong, SignExtend: Bool) ?*Value;
+
+pub const BuildLoad = LLVMBuildLoad;
+extern fn LLVMBuildLoad(arg0: *Builder, PointerVal: *Value, Name: [*]const u8) ?*Value;
+
+pub const ConstNull = LLVMConstNull;
+extern fn LLVMConstNull(Ty: *Type) ?*Value;
+
+pub const CreateStringAttribute = LLVMCreateStringAttribute;
+extern fn LLVMCreateStringAttribute(
+ C: *Context,
+ K: [*]const u8,
+ KLength: c_uint,
+ V: [*]const u8,
+ VLength: c_uint,
+) ?*Attribute;
+
+pub const CreateEnumAttribute = LLVMCreateEnumAttribute;
+extern fn LLVMCreateEnumAttribute(C: *Context, KindID: c_uint, Val: u64) ?*Attribute;
+
+pub const AddFunction = LLVMAddFunction;
+extern fn LLVMAddFunction(M: *Module, Name: [*]const u8, FunctionTy: *Type) ?*Value;
+
+pub const CreateCompileUnit = ZigLLVMCreateCompileUnit;
+extern fn ZigLLVMCreateCompileUnit(
+ dibuilder: *DIBuilder,
+ lang: c_uint,
+ difile: *DIFile,
+ producer: [*]const u8,
+ is_optimized: bool,
+ flags: [*]const u8,
+ runtime_version: c_uint,
+ split_name: [*]const u8,
+ dwo_id: u64,
+ emit_debug_info: bool,
+) ?*DICompileUnit;
+
+pub const CreateFile = ZigLLVMCreateFile;
+extern fn ZigLLVMCreateFile(dibuilder: *DIBuilder, filename: [*]const u8, directory: [*]const u8) ?*DIFile;
+
+pub const ArrayType = LLVMArrayType;
+extern fn LLVMArrayType(ElementType: *Type, ElementCount: c_uint) ?*Type;
+
+pub const CreateDIBuilder = ZigLLVMCreateDIBuilder;
+extern fn ZigLLVMCreateDIBuilder(module: *Module, allow_unresolved: bool) ?*DIBuilder;
+
+pub const PointerType = LLVMPointerType;
+extern fn LLVMPointerType(ElementType: *Type, AddressSpace: c_uint) ?*Type;
+
+pub const CreateBuilderInContext = LLVMCreateBuilderInContext;
+extern fn LLVMCreateBuilderInContext(C: *Context) ?*Builder;
+
+pub const IntTypeInContext = LLVMIntTypeInContext;
+extern fn LLVMIntTypeInContext(C: *Context, NumBits: c_uint) ?*Type;
+
+pub const ModuleCreateWithNameInContext = LLVMModuleCreateWithNameInContext;
+extern fn LLVMModuleCreateWithNameInContext(ModuleID: [*]const u8, C: *Context) ?*Module;
+
+pub const VoidTypeInContext = LLVMVoidTypeInContext;
+extern fn LLVMVoidTypeInContext(C: *Context) ?*Type;
+
+pub const ContextCreate = LLVMContextCreate;
+extern fn LLVMContextCreate() ?*Context;
+
+pub const ContextDispose = LLVMContextDispose;
+extern fn LLVMContextDispose(C: *Context) void;
+
+pub const CopyStringRepOfTargetData = LLVMCopyStringRepOfTargetData;
+extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) ?[*]u8;
+
+pub const CreateTargetDataLayout = LLVMCreateTargetDataLayout;
+extern fn LLVMCreateTargetDataLayout(T: *TargetMachine) ?*TargetData;
+
+pub const CreateTargetMachine = LLVMCreateTargetMachine;
+extern fn LLVMCreateTargetMachine(
+ T: *Target,
+ Triple: [*]const u8,
+ CPU: [*]const u8,
+ Features: [*]const u8,
+ Level: CodeGenOptLevel,
+ Reloc: RelocMode,
+ CodeModel: CodeModel,
+) ?*TargetMachine;
+
+pub const GetHostCPUName = LLVMGetHostCPUName;
+extern fn LLVMGetHostCPUName() ?[*]u8;
+
+pub const GetNativeFeatures = ZigLLVMGetNativeFeatures;
+extern fn ZigLLVMGetNativeFeatures() ?[*]u8;
+
pub const GetElementType = LLVMGetElementType;
-extern fn LLVMGetElementType(Ty: TypeRef) TypeRef;
+extern fn LLVMGetElementType(Ty: *Type) *Type;
pub const TypeOf = LLVMTypeOf;
-extern fn LLVMTypeOf(Val: ValueRef) TypeRef;
+extern fn LLVMTypeOf(Val: *Value) *Type;
pub const BuildStore = LLVMBuildStore;
-extern fn LLVMBuildStore(arg0: BuilderRef, Val: ValueRef, Ptr: ValueRef) ?ValueRef;
+extern fn LLVMBuildStore(arg0: *Builder, Val: *Value, Ptr: *Value) ?*Value;
pub const BuildAlloca = LLVMBuildAlloca;
-extern fn LLVMBuildAlloca(arg0: BuilderRef, Ty: TypeRef, Name: ?[*]const u8) ?ValueRef;
+extern fn LLVMBuildAlloca(arg0: *Builder, Ty: *Type, Name: ?[*]const u8) ?*Value;
pub const ConstInBoundsGEP = LLVMConstInBoundsGEP;
-pub extern fn LLVMConstInBoundsGEP(ConstantVal: ValueRef, ConstantIndices: [*]ValueRef, NumIndices: c_uint) ?ValueRef;
+pub extern fn LLVMConstInBoundsGEP(ConstantVal: *Value, ConstantIndices: [*]*Value, NumIndices: c_uint) ?*Value;
pub const GetTargetFromTriple = LLVMGetTargetFromTriple;
-extern fn LLVMGetTargetFromTriple(Triple: [*]const u8, T: *TargetRef, ErrorMessage: ?*[*]u8) Bool;
+extern fn LLVMGetTargetFromTriple(Triple: [*]const u8, T: **Target, ErrorMessage: ?*[*]u8) Bool;
pub const VerifyModule = LLVMVerifyModule;
-extern fn LLVMVerifyModule(M: ModuleRef, Action: VerifierFailureAction, OutMessage: *?[*]u8) Bool;
+extern fn LLVMVerifyModule(M: *Module, Action: VerifierFailureAction, OutMessage: *?[*]u8) Bool;
pub const GetInsertBlock = LLVMGetInsertBlock;
-extern fn LLVMGetInsertBlock(Builder: BuilderRef) BasicBlockRef;
+extern fn LLVMGetInsertBlock(Builder: *Builder) *BasicBlock;
pub const FunctionType = LLVMFunctionType;
extern fn LLVMFunctionType(
- ReturnType: TypeRef,
- ParamTypes: [*]TypeRef,
+ ReturnType: *Type,
+ ParamTypes: [*]*Type,
ParamCount: c_uint,
IsVarArg: Bool,
-) ?TypeRef;
+) ?*Type;
pub const GetParam = LLVMGetParam;
-extern fn LLVMGetParam(Fn: ValueRef, Index: c_uint) ValueRef;
+extern fn LLVMGetParam(Fn: *Value, Index: c_uint) *Value;
pub const AppendBasicBlockInContext = LLVMAppendBasicBlockInContext;
-extern fn LLVMAppendBasicBlockInContext(C: ContextRef, Fn: ValueRef, Name: [*]const u8) ?BasicBlockRef;
+extern fn LLVMAppendBasicBlockInContext(C: *Context, Fn: *Value, Name: [*]const u8) ?*BasicBlock;
pub const PositionBuilderAtEnd = LLVMPositionBuilderAtEnd;
-extern fn LLVMPositionBuilderAtEnd(Builder: BuilderRef, Block: BasicBlockRef) void;
+extern fn LLVMPositionBuilderAtEnd(Builder: *Builder, Block: *BasicBlock) void;
pub const AbortProcessAction = VerifierFailureAction.LLVMAbortProcessAction;
pub const PrintMessageAction = VerifierFailureAction.LLVMPrintMessageAction;
@@ -190,17 +267,17 @@ pub const FnInline = extern enum {
};
fn removeNullability(comptime T: type) type {
- comptime assert(@typeId(T) == builtin.TypeId.Optional);
- return T.Child;
+ comptime assert(@typeInfo(T).Pointer.size == @import("builtin").TypeInfo.Pointer.Size.C);
+ return *T.Child;
}
pub const BuildRet = LLVMBuildRet;
-extern fn LLVMBuildRet(arg0: BuilderRef, V: ?ValueRef) ?ValueRef;
+extern fn LLVMBuildRet(arg0: *Builder, V: ?*Value) ?*Value;
pub const TargetMachineEmitToFile = ZigLLVMTargetMachineEmitToFile;
extern fn ZigLLVMTargetMachineEmitToFile(
- targ_machine_ref: TargetMachineRef,
- module_ref: ModuleRef,
+ targ_machine_ref: *TargetMachine,
+ module_ref: *Module,
filename: [*]const u8,
output_type: EmitOutputType,
error_message: *[*]u8,
@@ -209,6 +286,6 @@ extern fn ZigLLVMTargetMachineEmitToFile(
) bool;
pub const BuildCall = ZigLLVMBuildCall;
-extern fn ZigLLVMBuildCall(B: BuilderRef, Fn: ValueRef, Args: [*]ValueRef, NumArgs: c_uint, CC: c_uint, fn_inline: FnInline, Name: [*]const u8) ?ValueRef;
+extern fn ZigLLVMBuildCall(B: *Builder, Fn: *Value, Args: [*]*Value, NumArgs: c_uint, CC: c_uint, fn_inline: FnInline, Name: [*]const u8) ?*Value;
pub const PrivateLinkage = c.LLVMLinkage.LLVMPrivateLinkage;
diff --git a/src-self-hosted/scope.zig b/src-self-hosted/scope.zig
index b14c073a9e..9a84ad256e 100644
--- a/src-self-hosted/scope.zig
+++ b/src-self-hosted/scope.zig
@@ -362,7 +362,7 @@ pub const Scope = struct {
pub const Param = struct {
index: usize,
typ: *Type,
- llvm_value: llvm.ValueRef,
+ llvm_value: *llvm.Value,
};
pub fn createParam(
diff --git a/src-self-hosted/target.zig b/src-self-hosted/target.zig
index 36381b820d..121242b505 100644
--- a/src-self-hosted/target.zig
+++ b/src-self-hosted/target.zig
@@ -457,8 +457,8 @@ pub const Target = union(enum) {
}
}
- pub fn llvmTargetFromTriple(triple: std.Buffer) !llvm.TargetRef {
- var result: llvm.TargetRef = undefined;
+ pub fn llvmTargetFromTriple(triple: std.Buffer) !*llvm.Target {
+ var result: *llvm.Target = undefined;
var err_msg: [*]u8 = undefined;
if (llvm.GetTargetFromTriple(triple.ptr(), &result, &err_msg) != 0) {
std.debug.warn("triple: {s} error: {s}\n", triple.ptr(), err_msg);
diff --git a/src-self-hosted/type.zig b/src-self-hosted/type.zig
index 790b51b7be..7d611bb787 100644
--- a/src-self-hosted/type.zig
+++ b/src-self-hosted/type.zig
@@ -51,8 +51,8 @@ pub const Type = struct {
pub fn getLlvmType(
base: *Type,
allocator: *Allocator,
- llvm_context: llvm.ContextRef,
- ) (error{OutOfMemory}!llvm.TypeRef) {
+ llvm_context: *llvm.Context,
+ ) (error{OutOfMemory}!*llvm.Type) {
switch (base.id) {
Id.Struct => return @fieldParentPtr(Struct, "base", base).getLlvmType(allocator, llvm_context),
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmType(allocator, llvm_context),
@@ -196,7 +196,7 @@ pub const Type = struct {
}
/// If you have an llvm conext handy, you can use it here.
- pub async fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: llvm.ContextRef) !u32 {
+ pub async fn getAbiAlignmentInContext(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
if (await (async base.abi_alignment.start() catch unreachable)) |ptr| return ptr.*;
base.abi_alignment.data = await (async base.resolveAbiAlignment(comp, llvm_context) catch unreachable);
@@ -205,7 +205,7 @@ pub const Type = struct {
}
/// Lower level function that does the work. See getAbiAlignment.
- async fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: llvm.ContextRef) !u32 {
+ async fn resolveAbiAlignment(base: *Type, comp: *Compilation, llvm_context: *llvm.Context) !u32 {
const llvm_type = try base.getLlvmType(comp.gpa(), llvm_context);
return @intCast(u32, llvm.ABIAlignmentOfType(comp.target_data_ref, llvm_type));
}
@@ -218,7 +218,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Struct, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Struct, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -496,13 +496,13 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Fn, allocator: *Allocator, llvm_context: llvm.ContextRef) !llvm.TypeRef {
+ pub fn getLlvmType(self: *Fn, allocator: *Allocator, llvm_context: *llvm.Context) !*llvm.Type {
const normal = &self.key.data.Normal;
const llvm_return_type = switch (normal.return_type.id) {
Type.Id.Void => llvm.VoidTypeInContext(llvm_context) orelse return error.OutOfMemory,
else => try normal.return_type.getLlvmType(allocator, llvm_context),
};
- const llvm_param_types = try allocator.alloc(llvm.TypeRef, normal.params.len);
+ const llvm_param_types = try allocator.alloc(*llvm.Type, normal.params.len);
defer allocator.free(llvm_param_types);
for (llvm_param_types) |*llvm_param_type, i| {
llvm_param_type.* = try normal.params[i].typ.getLlvmType(allocator, llvm_context);
@@ -559,7 +559,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Bool, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Bool, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -658,7 +658,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Int, allocator: *Allocator, llvm_context: llvm.ContextRef) !llvm.TypeRef {
+ pub fn getLlvmType(self: *Int, allocator: *Allocator, llvm_context: *llvm.Context) !*llvm.Type {
return llvm.IntTypeInContext(llvm_context, self.key.bit_count) orelse return error.OutOfMemory;
}
};
@@ -670,7 +670,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Float, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Float, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -836,7 +836,7 @@ pub const Type = struct {
return self;
}
- pub fn getLlvmType(self: *Pointer, allocator: *Allocator, llvm_context: llvm.ContextRef) !llvm.TypeRef {
+ pub fn getLlvmType(self: *Pointer, allocator: *Allocator, llvm_context: *llvm.Context) !*llvm.Type {
const elem_llvm_type = try self.key.child_type.getLlvmType(allocator, llvm_context);
return llvm.PointerType(elem_llvm_type, 0) orelse return error.OutOfMemory;
}
@@ -904,7 +904,7 @@ pub const Type = struct {
return self;
}
- pub fn getLlvmType(self: *Array, allocator: *Allocator, llvm_context: llvm.ContextRef) !llvm.TypeRef {
+ pub fn getLlvmType(self: *Array, allocator: *Allocator, llvm_context: *llvm.Context) !*llvm.Type {
const elem_llvm_type = try self.key.elem_type.getLlvmType(allocator, llvm_context);
return llvm.ArrayType(elem_llvm_type, @intCast(c_uint, self.key.len)) orelse return error.OutOfMemory;
}
@@ -917,7 +917,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Vector, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Vector, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -967,7 +967,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Optional, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Optional, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -979,7 +979,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *ErrorUnion, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *ErrorUnion, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -991,7 +991,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *ErrorSet, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *ErrorSet, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -1003,7 +1003,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Enum, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Enum, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -1015,7 +1015,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Union, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Union, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -1035,7 +1035,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *BoundFn, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *BoundFn, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -1055,7 +1055,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Opaque, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Opaque, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
@@ -1067,7 +1067,7 @@ pub const Type = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmType(self: *Promise, allocator: *Allocator, llvm_context: llvm.ContextRef) llvm.TypeRef {
+ pub fn getLlvmType(self: *Promise, allocator: *Allocator, llvm_context: *llvm.Context) *llvm.Type {
@panic("TODO");
}
};
diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig
index 9431c614b9..d9d4c3d1d9 100644
--- a/src-self-hosted/value.zig
+++ b/src-self-hosted/value.zig
@@ -57,7 +57,7 @@ pub const Value = struct {
std.debug.warn("{}", @tagName(base.id));
}
- pub fn getLlvmConst(base: *Value, ofile: *ObjectFile) (error{OutOfMemory}!?llvm.ValueRef) {
+ pub fn getLlvmConst(base: *Value, ofile: *ObjectFile) (error{OutOfMemory}!?*llvm.Value) {
switch (base.id) {
Id.Type => unreachable,
Id.Fn => return @fieldParentPtr(Fn, "base", base).getLlvmConst(ofile),
@@ -153,7 +153,7 @@ pub const Value = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmConst(self: *FnProto, ofile: *ObjectFile) !?llvm.ValueRef {
+ pub fn getLlvmConst(self: *FnProto, ofile: *ObjectFile) !?*llvm.Value {
const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
const llvm_fn = llvm.AddFunction(
ofile.module,
@@ -238,7 +238,7 @@ pub const Value = struct {
/// We know that the function definition will end up in an .o file somewhere.
/// Here, all we have to do is generate a global prototype.
/// TODO cache the prototype per ObjectFile
- pub fn getLlvmConst(self: *Fn, ofile: *ObjectFile) !?llvm.ValueRef {
+ pub fn getLlvmConst(self: *Fn, ofile: *ObjectFile) !?*llvm.Value {
const llvm_fn_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
const llvm_fn = llvm.AddFunction(
ofile.module,
@@ -283,7 +283,7 @@ pub const Value = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmConst(self: *Bool, ofile: *ObjectFile) ?llvm.ValueRef {
+ pub fn getLlvmConst(self: *Bool, ofile: *ObjectFile) ?*llvm.Value {
const llvm_type = llvm.Int1TypeInContext(ofile.context);
if (self.x) {
return llvm.ConstAllOnes(llvm_type);
@@ -381,7 +381,7 @@ pub const Value = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmConst(self: *Ptr, ofile: *ObjectFile) !?llvm.ValueRef {
+ pub fn getLlvmConst(self: *Ptr, ofile: *ObjectFile) !?*llvm.Value {
const llvm_type = self.base.typ.getLlvmType(ofile.arena, ofile.context);
// TODO carefully port the logic from codegen.cpp:gen_const_val_ptr
switch (self.special) {
@@ -391,7 +391,7 @@ pub const Value = struct {
const array_llvm_value = (try base_array.val.getLlvmConst(ofile)).?;
const ptr_bit_count = ofile.comp.target_ptr_bits;
const usize_llvm_type = llvm.IntTypeInContext(ofile.context, ptr_bit_count) orelse return error.OutOfMemory;
- const indices = []llvm.ValueRef{
+ const indices = []*llvm.Value{
llvm.ConstNull(usize_llvm_type) orelse return error.OutOfMemory,
llvm.ConstInt(usize_llvm_type, base_array.elem_index, 0) orelse return error.OutOfMemory,
};
@@ -459,7 +459,7 @@ pub const Value = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmConst(self: *Array, ofile: *ObjectFile) !?llvm.ValueRef {
+ pub fn getLlvmConst(self: *Array, ofile: *ObjectFile) !?*llvm.Value {
switch (self.special) {
Special.Undefined => {
const llvm_type = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
@@ -534,7 +534,7 @@ pub const Value = struct {
return self;
}
- pub fn getLlvmConst(self: *Int, ofile: *ObjectFile) !?llvm.ValueRef {
+ pub fn getLlvmConst(self: *Int, ofile: *ObjectFile) !?*llvm.Value {
switch (self.base.typ.id) {
Type.Id.Int => {
const type_ref = try self.base.typ.getLlvmType(ofile.arena, ofile.context);
diff --git a/src/ir.cpp b/src/ir.cpp
index 89528db185..7c46b21717 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8696,7 +8696,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
return result;
}
bool ok_allows_zero = (wanted_allows_zero &&
- (actual_allows_zero || wanted_ptr_type->data.pointer.is_const)) ||
+ (actual_allows_zero || !wanted_is_mutable)) ||
(!wanted_allows_zero && !actual_allows_zero);
if (!ok_allows_zero) {
result.id = ConstCastResultIdBadAllowsZero;
diff --git a/std/hash_map.zig b/std/hash_map.zig
index 716f04ff34..4519890bb7 100644
--- a/std/hash_map.zig
+++ b/std/hash_map.zig
@@ -496,6 +496,7 @@ pub fn autoHash(key: var, comptime rng: *std.rand.Random, comptime HashInt: type
builtin.TypeId.Pointer => |info| switch (info.size) {
builtin.TypeInfo.Pointer.Size.One => @compileError("TODO auto hash for single item pointers"),
builtin.TypeInfo.Pointer.Size.Many => @compileError("TODO auto hash for many item pointers"),
+ builtin.TypeInfo.Pointer.Size.C => @compileError("TODO auto hash C pointers"),
builtin.TypeInfo.Pointer.Size.Slice => {
const interval = std.math.max(1, key.len / 256);
var i: usize = 0;
@@ -543,6 +544,7 @@ pub fn autoEql(a: var, b: @typeOf(a)) bool {
builtin.TypeId.Pointer => |info| switch (info.size) {
builtin.TypeInfo.Pointer.Size.One => @compileError("TODO auto eql for single item pointers"),
builtin.TypeInfo.Pointer.Size.Many => @compileError("TODO auto eql for many item pointers"),
+ builtin.TypeInfo.Pointer.Size.C => @compileError("TODO auto eql for C pointers"),
builtin.TypeInfo.Pointer.Size.Slice => {
if (a.len != b.len) return false;
for (a) |a_item, i| {
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index ac8d413d2c..5e9b691641 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -92,15 +92,15 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var slice: []u8 = &buf;
\\ var opt_many_ptr: [*]u8 = slice.ptr;
\\ var ptr_opt_many_ptr = &opt_many_ptr;
- \\ var c_ptr: [*c]const [*c]u8 = ptr_opt_many_ptr;
+ \\ var c_ptr: [*c][*c]const u8 = ptr_opt_many_ptr;
\\}
,
".tmp_source.zig:6:24: error: expected type '*const [*]const u8', found '[*c]const [*c]const u8'",
".tmp_source.zig:6:24: note: pointer type child '[*c]const u8' cannot cast into pointer type child '[*]const u8'",
".tmp_source.zig:6:24: note: '[*c]const u8' could have null values which are illegal in type '[*]const u8'",
- ".tmp_source.zig:13:35: error: expected type '[*c]const [*c]u8', found '*[*]u8'",
- ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]u8'",
- ".tmp_source.zig:13:35: note: mutable '[*c]u8' allows illegal null values stored to type '[*]u8'",
+ ".tmp_source.zig:13:35: error: expected type '[*c][*c]const u8', found '*[*]u8'",
+ ".tmp_source.zig:13:35: note: pointer type child '[*]u8' cannot cast into pointer type child '[*c]const u8'",
+ ".tmp_source.zig:13:35: note: mutable '[*c]const u8' allows illegal null values stored to type '[*]u8'",
);
cases.addTest(
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 8d87fe2a20..eed7a765d7 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -1,5 +1,6 @@
const std = @import("std");
const expect = std.testing.expect;
+const expectError = std.testing.expectError;
test "dereference pointer" {
comptime testDerefPtr();
@@ -107,3 +108,19 @@ test "implicit casting between C pointer and optional non-C pointer" {
ptr_opt_many_ptr = c_ptr;
expect(ptr_opt_many_ptr.*.?[1] == 'o');
}
+
+test "implicit cast error unions with non-optional to optional pointer" {
+ const S = struct {
+ fn doTheTest() void {
+ expectError(error.Fail, foo());
+ }
+ fn foo() anyerror!?*u8 {
+ return bar() orelse error.Fail;
+ }
+ fn bar() ?*u8 {
+ return null;
+ }
+ };
+ S.doTheTest();
+ comptime S.doTheTest();
+}
From df87044fd6588452755014d5909e0db1b776deb2 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 16:10:12 -0500
Subject: [PATCH 195/218] omit nonnull attribute for C pointers
See #1059
---
src/analyze.cpp | 4 ++++
src/analyze.hpp | 1 +
src/codegen.cpp | 19 ++++++++++++++++---
src/target.cpp | 4 ++++
src/target.hpp | 1 +
5 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 90ce3d3371..55deafb3a8 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -4100,6 +4100,10 @@ ZigType *get_codegen_ptr_type(ZigType *type) {
return ty;
}
+bool type_is_nonnull_ptr(ZigType *type) {
+ return type_is_codegen_pointer(type) && !ptr_allows_addr_zero(type);
+}
+
bool type_is_codegen_pointer(ZigType *type) {
return get_codegen_ptr_type(type) == type;
}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 50e841baa1..845fb62534 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -46,6 +46,7 @@ void find_libc_lib_path(CodeGen *g);
bool type_has_bits(ZigType *type_entry);
bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
bool ptr_allows_addr_zero(ZigType *ptr_type);
+bool type_is_nonnull_ptr(ZigType *type);
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index dbb13ca885..bae9abe06d 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -617,9 +617,10 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
unsigned init_gen_i = 0;
if (!type_has_bits(return_type)) {
// nothing to do
- } else if (type_is_codegen_pointer(return_type)) {
+ } else if (type_is_nonnull_ptr(return_type)) {
addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull");
} else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) {
+ // Sret pointers must not be address 0
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull");
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret");
if (cc_want_sret_attr(cc)) {
@@ -637,6 +638,8 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn_table_entry) {
uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
if (err_ret_trace_arg_index != UINT32_MAX) {
+ // Error return trace memory is in the stack, which is impossible to be at address 0
+ // on any architecture.
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull");
}
@@ -1246,6 +1249,8 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val);
+ // Error return trace memory is in the stack, which is impossible to be at address 0
+ // on any architecture.
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
if (g->build_mode == BuildModeDebug) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
@@ -1320,9 +1325,13 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val);
+ // Error return trace memory is in the stack, which is impossible to be at address 0
+ // on any architecture.
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
addLLVMArgAttr(fn_val, (unsigned)0, "noalias");
addLLVMArgAttr(fn_val, (unsigned)0, "writeonly");
+ // Error return trace memory is in the stack, which is impossible to be at address 0
+ // on any architecture.
addLLVMArgAttr(fn_val, (unsigned)1, "nonnull");
addLLVMArgAttr(fn_val, (unsigned)1, "noalias");
addLLVMArgAttr(fn_val, (unsigned)1, "readonly");
@@ -1450,6 +1459,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) {
LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified));
addLLVMFnAttr(fn_val, "nounwind");
add_uwtable_attr(g, fn_val);
+ // Error return trace memory is in the stack, which is impossible to be at address 0
+ // on any architecture.
addLLVMArgAttr(fn_val, (unsigned)0, "nonnull");
if (g->build_mode == BuildModeDebug) {
ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true");
@@ -2051,7 +2062,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
case FnWalkIdAttrs: {
ZigType *ptr_type = get_codegen_ptr_type(ty);
if (ptr_type != nullptr) {
- if (ty->id != ZigTypeIdOptional) {
+ if (type_is_nonnull_ptr(ty)) {
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
}
if (ptr_type->data.pointer.is_const) {
@@ -2095,6 +2106,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
assert(handle_is_ptr(ty));
switch (fn_walk->id) {
case FnWalkIdAttrs:
+ // arrays passed to C ABI functions may not be at address 0
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
fn_walk->data.attrs.gen_i += 1;
@@ -2134,6 +2146,7 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
case FnWalkIdAttrs:
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "byval");
addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty));
+ // Byvalue parameters must not have address 0
addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull");
fn_walk->data.attrs.gen_i += 1;
break;
@@ -2266,7 +2279,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) {
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly");
}
- if (param_type->id == ZigTypeIdPointer) {
+ if (type_is_nonnull_ptr(param_type)) {
addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull");
}
break;
diff --git a/src/target.cpp b/src/target.cpp
index 6fea79518c..b1434c6871 100644
--- a/src/target.cpp
+++ b/src/target.cpp
@@ -807,6 +807,10 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
zig_unreachable();
}
+bool target_allows_addr_zero(const ZigTarget *target) {
+ return target->os == OsFreestanding;
+}
+
const char *target_o_file_ext(ZigTarget *target) {
if (target->env_type == ZigLLVM_MSVC || target->os == OsWindows || target->os == OsUefi) {
return ".obj";
diff --git a/src/target.hpp b/src/target.hpp
index a87b12351a..99d1cadf56 100644
--- a/src/target.hpp
+++ b/src/target.hpp
@@ -135,5 +135,6 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
ZigLLVM_OSType get_llvm_os_type(Os os_type);
bool target_is_arm(const ZigTarget *target);
+bool target_allows_addr_zero(const ZigTarget *target);
#endif
From 973a93d43b8b44d2ee8bfde09e78f8295470f337 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 18:59:20 -0500
Subject: [PATCH 196/218] add docs for C pointers
---
doc/langref.html.in | 60 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 3 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 82ec13c9bb..e5a60b0bc1 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -1694,7 +1694,7 @@ test "comptime @intToPtr" {
}
}
{#code_end#}
- {#see_also|Optional Pointers#}
+ {#see_also|Optional Pointers|@intToPtr|@ptrToInt#}
{#header_open|volatile#}
Loads and stores are assumed to not have side effects. If a given load or store
should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
@@ -1823,7 +1823,9 @@ fn foo(bytes: []u8) u32 {
}
{#code_end#}
{#header_close#}
+ {#see_also|C Pointers#}
{#header_close#}
+
{#header_open|Slices#}
{#code_begin|test_safety|index out of bounds#}
const assert = @import("std").debug.assert;
@@ -3981,7 +3983,7 @@ test "implicit cast - invoke a type as a function" {
{#code_end#}
Implicit casts are only allowed when it is completely unambiguous how to get from one type to another,
- and the transformation is guaranteed to be safe.
+ and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.
{#header_open|Implicit Cast: Stricter Qualification#}
@@ -6104,6 +6106,10 @@ test "call foo" {
Converts a pointer of one type to a pointer of another type.
+
+ {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
+ to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
+
{#header_close#}
{#header_open|@ptrToInt#}
@@ -7345,10 +7351,27 @@ fn bar(f: *Foo) void {
{#code_end#}
{#header_close#}
- {#header_open|Out of Bounds Float To Integer Cast#}
+ {#header_open|Out of Bounds Float to Integer Cast#}
TODO
{#header_close#}
+ {#header_open|Pointer Cast Invalid Null#}
+ At compile-time:
+ {#code_begin|test_err|null pointer casted to type#}
+comptime {
+ const opt_ptr: ?*i32 = null;
+ const ptr = @ptrCast(*i32, opt_ptr);
+}
+ {#code_end#}
+ At runtime:
+ {#code_begin|exe_err#}
+pub fn main() void {
+ var opt_ptr: ?*i32 = null;
+ var ptr = @ptrCast(*i32, opt_ptr);
+}
+ {#code_end#}
+ {#header_close#}
+
{#header_close#}
{#header_open|Memory#}
TODO: explain no default allocator in zig
@@ -7439,6 +7462,7 @@ pub fn main() void {
{#code_end#}
{#see_also|String Literals#}
{#header_close#}
+
{#header_open|Import from C Header File#}
The {#syntax#}@cImport{#endsyntax#} builtin function can be used
@@ -7477,6 +7501,36 @@ const c = @cImport({
{#code_end#}
{#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#}
{#header_close#}
+
+ {#header_open|C Pointers#}
+
+ This type is to be avoided whenever possible. The only valid reason for using a C pointer is in
+ auto-generated code from translating C code.
+
+
+ When importing C header files, it is ambiguous whether pointers should be translated as
+ single-item pointers ({#syntax#}*T{#endsyntax#}) or unknown-length pointers ({#syntax#}[*]T{#endsyntax#}).
+ C pointers are a compromise so that Zig code can utilize translated header files directly.
+
+ {#syntax#}[*c]T{#endsyntax#} - C pointer.
+
+ - Supports all the syntax of the other two pointer types.
+ - Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}.
+ When a C pointer is implicitly casted to a non-optional pointer, safety-checked
+ {#link|Undefined Behavior#} occurs if the address is 0.
+
+ - Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
+ {#link|Undefined Behavior#}. Optional C pointers introduce another bit to keep track of
+ null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
+ is unnecessary as one can use normal {#link|Optional Pointers#}.
+
+ - Supports {#link|implicit casting|Implicit Casts#} to and from integers.
+ - Supports comparison with integers.
+ - Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}
+ please!
+
+ {#header_close#}
+
{#header_open|Exporting a C Library#}
One of the primary use cases for Zig is exporting a library with the C ABI for other programming languages
From cc7060d0d934135d797bd2bc24288ecab095051a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 19:53:46 -0500
Subject: [PATCH 197/218] compile error for C pointer with align attribute
See #1059
---
src/ir.cpp | 5 +++++
test/compile_errors.zig | 12 ++++++++----
test/stage1/behavior/type_info.zig | 4 ++--
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 7c46b21717..6e190adf6f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5057,6 +5057,11 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
IrInstruction *align_value;
if (align_expr != nullptr) {
+ if (ptr_len == PtrLenC) {
+ exec_add_error_node(irb->codegen, irb->exec, node,
+ buf_sprintf("[*c] pointers may not have align attribute"));
+ return irb->codegen->invalid_instruction;
+ }
align_value = ir_gen_node(irb, align_expr, scope);
if (align_value == irb->codegen->invalid_instruction)
return align_value;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 5e9b691641..ab9eda3f15 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -118,13 +118,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
);
cases.addTest(
- "C pointer pointing to non C ABI compatible type",
+ "C pointer pointing to non C ABI compatible type or has align attr",
\\const Foo = struct {};
- \\export fn entry() [*c]Foo {
- \\ return undefined;
+ \\export fn a() void {
+ \\ const T = [*c]Foo;
+ \\}
+ \\export fn b() void {
+ \\ const T = [*c]align(4) u8;
\\}
,
- ".tmp_source.zig:2:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
+ ".tmp_source.zig:3:15: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
+ ".tmp_source.zig:6:15: error: [*c] pointers may not have align attribute",
);
cases.addTest(
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index dc185cc960..52e03c2d73 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -67,12 +67,12 @@ test "type info: C pointer type info" {
}
fn testCPtr() void {
- const ptr_info = @typeInfo([*c]align(4) const i8);
+ const ptr_info = @typeInfo([*c]const i8);
expect(TypeId(ptr_info) == TypeId.Pointer);
expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);
expect(ptr_info.Pointer.is_const);
expect(!ptr_info.Pointer.is_volatile);
- expect(ptr_info.Pointer.alignment == 4);
+ expect(ptr_info.Pointer.alignment == 1);
expect(ptr_info.Pointer.child == i8);
}
From d5bbd748711abc82272199869cf70faf1ea30f52 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 20:04:13 -0500
Subject: [PATCH 198/218] allow C pointers to have alignment
clang/gcc support pointer alignment attribute:
https://clang.llvm.org/docs/AttributeReference.html#align-value
---
src/ir.cpp | 5 -----
test/compile_errors.zig | 4 ----
test/stage1/behavior/type_info.zig | 4 ++--
3 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index 6e190adf6f..7c46b21717 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5057,11 +5057,6 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
IrInstruction *align_value;
if (align_expr != nullptr) {
- if (ptr_len == PtrLenC) {
- exec_add_error_node(irb->codegen, irb->exec, node,
- buf_sprintf("[*c] pointers may not have align attribute"));
- return irb->codegen->invalid_instruction;
- }
align_value = ir_gen_node(irb, align_expr, scope);
if (align_value == irb->codegen->invalid_instruction)
return align_value;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index ab9eda3f15..a2fd901197 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -123,12 +123,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn a() void {
\\ const T = [*c]Foo;
\\}
- \\export fn b() void {
- \\ const T = [*c]align(4) u8;
- \\}
,
".tmp_source.zig:3:15: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
- ".tmp_source.zig:6:15: error: [*c] pointers may not have align attribute",
);
cases.addTest(
diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig
index 52e03c2d73..dc185cc960 100644
--- a/test/stage1/behavior/type_info.zig
+++ b/test/stage1/behavior/type_info.zig
@@ -67,12 +67,12 @@ test "type info: C pointer type info" {
}
fn testCPtr() void {
- const ptr_info = @typeInfo([*c]const i8);
+ const ptr_info = @typeInfo([*c]align(4) const i8);
expect(TypeId(ptr_info) == TypeId.Pointer);
expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);
expect(ptr_info.Pointer.is_const);
expect(!ptr_info.Pointer.is_volatile);
- expect(ptr_info.Pointer.alignment == 1);
+ expect(ptr_info.Pointer.alignment == 4);
expect(ptr_info.Pointer.child == i8);
}
From d6e0d82c328b4f9d733364382cce0941a601e91a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 23:09:12 -0500
Subject: [PATCH 199/218] translate-c: back to *c_void for opaque types
See #1059
---
src/analyze.cpp | 2 +-
src/ir.cpp | 13 +++++++++----
src/translate_c.cpp | 34 ++++++++++++++++++++++++++++++++--
test/compile_errors.zig | 10 ++++++++++
test/translate_c.zig | 20 ++++++++++----------
5 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 55deafb3a8..1917784511 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -437,7 +437,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
// move this to a parameter
bool allow_zero = (ptr_len == PtrLenC);
assert(!type_is_invalid(child_type));
- assert(ptr_len != PtrLenUnknown || child_type->id != ZigTypeIdOpaque);
+ assert(ptr_len == PtrLenSingle || child_type->id != ZigTypeIdOpaque);
if (byte_alignment != 0) {
uint32_t abi_alignment = get_abi_alignment(g, child_type);
diff --git a/src/ir.cpp b/src/ir.cpp
index 7c46b21717..707eac0181 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21205,10 +21205,15 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
} else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) {
ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque"));
return ira->codegen->invalid_instruction;
- } else if (instruction->ptr_len == PtrLenC && !type_allowed_in_extern(ira->codegen, child_type)) {
- ir_add_error(ira, &instruction->base,
- buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name)));
- return ira->codegen->invalid_instruction;
+ } else if (instruction->ptr_len == PtrLenC) {
+ if (!type_allowed_in_extern(ira->codegen, child_type)) {
+ ir_add_error(ira, &instruction->base,
+ buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name)));
+ return ira->codegen->invalid_instruction;
+ } else if (child_type->id == ZigTypeIdOpaque) {
+ ir_add_error(ira, &instruction->base, buf_sprintf("C pointers cannot point opaque types"));
+ return ira->codegen->invalid_instruction;
+ }
}
uint32_t align_bytes;
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 63f04dae6c..42a7ab436d 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -763,6 +763,30 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
}
}
+static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &source_loc) {
+ switch (ty->getTypeClass()) {
+ case Type::Builtin: {
+ const BuiltinType *builtin_ty = static_cast(ty);
+ return builtin_ty->getKind() == BuiltinType::Void;
+ }
+ case Type::Record: {
+ const RecordType *record_ty = static_cast(ty);
+ return record_ty->getDecl()->getDefinition() == nullptr;
+ }
+ case Type::Elaborated: {
+ const ElaboratedType *elaborated_ty = static_cast(ty);
+ return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
+ }
+ case Type::Typedef: {
+ const TypedefType *typedef_ty = static_cast(ty);
+ const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
+ return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
+ }
+ default:
+ return false;
+ }
+}
+
static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
case Type::Builtin:
@@ -912,8 +936,14 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return trans_create_node_prefix_op(c, PrefixOpOptional, child_node);
}
- return trans_create_node_ptr_type(c, child_qt.isConstQualified(),
- child_qt.isVolatileQualified(), child_node, PtrLenC);
+ if (type_is_opaque(c, child_qt.getTypePtr(), source_loc)) {
+ AstNode *pointer_node = trans_create_node_ptr_type(c, child_qt.isConstQualified(),
+ child_qt.isVolatileQualified(), child_node, PtrLenSingle);
+ return trans_create_node_prefix_op(c, PrefixOpOptional, pointer_node);
+ } else {
+ return trans_create_node_ptr_type(c, child_qt.isConstQualified(),
+ child_qt.isVolatileQualified(), child_node, PtrLenC);
+ }
}
case Type::Typedef:
{
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index a2fd901197..1f641a9052 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,6 +1,16 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.addTest(
+ "C pointer to c_void",
+ \\export fn a() void {
+ \\ var x: *c_void = undefined;
+ \\ var y: [*c]c_void = x;
+ \\}
+ ,
+ ".tmp_source.zig:3:12: error: C pointers cannot point opaque types",
+ );
+
cases.addTest(
"directly embedding opaque type in struct and union",
\\const O = @OpaqueType();
diff --git a/test/translate_c.zig b/test/translate_c.zig
index b87b962edc..7385427dbe 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -202,7 +202,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("restrict -> noalias",
\\void foo(void *restrict bar, void *restrict);
,
- \\pub extern fn foo(noalias bar: [*c]c_void, noalias arg1: [*c]c_void) void;
+ \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
);
cases.add("simple struct",
@@ -275,7 +275,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const struct_Foo = @OpaqueType();
,
- \\pub extern fn some_func(foo: [*c]struct_Foo, x: c_int) [*c]struct_Foo;
+ \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
,
\\pub const Foo = struct_Foo;
);
@@ -336,7 +336,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
,
\\pub const Foo = c_void;
,
- \\pub extern fn fun(a: [*c]Foo) Foo;
+ \\pub extern fn fun(a: ?*Foo) Foo;
);
cases.add("generate inline func for #define global extern fn",
@@ -608,7 +608,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 6;
\\}
,
- \\pub export fn and_or_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
+ \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ if ((a != 0) and (b != 0)) return 0;
\\ if ((b != 0) and (c != 0)) return 1;
\\ if ((a != 0) and (c != 0)) return 2;
@@ -756,8 +756,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return x;
\\}
,
- \\pub export fn foo(x: [*c]c_ushort) [*c]c_void {
- \\ return @ptrCast([*c]c_void, x);
+ \\pub export fn foo(x: [*c]c_ushort) ?*c_void {
+ \\ return @ptrCast(?*c_void, x);
\\}
);
@@ -1276,7 +1276,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return !c;
\\}
,
- \\pub fn foo(a: c_int, b: f32, c: [*c]c_void) c_int {
+ \\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int {
\\ return !(a == 0);
\\ return !(a != 0);
\\ return !(b != 0);
@@ -1334,7 +1334,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ B,
\\ C,
\\};
- \\pub fn if_none_bool(a: c_int, b: f32, c: [*c]c_void, d: enum_SomeEnum) c_int {
+ \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != 0) return 2;
@@ -1351,7 +1351,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn while_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
+ \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != 0) return 2;
@@ -1367,7 +1367,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn for_none_bool(a: c_int, b: f32, c: [*c]c_void) c_int {
+ \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != 0) return 2;
From e025c70166d96d7a75a5039415321745f51f1f58 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 23:17:11 -0500
Subject: [PATCH 200/218] stage2: fix llvm.zig with opaque types back to
single-item pointer
---
src-self-hosted/llvm.zig | 20 ++++++++++----------
src-self-hosted/value.zig | 4 ++--
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/src-self-hosted/llvm.zig b/src-self-hosted/llvm.zig
index 704e83c3c6..5cb95682ab 100644
--- a/src-self-hosted/llvm.zig
+++ b/src-self-hosted/llvm.zig
@@ -11,16 +11,16 @@ const assert = @import("std").debug.assert;
pub const AttributeIndex = c_uint;
pub const Bool = c_int;
-pub const Builder = c.LLVMBuilderRef.Child;
-pub const Context = c.LLVMContextRef.Child;
-pub const Module = c.LLVMModuleRef.Child;
-pub const Value = c.LLVMValueRef.Child;
-pub const Type = c.LLVMTypeRef.Child;
-pub const BasicBlock = c.LLVMBasicBlockRef.Child;
-pub const Attribute = c.LLVMAttributeRef.Child;
-pub const Target = c.LLVMTargetRef.Child;
-pub const TargetMachine = c.LLVMTargetMachineRef.Child;
-pub const TargetData = c.LLVMTargetDataRef.Child;
+pub const Builder = c.LLVMBuilderRef.Child.Child;
+pub const Context = c.LLVMContextRef.Child.Child;
+pub const Module = c.LLVMModuleRef.Child.Child;
+pub const Value = c.LLVMValueRef.Child.Child;
+pub const Type = c.LLVMTypeRef.Child.Child;
+pub const BasicBlock = c.LLVMBasicBlockRef.Child.Child;
+pub const Attribute = c.LLVMAttributeRef.Child.Child;
+pub const Target = c.LLVMTargetRef.Child.Child;
+pub const TargetMachine = c.LLVMTargetMachineRef.Child.Child;
+pub const TargetData = c.LLVMTargetDataRef.Child.Child;
pub const DIBuilder = c.ZigLLVMDIBuilder;
pub const DIFile = c.ZigLLVMDIFile;
pub const DICompileUnit = c.ZigLLVMDICompileUnit;
diff --git a/src-self-hosted/value.zig b/src-self-hosted/value.zig
index d9d4c3d1d9..d8c0f7b5c8 100644
--- a/src-self-hosted/value.zig
+++ b/src-self-hosted/value.zig
@@ -283,8 +283,8 @@ pub const Value = struct {
comp.gpa().destroy(self);
}
- pub fn getLlvmConst(self: *Bool, ofile: *ObjectFile) ?*llvm.Value {
- const llvm_type = llvm.Int1TypeInContext(ofile.context);
+ pub fn getLlvmConst(self: *Bool, ofile: *ObjectFile) !?*llvm.Value {
+ const llvm_type = llvm.Int1TypeInContext(ofile.context) orelse return error.OutOfMemory;
if (self.x) {
return llvm.ConstAllOnes(llvm_type);
} else {
From 18ad50970f81bd4b07892a6651487be81effc4c7 Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Fri, 15 Feb 2019 17:32:13 +1300
Subject: [PATCH 201/218] Make parseFloat stricter in what it accepts as input
---
std/fmt/parse_float.zig | 79 +++++++++++++++++++----------------------
std/json.zig | 2 +-
2 files changed, 38 insertions(+), 43 deletions(-)
diff --git a/std/fmt/parse_float.zig b/std/fmt/parse_float.zig
index b83cdbbbb2..de9619efe2 100644
--- a/std/fmt/parse_float.zig
+++ b/std/fmt/parse_float.zig
@@ -84,10 +84,6 @@ const Z96 = struct {
w += u64(d.d2) -% u64(s.d2);
d.d2 = @truncate(u32, w);
}
-
- fn dump(d: Z96) void {
- std.debug.warn("{} {} {}\n", d.d0, d.d1, d.d2);
- }
};
const FloatRepr = struct {
@@ -178,7 +174,6 @@ fn convertRepr(comptime T: type, n: FloatRepr) T {
}
const State = enum {
- SkipLeadingWhitespace,
MaybeSign,
LeadingMantissaZeros,
LeadingFractionalZeros,
@@ -187,7 +182,6 @@ const State = enum {
ExponentSign,
LeadingExponentZeros,
Exponent,
- Stop,
};
const ParseResult = enum {
@@ -206,27 +200,19 @@ inline fn isSpace(c: u8) bool {
return (c >= 0x09 and c <= 0x13) or c == 0x20;
}
-fn parseRepr(s: []const u8, n: *FloatRepr) ParseResult {
+fn parseRepr(s: []const u8, n: *FloatRepr) !ParseResult {
var digit_index: usize = 0;
var negative = false;
var negative_exp = false;
var exponent: i32 = 0;
- var state = State.SkipLeadingWhitespace;
+ var state = State.MaybeSign;
var i: usize = 0;
- loop: while (state != State.Stop and i < s.len) {
+ loop: while (i < s.len) {
const c = s[i];
switch (state) {
- State.SkipLeadingWhitespace => {
- if (isSpace(c)) {
- i += 1;
- } else {
- state = State.MaybeSign;
- }
- },
-
State.MaybeSign => {
state = State.LeadingMantissaZeros;
@@ -238,7 +224,7 @@ fn parseRepr(s: []const u8, n: *FloatRepr) ParseResult {
} else if (isDigit(c) or c == '.') {
// continue
} else {
- state = State.Stop;
+ return error.InvalidCharacter;
}
},
@@ -329,11 +315,9 @@ fn parseRepr(s: []const u8, n: *FloatRepr) ParseResult {
i += 1;
} else {
- state = State.Stop;
+ return error.InvalidCharacter;
}
},
-
- State.Stop => break :loop,
}
}
@@ -371,12 +355,10 @@ fn caseInEql(a: []const u8, b: []const u8) bool {
return true;
}
-pub fn parseFloat(comptime T: type, s: []const u8) T {
- var r = FloatRepr{
- .negative = false,
- .exponent = 0,
- .mantissa = 0,
- };
+pub fn parseFloat(comptime T: type, s: []const u8) !T {
+ if (s.len == 0) {
+ return error.InvalidCharacter;
+ }
if (caseInEql(s, "nan")) {
return std.math.nan(T);
@@ -386,7 +368,13 @@ pub fn parseFloat(comptime T: type, s: []const u8) T {
return -std.math.inf(T);
}
- return switch (parseRepr(s, &r)) {
+ var r = FloatRepr{
+ .negative = false,
+ .exponent = 0,
+ .mantissa = 0,
+ };
+
+ return switch (try parseRepr(s, &r)) {
ParseResult.Ok => convertRepr(T, r),
ParseResult.PlusZero => 0.0,
ParseResult.MinusZero => -T(0.0),
@@ -396,30 +384,37 @@ pub fn parseFloat(comptime T: type, s: []const u8) T {
}
test "fmt.parseFloat" {
- const assert = std.debug.assert;
+ const testing = std.testing;
+ const expect = testing.expect;
+ const expectEqual = testing.expectEqual;
const approxEq = std.math.approxEq;
const epsilon = 1e-7;
- inline for ([]type{ f32, f64, f128 }) |T| {
+ inline for ([]type{ f16, f32, f64, f128 }) |T| {
const Z = @IntType(false, T.bit_count);
- assert(parseFloat(T, "0") == 0.0);
- assert(parseFloat(T, "+0") == 0.0);
- assert(parseFloat(T, "-0") == 0.0);
+ testing.expectError(error.InvalidCharacter, parseFloat(T, ""));
+ testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));
+ testing.expectError(error.InvalidCharacter, parseFloat(T, "1abc"));
- assert(approxEq(T, parseFloat(T, "3.141"), 3.141, epsilon));
- assert(approxEq(T, parseFloat(T, "-3.141"), -3.141, epsilon));
+ expectEqual(try parseFloat(T, "0"), 0.0);
+ expectEqual((try parseFloat(T, "0")), 0.0);
+ expectEqual((try parseFloat(T, "+0")), 0.0);
+ expectEqual((try parseFloat(T, "-0")), 0.0);
- assert(parseFloat(T, "1e-700") == 0);
- assert(parseFloat(T, "1e+700") == std.math.inf(T));
+ expect(approxEq(T, try parseFloat(T, "3.141"), 3.141, epsilon));
+ expect(approxEq(T, try parseFloat(T, "-3.141"), -3.141, epsilon));
- assert(@bitCast(Z, parseFloat(T, "nAn")) == @bitCast(Z, std.math.nan(T)));
- assert(parseFloat(T, "inF") == std.math.inf(T));
- assert(parseFloat(T, "-INF") == -std.math.inf(T));
+ expectEqual((try parseFloat(T, "1e-700")), 0);
+ expectEqual((try parseFloat(T, "1e+700")), std.math.inf(T));
+
+ expectEqual(@bitCast(Z, try parseFloat(T, "nAn")), @bitCast(Z, std.math.nan(T)));
+ expectEqual((try parseFloat(T, "inF")), std.math.inf(T));
+ expectEqual((try parseFloat(T, "-INF")), -std.math.inf(T));
if (T != f16) {
- assert(approxEq(T, parseFloat(T, "123142.1"), 123142.1, epsilon));
- assert(approxEq(T, parseFloat(T, "-123142.1124"), T(-123142.1124), epsilon));
+ expect(approxEq(T, try parseFloat(T, "123142.1"), 123142.1, epsilon));
+ expect(approxEq(T, try parseFloat(T, "-123142.1124"), T(-123142.1124), epsilon));
}
}
}
diff --git a/std/json.zig b/std/json.zig
index 5a28d9ab41..dd053e7635 100644
--- a/std/json.zig
+++ b/std/json.zig
@@ -1345,7 +1345,7 @@ pub const Parser = struct {
return if (token.number_is_integer)
Value{ .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }
else
- Value{ .Float = std.fmt.parseFloat(f64, token.slice(input, i)) };
+ Value{ .Float = try std.fmt.parseFloat(f64, token.slice(input, i)) };
}
};
From 170ec504ec3201a89cb8121ea59e5d845f5cd1d1 Mon Sep 17 00:00:00 2001
From: Marc Tiehuis
Date: Fri, 15 Feb 2019 17:37:55 +1300
Subject: [PATCH 202/218] Use official llvm mirror for compiler-rt commit ref
---
std/special/compiler_rt/addXf3.zig | 2 +-
std/special/compiler_rt/addXf3_test.zig | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/std/special/compiler_rt/addXf3.zig b/std/special/compiler_rt/addXf3.zig
index 5f7f73c44f..09413b2328 100644
--- a/std/special/compiler_rt/addXf3.zig
+++ b/std/special/compiler_rt/addXf3.zig
@@ -1,6 +1,6 @@
// Ported from:
//
-// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/lib/builtins/fp_add_impl.inc
+// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/lib/builtins/fp_add_impl.inc
const std = @import("std");
const builtin = @import("builtin");
diff --git a/std/special/compiler_rt/addXf3_test.zig b/std/special/compiler_rt/addXf3_test.zig
index f374a67433..099b737976 100644
--- a/std/special/compiler_rt/addXf3_test.zig
+++ b/std/special/compiler_rt/addXf3_test.zig
@@ -1,7 +1,7 @@
// Ported from:
//
-// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/test/builtins/Unit/addtf3_test.c
-// https://github.com/llvm-mirror/compiler-rt/blob/92f7768ce940f6437b32ecc0985a1446cd040f7a/test/builtins/Unit/subtf3_test.c
+// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c
+// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/subtf3_test.c
const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);
const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);
From 71d7100aa830652490d3995bf4e1319f31b5e647 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 23:38:14 -0500
Subject: [PATCH 203/218] darwin: fix pointer cast in mmap
---
std/os/darwin.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/std/os/darwin.zig b/std/os/darwin.zig
index c64ce807b6..3e883abbab 100644
--- a/std/os/darwin.zig
+++ b/std/os/darwin.zig
@@ -665,7 +665,7 @@ pub fn pwrite(fd: i32, buf: [*]const u8, nbyte: usize, offset: u64) usize {
pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
const ptr_result = c.mmap(
- @ptrCast(*c_void, address),
+ @ptrCast(?*c_void, address),
length,
@bitCast(c_int, @intCast(c_uint, prot)),
@bitCast(c_int, c_uint(flags)),
From 99b19adeb31469cbc4a906f036bb4d70d8730916 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 14 Feb 2019 23:46:53 -0500
Subject: [PATCH 204/218] stage2: fix windows regressions
---
src-self-hosted/libc_installation.zig | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig
index edcb9dc579..d3a461bcd9 100644
--- a/src-self-hosted/libc_installation.zig
+++ b/src-self-hosted/libc_installation.zig
@@ -154,8 +154,8 @@ pub const LibCInstallation = struct {
c.ZigFindWindowsSdkError.None => {
windows_sdk = sdk;
- if (sdk.msvc_lib_dir_ptr) |ptr| {
- self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]);
+ if (sdk.msvc_lib_dir_ptr != 0) {
+ self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, sdk.msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
}
try group.call(findNativeKernel32LibDir, self, loop, sdk);
try group.call(findNativeIncludeDirWindows, self, loop, sdk);
@@ -437,20 +437,20 @@ const Search = struct {
fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search {
var search_end: usize = 0;
- if (sdk.path10_ptr) |path10_ptr| {
- if (sdk.version10_ptr) |ver10_ptr| {
+ if (sdk.path10_ptr != 0) {
+ if (sdk.version10_ptr != 0) {
search_buf[search_end] = Search{
- .path = path10_ptr[0..sdk.path10_len],
- .version = ver10_ptr[0..sdk.version10_len],
+ .path = sdk.path10_ptr[0..sdk.path10_len],
+ .version = sdk.version10_ptr[0..sdk.version10_len],
};
search_end += 1;
}
}
- if (sdk.path81_ptr) |path81_ptr| {
- if (sdk.version81_ptr) |ver81_ptr| {
+ if (sdk.path81_ptr != 0) {
+ if (sdk.version81_ptr != 0) {
search_buf[search_end] = Search{
- .path = path81_ptr[0..sdk.path81_len],
- .version = ver81_ptr[0..sdk.version81_len],
+ .path = sdk.path81_ptr[0..sdk.path81_len],
+ .version = sdk.version81_ptr[0..sdk.version81_len],
};
search_end += 1;
}
From ee5e196f8832359cfe05808677f143d4f460f6bc Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 15 Feb 2019 02:02:19 -0500
Subject: [PATCH 205/218] add test for truncate on comptime integers
closes #703
---
test/stage1/behavior/truncate.zig | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/test/stage1/behavior/truncate.zig b/test/stage1/behavior/truncate.zig
index 568346369f..099b6c3359 100644
--- a/test/stage1/behavior/truncate.zig
+++ b/test/stage1/behavior/truncate.zig
@@ -29,3 +29,8 @@ test "truncate sign mismatch but comptime known so it works anyway" {
var result = @truncate(i8, x);
expect(result == 10);
}
+
+test "truncate on comptime integer" {
+ var x = @truncate(u16, 9999);
+ expect(x == 9999);
+}
From 7293e012d7956b892380517e914108ffadc6941b Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 15 Feb 2019 18:05:50 -0500
Subject: [PATCH 206/218] breaking: fix @sizeOf to be alloc size rather than
store size
* Fixes breaches of the guarantee that `@sizeOf(T) >= @alignOf(T)`
* Fixes std.mem.secureZero for integers where this guarantee previously
was breached
* Fixes std.mem.Allocator for integers where this guarantee previously
was breached
Closes #1851
Closes #1864
---
doc/langref.html.in | 9 ++++--
src/analyze.cpp | 37 +++++++++++++++++++---
src/analyze.hpp | 1 +
src/ir.cpp | 28 ++++++++++++-----
std/io.zig | 13 +++-----
std/mem.zig | 49 ++++++++++++------------------
test/stage1/behavior.zig | 1 +
test/stage1/behavior/bugs/1851.zig | 27 ++++++++++++++++
8 files changed, 113 insertions(+), 52 deletions(-)
create mode 100644 test/stage1/behavior/bugs/1851.zig
diff --git a/doc/langref.html.in b/doc/langref.html.in
index e5a60b0bc1..1341bf1be5 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6299,10 +6299,15 @@ pub const FloatMode = enum {
{#syntax#}@sizeOf(comptime T: type) comptime_int{#endsyntax#}
This function returns the number of bytes it takes to store {#syntax#}T{#endsyntax#} in memory.
-
-
The result is a target-specific compile time constant.
+
+ This size may contain padding bytes. If there were two consecutive T in memory, this would be the offset
+ in bytes between element at index 0 and the element at index 1. For {#link|integer|Integers#},
+ consider whether you want to use {#syntax#}@sizeOf(T){#endsyntax#} or
+ {#syntax#}@typeInfo(T).Int.bits{#endsyntax#}.
+
+ {#see_also|@typeInfo#}
{#header_close#}
{#header_open|@sliceToBytes#}
diff --git a/src/analyze.cpp b/src/analyze.cpp
index e2a96da7c3..7949493586 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -356,6 +356,28 @@ uint64_t type_size(CodeGen *g, ZigType *type_entry) {
}
}
+ return LLVMABISizeOfType(g->target_data_ref, type_entry->type_ref);
+}
+
+uint64_t type_size_store(CodeGen *g, ZigType *type_entry) {
+ assert(type_is_complete(type_entry));
+
+ if (!type_has_bits(type_entry))
+ return 0;
+
+ if (type_entry->id == ZigTypeIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) {
+ uint64_t size_in_bits = type_size_bits(g, type_entry);
+ return (size_in_bits + 7) / 8;
+ } else if (type_entry->id == ZigTypeIdArray) {
+ ZigType *child_type = type_entry->data.array.child_type;
+ if (child_type->id == ZigTypeIdStruct &&
+ child_type->data.structure.layout == ContainerLayoutPacked)
+ {
+ uint64_t size_in_bits = type_size_bits(g, type_entry);
+ return (size_in_bits + 7) / 8;
+ }
+ }
+
return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref);
}
@@ -6230,14 +6252,19 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
case ZigTypeIdStruct:
{
if (is_slice(type_entry)) {
- ConstPtrValue *ptr = &const_val->data.x_struct.fields[slice_ptr_index].data.x_ptr;
- assert(ptr->special == ConstPtrSpecialBaseArray);
- ConstExprValue *array = ptr->data.base_array.array_val;
- size_t start = ptr->data.base_array.elem_index;
-
ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index];
size_t len = bigint_as_unsigned(&len_val->data.x_bigint);
+ ConstExprValue *ptr_val = &const_val->data.x_struct.fields[slice_ptr_index];
+ if (ptr_val->special == ConstValSpecialUndef) {
+ assert(len == 0);
+ buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name));
+ return;
+ }
+ assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
+ ConstExprValue *array = ptr_val->data.x_ptr.data.base_array.array_val;
+ size_t start = ptr_val->data.x_ptr.data.base_array.elem_index;
+
render_const_val_array(g, buf, &type_entry->name, array, start, len);
} else {
buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name));
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 845fb62534..7ded651e95 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -19,6 +19,7 @@ ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const);
ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_const,
bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count);
uint64_t type_size(CodeGen *g, ZigType *type_entry);
+uint64_t type_size_store(CodeGen *g, ZigType *type_entry);
uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
ZigType *get_vector_type(CodeGen *g, uint32_t len, ZigType *elem_type);
diff --git a/src/ir.cpp b/src/ir.cpp
index c9262038e0..92cdd8c891 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -14331,15 +14331,15 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source
if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown)))
return ErrorSemanticAnalyzeFail;
- size_t src_size = type_size(codegen, pointee->type);
- size_t dst_size = type_size(codegen, out_val->type);
-
- if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
- copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
- return ErrorNone;
- }
+ // We don't need to read the padding bytes, so we look at type_size_store bytes
+ size_t src_size = type_size_store(codegen, pointee->type);
+ size_t dst_size = type_size_store(codegen, out_val->type);
if (dst_size <= src_size) {
+ if (types_have_same_zig_comptime_repr(pointee->type, out_val->type)) {
+ copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
+ return ErrorNone;
+ }
Buf buf = BUF_INIT;
buf_resize(&buf, src_size);
buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee);
@@ -15798,6 +15798,8 @@ static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructio
static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
IrInstructionToPtrType *to_ptr_type_instruction)
{
+ Error err;
+
IrInstruction *value = to_ptr_type_instruction->value->child;
ZigType *type_entry = value->value.type;
if (type_is_invalid(type_entry))
@@ -15813,7 +15815,17 @@ static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira,
ptr_type = get_pointer_to_type(ira->codegen,
type_entry->data.pointer.child_type->data.array.child_type, type_entry->data.pointer.is_const);
} else if (is_slice(type_entry)) {
- ptr_type = adjust_ptr_len(ira->codegen, type_entry->data.structure.fields[0].type_entry, PtrLenSingle);
+ ZigType *slice_ptr_type = type_entry->data.structure.fields[0].type_entry;
+ ptr_type = adjust_ptr_len(ira->codegen, slice_ptr_type, PtrLenSingle);
+ // If the pointer is over-aligned, we may have to reduce it based on the alignment of the element type.
+ if (slice_ptr_type->data.pointer.explicit_alignment != 0) {
+ ZigType *elem_type = slice_ptr_type->data.pointer.child_type;
+ if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown)))
+ return ira->codegen->invalid_instruction;
+ uint32_t elem_align = get_abi_alignment(ira->codegen, elem_type);
+ uint32_t reduced_align = min(elem_align, slice_ptr_type->data.pointer.explicit_alignment);
+ ptr_type = adjust_ptr_align(ira->codegen, ptr_type, reduced_align);
+ }
} else if (type_entry->id == ZigTypeIdArgTuple) {
ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad);
if (!arg_tuple_val)
diff --git a/std/io.zig b/std/io.zig
index d7e8507f9b..6c70834b52 100644
--- a/std/io.zig
+++ b/std/io.zig
@@ -935,8 +935,6 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {
};
}
-
-
pub const BufferedAtomicFile = struct {
atomic_file: os.AtomicFile,
file_stream: os.File.OutStream,
@@ -978,7 +976,6 @@ pub const BufferedAtomicFile = struct {
}
};
-
pub fn readLine(buf: *std.Buffer) ![]u8 {
var stdin = try getStdIn();
var stdin_stream = stdin.inStream();
@@ -1073,13 +1070,13 @@ pub fn Deserializer(comptime endian: builtin.Endian, is_packed: bool, comptime E
else => in_stream,
} };
}
-
+
pub fn alignToByte(self: *Self) void {
- if(!is_packed) return;
+ if (!is_packed) return;
self.in_stream.alignToByte();
}
- //@BUG: inferred error issue. See: #1386
+ //@BUG: inferred error issue. See: #1386
fn deserializeInt(self: *Self, comptime T: type) (Error || error{EndOfStream})!T {
comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));
@@ -1088,7 +1085,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, is_packed: bool, comptime E
const U = @IntType(false, t_bit_count);
const Log2U = math.Log2Int(U);
- const int_size = @sizeOf(U);
+ const int_size = (U.bit_count + 7) / 8;
if (is_packed) {
const result = try self.in_stream.readBitsNoEof(U, t_bit_count);
@@ -1301,7 +1298,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime is_packed: bool, com
const U = @IntType(false, t_bit_count);
const Log2U = math.Log2Int(U);
- const int_size = @sizeOf(U);
+ const int_size = (U.bit_count + 7) / 8;
const u_value = @bitCast(U, value);
diff --git a/std/mem.zig b/std/mem.zig
index 1c7523bf13..39b9701754 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -423,8 +423,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin.
/// This function cannot fail and cannot cause undefined behavior.
/// Assumes the endianness of memory is native. This means the function can
/// simply pointer cast memory.
-pub fn readIntNative(comptime T: type, bytes: *const [@sizeOf(T)]u8) T {
- comptime assert(T.bit_count % 8 == 0);
+pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T {
return @ptrCast(*align(1) const T, bytes).*;
}
@@ -432,7 +431,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@sizeOf(T)]u8) T {
/// The bit count of T must be evenly divisible by 8.
/// This function cannot fail and cannot cause undefined behavior.
/// Assumes the endianness of memory is foreign, so it must byte-swap.
-pub fn readIntForeign(comptime T: type, bytes: *const [@sizeOf(T)]u8) T {
+pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T {
return @bswap(T, readIntNative(T, bytes));
}
@@ -446,22 +445,20 @@ pub const readIntBig = switch (builtin.endian) {
builtin.Endian.Big => readIntNative,
};
-/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
+/// Asserts that bytes.len >= T.bit_count / 8. Reads the integer starting from index 0
/// and ignores extra bytes.
-/// Note that @sizeOf(u24) is 3.
/// The bit count of T must be evenly divisible by 8.
/// Assumes the endianness of memory is native. This means the function can
/// simply pointer cast memory.
pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T {
- assert(@sizeOf(u24) == 3);
- assert(bytes.len >= @sizeOf(T));
+ const n = @divExact(T.bit_count, 8);
+ assert(bytes.len >= n);
// TODO https://github.com/ziglang/zig/issues/863
- return readIntNative(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr));
+ return readIntNative(T, @ptrCast(*const [n]u8, bytes.ptr));
}
-/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
+/// Asserts that bytes.len >= T.bit_count / 8. Reads the integer starting from index 0
/// and ignores extra bytes.
-/// Note that @sizeOf(u24) is 3.
/// The bit count of T must be evenly divisible by 8.
/// Assumes the endianness of memory is foreign, so it must byte-swap.
pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T {
@@ -481,7 +478,7 @@ pub const readIntSliceBig = switch (builtin.endian) {
/// Reads an integer from memory with bit count specified by T.
/// The bit count of T must be evenly divisible by 8.
/// This function cannot fail and cannot cause undefined behavior.
-pub fn readInt(comptime T: type, bytes: *const [@sizeOf(T)]u8, endian: builtin.Endian) T {
+pub fn readInt(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8, endian: builtin.Endian) T {
if (endian == builtin.endian) {
return readIntNative(T, bytes);
} else {
@@ -489,15 +486,14 @@ pub fn readInt(comptime T: type, bytes: *const [@sizeOf(T)]u8, endian: builtin.E
}
}
-/// Asserts that bytes.len >= @sizeOf(T). Reads the integer starting from index 0
+/// Asserts that bytes.len >= T.bit_count / 8. Reads the integer starting from index 0
/// and ignores extra bytes.
-/// Note that @sizeOf(u24) is 3.
/// The bit count of T must be evenly divisible by 8.
pub fn readIntSlice(comptime T: type, bytes: []const u8, endian: builtin.Endian) T {
- assert(@sizeOf(u24) == 3);
- assert(bytes.len >= @sizeOf(T));
+ const n = @divExact(T.bit_count, 8);
+ assert(bytes.len >= n);
// TODO https://github.com/ziglang/zig/issues/863
- return readInt(T, @ptrCast(*const [@sizeOf(T)]u8, bytes.ptr), endian);
+ return readInt(T, @ptrCast(*const [n]u8, bytes.ptr), endian);
}
test "comptime read/write int" {
@@ -540,7 +536,7 @@ test "readIntBig and readIntLittle" {
/// accepts any integer bit width.
/// This function stores in native endian, which means it is implemented as a simple
/// memory store.
-pub fn writeIntNative(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
+pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value: T) void {
@ptrCast(*align(1) T, buf).* = value;
}
@@ -548,7 +544,7 @@ pub fn writeIntNative(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
/// This function always succeeds, has defined behavior for all inputs, but
/// the integer bit width must be divisible by 8.
/// This function stores in foreign endian, which means it does a @bswap first.
-pub fn writeIntForeign(comptime T: type, buf: *[@sizeOf(T)]u8, value: T) void {
+pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void {
writeIntNative(T, buf, @bswap(T, value));
}
@@ -565,8 +561,7 @@ pub const writeIntBig = switch (builtin.endian) {
/// Writes an integer to memory, storing it in twos-complement.
/// This function always succeeds, has defined behavior for all inputs, but
/// the integer bit width must be divisible by 8.
-pub fn writeInt(comptime T: type, buffer: *[@sizeOf(T)]u8, value: T, endian: builtin.Endian) void {
- comptime assert(T.bit_count % 8 == 0);
+pub fn writeInt(comptime T: type, buffer: *[@divExact(T.bit_count, 8)]u8, value: T, endian: builtin.Endian) void {
if (endian == builtin.endian) {
return writeIntNative(T, buffer, value);
} else {
@@ -575,15 +570,13 @@ pub fn writeInt(comptime T: type, buffer: *[@sizeOf(T)]u8, value: T, endian: bui
}
/// Writes a twos-complement little-endian integer to memory.
-/// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
+/// Asserts that buf.len >= T.bit_count / 8.
/// The bit count of T must be divisible by 8.
/// Any extra bytes in buffer after writing the integer are set to zero. To
/// avoid the branch to check for extra buffer bytes, use writeIntLittle
/// instead.
pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
- comptime assert(@sizeOf(u24) == 3);
- comptime assert(T.bit_count % 8 == 0);
- assert(buffer.len >= @sizeOf(T));
+ assert(buffer.len >= @divExact(T.bit_count, 8));
// TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
const uint = @IntType(false, T.bit_count);
@@ -595,14 +588,12 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
}
/// Writes a twos-complement big-endian integer to memory.
-/// Asserts that buffer.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
+/// Asserts that buffer.len >= T.bit_count / 8.
/// The bit count of T must be divisible by 8.
/// Any extra bytes in buffer before writing the integer are set to zero. To
/// avoid the branch to check for extra buffer bytes, use writeIntBig instead.
pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
- comptime assert(@sizeOf(u24) == 3);
- comptime assert(T.bit_count % 8 == 0);
- assert(buffer.len >= @sizeOf(T));
+ assert(buffer.len >= @divExact(T.bit_count, 8));
// TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
const uint = @IntType(false, T.bit_count);
@@ -626,7 +617,7 @@ pub const writeIntSliceForeign = switch (builtin.endian) {
};
/// Writes a twos-complement integer to memory, with the specified endianness.
-/// Asserts that buf.len >= @sizeOf(T). Note that @sizeOf(u24) is 3.
+/// Asserts that buf.len >= T.bit_count / 8.
/// The bit count of T must be evenly divisible by 8.
/// Any extra bytes in buffer not part of the integer are set to zero, with
/// respect to endianness. To avoid the branch to check for extra buffer bytes,
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index 1fa00b34fd..df311637fa 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -17,6 +17,7 @@ comptime {
_ = @import("behavior/bugs/1421.zig");
_ = @import("behavior/bugs/1442.zig");
_ = @import("behavior/bugs/1486.zig");
+ _ = @import("behavior/bugs/1851.zig");
_ = @import("behavior/bugs/394.zig");
_ = @import("behavior/bugs/655.zig");
_ = @import("behavior/bugs/656.zig");
diff --git a/test/stage1/behavior/bugs/1851.zig b/test/stage1/behavior/bugs/1851.zig
new file mode 100644
index 0000000000..ff9ab419f8
--- /dev/null
+++ b/test/stage1/behavior/bugs/1851.zig
@@ -0,0 +1,27 @@
+const std = @import("std");
+const expect = std.testing.expect;
+
+test "allocation and looping over 3-byte integer" {
+ expect(@sizeOf(u24) == 4);
+ expect(@sizeOf([1]u24) == 4);
+ expect(@alignOf(u24) == 4);
+ expect(@alignOf([1]u24) == 4);
+ var buffer: [100]u8 = undefined;
+ const a = &std.heap.FixedBufferAllocator.init(&buffer).allocator;
+
+ var x = a.alloc(u24, 2) catch unreachable;
+ expect(x.len == 2);
+ x[0] = 0xFFFFFF;
+ x[1] = 0xFFFFFF;
+
+ const bytes = @sliceToBytes(x);
+ expect(@typeOf(bytes) == []align(4) u8);
+ expect(bytes.len == 8);
+
+ for (bytes) |*b| {
+ b.* = 0x00;
+ }
+
+ expect(x[0] == 0x00);
+ expect(x[1] == 0x00);
+}
From a05e224150a5a4bcad5ab1b399b43db8a0e28104 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 15 Feb 2019 19:19:28 -0500
Subject: [PATCH 207/218] typecheck the panic function
this adds the prototype of panic to @import("builtin")
and then uses it to do an implicit cast of the panic
function to this prototype, rather than redoing all the
implicit cast logic.
closes #1894
closes #1895
---
src/all_types.hpp | 1 +
src/analyze.cpp | 61 +++++++++++++++--------------------------
src/analyze.hpp | 1 +
src/codegen.cpp | 4 +++
src/ir.cpp | 15 ++++++----
src/ir.hpp | 2 +-
test/compile_errors.zig | 14 ++++++++--
7 files changed, 50 insertions(+), 48 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index bafe316c3d..6fbd987b9e 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -1758,6 +1758,7 @@ struct CodeGen {
ZigFn *cur_fn;
ZigFn *main_fn;
ZigFn *panic_fn;
+ TldFn *panic_tld_fn;
AstNode *root_export_decl;
CacheHash cache_hash;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 7949493586..12e245bd72 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1351,7 +1351,7 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no
size_t backward_branch_count = 0;
return ir_eval_const_value(g, scope, node, type_entry,
&backward_branch_count, default_backward_branch_quota,
- nullptr, nullptr, node, type_name, nullptr);
+ nullptr, nullptr, node, type_name, nullptr, nullptr);
}
ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) {
@@ -3247,36 +3247,19 @@ static bool scope_is_root_decls(Scope *scope) {
zig_unreachable();
}
-static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, ZigType *fn_type) {
- add_node_error(g, proto_node,
- buf_sprintf("expected 'fn([]const u8, ?*builtin.StackTrace) noreturn', found '%s'",
- buf_ptr(&fn_type->name)));
-}
+void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn) {
+ ConstExprValue *panic_fn_type_val = get_builtin_value(g, "PanicFn");
+ assert(panic_fn_type_val != nullptr);
+ assert(panic_fn_type_val->type->id == ZigTypeIdMetaType);
+ ZigType *panic_fn_type = panic_fn_type_val->data.x_type;
-static void typecheck_panic_fn(CodeGen *g, ZigFn *panic_fn) {
- AstNode *proto_node = panic_fn->proto_node;
- assert(proto_node->type == NodeTypeFnProto);
- ZigType *fn_type = panic_fn->type_entry;
- FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
- if (fn_type_id->param_count != 2) {
- return wrong_panic_prototype(g, proto_node, fn_type);
- }
- ZigType *const_u8_ptr = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false,
- PtrLenUnknown, 0, 0, 0);
- ZigType *const_u8_slice = get_slice_type(g, const_u8_ptr);
- if (fn_type_id->param_info[0].type != const_u8_slice) {
- return wrong_panic_prototype(g, proto_node, fn_type);
- }
+ AstNode *fake_decl = allocate(1);
+ *fake_decl = *panic_fn->proto_node;
+ fake_decl->type = NodeTypeSymbol;
+ fake_decl->data.symbol_expr.symbol = &panic_fn->symbol_name;
- ZigType *optional_ptr_to_stack_trace_type = get_optional_type(g, get_ptr_to_stack_trace_type(g));
- if (fn_type_id->param_info[1].type != optional_ptr_to_stack_trace_type) {
- return wrong_panic_prototype(g, proto_node, fn_type);
- }
-
- ZigType *actual_return_type = fn_type_id->return_type;
- if (actual_return_type != g->builtin_types.entry_unreachable) {
- return wrong_panic_prototype(g, proto_node, fn_type);
- }
+ // call this for the side effects of casting to panic_fn_type
+ analyze_const_value(g, tld_fn->base.parent_scope, fake_decl, panic_fn_type, nullptr);
}
ZigType *get_test_fn_type(CodeGen *g) {
@@ -3371,18 +3354,18 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
if (!fn_table_entry->type_entry->data.fn.is_generic) {
if (fn_def_node)
g->fn_defs.append(fn_table_entry);
+ }
- if (scope_is_root_decls(tld_fn->base.parent_scope) &&
- (import == g->root_import || import->package == g->panic_package))
+ if (scope_is_root_decls(tld_fn->base.parent_scope) &&
+ (import == g->root_import || import->package == g->panic_package))
+ {
+ if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
+ g->main_fn = fn_table_entry;
+ } else if ((import->package == g->panic_package || g->have_pub_panic) &&
+ buf_eql_str(&fn_table_entry->symbol_name, "panic"))
{
- if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) {
- g->main_fn = fn_table_entry;
- } else if ((import->package == g->panic_package || g->have_pub_panic) &&
- buf_eql_str(&fn_table_entry->symbol_name, "panic"))
- {
- g->panic_fn = fn_table_entry;
- typecheck_panic_fn(g, fn_table_entry);
- }
+ g->panic_fn = fn_table_entry;
+ g->panic_tld_fn = tld_fn;
}
}
} else if (source_node->type == NodeTypeTestDecl) {
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 7ded651e95..956ef47309 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -239,4 +239,5 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);
Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
ConstExprValue *const_val, ZigType *wanted_type);
+void typecheck_panic_fn(CodeGen *g, TldFn *tld_fn, ZigFn *panic_fn);
#endif
diff --git a/src/codegen.cpp b/src/codegen.cpp
index d2662b10d2..d2b2836b0c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -7144,6 +7144,8 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
" instruction_addresses: []usize,\n"
"};\n\n");
+ buf_append_str(contents, "pub const PanicFn = fn([]const u8, ?*StackTrace) noreturn;\n\n");
+
const char *cur_os = nullptr;
{
buf_appendf(contents, "pub const Os = enum {\n");
@@ -7913,6 +7915,8 @@ static void gen_root_source(CodeGen *g) {
}
}
+ typecheck_panic_fn(g, g->panic_tld_fn, g->panic_fn);
+
report_errors_and_maybe_exit(g);
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 92cdd8c891..0fcbb60fe8 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -9949,7 +9949,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
- IrExecutable *parent_exec)
+ IrExecutable *parent_exec, AstNode *expected_type_source_node)
{
if (expected_type != nullptr && type_is_invalid(expected_type))
return &codegen->invalid_instruction->value;
@@ -9985,7 +9985,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
analyzed_executable->backward_branch_count = backward_branch_count;
analyzed_executable->backward_branch_quota = backward_branch_quota;
analyzed_executable->begin_scope = scope;
- ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node);
+ ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, expected_type_source_node);
if (type_is_invalid(result_type))
return &codegen->invalid_instruction->value;
@@ -10863,10 +10863,13 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
}
break;
}
+ case ConstCastResultIdFnIsGeneric:
+ add_error_note(ira->codegen, parent_msg, source_node,
+ buf_sprintf("only one of the functions is generic"));
+ break;
case ConstCastResultIdFnAlign: // TODO
case ConstCastResultIdFnCC: // TODO
case ConstCastResultIdFnVarArgs: // TODO
- case ConstCastResultIdFnIsGeneric: // TODO
case ConstCastResultIdFnReturnType: // TODO
case ConstCastResultIdFnArgCount: // TODO
case ConstCastResultIdFnGenericArgCount: // TODO
@@ -13856,7 +13859,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
AstNode *body_node = fn_entry->body_node;
result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type,
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry,
- nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec);
+ nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node);
if (inferred_err_set_type != nullptr) {
inferred_err_set_type->data.error_set.infer_fn = nullptr;
@@ -14052,7 +14055,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope,
fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen),
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota,
- nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec);
+ nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr);
IrInstructionConst *const_instruction = ir_create_instruction(&ira->new_irb,
impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr);
const_instruction->base.value = *align_result;
@@ -18464,7 +18467,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
ZigType *void_type = ira->codegen->builtin_types.entry_void;
ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type,
ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr,
- &cimport_scope->buf, block_node, nullptr, nullptr);
+ &cimport_scope->buf, block_node, nullptr, nullptr, nullptr);
if (type_is_invalid(cimport_result->type))
return ira->codegen->invalid_instruction;
diff --git a/src/ir.hpp b/src/ir.hpp
index 0a7c614812..0b85ad2c55 100644
--- a/src/ir.hpp
+++ b/src/ir.hpp
@@ -16,7 +16,7 @@ bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
- IrExecutable *parent_exec);
+ IrExecutable *parent_exec, AstNode *expected_type_source_node);
ZigType *ir_analyze(CodeGen *g, IrExecutable *old_executable, IrExecutable *new_executable,
ZigType *expected_type, AstNode *expected_type_source_node);
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index e7108cb36a..9ef4af4162 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -346,13 +346,23 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
);
cases.add(
- "Panic declared with wrong type signature in tests",
+ "wrong panic signature, runtime function",
\\test "" {}
\\
\\pub fn panic() void {}
\\
,
- ".tmp_source.zig:3:5: error: expected 'fn([]const u8, ?*builtin.StackTrace) noreturn', found 'fn() void'",
+ ".tmp_source.zig:3:5: error: expected type 'fn([]const u8, ?*StackTrace) noreturn', found 'fn() void'",
+ );
+
+ cases.add(
+ "wrong panic signature, generic function",
+ \\pub fn panic(comptime msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn {
+ \\ while (true) {}
+ \\}
+ ,
+ ".tmp_source.zig:1:5: error: expected type 'fn([]const u8, ?*StackTrace) noreturn', found 'fn([]const u8,var)var'",
+ ".tmp_source.zig:1:5: note: only one of the functions is generic",
);
cases.add(
From 5736a9c6a9b357ab346dd8fcbe64f5d729d6d244 Mon Sep 17 00:00:00 2001
From: emekoi
Date: Tue, 12 Feb 2019 10:21:45 -0600
Subject: [PATCH 208/218] removed hidden union tag in release modes
---
src/analyze.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 12e245bd72..9941104bc4 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -2886,7 +2886,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) {
union_type->data.unionation.have_explicit_tag_type = decl_node->data.container_decl.auto_enum ||
enum_type_node != nullptr;
bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto);
- bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr);
+ bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr) && !(g->build_mode == BuildModeFastRelease || g->build_mode == BuildModeSmallRelease);
ZigType *tag_type;
bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety);
bool *covered_enum_fields;
From ba56f365c813440b79c1710c6a8b0fd591883e13 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 16 Feb 2019 00:42:56 -0500
Subject: [PATCH 209/218] bring zig fmt to stage1
---
CMakeLists.txt | 5 +
src-self-hosted/main.zig | 6 +-
src/main.cpp | 36 ++++-
std/special/fmt_runner.zig | 265 +++++++++++++++++++++++++++++++++++++
4 files changed, 305 insertions(+), 7 deletions(-)
create mode 100644 std/special/fmt_runner.zig
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8e80c65dbd..db5f50908c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -652,6 +652,7 @@ set(ZIG_STD_FILES
"special/compiler_rt/udivmodti4.zig"
"special/compiler_rt/udivti3.zig"
"special/compiler_rt/umodti3.zig"
+ "special/fmt_runner.zig"
"special/init-exe/build.zig"
"special/init-exe/src/main.zig"
"special/init-lib/build.zig"
@@ -905,3 +906,7 @@ foreach(file ${ZIG_STD_FILES})
get_filename_component(file_dir "${ZIG_STD_DEST}/${file}" DIRECTORY)
install(FILES "${CMAKE_SOURCE_DIR}/std/${file}" DESTINATION "${file_dir}")
endforeach()
+
+install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/arg.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
+install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/main.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
+install(FILES "${CMAKE_SOURCE_DIR}/src-self-hosted/errmsg.zig" DESTINATION "${ZIG_STD_DEST}/special/fmt/")
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 64aa729469..42556beaed 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -24,7 +24,7 @@ var stderr_file: os.File = undefined;
var stderr: *io.OutStream(os.File.WriteError) = undefined;
var stdout: *io.OutStream(os.File.WriteError) = undefined;
-const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
+pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB
const usage =
\\usage: zig [command] [options]
@@ -510,7 +510,7 @@ fn cmdBuildObj(allocator: *Allocator, args: []const []const u8) !void {
return buildOutputType(allocator, args, Compilation.Kind.Obj);
}
-const usage_fmt =
+pub const usage_fmt =
\\usage: zig fmt [file]...
\\
\\ Formats the input files and modifies them in-place.
@@ -527,7 +527,7 @@ const usage_fmt =
\\
;
-const args_fmt_spec = []Flag{
+pub const args_fmt_spec = []Flag{
Flag.Bool("--help"),
Flag.Bool("--check"),
Flag.Option("--color", []const []const u8{
diff --git a/src/main.cpp b/src/main.cpp
index 73a1d75d42..78446f9e98 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -21,8 +21,8 @@ static int print_error_usage(const char *arg0) {
return EXIT_FAILURE;
}
-static int print_full_usage(const char *arg0) {
- fprintf(stdout,
+static int print_full_usage(const char *arg0, FILE *file, int return_code) {
+ fprintf(file,
"Usage: %s [command] [options]\n"
"\n"
"Commands:\n"
@@ -31,6 +31,7 @@ static int print_full_usage(const char *arg0) {
" build-lib [source] create library from source or object files\n"
" build-obj [source] create object from source or assembly\n"
" builtin show the source code of that @import(\"builtin\")\n"
+ " fmt parse files and render in canonical zig format\n"
" help show this usage information\n"
" id print the base64-encoded compiler id\n"
" init-exe initialize a `zig build` application in the cwd\n"
@@ -106,7 +107,7 @@ static int print_full_usage(const char *arg0) {
" --test-cmd [arg] specify test execution command one arg at a time\n"
" --test-cmd-bin appends test binary path to test cmd args\n"
, arg0);
- return EXIT_SUCCESS;
+ return return_code;
}
static const char *ZIG_ZEN = "\n"
@@ -515,6 +516,31 @@ int main(int argc, char **argv) {
fprintf(stderr, "\n");
}
return (term.how == TerminationIdClean) ? term.code : -1;
+ } else if (argc >= 2 && strcmp(argv[1], "fmt") == 0) {
+ init_all_targets();
+ Buf *fmt_runner_path = buf_alloc();
+ os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
+ CodeGen *g = codegen_create(fmt_runner_path, nullptr, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
+ nullptr);
+ g->is_single_threaded = true;
+ codegen_set_out_name(g, buf_create_from_str("fmt"));
+ g->enable_cache = true;
+
+ codegen_build_and_link(g);
+
+ ZigList args = {0};
+ for (int i = 2; i < argc; i += 1) {
+ args.append(argv[i]);
+ }
+ args.append(nullptr);
+ const char *exec_path = buf_ptr(&g->output_file_path);
+
+ os_execv(exec_path, args.items);
+
+ args.pop();
+ Termination term;
+ os_spawn_process(exec_path, args, &term);
+ return term.code;
}
for (int i = 1; i < argc; i += 1) {
@@ -527,6 +553,8 @@ int main(int argc, char **argv) {
build_mode = BuildModeSafeRelease;
} else if (strcmp(arg, "--release-small") == 0) {
build_mode = BuildModeSmallRelease;
+ } else if (strcmp(arg, "--help") == 0) {
+ return print_full_usage(arg0, stderr, EXIT_FAILURE);
} else if (strcmp(arg, "--strip") == 0) {
strip = true;
} else if (strcmp(arg, "--static") == 0) {
@@ -1080,7 +1108,7 @@ int main(int argc, char **argv) {
}
}
case CmdHelp:
- return print_full_usage(arg0);
+ return print_full_usage(arg0, stdout, EXIT_SUCCESS);
case CmdVersion:
printf("%s\n", ZIG_VERSION_STRING);
return EXIT_SUCCESS;
diff --git a/std/special/fmt_runner.zig b/std/special/fmt_runner.zig
new file mode 100644
index 0000000000..b6b728f5cf
--- /dev/null
+++ b/std/special/fmt_runner.zig
@@ -0,0 +1,265 @@
+const std = @import("std");
+const builtin = @import("builtin");
+
+const os = std.os;
+const io = std.io;
+const mem = std.mem;
+const Allocator = mem.Allocator;
+const ArrayList = std.ArrayList;
+const Buffer = std.Buffer;
+const ast = std.zig.ast;
+
+const arg = @import("fmt/arg.zig");
+const self_hosted_main = @import("fmt/main.zig");
+const Args = arg.Args;
+const Flag = arg.Flag;
+const errmsg = @import("fmt/errmsg.zig");
+
+var stderr_file: os.File = undefined;
+var stderr: *io.OutStream(os.File.WriteError) = undefined;
+var stdout: *io.OutStream(os.File.WriteError) = undefined;
+
+// This brings `zig fmt` to stage 1.
+pub fn main() !void {
+ // Here we use an ArenaAllocator backed by a DirectAllocator because `zig fmt` is a short-lived,
+ // one shot program. We don't need to waste time freeing memory and finding places to squish
+ // bytes into. So we free everything all at once at the very end.
+ var direct_allocator = std.heap.DirectAllocator.init();
+ var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
+ const allocator = &arena.allocator;
+
+ var stdout_file = try std.io.getStdOut();
+ var stdout_out_stream = stdout_file.outStream();
+ stdout = &stdout_out_stream.stream;
+
+ stderr_file = try std.io.getStdErr();
+ var stderr_out_stream = stderr_file.outStream();
+ stderr = &stderr_out_stream.stream;
+ const args = try std.os.argsAlloc(allocator);
+
+ var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args);
+ defer flags.deinit();
+
+ if (flags.present("help")) {
+ try stdout.write(self_hosted_main.usage_fmt);
+ os.exit(0);
+ }
+
+ const color = blk: {
+ if (flags.single("color")) |color_flag| {
+ if (mem.eql(u8, color_flag, "auto")) {
+ break :blk errmsg.Color.Auto;
+ } else if (mem.eql(u8, color_flag, "on")) {
+ break :blk errmsg.Color.On;
+ } else if (mem.eql(u8, color_flag, "off")) {
+ break :blk errmsg.Color.Off;
+ } else unreachable;
+ } else {
+ break :blk errmsg.Color.Auto;
+ }
+ };
+
+ if (flags.present("stdin")) {
+ if (flags.positionals.len != 0) {
+ try stderr.write("cannot use --stdin with positional arguments\n");
+ os.exit(1);
+ }
+
+ var stdin_file = try io.getStdIn();
+ var stdin = stdin_file.inStream();
+
+ const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
+ defer allocator.free(source_code);
+
+ var tree = std.zig.parse(allocator, source_code) catch |err| {
+ try stderr.print("error parsing stdin: {}\n", err);
+ os.exit(1);
+ };
+ defer tree.deinit();
+
+ var error_it = tree.errors.iterator(0);
+ while (error_it.next()) |parse_error| {
+ try printErrMsgToFile(allocator, parse_error, &tree, "", stderr_file, color);
+ }
+ if (tree.errors.len != 0) {
+ os.exit(1);
+ }
+ if (flags.present("check")) {
+ const anything_changed = try std.zig.render(allocator, io.null_out_stream, &tree);
+ const code = if (anything_changed) u8(1) else u8(0);
+ os.exit(code);
+ }
+
+ _ = try std.zig.render(allocator, stdout, &tree);
+ return;
+ }
+
+ if (flags.positionals.len == 0) {
+ try stderr.write("expected at least one source file argument\n");
+ os.exit(1);
+ }
+
+ if (flags.positionals.len == 0) {
+ try stderr.write("expected at least one source file argument\n");
+ os.exit(1);
+ }
+
+ var fmt = Fmt{
+ .seen = Fmt.SeenMap.init(allocator),
+ .any_error = false,
+ .color = color,
+ .allocator = allocator,
+ };
+
+ const check_mode = flags.present("check");
+
+ for (flags.positionals.toSliceConst()) |file_path| {
+ try fmtPath(&fmt, file_path, check_mode);
+ }
+ if (fmt.any_error) {
+ os.exit(1);
+ }
+}
+
+const FmtError = error{
+ SystemResources,
+ OperationAborted,
+ IoPending,
+ BrokenPipe,
+ Unexpected,
+ WouldBlock,
+ FileClosed,
+ DestinationAddressRequired,
+ DiskQuota,
+ FileTooBig,
+ InputOutput,
+ NoSpaceLeft,
+ AccessDenied,
+ OutOfMemory,
+ RenameAcrossMountPoints,
+ ReadOnlyFileSystem,
+ LinkQuotaExceeded,
+ FileBusy,
+} || os.File.OpenError;
+
+fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
+ const file_path = try std.mem.dupe(fmt.allocator, u8, file_path_ref);
+ defer fmt.allocator.free(file_path);
+
+ if (try fmt.seen.put(file_path, {})) |_| return;
+
+ const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
+ error.IsDir, error.AccessDenied => {
+ // TODO make event based (and dir.next())
+ var dir = try std.os.Dir.open(fmt.allocator, file_path);
+ defer dir.close();
+
+ while (try dir.next()) |entry| {
+ if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
+ const full_path = try os.path.join(fmt.allocator, [][]const u8{ file_path, entry.name });
+ try fmtPath(fmt, full_path, check_mode);
+ }
+ }
+ return;
+ },
+ else => {
+ // TODO lock stderr printing
+ try stderr.print("unable to open '{}': {}\n", file_path, err);
+ fmt.any_error = true;
+ return;
+ },
+ };
+ defer fmt.allocator.free(source_code);
+
+ var tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
+ try stderr.print("error parsing file '{}': {}\n", file_path, err);
+ fmt.any_error = true;
+ return;
+ };
+ defer tree.deinit();
+
+ var error_it = tree.errors.iterator(0);
+ while (error_it.next()) |parse_error| {
+ try printErrMsgToFile(fmt.allocator, parse_error, &tree, file_path, stderr_file, fmt.color);
+ }
+ if (tree.errors.len != 0) {
+ fmt.any_error = true;
+ return;
+ }
+
+ if (check_mode) {
+ const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, &tree);
+ if (anything_changed) {
+ try stderr.print("{}\n", file_path);
+ fmt.any_error = true;
+ }
+ } else {
+ // TODO make this evented
+ const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
+ defer baf.destroy();
+
+ const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), &tree);
+ if (anything_changed) {
+ try stderr.print("{}\n", file_path);
+ try baf.finish();
+ }
+ }
+}
+
+const Fmt = struct {
+ seen: SeenMap,
+ any_error: bool,
+ color: errmsg.Color,
+ allocator: *mem.Allocator,
+
+ const SeenMap = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
+};
+
+fn printErrMsgToFile(allocator: *mem.Allocator, parse_error: *const ast.Error, tree: *ast.Tree,
+ path: []const u8, file: os.File, color: errmsg.Color,) !void
+{
+ const color_on = switch (color) {
+ errmsg.Color.Auto => file.isTty(),
+ errmsg.Color.On => true,
+ errmsg.Color.Off => false,
+ };
+ const lok_token = parse_error.loc();
+ const span = errmsg.Span{
+ .first = lok_token,
+ .last = lok_token,
+ };
+
+ const first_token = tree.tokens.at(span.first);
+ const last_token = tree.tokens.at(span.last);
+ const start_loc = tree.tokenLocationPtr(0, first_token);
+ const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
+
+ var text_buf = try std.Buffer.initSize(allocator, 0);
+ var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
+ try parse_error.render(&tree.tokens, out_stream);
+ const text = text_buf.toOwnedSlice();
+
+ const stream = &file.outStream().stream;
+ if (!color_on) {
+ try stream.print(
+ "{}:{}:{}: error: {}\n",
+ path,
+ start_loc.line + 1,
+ start_loc.column + 1,
+ text,
+ );
+ return;
+ }
+
+ try stream.print(
+ "{}:{}:{}: error: {}\n{}\n",
+ path,
+ start_loc.line + 1,
+ start_loc.column + 1,
+ text,
+ tree.source[start_loc.line_start..start_loc.line_end],
+ );
+ try stream.writeByteNTimes(' ', start_loc.column);
+ try stream.writeByteNTimes('~', last_token.end - first_token.start);
+ try stream.write("\n");
+}
From a97362e67739c94d6266cc2d1352dd9bb1b713be Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 16 Feb 2019 12:24:02 -0500
Subject: [PATCH 210/218] fmt_runner: remove redundant check
---
std/special/fmt_runner.zig | 5 -----
1 file changed, 5 deletions(-)
diff --git a/std/special/fmt_runner.zig b/std/special/fmt_runner.zig
index b6b728f5cf..46ced0e136 100644
--- a/std/special/fmt_runner.zig
+++ b/std/special/fmt_runner.zig
@@ -99,11 +99,6 @@ pub fn main() !void {
os.exit(1);
}
- if (flags.positionals.len == 0) {
- try stderr.write("expected at least one source file argument\n");
- os.exit(1);
- }
-
var fmt = Fmt{
.seen = Fmt.SeenMap.init(allocator),
.any_error = false,
From f4c5bcfea5f02dec30d7adede0550c95af424c71 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 16 Feb 2019 13:34:32 -0500
Subject: [PATCH 211/218] refactor translate-c - no more using namespace clang
this is in preparation for #1964
---
src/translate_c.cpp | 2276 +++++++++++++++++++++----------------------
1 file changed, 1137 insertions(+), 1139 deletions(-)
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 710314d1cb..7d618466b2 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -30,8 +30,6 @@
#include
-using namespace clang;
-
struct Alias {
Buf *new_name;
Buf *canon_name;
@@ -87,13 +85,13 @@ struct Context {
HashMap decl_table;
HashMap macro_table;
HashMap global_table;
- SourceManager *source_manager;
+ clang::SourceManager *source_manager;
ZigList aliases;
AstNode *source_node;
bool warnings_on;
CodeGen *codegen;
- ASTContext *ctx;
+ clang::ASTContext *ctx;
TransScopeRoot *global_scope;
HashMap ptr_params;
@@ -117,21 +115,21 @@ static TransScopeSwitch *trans_scope_switch_create(Context *c, TransScope *paren
static TransScopeBlock *trans_scope_block_find(TransScope *scope);
-static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl);
-static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl);
-static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl);
+static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl);
+static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl);
+static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl);
-static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
+static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt,
ResultUsed result_used, TransLRValue lrval,
AstNode **out_node, TransScope **out_child_scope,
TransScope **out_node_scope);
-static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node);
-static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
-static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc);
-static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval);
+static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node);
+static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
+static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc);
+static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval);
ATTRIBUTE_PRINTF(3, 4)
-static void emit_warning(Context *c, const SourceLocation &sl, const char *format, ...) {
+static void emit_warning(Context *c, const clang::SourceLocation &sl, const char *format, ...) {
if (!c->warnings_on) {
return;
}
@@ -471,8 +469,8 @@ static Buf *string_ref_to_buf(StringRef string_ref) {
return buf_create_from_mem((const char *)string_ref.bytes_begin(), string_ref.size());
}
-static const char *decl_name(const Decl *decl) {
- const NamedDecl *named_decl = static_cast(decl);
+static const char *decl_name(const clang::Decl *decl) {
+ const clang::NamedDecl *named_decl = static_cast(decl);
return (const char *)named_decl->getName().bytes_begin();
}
@@ -490,20 +488,20 @@ static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int)
}
-static const Type *qual_type_canon(QualType qt) {
+static const clang::Type *qual_type_canon(clang::QualType qt) {
return qt.getCanonicalType().getTypePtr();
}
-static QualType get_expr_qual_type(Context *c, const Expr *expr) {
+static clang::QualType get_expr_qual_type(Context *c, const clang::Expr *expr) {
// String literals in C are `char *` but they should really be `const char *`.
- if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
- const ImplicitCastExpr *cast_expr = static_cast(expr);
- if (cast_expr->getCastKind() == CK_ArrayToPointerDecay) {
- const Expr *sub_expr = cast_expr->getSubExpr();
- if (sub_expr->getStmtClass() == Stmt::StringLiteralClass) {
- QualType array_qt = sub_expr->getType();
- const ArrayType *array_type = static_cast(array_qt.getTypePtr());
- QualType pointee_qt = array_type->getElementType();
+ if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
+ const clang::ImplicitCastExpr *cast_expr = static_cast(expr);
+ if (cast_expr->getCastKind() == clang::CK_ArrayToPointerDecay) {
+ const clang::Expr *sub_expr = cast_expr->getSubExpr();
+ if (sub_expr->getStmtClass() == clang::Stmt::StringLiteralClass) {
+ clang::QualType array_qt = sub_expr->getType();
+ const clang::ArrayType *array_type = static_cast(array_qt.getTypePtr());
+ clang::QualType pointee_qt = array_type->getElementType();
pointee_qt.addConst();
return c->ctx->getPointerType(pointee_qt);
}
@@ -512,19 +510,19 @@ static QualType get_expr_qual_type(Context *c, const Expr *expr) {
return expr->getType();
}
-static QualType get_expr_qual_type_before_implicit_cast(Context *c, const Expr *expr) {
- if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
- const ImplicitCastExpr *cast_expr = static_cast(expr);
+static clang::QualType get_expr_qual_type_before_implicit_cast(Context *c, const clang::Expr *expr) {
+ if (expr->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
+ const clang::ImplicitCastExpr *cast_expr = static_cast(expr);
return get_expr_qual_type(c, cast_expr->getSubExpr());
}
return expr->getType();
}
-static AstNode *get_expr_type(Context *c, const Expr *expr) {
+static AstNode *get_expr_type(Context *c, const clang::Expr *expr) {
return trans_qual_type(c, get_expr_qual_type(c, expr), expr->getLocStart());
}
-static bool qual_types_equal(QualType t1, QualType t2) {
+static bool qual_types_equal(clang::QualType t1, clang::QualType t2) {
if (t1.isConstQualified() != t2.isConstQualified()) {
return false;
}
@@ -541,37 +539,37 @@ static bool is_c_void_type(AstNode *node) {
return (node->type == NodeTypeSymbol && buf_eql_str(node->data.symbol_expr.symbol, "c_void"));
}
-static bool expr_types_equal(Context *c, const Expr *expr1, const Expr *expr2) {
- QualType t1 = get_expr_qual_type(c, expr1);
- QualType t2 = get_expr_qual_type(c, expr2);
+static bool expr_types_equal(Context *c, const clang::Expr *expr1, const clang::Expr *expr2) {
+ clang::QualType t1 = get_expr_qual_type(c, expr1);
+ clang::QualType t2 = get_expr_qual_type(c, expr2);
return qual_types_equal(t1, t2);
}
-static bool qual_type_is_ptr(QualType qt) {
- const Type *ty = qual_type_canon(qt);
- return ty->getTypeClass() == Type::Pointer;
+static bool qual_type_is_ptr(clang::QualType qt) {
+ const clang::Type *ty = qual_type_canon(qt);
+ return ty->getTypeClass() == clang::Type::Pointer;
}
-static const FunctionProtoType *qual_type_get_fn_proto(QualType qt, bool *is_ptr) {
- const Type *ty = qual_type_canon(qt);
+static const clang::FunctionProtoType *qual_type_get_fn_proto(clang::QualType qt, bool *is_ptr) {
+ const clang::Type *ty = qual_type_canon(qt);
*is_ptr = false;
- if (ty->getTypeClass() == Type::Pointer) {
+ if (ty->getTypeClass() == clang::Type::Pointer) {
*is_ptr = true;
- const PointerType *pointer_ty = static_cast(ty);
- QualType child_qt = pointer_ty->getPointeeType();
+ const clang::PointerType *pointer_ty = static_cast(ty);
+ clang::QualType child_qt = pointer_ty->getPointeeType();
ty = child_qt.getTypePtr();
}
- if (ty->getTypeClass() == Type::FunctionProto) {
- return static_cast(ty);
+ if (ty->getTypeClass() == clang::Type::FunctionProto) {
+ return static_cast(ty);
}
return nullptr;
}
-static bool qual_type_is_fn_ptr(QualType qt) {
+static bool qual_type_is_fn_ptr(clang::QualType qt) {
bool is_ptr;
if (qual_type_get_fn_proto(qt, &is_ptr)) {
return is_ptr;
@@ -580,30 +578,30 @@ static bool qual_type_is_fn_ptr(QualType qt) {
return false;
}
-static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const SourceLocation &source_loc) {
- const Type *ty = qt.getTypePtr();
+static uint32_t qual_type_int_bit_width(Context *c, const clang::QualType &qt, const clang::SourceLocation &source_loc) {
+ const clang::Type *ty = qt.getTypePtr();
switch (ty->getTypeClass()) {
- case Type::Builtin:
+ case clang::Type::Builtin:
{
- const BuiltinType *builtin_ty = static_cast(ty);
+ const clang::BuiltinType *builtin_ty = static_cast(ty);
switch (builtin_ty->getKind()) {
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- case BuiltinType::Char_S:
- case BuiltinType::SChar:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
return 8;
- case BuiltinType::UInt128:
- case BuiltinType::Int128:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Int128:
return 128;
default:
return 0;
}
zig_unreachable();
}
- case Type::Typedef:
+ case clang::Type::Typedef:
{
- const TypedefType *typedef_ty = static_cast(ty);
- const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
+ const clang::TypedefType *typedef_ty = static_cast(ty);
+ const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
const char *type_name = decl_name(typedef_decl);
if (strcmp(type_name, "uint8_t") == 0 || strcmp(type_name, "int8_t") == 0) {
return 8;
@@ -624,8 +622,8 @@ static uint32_t qual_type_int_bit_width(Context *c, const QualType &qt, const So
}
-static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt,
- const SourceLocation &source_loc)
+static AstNode *qual_type_to_log2_int_ref(Context *c, const clang::QualType &qt,
+ const clang::SourceLocation &source_loc)
{
uint32_t int_bit_width = qual_type_int_bit_width(c, qt, source_loc);
if (int_bit_width != 0) {
@@ -643,7 +641,7 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt,
// FieldAccess
// FnCall (.builtin = true)
// Symbol "import"
-// StringLiteral "std"
+// clang::StringLiteral "std"
// Symbol "math"
// Symbol "Log2Int"
// zig_type_node
@@ -657,21 +655,21 @@ static AstNode *qual_type_to_log2_int_ref(Context *c, const QualType &qt,
return log2int_fn_call;
}
-static bool qual_type_child_is_fn_proto(const QualType &qt) {
- if (qt.getTypePtr()->getTypeClass() == Type::Paren) {
- const ParenType *paren_type = static_cast(qt.getTypePtr());
- if (paren_type->getInnerType()->getTypeClass() == Type::FunctionProto) {
+static bool qual_type_child_is_fn_proto(const clang::QualType &qt) {
+ if (qt.getTypePtr()->getTypeClass() == clang::Type::Paren) {
+ const clang::ParenType *paren_type = static_cast(qt.getTypePtr());
+ if (paren_type->getInnerType()->getTypeClass() == clang::Type::FunctionProto) {
return true;
}
- } else if (qt.getTypePtr()->getTypeClass() == Type::Attributed) {
- const AttributedType *attr_type = static_cast(qt.getTypePtr());
+ } else if (qt.getTypePtr()->getTypeClass() == clang::Type::Attributed) {
+ const clang::AttributedType *attr_type = static_cast(qt.getTypePtr());
return qual_type_child_is_fn_proto(attr_type->getEquivalentType());
}
return false;
}
-static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location, QualType dest_type,
- QualType src_type, AstNode *expr)
+static AstNode* trans_c_cast(Context *c, const clang::SourceLocation &source_location, clang::QualType dest_type,
+ clang::QualType src_type, AstNode *expr)
{
if (qual_types_equal(dest_type, src_type)) {
return expr;
@@ -688,72 +686,72 @@ static AstNode* trans_c_cast(Context *c, const SourceLocation &source_location,
return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);
}
-static bool c_is_signed_integer(Context *c, QualType qt) {
- const Type *c_type = qual_type_canon(qt);
- if (c_type->getTypeClass() != Type::Builtin)
+static bool c_is_signed_integer(Context *c, clang::QualType qt) {
+ const clang::Type *c_type = qual_type_canon(qt);
+ if (c_type->getTypeClass() != clang::Type::Builtin)
return false;
- const BuiltinType *builtin_ty = static_cast(c_type);
+ const clang::BuiltinType *builtin_ty = static_cast(c_type);
switch (builtin_ty->getKind()) {
- case BuiltinType::SChar:
- case BuiltinType::Short:
- case BuiltinType::Int:
- case BuiltinType::Long:
- case BuiltinType::LongLong:
- case BuiltinType::Int128:
- case BuiltinType::WChar_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::WChar_S:
return true;
default:
return false;
}
}
-static bool c_is_unsigned_integer(Context *c, QualType qt) {
- const Type *c_type = qual_type_canon(qt);
- if (c_type->getTypeClass() != Type::Builtin)
+static bool c_is_unsigned_integer(Context *c, clang::QualType qt) {
+ const clang::Type *c_type = qual_type_canon(qt);
+ if (c_type->getTypeClass() != clang::Type::Builtin)
return false;
- const BuiltinType *builtin_ty = static_cast(c_type);
+ const clang::BuiltinType *builtin_ty = static_cast(c_type);
switch (builtin_ty->getKind()) {
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- case BuiltinType::Char_S:
- case BuiltinType::UShort:
- case BuiltinType::UInt:
- case BuiltinType::ULong:
- case BuiltinType::ULongLong:
- case BuiltinType::UInt128:
- case BuiltinType::WChar_U:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::WChar_U:
return true;
default:
return false;
}
}
-static bool c_is_builtin_type(Context *c, QualType qt, BuiltinType::Kind kind) {
- const Type *c_type = qual_type_canon(qt);
- if (c_type->getTypeClass() != Type::Builtin)
+static bool c_is_builtin_type(Context *c, clang::QualType qt, clang::BuiltinType::Kind kind) {
+ const clang::Type *c_type = qual_type_canon(qt);
+ if (c_type->getTypeClass() != clang::Type::Builtin)
return false;
- const BuiltinType *builtin_ty = static_cast(c_type);
+ const clang::BuiltinType *builtin_ty = static_cast(c_type);
return builtin_ty->getKind() == kind;
}
-static bool c_is_float(Context *c, QualType qt) {
- const Type *c_type = qt.getTypePtr();
- if (c_type->getTypeClass() != Type::Builtin)
+static bool c_is_float(Context *c, clang::QualType qt) {
+ const clang::Type *c_type = qt.getTypePtr();
+ if (c_type->getTypeClass() != clang::Type::Builtin)
return false;
- const BuiltinType *builtin_ty = static_cast(c_type);
+ const clang::BuiltinType *builtin_ty = static_cast(c_type);
switch (builtin_ty->getKind()) {
- case BuiltinType::Half:
- case BuiltinType::Float:
- case BuiltinType::Double:
- case BuiltinType::Float128:
- case BuiltinType::LongDouble:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::LongDouble:
return true;
default:
return false;
}
}
-static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
+static bool qual_type_has_wrapping_overflow(Context *c, clang::QualType qt) {
if (c_is_signed_integer(c, qt) || c_is_float(c, qt)) {
// float and signed integer overflow is undefined behavior.
return false;
@@ -763,23 +761,23 @@ static bool qual_type_has_wrapping_overflow(Context *c, QualType qt) {
}
}
-static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &source_loc) {
+static bool type_is_opaque(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
- case Type::Builtin: {
- const BuiltinType *builtin_ty = static_cast(ty);
- return builtin_ty->getKind() == BuiltinType::Void;
+ case clang::Type::Builtin: {
+ const clang::BuiltinType *builtin_ty = static_cast(ty);
+ return builtin_ty->getKind() == clang::BuiltinType::Void;
}
- case Type::Record: {
- const RecordType *record_ty = static_cast(ty);
+ case clang::Type::Record: {
+ const clang::RecordType *record_ty = static_cast(ty);
return record_ty->getDecl()->getDefinition() == nullptr;
}
- case Type::Elaborated: {
- const ElaboratedType *elaborated_ty = static_cast(ty);
+ case clang::Type::Elaborated: {
+ const clang::ElaboratedType *elaborated_ty = static_cast(ty);
return type_is_opaque(c, elaborated_ty->getNamedType().getTypePtr(), source_loc);
}
- case Type::Typedef: {
- const TypedefType *typedef_ty = static_cast(ty);
- const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
+ case clang::Type::Typedef: {
+ const clang::TypedefType *typedef_ty = static_cast(ty);
+ const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
return type_is_opaque(c, typedef_decl->getUnderlyingType().getTypePtr(), source_loc);
}
default:
@@ -787,145 +785,145 @@ static bool type_is_opaque(Context *c, const Type *ty, const SourceLocation &sou
}
}
-static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &source_loc) {
+static AstNode *trans_type(Context *c, const clang::Type *ty, const clang::SourceLocation &source_loc) {
switch (ty->getTypeClass()) {
- case Type::Builtin:
+ case clang::Type::Builtin:
{
- const BuiltinType *builtin_ty = static_cast(ty);
+ const clang::BuiltinType *builtin_ty = static_cast(ty);
switch (builtin_ty->getKind()) {
- case BuiltinType::Void:
+ case clang::BuiltinType::Void:
return trans_create_node_symbol_str(c, "c_void");
- case BuiltinType::Bool:
+ case clang::BuiltinType::Bool:
return trans_create_node_symbol_str(c, "bool");
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- case BuiltinType::Char_S:
- case BuiltinType::Char8:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::Char8:
return trans_create_node_symbol_str(c, "u8");
- case BuiltinType::SChar:
+ case clang::BuiltinType::SChar:
return trans_create_node_symbol_str(c, "i8");
- case BuiltinType::UShort:
+ case clang::BuiltinType::UShort:
return trans_create_node_symbol_str(c, "c_ushort");
- case BuiltinType::UInt:
+ case clang::BuiltinType::UInt:
return trans_create_node_symbol_str(c, "c_uint");
- case BuiltinType::ULong:
+ case clang::BuiltinType::ULong:
return trans_create_node_symbol_str(c, "c_ulong");
- case BuiltinType::ULongLong:
+ case clang::BuiltinType::ULongLong:
return trans_create_node_symbol_str(c, "c_ulonglong");
- case BuiltinType::Short:
+ case clang::BuiltinType::Short:
return trans_create_node_symbol_str(c, "c_short");
- case BuiltinType::Int:
+ case clang::BuiltinType::Int:
return trans_create_node_symbol_str(c, "c_int");
- case BuiltinType::Long:
+ case clang::BuiltinType::Long:
return trans_create_node_symbol_str(c, "c_long");
- case BuiltinType::LongLong:
+ case clang::BuiltinType::LongLong:
return trans_create_node_symbol_str(c, "c_longlong");
- case BuiltinType::UInt128:
+ case clang::BuiltinType::UInt128:
return trans_create_node_symbol_str(c, "u128");
- case BuiltinType::Int128:
+ case clang::BuiltinType::Int128:
return trans_create_node_symbol_str(c, "i128");
- case BuiltinType::Float:
+ case clang::BuiltinType::Float:
return trans_create_node_symbol_str(c, "f32");
- case BuiltinType::Double:
+ case clang::BuiltinType::Double:
return trans_create_node_symbol_str(c, "f64");
- case BuiltinType::Float128:
+ case clang::BuiltinType::Float128:
return trans_create_node_symbol_str(c, "f128");
- case BuiltinType::Float16:
+ case clang::BuiltinType::Float16:
return trans_create_node_symbol_str(c, "f16");
- case BuiltinType::LongDouble:
+ case clang::BuiltinType::LongDouble:
return trans_create_node_symbol_str(c, "c_longdouble");
- case BuiltinType::WChar_U:
- case BuiltinType::Char16:
- case BuiltinType::Char32:
- case BuiltinType::WChar_S:
- case BuiltinType::Half:
- case BuiltinType::NullPtr:
- case BuiltinType::ObjCId:
- case BuiltinType::ObjCClass:
- case BuiltinType::ObjCSel:
- case BuiltinType::OMPArraySection:
- case BuiltinType::Dependent:
- case BuiltinType::Overload:
- case BuiltinType::BoundMember:
- case BuiltinType::PseudoObject:
- case BuiltinType::UnknownAny:
- case BuiltinType::BuiltinFn:
- case BuiltinType::ARCUnbridgedCast:
- case BuiltinType::ShortAccum:
- case BuiltinType::Accum:
- case BuiltinType::LongAccum:
- case BuiltinType::UShortAccum:
- case BuiltinType::UAccum:
- case BuiltinType::ULongAccum:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::OMPArraySection:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::ShortAccum:
+ case clang::BuiltinType::Accum:
+ case clang::BuiltinType::LongAccum:
+ case clang::BuiltinType::UShortAccum:
+ case clang::BuiltinType::UAccum:
+ case clang::BuiltinType::ULongAccum:
- case BuiltinType::OCLImage1dRO:
- case BuiltinType::OCLImage1dArrayRO:
- case BuiltinType::OCLImage1dBufferRO:
- case BuiltinType::OCLImage2dRO:
- case BuiltinType::OCLImage2dArrayRO:
- case BuiltinType::OCLImage2dDepthRO:
- case BuiltinType::OCLImage2dArrayDepthRO:
- case BuiltinType::OCLImage2dMSAARO:
- case BuiltinType::OCLImage2dArrayMSAARO:
- case BuiltinType::OCLImage2dMSAADepthRO:
- case BuiltinType::OCLImage2dArrayMSAADepthRO:
- case BuiltinType::OCLImage3dRO:
- case BuiltinType::OCLImage1dWO:
- case BuiltinType::OCLImage1dArrayWO:
- case BuiltinType::OCLImage1dBufferWO:
- case BuiltinType::OCLImage2dWO:
- case BuiltinType::OCLImage2dArrayWO:
- case BuiltinType::OCLImage2dDepthWO:
- case BuiltinType::OCLImage2dArrayDepthWO:
- case BuiltinType::OCLImage2dMSAAWO:
- case BuiltinType::OCLImage2dArrayMSAAWO:
- case BuiltinType::OCLImage2dMSAADepthWO:
- case BuiltinType::OCLImage2dArrayMSAADepthWO:
- case BuiltinType::OCLImage3dWO:
- case BuiltinType::OCLImage1dRW:
- case BuiltinType::OCLImage1dArrayRW:
- case BuiltinType::OCLImage1dBufferRW:
- case BuiltinType::OCLImage2dRW:
- case BuiltinType::OCLImage2dArrayRW:
- case BuiltinType::OCLImage2dDepthRW:
- case BuiltinType::OCLImage2dArrayDepthRW:
- case BuiltinType::OCLImage2dMSAARW:
- case BuiltinType::OCLImage2dArrayMSAARW:
- case BuiltinType::OCLImage2dMSAADepthRW:
- case BuiltinType::OCLImage2dArrayMSAADepthRW:
- case BuiltinType::OCLImage3dRW:
- case BuiltinType::OCLSampler:
- case BuiltinType::OCLEvent:
- case BuiltinType::OCLClkEvent:
- case BuiltinType::OCLQueue:
- case BuiltinType::OCLReserveID:
- case BuiltinType::ShortFract:
- case BuiltinType::Fract:
- case BuiltinType::LongFract:
- case BuiltinType::UShortFract:
- case BuiltinType::UFract:
- case BuiltinType::ULongFract:
- case BuiltinType::SatShortAccum:
- case BuiltinType::SatAccum:
- case BuiltinType::SatLongAccum:
- case BuiltinType::SatUShortAccum:
- case BuiltinType::SatUAccum:
- case BuiltinType::SatULongAccum:
- case BuiltinType::SatShortFract:
- case BuiltinType::SatFract:
- case BuiltinType::SatLongFract:
- case BuiltinType::SatUShortFract:
- case BuiltinType::SatUFract:
- case BuiltinType::SatULongFract:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dDepthRO:
+ case clang::BuiltinType::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::OCLImage2dMSAARO:
+ case clang::BuiltinType::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dDepthWO:
+ case clang::BuiltinType::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::OCLImage2dMSAAWO:
+ case clang::BuiltinType::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage2dDepthRW:
+ case clang::BuiltinType::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::OCLImage2dMSAARW:
+ case clang::BuiltinType::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::OCLImage3dRW:
+ case clang::BuiltinType::OCLSampler:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLClkEvent:
+ case clang::BuiltinType::OCLQueue:
+ case clang::BuiltinType::OCLReserveID:
+ case clang::BuiltinType::ShortFract:
+ case clang::BuiltinType::Fract:
+ case clang::BuiltinType::LongFract:
+ case clang::BuiltinType::UShortFract:
+ case clang::BuiltinType::UFract:
+ case clang::BuiltinType::ULongFract:
+ case clang::BuiltinType::SatShortAccum:
+ case clang::BuiltinType::SatAccum:
+ case clang::BuiltinType::SatLongAccum:
+ case clang::BuiltinType::SatUShortAccum:
+ case clang::BuiltinType::SatUAccum:
+ case clang::BuiltinType::SatULongAccum:
+ case clang::BuiltinType::SatShortFract:
+ case clang::BuiltinType::SatFract:
+ case clang::BuiltinType::SatLongFract:
+ case clang::BuiltinType::SatUShortFract:
+ case clang::BuiltinType::SatUFract:
+ case clang::BuiltinType::SatULongFract:
emit_warning(c, source_loc, "unsupported builtin type");
return nullptr;
}
break;
}
- case Type::Pointer:
+ case clang::Type::Pointer:
{
- const PointerType *pointer_ty = static_cast(ty);
- QualType child_qt = pointer_ty->getPointeeType();
+ const clang::PointerType *pointer_ty = static_cast(ty);
+ clang::QualType child_qt = pointer_ty->getPointeeType();
AstNode *child_node = trans_qual_type(c, child_qt, source_loc);
if (child_node == nullptr) {
emit_warning(c, source_loc, "pointer to unsupported type");
@@ -945,84 +943,84 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
child_qt.isVolatileQualified(), child_node, PtrLenC);
}
}
- case Type::Typedef:
+ case clang::Type::Typedef:
{
- const TypedefType *typedef_ty = static_cast(ty);
- const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
+ const clang::TypedefType *typedef_ty = static_cast(ty);
+ const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
return resolve_typedef_decl(c, typedef_decl);
}
- case Type::Elaborated:
+ case clang::Type::Elaborated:
{
- const ElaboratedType *elaborated_ty = static_cast(ty);
+ const clang::ElaboratedType *elaborated_ty = static_cast(ty);
switch (elaborated_ty->getKeyword()) {
- case ETK_Struct:
- case ETK_Enum:
- case ETK_Union:
+ case clang::ETK_Struct:
+ case clang::ETK_Enum:
+ case clang::ETK_Union:
return trans_qual_type(c, elaborated_ty->getNamedType(), source_loc);
- case ETK_Interface:
- case ETK_Class:
- case ETK_Typename:
- case ETK_None:
+ case clang::ETK_Interface:
+ case clang::ETK_Class:
+ case clang::ETK_Typename:
+ case clang::ETK_None:
emit_warning(c, source_loc, "unsupported elaborated type");
return nullptr;
}
}
- case Type::FunctionProto:
+ case clang::Type::FunctionProto:
{
- const FunctionProtoType *fn_proto_ty = static_cast(ty);
+ const clang::FunctionProtoType *fn_proto_ty = static_cast(ty);
AstNode *proto_node = trans_create_node(c, NodeTypeFnProto);
switch (fn_proto_ty->getCallConv()) {
- case CC_C: // __attribute__((cdecl))
+ case clang::CC_C: // __attribute__((cdecl))
proto_node->data.fn_proto.cc = CallingConventionC;
proto_node->data.fn_proto.is_extern = true;
break;
- case CC_X86StdCall: // __attribute__((stdcall))
+ case clang::CC_X86StdCall: // __attribute__((stdcall))
proto_node->data.fn_proto.cc = CallingConventionStdcall;
break;
- case CC_X86FastCall: // __attribute__((fastcall))
+ case clang::CC_X86FastCall: // __attribute__((fastcall))
emit_warning(c, source_loc, "unsupported calling convention: x86 fastcall");
return nullptr;
- case CC_X86ThisCall: // __attribute__((thiscall))
+ case clang::CC_X86ThisCall: // __attribute__((thiscall))
emit_warning(c, source_loc, "unsupported calling convention: x86 thiscall");
return nullptr;
- case CC_X86VectorCall: // __attribute__((vectorcall))
+ case clang::CC_X86VectorCall: // __attribute__((vectorcall))
emit_warning(c, source_loc, "unsupported calling convention: x86 vectorcall");
return nullptr;
- case CC_X86Pascal: // __attribute__((pascal))
+ case clang::CC_X86Pascal: // __attribute__((pascal))
emit_warning(c, source_loc, "unsupported calling convention: x86 pascal");
return nullptr;
- case CC_Win64: // __attribute__((ms_abi))
+ case clang::CC_Win64: // __attribute__((ms_abi))
emit_warning(c, source_loc, "unsupported calling convention: win64");
return nullptr;
- case CC_X86_64SysV: // __attribute__((sysv_abi))
+ case clang::CC_X86_64SysV: // __attribute__((sysv_abi))
emit_warning(c, source_loc, "unsupported calling convention: x86 64sysv");
return nullptr;
- case CC_X86RegCall:
+ case clang::CC_X86RegCall:
emit_warning(c, source_loc, "unsupported calling convention: x86 reg");
return nullptr;
- case CC_AAPCS: // __attribute__((pcs("aapcs")))
+ case clang::CC_AAPCS: // __attribute__((pcs("aapcs")))
emit_warning(c, source_loc, "unsupported calling convention: aapcs");
return nullptr;
- case CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
+ case clang::CC_AAPCS_VFP: // __attribute__((pcs("aapcs-vfp")))
emit_warning(c, source_loc, "unsupported calling convention: aapcs-vfp");
return nullptr;
- case CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
+ case clang::CC_IntelOclBicc: // __attribute__((intel_ocl_bicc))
emit_warning(c, source_loc, "unsupported calling convention: intel_ocl_bicc");
return nullptr;
- case CC_SpirFunction: // default for OpenCL functions on SPIR target
+ case clang::CC_SpirFunction: // default for OpenCL functions on SPIR target
emit_warning(c, source_loc, "unsupported calling convention: SPIR function");
return nullptr;
- case CC_OpenCLKernel:
+ case clang::CC_OpenCLKernel:
emit_warning(c, source_loc, "unsupported calling convention: OpenCLKernel");
return nullptr;
- case CC_Swift:
+ case clang::CC_Swift:
emit_warning(c, source_loc, "unsupported calling convention: Swift");
return nullptr;
- case CC_PreserveMost:
+ case clang::CC_PreserveMost:
emit_warning(c, source_loc, "unsupported calling convention: PreserveMost");
return nullptr;
- case CC_PreserveAll:
+ case clang::CC_PreserveAll:
emit_warning(c, source_loc, "unsupported calling convention: PreserveAll");
return nullptr;
}
@@ -1040,7 +1038,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return nullptr;
}
// convert c_void to actual void (only for return type)
- // we do want to look at the AstNode instead of QualType, because
+ // we do want to look at the AstNode instead of clang::QualType, because
// if they do something like:
// typedef Foo void;
// void foo(void) -> Foo;
@@ -1057,7 +1055,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
}
for (size_t i = 0; i < param_count; i += 1) {
- QualType qt = fn_proto_ty->getParamType(i);
+ clang::QualType qt = fn_proto_ty->getParamType(i);
AstNode *param_type_node = trans_qual_type(c, qt, source_loc);
if (param_type_node == nullptr) {
@@ -1080,19 +1078,19 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
return proto_node;
}
- case Type::Record:
+ case clang::Type::Record:
{
- const RecordType *record_ty = static_cast(ty);
+ const clang::RecordType *record_ty = static_cast(ty);
return resolve_record_decl(c, record_ty->getDecl());
}
- case Type::Enum:
+ case clang::Type::Enum:
{
- const EnumType *enum_ty = static_cast(ty);
+ const clang::EnumType *enum_ty = static_cast(ty);
return resolve_enum_decl(c, enum_ty->getDecl());
}
- case Type::ConstantArray:
+ case clang::Type::ConstantArray:
{
- const ConstantArrayType *const_arr_ty = static_cast(ty);
+ const clang::ConstantArrayType *const_arr_ty = static_cast(ty);
AstNode *child_type_node = trans_qual_type(c, const_arr_ty->getElementType(), source_loc);
if (child_type_node == nullptr) {
emit_warning(c, source_loc, "unresolved array element type");
@@ -1102,25 +1100,25 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
AstNode *size_node = trans_create_node_unsigned(c, size);
return trans_create_node_array_type(c, size_node, child_type_node);
}
- case Type::Paren:
+ case clang::Type::Paren:
{
- const ParenType *paren_ty = static_cast(ty);
+ const clang::ParenType *paren_ty = static_cast(ty);
return trans_qual_type(c, paren_ty->getInnerType(), source_loc);
}
- case Type::Decayed:
+ case clang::Type::Decayed:
{
- const DecayedType *decayed_ty = static_cast(ty);
+ const clang::DecayedType *decayed_ty = static_cast(ty);
return trans_qual_type(c, decayed_ty->getDecayedType(), source_loc);
}
- case Type::Attributed:
+ case clang::Type::Attributed:
{
- const AttributedType *attributed_ty = static_cast(ty);
+ const clang::AttributedType *attributed_ty = static_cast(ty);
return trans_qual_type(c, attributed_ty->getEquivalentType(), source_loc);
}
- case Type::IncompleteArray:
+ case clang::Type::IncompleteArray:
{
- const IncompleteArrayType *incomplete_array_ty = static_cast(ty);
- QualType child_qt = incomplete_array_ty->getElementType();
+ const clang::IncompleteArrayType *incomplete_array_ty = static_cast(ty);
+ clang::QualType child_qt = incomplete_array_ty->getElementType();
AstNode *child_type_node = trans_qual_type(c, child_qt, source_loc);
if (child_type_node == nullptr) {
emit_warning(c, source_loc, "unresolved array element type");
@@ -1130,56 +1128,56 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
child_qt.isVolatileQualified(), child_type_node, PtrLenC);
return pointer_node;
}
- case Type::BlockPointer:
- case Type::LValueReference:
- case Type::RValueReference:
- case Type::MemberPointer:
- case Type::VariableArray:
- case Type::DependentSizedArray:
- case Type::DependentSizedExtVector:
- case Type::Vector:
- case Type::ExtVector:
- case Type::FunctionNoProto:
- case Type::UnresolvedUsing:
- case Type::Adjusted:
- case Type::TypeOfExpr:
- case Type::TypeOf:
- case Type::Decltype:
- case Type::UnaryTransform:
- case Type::TemplateTypeParm:
- case Type::SubstTemplateTypeParm:
- case Type::SubstTemplateTypeParmPack:
- case Type::TemplateSpecialization:
- case Type::Auto:
- case Type::InjectedClassName:
- case Type::DependentName:
- case Type::DependentTemplateSpecialization:
- case Type::PackExpansion:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::Complex:
- case Type::ObjCObjectPointer:
- case Type::Atomic:
- case Type::Pipe:
- case Type::ObjCTypeParam:
- case Type::DeducedTemplateSpecialization:
- case Type::DependentAddressSpace:
- case Type::DependentVector:
+ case clang::Type::BlockPointer:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::MemberPointer:
+ case clang::Type::VariableArray:
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ case clang::Type::FunctionNoProto:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Adjusted:
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::UnaryTransform:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Auto:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ case clang::Type::Complex:
+ case clang::Type::ObjCObjectPointer:
+ case clang::Type::Atomic:
+ case clang::Type::Pipe:
+ case clang::Type::ObjCTypeParam:
+ case clang::Type::DeducedTemplateSpecialization:
+ case clang::Type::DependentAddressSpace:
+ case clang::Type::DependentVector:
emit_warning(c, source_loc, "unsupported type: '%s'", ty->getTypeClassName());
return nullptr;
}
zig_unreachable();
}
-static AstNode *trans_qual_type(Context *c, QualType qt, const SourceLocation &source_loc) {
+static AstNode *trans_qual_type(Context *c, clang::QualType qt, const clang::SourceLocation &source_loc) {
return trans_type(c, qt.getTypePtr(), source_loc);
}
-static int trans_compound_stmt_inline(Context *c, TransScope *scope, const CompoundStmt *stmt,
+static int trans_compound_stmt_inline(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
AstNode *block_node, TransScope **out_node_scope)
{
assert(block_node->type == NodeTypeBlock);
- for (CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
+ for (clang::CompoundStmt::const_body_iterator it = stmt->body_begin(), end_it = stmt->body_end(); it != end_it; ++it) {
AstNode *child_node;
scope = trans_stmt(c, scope, *it, &child_node);
if (scope == nullptr)
@@ -1193,7 +1191,7 @@ static int trans_compound_stmt_inline(Context *c, TransScope *scope, const Compo
return ErrorNone;
}
-static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const CompoundStmt *stmt,
+static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const clang::CompoundStmt *stmt,
TransScope **out_node_scope)
{
TransScopeBlock *child_scope_block = trans_scope_block_create(c, scope);
@@ -1202,8 +1200,8 @@ static AstNode *trans_compound_stmt(Context *c, TransScope *scope, const Compoun
return child_scope_block->node;
}
-static AstNode *trans_return_stmt(Context *c, TransScope *scope, const ReturnStmt *stmt) {
- const Expr *value_expr = stmt->getRetValue();
+static AstNode *trans_return_stmt(Context *c, TransScope *scope, const clang::ReturnStmt *stmt) {
+ const clang::Expr *value_expr = stmt->getRetValue();
if (value_expr == nullptr) {
return trans_create_node(c, NodeTypeReturnExpr);
} else {
@@ -1215,7 +1213,7 @@ static AstNode *trans_return_stmt(Context *c, TransScope *scope, const ReturnStm
}
}
-static AstNode *trans_integer_literal(Context *c, const IntegerLiteral *stmt) {
+static AstNode *trans_integer_literal(Context *c, const clang::IntegerLiteral *stmt) {
llvm::APSInt result;
if (!stmt->EvaluateAsInt(result, *c->ctx)) {
emit_warning(c, stmt->getLocStart(), "invalid integer literal");
@@ -1225,13 +1223,13 @@ static AstNode *trans_integer_literal(Context *c, const IntegerLiteral *stmt) {
}
static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const ConditionalOperator *stmt)
+ const clang::ConditionalOperator *stmt)
{
AstNode *node = trans_create_node(c, NodeTypeIfBoolExpr);
- Expr *cond_expr = stmt->getCond();
- Expr *true_expr = stmt->getTrueExpr();
- Expr *false_expr = stmt->getFalseExpr();
+ clang::Expr *cond_expr = stmt->getCond();
+ clang::Expr *true_expr = stmt->getTrueExpr();
+ clang::Expr *false_expr = stmt->getFalseExpr();
node->data.if_bool_expr.condition = trans_expr(c, ResultUsedYes, scope, cond_expr, TransRValue);
if (node->data.if_bool_expr.condition == nullptr)
@@ -1248,7 +1246,7 @@ static AstNode *trans_conditional_operator(Context *c, ResultUsed result_used, T
return maybe_suppress_result(c, result_used, node);
}
-static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, BinOpType bin_op, Expr *rhs) {
+static AstNode *trans_create_bin_op(Context *c, TransScope *scope, clang::Expr *lhs, BinOpType bin_op, clang::Expr *rhs) {
AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
node->data.bin_op_expr.bin_op = bin_op;
@@ -1263,7 +1261,7 @@ static AstNode *trans_create_bin_op(Context *c, TransScope *scope, Expr *lhs, Bi
return node;
}
-static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, Expr *lhs, BinOpType bin_op, Expr *rhs) {
+static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, clang::Expr *lhs, BinOpType bin_op, clang::Expr *rhs) {
assert(bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeBoolOr);
AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
node->data.bin_op_expr.bin_op = bin_op;
@@ -1279,7 +1277,7 @@ static AstNode *trans_create_bool_bin_op(Context *c, TransScope *scope, Expr *lh
return node;
}
-static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, Expr *lhs, Expr *rhs) {
+static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransScope *scope, clang::Expr *lhs, clang::Expr *rhs) {
if (result_used == ResultUsedNo) {
// common case
AstNode *node = trans_create_node(c, NodeTypeBinOpExpr);
@@ -1330,10 +1328,10 @@ static AstNode *trans_create_assign(Context *c, ResultUsed result_used, TransSco
}
}
-static AstNode *trans_create_shift_op(Context *c, TransScope *scope, QualType result_type,
- Expr *lhs_expr, BinOpType bin_op, Expr *rhs_expr)
+static AstNode *trans_create_shift_op(Context *c, TransScope *scope, clang::QualType result_type,
+ clang::Expr *lhs_expr, BinOpType bin_op, clang::Expr *rhs_expr)
{
- const SourceLocation &rhs_location = rhs_expr->getLocStart();
+ const clang::SourceLocation &rhs_location = rhs_expr->getLocStart();
AstNode *rhs_type = qual_type_to_log2_int_ref(c, result_type, rhs_location);
// lhs >> u5(rh)
@@ -1347,22 +1345,22 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, QualType re
return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
}
-static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const BinaryOperator *stmt) {
+static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::BinaryOperator *stmt) {
switch (stmt->getOpcode()) {
- case BO_PtrMemD:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemD");
+ case clang::BO_PtrMemD:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_PtrMemD");
return nullptr;
- case BO_PtrMemI:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_PtrMemI");
+ case clang::BO_PtrMemI:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_PtrMemI");
return nullptr;
- case BO_Cmp:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: BO_Cmp");
+ case clang::BO_Cmp:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C binary operators: clang::BO_Cmp");
return nullptr;
- case BO_Mul:
+ case clang::BO_Mul:
return trans_create_bin_op(c, scope, stmt->getLHS(),
qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeMultWrap : BinOpTypeMult,
stmt->getRHS());
- case BO_Div:
+ case clang::BO_Div:
if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
// unsigned/float division uses the operator
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeDiv, stmt->getRHS());
@@ -1377,7 +1375,7 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
fn_call->data.fn_call_expr.params.append(rhs);
return fn_call;
}
- case BO_Rem:
+ case clang::BO_Rem:
if (qual_type_has_wrapping_overflow(c, stmt->getType())) {
// unsigned/float division uses the operator
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeMod, stmt->getRHS());
@@ -1392,43 +1390,43 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
fn_call->data.fn_call_expr.params.append(rhs);
return fn_call;
}
- case BO_Add:
+ case clang::BO_Add:
return trans_create_bin_op(c, scope, stmt->getLHS(),
qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeAddWrap : BinOpTypeAdd,
stmt->getRHS());
- case BO_Sub:
+ case clang::BO_Sub:
return trans_create_bin_op(c, scope, stmt->getLHS(),
qual_type_has_wrapping_overflow(c, stmt->getType()) ? BinOpTypeSubWrap : BinOpTypeSub,
stmt->getRHS());
- case BO_Shl:
+ case clang::BO_Shl:
return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftLeft, stmt->getRHS());
- case BO_Shr:
+ case clang::BO_Shr:
return trans_create_shift_op(c, scope, stmt->getType(), stmt->getLHS(), BinOpTypeBitShiftRight, stmt->getRHS());
- case BO_LT:
+ case clang::BO_LT:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessThan, stmt->getRHS());
- case BO_GT:
+ case clang::BO_GT:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterThan, stmt->getRHS());
- case BO_LE:
+ case clang::BO_LE:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpLessOrEq, stmt->getRHS());
- case BO_GE:
+ case clang::BO_GE:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpGreaterOrEq, stmt->getRHS());
- case BO_EQ:
+ case clang::BO_EQ:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpEq, stmt->getRHS());
- case BO_NE:
+ case clang::BO_NE:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeCmpNotEq, stmt->getRHS());
- case BO_And:
+ case clang::BO_And:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinAnd, stmt->getRHS());
- case BO_Xor:
+ case clang::BO_Xor:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinXor, stmt->getRHS());
- case BO_Or:
+ case clang::BO_Or:
return trans_create_bin_op(c, scope, stmt->getLHS(), BinOpTypeBinOr, stmt->getRHS());
- case BO_LAnd:
+ case clang::BO_LAnd:
return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolAnd, stmt->getRHS());
- case BO_LOr:
+ case clang::BO_LOr:
return trans_create_bool_bin_op(c, scope, stmt->getLHS(), BinOpTypeBoolOr, stmt->getRHS());
- case BO_Assign:
+ case clang::BO_Assign:
return trans_create_assign(c, result_used, scope, stmt->getLHS(), stmt->getRHS());
- case BO_Comma:
+ case clang::BO_Comma:
{
TransScopeBlock *scope_block = trans_scope_block_create(c, scope);
Buf *label_name = buf_create_from_str("x");
@@ -1445,16 +1443,16 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
scope_block->node->data.block.statements.append(trans_create_node_break(c, label_name, maybe_suppress_result(c, result_used, rhs)));
return scope_block->node;
}
- case BO_MulAssign:
- case BO_DivAssign:
- case BO_RemAssign:
- case BO_AddAssign:
- case BO_SubAssign:
- case BO_ShlAssign:
- case BO_ShrAssign:
- case BO_AndAssign:
- case BO_XorAssign:
- case BO_OrAssign:
+ case clang::BO_MulAssign:
+ case clang::BO_DivAssign:
+ case clang::BO_RemAssign:
+ case clang::BO_AddAssign:
+ case clang::BO_SubAssign:
+ case clang::BO_ShlAssign:
+ case clang::BO_ShrAssign:
+ case clang::BO_AndAssign:
+ case clang::BO_XorAssign:
+ case clang::BO_OrAssign:
zig_unreachable();
}
@@ -1462,9 +1460,9 @@ static AstNode *trans_binary_operator(Context *c, ResultUsed result_used, TransS
}
static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result_used, TransScope *scope,
- const CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
+ const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
{
- const SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
+ const clang::SourceLocation &rhs_location = stmt->getRHS()->getLocStart();
AstNode *rhs_type = qual_type_to_log2_int_ref(c, stmt->getComputationLHSType(), rhs_location);
bool use_intermediate_casts = stmt->getComputationLHSType().getTypePtr() != stmt->getComputationResultType().getTypePtr();
@@ -1544,7 +1542,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
}
static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used, TransScope *scope,
- const CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
+ const clang::CompoundAssignOperator *stmt, BinOpType assign_op, BinOpType bin_op)
{
if (result_used == ResultUsedNo) {
// simple common case, where the C and Zig are identical:
@@ -1604,76 +1602,76 @@ static AstNode *trans_create_compound_assign(Context *c, ResultUsed result_used,
static AstNode *trans_compound_assign_operator(Context *c, ResultUsed result_used, TransScope *scope,
- const CompoundAssignOperator *stmt)
+ const clang::CompoundAssignOperator *stmt)
{
switch (stmt->getOpcode()) {
- case BO_MulAssign:
+ case clang::BO_MulAssign:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimesWrap, BinOpTypeMultWrap);
else
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignTimes, BinOpTypeMult);
- case BO_DivAssign:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_DivAssign");
+ case clang::BO_DivAssign:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: clang::BO_DivAssign");
return nullptr;
- case BO_RemAssign:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_RemAssign");
+ case clang::BO_RemAssign:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: clang::BO_RemAssign");
return nullptr;
- case BO_Cmp:
- emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: BO_Cmp");
+ case clang::BO_Cmp:
+ emit_warning(c, stmt->getLocStart(), "TODO handle more C compound assign operators: clang::BO_Cmp");
return nullptr;
- case BO_AddAssign:
+ case clang::BO_AddAssign:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap, BinOpTypeAddWrap);
else
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignPlus, BinOpTypeAdd);
- case BO_SubAssign:
+ case clang::BO_SubAssign:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap, BinOpTypeSubWrap);
else
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignMinus, BinOpTypeSub);
- case BO_ShlAssign:
+ case clang::BO_ShlAssign:
return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftLeft, BinOpTypeBitShiftLeft);
- case BO_ShrAssign:
+ case clang::BO_ShrAssign:
return trans_create_compound_assign_shift(c, result_used, scope, stmt, BinOpTypeAssignBitShiftRight, BinOpTypeBitShiftRight);
- case BO_AndAssign:
+ case clang::BO_AndAssign:
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitAnd, BinOpTypeBinAnd);
- case BO_XorAssign:
+ case clang::BO_XorAssign:
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitXor, BinOpTypeBinXor);
- case BO_OrAssign:
+ case clang::BO_OrAssign:
return trans_create_compound_assign(c, result_used, scope, stmt, BinOpTypeAssignBitOr, BinOpTypeBinOr);
- case BO_PtrMemD:
- case BO_PtrMemI:
- case BO_Assign:
- case BO_Mul:
- case BO_Div:
- case BO_Rem:
- case BO_Add:
- case BO_Sub:
- case BO_Shl:
- case BO_Shr:
- case BO_LT:
- case BO_GT:
- case BO_LE:
- case BO_GE:
- case BO_EQ:
- case BO_NE:
- case BO_And:
- case BO_Xor:
- case BO_Or:
- case BO_LAnd:
- case BO_LOr:
- case BO_Comma:
+ case clang::BO_PtrMemD:
+ case clang::BO_PtrMemI:
+ case clang::BO_Assign:
+ case clang::BO_Mul:
+ case clang::BO_Div:
+ case clang::BO_Rem:
+ case clang::BO_Add:
+ case clang::BO_Sub:
+ case clang::BO_Shl:
+ case clang::BO_Shr:
+ case clang::BO_LT:
+ case clang::BO_GT:
+ case clang::BO_LE:
+ case clang::BO_GE:
+ case clang::BO_EQ:
+ case clang::BO_NE:
+ case clang::BO_And:
+ case clang::BO_Xor:
+ case clang::BO_Or:
+ case clang::BO_LAnd:
+ case clang::BO_LOr:
+ case clang::BO_Comma:
zig_unreachable();
}
zig_unreachable();
}
-static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const ImplicitCastExpr *stmt) {
+static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const clang::ImplicitCastExpr *stmt) {
switch (stmt->getCastKind()) {
- case CK_LValueToRValue:
+ case clang::CK_LValueToRValue:
return trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
- case CK_IntegralCast:
+ case clang::CK_IntegralCast:
{
AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
if (target_node == nullptr)
@@ -1681,15 +1679,15 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im
return trans_c_cast(c, stmt->getExprLoc(), stmt->getType(),
stmt->getSubExpr()->getType(), target_node);
}
- case CK_FunctionToPointerDecay:
- case CK_ArrayToPointerDecay:
+ case clang::CK_FunctionToPointerDecay:
+ case clang::CK_ArrayToPointerDecay:
{
AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
if (target_node == nullptr)
return nullptr;
return target_node;
}
- case CK_BitCast:
+ case clang::CK_BitCast:
{
AstNode *target_node = trans_expr(c, ResultUsedYes, scope, stmt->getSubExpr(), TransRValue);
if (target_node == nullptr)
@@ -1706,170 +1704,170 @@ static AstNode *trans_implicit_cast_expr(Context *c, TransScope *scope, const Im
node->data.fn_call_expr.params.append(target_node);
return node;
}
- case CK_NullToPointer:
+ case clang::CK_NullToPointer:
return trans_create_node_unsigned(c, 0);
- case CK_Dependent:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dependent");
+ case clang::CK_Dependent:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_Dependent");
return nullptr;
- case CK_LValueBitCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_LValueBitCast");
+ case clang::CK_LValueBitCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_LValueBitCast");
return nullptr;
- case CK_NoOp:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_NoOp");
+ case clang::CK_NoOp:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_NoOp");
return nullptr;
- case CK_BaseToDerived:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_BaseToDerived");
+ case clang::CK_BaseToDerived:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_BaseToDerived");
return nullptr;
- case CK_DerivedToBase:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_DerivedToBase");
+ case clang::CK_DerivedToBase:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_DerivedToBase");
return nullptr;
- case CK_UncheckedDerivedToBase:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_UncheckedDerivedToBase");
+ case clang::CK_UncheckedDerivedToBase:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_UncheckedDerivedToBase");
return nullptr;
- case CK_Dynamic:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_Dynamic");
+ case clang::CK_Dynamic:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_Dynamic");
return nullptr;
- case CK_ToUnion:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ToUnion");
+ case clang::CK_ToUnion:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ToUnion");
return nullptr;
- case CK_NullToMemberPointer:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_NullToMemberPointer");
+ case clang::CK_NullToMemberPointer:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_NullToMemberPointer");
return nullptr;
- case CK_BaseToDerivedMemberPointer:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_BaseToDerivedMemberPointer");
+ case clang::CK_BaseToDerivedMemberPointer:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_BaseToDerivedMemberPointer");
return nullptr;
- case CK_DerivedToBaseMemberPointer:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_DerivedToBaseMemberPointer");
+ case clang::CK_DerivedToBaseMemberPointer:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_DerivedToBaseMemberPointer");
return nullptr;
- case CK_MemberPointerToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_MemberPointerToBoolean");
+ case clang::CK_MemberPointerToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_MemberPointerToBoolean");
return nullptr;
- case CK_ReinterpretMemberPointer:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ReinterpretMemberPointer");
+ case clang::CK_ReinterpretMemberPointer:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ReinterpretMemberPointer");
return nullptr;
- case CK_UserDefinedConversion:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_UserDefinedConversion");
+ case clang::CK_UserDefinedConversion:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_UserDefinedConversion");
return nullptr;
- case CK_ConstructorConversion:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ConstructorConversion");
+ case clang::CK_ConstructorConversion:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ConstructorConversion");
return nullptr;
- case CK_IntegralToPointer:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralToPointer");
+ case clang::CK_IntegralToPointer:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralToPointer");
return nullptr;
- case CK_PointerToIntegral:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_PointerToIntegral");
+ case clang::CK_PointerToIntegral:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_PointerToIntegral");
return nullptr;
- case CK_PointerToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_PointerToBoolean");
+ case clang::CK_PointerToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_PointerToBoolean");
return nullptr;
- case CK_ToVoid:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ToVoid");
+ case clang::CK_ToVoid:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ToVoid");
return nullptr;
- case CK_VectorSplat:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_VectorSplat");
+ case clang::CK_VectorSplat:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_VectorSplat");
return nullptr;
- case CK_IntegralToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralToBoolean");
+ case clang::CK_IntegralToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralToBoolean");
return nullptr;
- case CK_IntegralToFloating:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralToFloating");
+ case clang::CK_IntegralToFloating:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralToFloating");
return nullptr;
- case CK_FloatingToIntegral:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingToIntegral");
+ case clang::CK_FloatingToIntegral:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingToIntegral");
return nullptr;
- case CK_FloatingToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingToBoolean");
+ case clang::CK_FloatingToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingToBoolean");
return nullptr;
- case CK_BooleanToSignedIntegral:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_BooleanToSignedIntegral");
+ case clang::CK_BooleanToSignedIntegral:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_BooleanToSignedIntegral");
return nullptr;
- case CK_FloatingCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingCast");
+ case clang::CK_FloatingCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingCast");
return nullptr;
- case CK_CPointerToObjCPointerCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_CPointerToObjCPointerCast");
+ case clang::CK_CPointerToObjCPointerCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_CPointerToObjCPointerCast");
return nullptr;
- case CK_BlockPointerToObjCPointerCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_BlockPointerToObjCPointerCast");
+ case clang::CK_BlockPointerToObjCPointerCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_BlockPointerToObjCPointerCast");
return nullptr;
- case CK_AnyPointerToBlockPointerCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_AnyPointerToBlockPointerCast");
+ case clang::CK_AnyPointerToBlockPointerCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_AnyPointerToBlockPointerCast");
return nullptr;
- case CK_ObjCObjectLValueCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ObjCObjectLValueCast");
+ case clang::CK_ObjCObjectLValueCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ObjCObjectLValueCast");
return nullptr;
- case CK_FloatingRealToComplex:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingRealToComplex");
+ case clang::CK_FloatingRealToComplex:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingRealToComplex");
return nullptr;
- case CK_FloatingComplexToReal:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingComplexToReal");
+ case clang::CK_FloatingComplexToReal:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingComplexToReal");
return nullptr;
- case CK_FloatingComplexToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingComplexToBoolean");
+ case clang::CK_FloatingComplexToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingComplexToBoolean");
return nullptr;
- case CK_FloatingComplexCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingComplexCast");
+ case clang::CK_FloatingComplexCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingComplexCast");
return nullptr;
- case CK_FloatingComplexToIntegralComplex:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_FloatingComplexToIntegralComplex");
+ case clang::CK_FloatingComplexToIntegralComplex:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_FloatingComplexToIntegralComplex");
return nullptr;
- case CK_IntegralRealToComplex:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralRealToComplex");
+ case clang::CK_IntegralRealToComplex:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralRealToComplex");
return nullptr;
- case CK_IntegralComplexToReal:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralComplexToReal");
+ case clang::CK_IntegralComplexToReal:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralComplexToReal");
return nullptr;
- case CK_IntegralComplexToBoolean:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralComplexToBoolean");
+ case clang::CK_IntegralComplexToBoolean:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralComplexToBoolean");
return nullptr;
- case CK_IntegralComplexCast:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralComplexCast");
+ case clang::CK_IntegralComplexCast:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralComplexCast");
return nullptr;
- case CK_IntegralComplexToFloatingComplex:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntegralComplexToFloatingComplex");
+ case clang::CK_IntegralComplexToFloatingComplex:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntegralComplexToFloatingComplex");
return nullptr;
- case CK_ARCProduceObject:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ARCProduceObject");
+ case clang::CK_ARCProduceObject:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ARCProduceObject");
return nullptr;
- case CK_ARCConsumeObject:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ARCConsumeObject");
+ case clang::CK_ARCConsumeObject:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ARCConsumeObject");
return nullptr;
- case CK_ARCReclaimReturnedObject:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ARCReclaimReturnedObject");
+ case clang::CK_ARCReclaimReturnedObject:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ARCReclaimReturnedObject");
return nullptr;
- case CK_ARCExtendBlockObject:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ARCExtendBlockObject");
+ case clang::CK_ARCExtendBlockObject:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ARCExtendBlockObject");
return nullptr;
- case CK_AtomicToNonAtomic:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_AtomicToNonAtomic");
+ case clang::CK_AtomicToNonAtomic:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_AtomicToNonAtomic");
return nullptr;
- case CK_NonAtomicToAtomic:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_NonAtomicToAtomic");
+ case clang::CK_NonAtomicToAtomic:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_NonAtomicToAtomic");
return nullptr;
- case CK_CopyAndAutoreleaseBlockObject:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_CopyAndAutoreleaseBlockObject");
+ case clang::CK_CopyAndAutoreleaseBlockObject:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_CopyAndAutoreleaseBlockObject");
return nullptr;
- case CK_BuiltinFnToFnPtr:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_BuiltinFnToFnPtr");
+ case clang::CK_BuiltinFnToFnPtr:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_BuiltinFnToFnPtr");
return nullptr;
- case CK_ZeroToOCLEvent:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ZeroToOCLEvent");
+ case clang::CK_ZeroToOCLEvent:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ZeroToOCLEvent");
return nullptr;
- case CK_ZeroToOCLQueue:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_ZeroToOCLQueue");
+ case clang::CK_ZeroToOCLQueue:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_ZeroToOCLQueue");
return nullptr;
- case CK_AddressSpaceConversion:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_AddressSpaceConversion");
+ case clang::CK_AddressSpaceConversion:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_AddressSpaceConversion");
return nullptr;
- case CK_IntToOCLSampler:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast CK_IntToOCLSampler");
+ case clang::CK_IntToOCLSampler:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation cast clang::CK_IntToOCLSampler");
return nullptr;
}
zig_unreachable();
}
-static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const DeclRefExpr *stmt, TransLRValue lrval) {
- const ValueDecl *value_decl = stmt->getDecl();
+static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const clang::DeclRefExpr *stmt, TransLRValue lrval) {
+ const clang::ValueDecl *value_decl = stmt->getDecl();
Buf *c_symbol_name = buf_create_from_str(decl_name(value_decl));
Buf *zig_symbol_name = trans_lookup_zig_symbol(c, scope, c_symbol_name);
if (lrval == TransLValue) {
@@ -1879,9 +1877,9 @@ static AstNode *trans_decl_ref_expr(Context *c, TransScope *scope, const DeclRef
}
static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, TransScope *scope,
- const UnaryOperator *stmt, BinOpType assign_op)
+ const clang::UnaryOperator *stmt, BinOpType assign_op)
{
- Expr *op_expr = stmt->getSubExpr();
+ clang::Expr *op_expr = stmt->getSubExpr();
if (result_used == ResultUsedNo) {
// common case
@@ -1935,9 +1933,9 @@ static AstNode *trans_create_post_crement(Context *c, ResultUsed result_used, Tr
}
static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, TransScope *scope,
- const UnaryOperator *stmt, BinOpType assign_op)
+ const clang::UnaryOperator *stmt, BinOpType assign_op)
{
- Expr *op_expr = stmt->getSubExpr();
+ clang::Expr *op_expr = stmt->getSubExpr();
if (result_used == ResultUsedNo) {
// common case
@@ -1984,36 +1982,36 @@ static AstNode *trans_create_pre_crement(Context *c, ResultUsed result_used, Tra
return child_scope->node;
}
-static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const UnaryOperator *stmt) {
+static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransScope *scope, const clang::UnaryOperator *stmt) {
switch (stmt->getOpcode()) {
- case UO_PostInc:
+ case clang::UO_PostInc:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
else
return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
- case UO_PostDec:
+ case clang::UO_PostDec:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
else
return trans_create_post_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
- case UO_PreInc:
+ case clang::UO_PreInc:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlusWrap);
else
return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignPlus);
- case UO_PreDec:
+ case clang::UO_PreDec:
if (qual_type_has_wrapping_overflow(c, stmt->getType()))
return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinusWrap);
else
return trans_create_pre_crement(c, result_used, scope, stmt, BinOpTypeAssignMinus);
- case UO_AddrOf:
+ case clang::UO_AddrOf:
{
AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransLValue);
if (value_node == nullptr)
return value_node;
return trans_create_node_addr_of(c, value_node);
}
- case UO_Deref:
+ case clang::UO_Deref:
{
AstNode *value_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), TransRValue);
if (value_node == nullptr)
@@ -2024,12 +2022,12 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
AstNode *unwrapped = trans_create_node_unwrap_null(c, value_node);
return trans_create_node_ptr_deref(c, unwrapped);
}
- case UO_Plus:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Plus");
+ case clang::UO_Plus:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Plus");
return nullptr;
- case UO_Minus:
+ case clang::UO_Minus:
{
- Expr *op_expr = stmt->getSubExpr();
+ clang::Expr *op_expr = stmt->getSubExpr();
if (!qual_type_has_wrapping_overflow(c, op_expr->getType())) {
AstNode *node = trans_create_node(c, NodeTypePrefixOpExpr);
node->data.prefix_op_expr.prefix_op = PrefixOpNegation;
@@ -2055,41 +2053,41 @@ static AstNode *trans_unary_operator(Context *c, ResultUsed result_used, TransSc
return nullptr;
}
}
- case UO_Not:
+ case clang::UO_Not:
{
- Expr *op_expr = stmt->getSubExpr();
+ clang::Expr *op_expr = stmt->getSubExpr();
AstNode *sub_node = trans_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
if (sub_node == nullptr)
return nullptr;
return trans_create_node_prefix_op(c, PrefixOpBinNot, sub_node);
}
- case UO_LNot:
+ case clang::UO_LNot:
{
- Expr *op_expr = stmt->getSubExpr();
+ clang::Expr *op_expr = stmt->getSubExpr();
AstNode *sub_node = trans_bool_expr(c, ResultUsedYes, scope, op_expr, TransRValue);
if (sub_node == nullptr)
return nullptr;
return trans_create_node_prefix_op(c, PrefixOpBoolNot, sub_node);
}
- case UO_Real:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Real");
+ case clang::UO_Real:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Real");
return nullptr;
- case UO_Imag:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Imag");
+ case clang::UO_Imag:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Imag");
return nullptr;
- case UO_Extension:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Extension");
+ case clang::UO_Extension:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Extension");
return nullptr;
- case UO_Coawait:
- emit_warning(c, stmt->getLocStart(), "TODO handle C translation UO_Coawait");
+ case clang::UO_Coawait:
+ emit_warning(c, stmt->getLocStart(), "TODO handle C translation clang::UO_Coawait");
return nullptr;
}
zig_unreachable();
}
-static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt *stmt,
+static int trans_local_declaration(Context *c, TransScope *scope, const clang::DeclStmt *stmt,
AstNode **out_node, TransScope **out_scope)
{
// declarations are added via the scope
@@ -2099,11 +2097,11 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt
assert(scope_block != nullptr);
for (auto iter = stmt->decl_begin(); iter != stmt->decl_end(); iter++) {
- Decl *decl = *iter;
+ clang::Decl *decl = *iter;
switch (decl->getKind()) {
- case Decl::Var: {
- VarDecl *var_decl = (VarDecl *)decl;
- QualType qual_type = var_decl->getTypeSourceInfo()->getType();
+ case clang::Decl::Var: {
+ clang::VarDecl *var_decl = (clang::VarDecl *)decl;
+ clang::QualType qual_type = var_decl->getTypeSourceInfo()->getType();
AstNode *init_node = nullptr;
if (var_decl->hasInit()) {
init_node = trans_expr(c, ResultUsedYes, scope, var_decl->getInit(), TransRValue);
@@ -2128,220 +2126,220 @@ static int trans_local_declaration(Context *c, TransScope *scope, const DeclStmt
scope_block->node->data.block.statements.append(node);
continue;
}
- case Decl::AccessSpec:
+ case clang::Decl::AccessSpec:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind AccessSpec");
return ErrorUnexpected;
- case Decl::Block:
+ case clang::Decl::Block:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Block");
return ErrorUnexpected;
- case Decl::Captured:
+ case clang::Decl::Captured:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Captured");
return ErrorUnexpected;
- case Decl::ClassScopeFunctionSpecialization:
+ case clang::Decl::ClassScopeFunctionSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassScopeFunctionSpecialization");
return ErrorUnexpected;
- case Decl::Empty:
+ case clang::Decl::Empty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Empty");
return ErrorUnexpected;
- case Decl::Export:
+ case clang::Decl::Export:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Export");
return ErrorUnexpected;
- case Decl::ExternCContext:
+ case clang::Decl::ExternCContext:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ExternCContext");
return ErrorUnexpected;
- case Decl::FileScopeAsm:
+ case clang::Decl::FileScopeAsm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FileScopeAsm");
return ErrorUnexpected;
- case Decl::Friend:
+ case clang::Decl::Friend:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Friend");
return ErrorUnexpected;
- case Decl::FriendTemplate:
+ case clang::Decl::FriendTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FriendTemplate");
return ErrorUnexpected;
- case Decl::Import:
+ case clang::Decl::Import:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Import");
return ErrorUnexpected;
- case Decl::LinkageSpec:
+ case clang::Decl::LinkageSpec:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind LinkageSpec");
return ErrorUnexpected;
- case Decl::Label:
+ case clang::Decl::Label:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Label");
return ErrorUnexpected;
- case Decl::Namespace:
+ case clang::Decl::Namespace:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Namespace");
return ErrorUnexpected;
- case Decl::NamespaceAlias:
+ case clang::Decl::NamespaceAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind NamespaceAlias");
return ErrorUnexpected;
- case Decl::ObjCCompatibleAlias:
+ case clang::Decl::ObjCCompatibleAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCompatibleAlias");
return ErrorUnexpected;
- case Decl::ObjCCategory:
+ case clang::Decl::ObjCCategory:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCategory");
return ErrorUnexpected;
- case Decl::ObjCCategoryImpl:
+ case clang::Decl::ObjCCategoryImpl:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCCategoryImpl");
return ErrorUnexpected;
- case Decl::ObjCImplementation:
+ case clang::Decl::ObjCImplementation:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCImplementation");
return ErrorUnexpected;
- case Decl::ObjCInterface:
+ case clang::Decl::ObjCInterface:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCInterface");
return ErrorUnexpected;
- case Decl::ObjCProtocol:
+ case clang::Decl::ObjCProtocol:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCProtocol");
return ErrorUnexpected;
- case Decl::ObjCMethod:
+ case clang::Decl::ObjCMethod:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCMethod");
return ErrorUnexpected;
- case Decl::ObjCProperty:
+ case clang::Decl::ObjCProperty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCProperty");
return ErrorUnexpected;
- case Decl::BuiltinTemplate:
+ case clang::Decl::BuiltinTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind BuiltinTemplate");
return ErrorUnexpected;
- case Decl::ClassTemplate:
+ case clang::Decl::ClassTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplate");
return ErrorUnexpected;
- case Decl::FunctionTemplate:
+ case clang::Decl::FunctionTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind FunctionTemplate");
return ErrorUnexpected;
- case Decl::TypeAliasTemplate:
+ case clang::Decl::TypeAliasTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TypeAliasTemplate");
return ErrorUnexpected;
- case Decl::VarTemplate:
+ case clang::Decl::VarTemplate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplate");
return ErrorUnexpected;
- case Decl::TemplateTemplateParm:
+ case clang::Decl::TemplateTemplateParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TemplateTemplateParm");
return ErrorUnexpected;
- case Decl::Enum:
+ case clang::Decl::Enum:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Enum");
return ErrorUnexpected;
- case Decl::Record:
+ case clang::Decl::Record:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Record");
return ErrorUnexpected;
- case Decl::CXXRecord:
+ case clang::Decl::CXXRecord:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXRecord");
return ErrorUnexpected;
- case Decl::ClassTemplateSpecialization:
+ case clang::Decl::ClassTemplateSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplateSpecialization");
return ErrorUnexpected;
- case Decl::ClassTemplatePartialSpecialization:
+ case clang::Decl::ClassTemplatePartialSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ClassTemplatePartialSpecialization");
return ErrorUnexpected;
- case Decl::TemplateTypeParm:
+ case clang::Decl::TemplateTypeParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TemplateTypeParm");
return ErrorUnexpected;
- case Decl::ObjCTypeParam:
+ case clang::Decl::ObjCTypeParam:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCTypeParam");
return ErrorUnexpected;
- case Decl::TypeAlias:
+ case clang::Decl::TypeAlias:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TypeAlias");
return ErrorUnexpected;
- case Decl::Typedef:
+ case clang::Decl::Typedef:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Typedef");
return ErrorUnexpected;
- case Decl::UnresolvedUsingTypename:
+ case clang::Decl::UnresolvedUsingTypename:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UnresolvedUsingTypename");
return ErrorUnexpected;
- case Decl::Using:
+ case clang::Decl::Using:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Using");
return ErrorUnexpected;
- case Decl::UsingDirective:
+ case clang::Decl::UsingDirective:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingDirective");
return ErrorUnexpected;
- case Decl::UsingPack:
+ case clang::Decl::UsingPack:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingPack");
return ErrorUnexpected;
- case Decl::UsingShadow:
+ case clang::Decl::UsingShadow:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UsingShadow");
return ErrorUnexpected;
- case Decl::ConstructorUsingShadow:
+ case clang::Decl::ConstructorUsingShadow:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ConstructorUsingShadow");
return ErrorUnexpected;
- case Decl::Binding:
+ case clang::Decl::Binding:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Binding");
return ErrorUnexpected;
- case Decl::Field:
+ case clang::Decl::Field:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Field");
return ErrorUnexpected;
- case Decl::ObjCAtDefsField:
+ case clang::Decl::ObjCAtDefsField:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCAtDefsField");
return ErrorUnexpected;
- case Decl::ObjCIvar:
+ case clang::Decl::ObjCIvar:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCIvar");
return ErrorUnexpected;
- case Decl::Function:
+ case clang::Decl::Function:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Function");
return ErrorUnexpected;
- case Decl::CXXDeductionGuide:
+ case clang::Decl::CXXDeductionGuide:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXDeductionGuide");
return ErrorUnexpected;
- case Decl::CXXMethod:
+ case clang::Decl::CXXMethod:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXMethod");
return ErrorUnexpected;
- case Decl::CXXConstructor:
+ case clang::Decl::CXXConstructor:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXConstructor");
return ErrorUnexpected;
- case Decl::CXXConversion:
+ case clang::Decl::CXXConversion:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXConversion");
return ErrorUnexpected;
- case Decl::CXXDestructor:
+ case clang::Decl::CXXDestructor:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind CXXDestructor");
return ErrorUnexpected;
- case Decl::MSProperty:
+ case clang::Decl::MSProperty:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind MSProperty");
return ErrorUnexpected;
- case Decl::NonTypeTemplateParm:
+ case clang::Decl::NonTypeTemplateParm:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind NonTypeTemplateParm");
return ErrorUnexpected;
- case Decl::Decomposition:
+ case clang::Decl::Decomposition:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind Decomposition");
return ErrorUnexpected;
- case Decl::ImplicitParam:
+ case clang::Decl::ImplicitParam:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ImplicitParam");
return ErrorUnexpected;
- case Decl::OMPCapturedExpr:
+ case clang::Decl::OMPCapturedExpr:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPCapturedExpr");
return ErrorUnexpected;
- case Decl::ParmVar:
+ case clang::Decl::ParmVar:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ParmVar");
return ErrorUnexpected;
- case Decl::VarTemplateSpecialization:
+ case clang::Decl::VarTemplateSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplateSpecialization");
return ErrorUnexpected;
- case Decl::VarTemplatePartialSpecialization:
+ case clang::Decl::VarTemplatePartialSpecialization:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind VarTemplatePartialSpecialization");
return ErrorUnexpected;
- case Decl::EnumConstant:
+ case clang::Decl::EnumConstant:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind EnumConstant");
return ErrorUnexpected;
- case Decl::IndirectField:
+ case clang::Decl::IndirectField:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind IndirectField");
return ErrorUnexpected;
- case Decl::OMPDeclareReduction:
+ case clang::Decl::OMPDeclareReduction:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPDeclareReduction");
return ErrorUnexpected;
- case Decl::UnresolvedUsingValue:
+ case clang::Decl::UnresolvedUsingValue:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind UnresolvedUsingValue");
return ErrorUnexpected;
- case Decl::OMPThreadPrivate:
+ case clang::Decl::OMPThreadPrivate:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind OMPThreadPrivate");
return ErrorUnexpected;
- case Decl::ObjCPropertyImpl:
+ case clang::Decl::ObjCPropertyImpl:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind ObjCPropertyImpl");
return ErrorUnexpected;
- case Decl::PragmaComment:
+ case clang::Decl::PragmaComment:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind PragmaComment");
return ErrorUnexpected;
- case Decl::PragmaDetectMismatch:
+ case clang::Decl::PragmaDetectMismatch:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind PragmaDetectMismatch");
return ErrorUnexpected;
- case Decl::StaticAssert:
+ case clang::Decl::StaticAssert:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind StaticAssert");
return ErrorUnexpected;
- case Decl::TranslationUnit:
+ case clang::Decl::TranslationUnit:
emit_warning(c, stmt->getLocStart(), "TODO handle decl kind TranslationUnit");
return ErrorUnexpected;
}
@@ -2368,7 +2366,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)
return trans_create_node_bin_op(c, expr, BinOpTypeCmpNotEq, bitcast);
}
-static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr, TransLRValue lrval) {
+static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr, TransLRValue lrval) {
AstNode *res = trans_expr(c, result_used, scope, expr, lrval);
if (res == nullptr)
return nullptr;
@@ -2405,133 +2403,133 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
}
- const Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr();
+ const clang::Type *ty = get_expr_qual_type_before_implicit_cast(c, expr).getTypePtr();
auto classs = ty->getTypeClass();
switch (classs) {
- case Type::Builtin:
+ case clang::Type::Builtin:
{
- const BuiltinType *builtin_ty = static_cast(ty);
+ const clang::BuiltinType *builtin_ty = static_cast(ty);
switch (builtin_ty->getKind()) {
- case BuiltinType::Bool:
- case BuiltinType::Char_U:
- case BuiltinType::UChar:
- case BuiltinType::Char_S:
- case BuiltinType::SChar:
- case BuiltinType::UShort:
- case BuiltinType::UInt:
- case BuiltinType::ULong:
- case BuiltinType::ULongLong:
- case BuiltinType::Short:
- case BuiltinType::Int:
- case BuiltinType::Long:
- case BuiltinType::LongLong:
- case BuiltinType::UInt128:
- case BuiltinType::Int128:
- case BuiltinType::Float:
- case BuiltinType::Double:
- case BuiltinType::Float128:
- case BuiltinType::LongDouble:
- case BuiltinType::WChar_U:
- case BuiltinType::Char8:
- case BuiltinType::Char16:
- case BuiltinType::Char32:
- case BuiltinType::WChar_S:
- case BuiltinType::Float16:
+ case clang::BuiltinType::Bool:
+ case clang::BuiltinType::Char_U:
+ case clang::BuiltinType::UChar:
+ case clang::BuiltinType::Char_S:
+ case clang::BuiltinType::SChar:
+ case clang::BuiltinType::UShort:
+ case clang::BuiltinType::UInt:
+ case clang::BuiltinType::ULong:
+ case clang::BuiltinType::ULongLong:
+ case clang::BuiltinType::Short:
+ case clang::BuiltinType::Int:
+ case clang::BuiltinType::Long:
+ case clang::BuiltinType::LongLong:
+ case clang::BuiltinType::UInt128:
+ case clang::BuiltinType::Int128:
+ case clang::BuiltinType::Float:
+ case clang::BuiltinType::Double:
+ case clang::BuiltinType::Float128:
+ case clang::BuiltinType::LongDouble:
+ case clang::BuiltinType::WChar_U:
+ case clang::BuiltinType::Char8:
+ case clang::BuiltinType::Char16:
+ case clang::BuiltinType::Char32:
+ case clang::BuiltinType::WChar_S:
+ case clang::BuiltinType::Float16:
return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq, trans_create_node_unsigned_negative(c, 0, false));
- case BuiltinType::NullPtr:
+ case clang::BuiltinType::NullPtr:
return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
trans_create_node_unsigned(c, 0));
- case BuiltinType::Void:
- case BuiltinType::Half:
- case BuiltinType::ObjCId:
- case BuiltinType::ObjCClass:
- case BuiltinType::ObjCSel:
- case BuiltinType::OMPArraySection:
- case BuiltinType::Dependent:
- case BuiltinType::Overload:
- case BuiltinType::BoundMember:
- case BuiltinType::PseudoObject:
- case BuiltinType::UnknownAny:
- case BuiltinType::BuiltinFn:
- case BuiltinType::ARCUnbridgedCast:
- case BuiltinType::OCLImage1dRO:
- case BuiltinType::OCLImage1dArrayRO:
- case BuiltinType::OCLImage1dBufferRO:
- case BuiltinType::OCLImage2dRO:
- case BuiltinType::OCLImage2dArrayRO:
- case BuiltinType::OCLImage2dDepthRO:
- case BuiltinType::OCLImage2dArrayDepthRO:
- case BuiltinType::OCLImage2dMSAARO:
- case BuiltinType::OCLImage2dArrayMSAARO:
- case BuiltinType::OCLImage2dMSAADepthRO:
- case BuiltinType::OCLImage2dArrayMSAADepthRO:
- case BuiltinType::OCLImage3dRO:
- case BuiltinType::OCLImage1dWO:
- case BuiltinType::OCLImage1dArrayWO:
- case BuiltinType::OCLImage1dBufferWO:
- case BuiltinType::OCLImage2dWO:
- case BuiltinType::OCLImage2dArrayWO:
- case BuiltinType::OCLImage2dDepthWO:
- case BuiltinType::OCLImage2dArrayDepthWO:
- case BuiltinType::OCLImage2dMSAAWO:
- case BuiltinType::OCLImage2dArrayMSAAWO:
- case BuiltinType::OCLImage2dMSAADepthWO:
- case BuiltinType::OCLImage2dArrayMSAADepthWO:
- case BuiltinType::OCLImage3dWO:
- case BuiltinType::OCLImage1dRW:
- case BuiltinType::OCLImage1dArrayRW:
- case BuiltinType::OCLImage1dBufferRW:
- case BuiltinType::OCLImage2dRW:
- case BuiltinType::OCLImage2dArrayRW:
- case BuiltinType::OCLImage2dDepthRW:
- case BuiltinType::OCLImage2dArrayDepthRW:
- case BuiltinType::OCLImage2dMSAARW:
- case BuiltinType::OCLImage2dArrayMSAARW:
- case BuiltinType::OCLImage2dMSAADepthRW:
- case BuiltinType::OCLImage2dArrayMSAADepthRW:
- case BuiltinType::OCLImage3dRW:
- case BuiltinType::OCLSampler:
- case BuiltinType::OCLEvent:
- case BuiltinType::OCLClkEvent:
- case BuiltinType::OCLQueue:
- case BuiltinType::OCLReserveID:
- case BuiltinType::ShortAccum:
- case BuiltinType::Accum:
- case BuiltinType::LongAccum:
- case BuiltinType::UShortAccum:
- case BuiltinType::UAccum:
- case BuiltinType::ULongAccum:
- case BuiltinType::ShortFract:
- case BuiltinType::Fract:
- case BuiltinType::LongFract:
- case BuiltinType::UShortFract:
- case BuiltinType::UFract:
- case BuiltinType::ULongFract:
- case BuiltinType::SatShortAccum:
- case BuiltinType::SatAccum:
- case BuiltinType::SatLongAccum:
- case BuiltinType::SatUShortAccum:
- case BuiltinType::SatUAccum:
- case BuiltinType::SatULongAccum:
- case BuiltinType::SatShortFract:
- case BuiltinType::SatFract:
- case BuiltinType::SatLongFract:
- case BuiltinType::SatUShortFract:
- case BuiltinType::SatUFract:
- case BuiltinType::SatULongFract:
+ case clang::BuiltinType::Void:
+ case clang::BuiltinType::Half:
+ case clang::BuiltinType::ObjCId:
+ case clang::BuiltinType::ObjCClass:
+ case clang::BuiltinType::ObjCSel:
+ case clang::BuiltinType::OMPArraySection:
+ case clang::BuiltinType::Dependent:
+ case clang::BuiltinType::Overload:
+ case clang::BuiltinType::BoundMember:
+ case clang::BuiltinType::PseudoObject:
+ case clang::BuiltinType::UnknownAny:
+ case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::OCLImage1dRO:
+ case clang::BuiltinType::OCLImage1dArrayRO:
+ case clang::BuiltinType::OCLImage1dBufferRO:
+ case clang::BuiltinType::OCLImage2dRO:
+ case clang::BuiltinType::OCLImage2dArrayRO:
+ case clang::BuiltinType::OCLImage2dDepthRO:
+ case clang::BuiltinType::OCLImage2dArrayDepthRO:
+ case clang::BuiltinType::OCLImage2dMSAARO:
+ case clang::BuiltinType::OCLImage2dArrayMSAARO:
+ case clang::BuiltinType::OCLImage2dMSAADepthRO:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthRO:
+ case clang::BuiltinType::OCLImage3dRO:
+ case clang::BuiltinType::OCLImage1dWO:
+ case clang::BuiltinType::OCLImage1dArrayWO:
+ case clang::BuiltinType::OCLImage1dBufferWO:
+ case clang::BuiltinType::OCLImage2dWO:
+ case clang::BuiltinType::OCLImage2dArrayWO:
+ case clang::BuiltinType::OCLImage2dDepthWO:
+ case clang::BuiltinType::OCLImage2dArrayDepthWO:
+ case clang::BuiltinType::OCLImage2dMSAAWO:
+ case clang::BuiltinType::OCLImage2dArrayMSAAWO:
+ case clang::BuiltinType::OCLImage2dMSAADepthWO:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthWO:
+ case clang::BuiltinType::OCLImage3dWO:
+ case clang::BuiltinType::OCLImage1dRW:
+ case clang::BuiltinType::OCLImage1dArrayRW:
+ case clang::BuiltinType::OCLImage1dBufferRW:
+ case clang::BuiltinType::OCLImage2dRW:
+ case clang::BuiltinType::OCLImage2dArrayRW:
+ case clang::BuiltinType::OCLImage2dDepthRW:
+ case clang::BuiltinType::OCLImage2dArrayDepthRW:
+ case clang::BuiltinType::OCLImage2dMSAARW:
+ case clang::BuiltinType::OCLImage2dArrayMSAARW:
+ case clang::BuiltinType::OCLImage2dMSAADepthRW:
+ case clang::BuiltinType::OCLImage2dArrayMSAADepthRW:
+ case clang::BuiltinType::OCLImage3dRW:
+ case clang::BuiltinType::OCLSampler:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLClkEvent:
+ case clang::BuiltinType::OCLQueue:
+ case clang::BuiltinType::OCLReserveID:
+ case clang::BuiltinType::ShortAccum:
+ case clang::BuiltinType::Accum:
+ case clang::BuiltinType::LongAccum:
+ case clang::BuiltinType::UShortAccum:
+ case clang::BuiltinType::UAccum:
+ case clang::BuiltinType::ULongAccum:
+ case clang::BuiltinType::ShortFract:
+ case clang::BuiltinType::Fract:
+ case clang::BuiltinType::LongFract:
+ case clang::BuiltinType::UShortFract:
+ case clang::BuiltinType::UFract:
+ case clang::BuiltinType::ULongFract:
+ case clang::BuiltinType::SatShortAccum:
+ case clang::BuiltinType::SatAccum:
+ case clang::BuiltinType::SatLongAccum:
+ case clang::BuiltinType::SatUShortAccum:
+ case clang::BuiltinType::SatUAccum:
+ case clang::BuiltinType::SatULongAccum:
+ case clang::BuiltinType::SatShortFract:
+ case clang::BuiltinType::SatFract:
+ case clang::BuiltinType::SatLongFract:
+ case clang::BuiltinType::SatUShortFract:
+ case clang::BuiltinType::SatUFract:
+ case clang::BuiltinType::SatULongFract:
return res;
}
break;
}
- case Type::Pointer:
+ case clang::Type::Pointer:
return trans_create_node_bin_op(c, res, BinOpTypeCmpNotEq,
trans_create_node_unsigned(c, 0));
- case Type::Typedef:
+ case clang::Type::Typedef:
{
- const TypedefType *typedef_ty = static_cast(ty);
- const TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
+ const clang::TypedefType *typedef_ty = static_cast(ty);
+ const clang::TypedefNameDecl *typedef_decl = typedef_ty->getDecl();
auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
@@ -2540,79 +2538,79 @@ static AstNode *trans_bool_expr(Context *c, ResultUsed result_used, TransScope *
return res;
}
- case Type::Enum:
+ case clang::Type::Enum:
{
- const EnumType *enum_ty = static_cast(ty);
+ const clang::EnumType *enum_ty = static_cast(ty);
AstNode *enum_type = resolve_enum_decl(c, enum_ty->getDecl());
return to_enum_zero_cmp(c, res, enum_type);
}
- case Type::Elaborated:
+ case clang::Type::Elaborated:
{
- const ElaboratedType *elaborated_ty = static_cast(ty);
+ const clang::ElaboratedType *elaborated_ty = static_cast(ty);
switch (elaborated_ty->getKeyword()) {
- case ETK_Enum: {
+ case clang::ETK_Enum: {
AstNode *enum_type = trans_qual_type(c, elaborated_ty->getNamedType(), expr->getLocStart());
return to_enum_zero_cmp(c, res, enum_type);
}
- case ETK_Struct:
- case ETK_Union:
- case ETK_Interface:
- case ETK_Class:
- case ETK_Typename:
- case ETK_None:
+ case clang::ETK_Struct:
+ case clang::ETK_Union:
+ case clang::ETK_Interface:
+ case clang::ETK_Class:
+ case clang::ETK_Typename:
+ case clang::ETK_None:
return res;
}
}
- case Type::FunctionProto:
- case Type::Record:
- case Type::ConstantArray:
- case Type::Paren:
- case Type::Decayed:
- case Type::Attributed:
- case Type::IncompleteArray:
- case Type::BlockPointer:
- case Type::LValueReference:
- case Type::RValueReference:
- case Type::MemberPointer:
- case Type::VariableArray:
- case Type::DependentSizedArray:
- case Type::DependentSizedExtVector:
- case Type::Vector:
- case Type::ExtVector:
- case Type::FunctionNoProto:
- case Type::UnresolvedUsing:
- case Type::Adjusted:
- case Type::TypeOfExpr:
- case Type::TypeOf:
- case Type::Decltype:
- case Type::UnaryTransform:
- case Type::TemplateTypeParm:
- case Type::SubstTemplateTypeParm:
- case Type::SubstTemplateTypeParmPack:
- case Type::TemplateSpecialization:
- case Type::Auto:
- case Type::InjectedClassName:
- case Type::DependentName:
- case Type::DependentTemplateSpecialization:
- case Type::PackExpansion:
- case Type::ObjCObject:
- case Type::ObjCInterface:
- case Type::Complex:
- case Type::ObjCObjectPointer:
- case Type::Atomic:
- case Type::Pipe:
- case Type::ObjCTypeParam:
- case Type::DeducedTemplateSpecialization:
- case Type::DependentAddressSpace:
- case Type::DependentVector:
+ case clang::Type::FunctionProto:
+ case clang::Type::Record:
+ case clang::Type::ConstantArray:
+ case clang::Type::Paren:
+ case clang::Type::Decayed:
+ case clang::Type::Attributed:
+ case clang::Type::IncompleteArray:
+ case clang::Type::BlockPointer:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ case clang::Type::MemberPointer:
+ case clang::Type::VariableArray:
+ case clang::Type::DependentSizedArray:
+ case clang::Type::DependentSizedExtVector:
+ case clang::Type::Vector:
+ case clang::Type::ExtVector:
+ case clang::Type::FunctionNoProto:
+ case clang::Type::UnresolvedUsing:
+ case clang::Type::Adjusted:
+ case clang::Type::TypeOfExpr:
+ case clang::Type::TypeOf:
+ case clang::Type::Decltype:
+ case clang::Type::UnaryTransform:
+ case clang::Type::TemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParm:
+ case clang::Type::SubstTemplateTypeParmPack:
+ case clang::Type::TemplateSpecialization:
+ case clang::Type::Auto:
+ case clang::Type::InjectedClassName:
+ case clang::Type::DependentName:
+ case clang::Type::DependentTemplateSpecialization:
+ case clang::Type::PackExpansion:
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ case clang::Type::Complex:
+ case clang::Type::ObjCObjectPointer:
+ case clang::Type::Atomic:
+ case clang::Type::Pipe:
+ case clang::Type::ObjCTypeParam:
+ case clang::Type::DeducedTemplateSpecialization:
+ case clang::Type::DependentAddressSpace:
+ case clang::Type::DependentVector:
return res;
}
zig_unreachable();
}
-static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt *stmt) {
+static AstNode *trans_while_loop(Context *c, TransScope *scope, const clang::WhileStmt *stmt) {
TransScopeWhile *while_scope = trans_scope_while_create(c, scope);
while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, scope, stmt->getCond(), TransRValue);
@@ -2627,7 +2625,7 @@ static AstNode *trans_while_loop(Context *c, TransScope *scope, const WhileStmt
return while_scope->node;
}
-static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *stmt) {
+static AstNode *trans_if_statement(Context *c, TransScope *scope, const clang::IfStmt *stmt) {
// if (c) t
// if (c) t else e
AstNode *if_node = trans_create_node(c, NodeTypeIfBoolExpr);
@@ -2649,7 +2647,7 @@ static AstNode *trans_if_statement(Context *c, TransScope *scope, const IfStmt *
return if_node;
}
-static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const CallExpr *stmt) {
+static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::CallExpr *stmt) {
AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
AstNode *callee_raw_node = trans_expr(c, ResultUsedYes, scope, stmt->getCallee(), TransRValue);
@@ -2657,16 +2655,16 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
return nullptr;
bool is_ptr = false;
- const FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
+ const clang::FunctionProtoType *fn_ty = qual_type_get_fn_proto(stmt->getCallee()->getType(), &is_ptr);
AstNode *callee_node = nullptr;
if (is_ptr && fn_ty) {
- if (stmt->getCallee()->getStmtClass() == Stmt::ImplicitCastExprClass) {
- const ImplicitCastExpr *implicit_cast = static_cast(stmt->getCallee());
- if (implicit_cast->getCastKind() == CK_FunctionToPointerDecay) {
- if (implicit_cast->getSubExpr()->getStmtClass() == Stmt::DeclRefExprClass) {
- const DeclRefExpr *decl_ref = static_cast(implicit_cast->getSubExpr());
- const Decl *decl = decl_ref->getFoundDecl();
- if (decl->getKind() == Decl::Function) {
+ if (stmt->getCallee()->getStmtClass() == clang::Stmt::ImplicitCastExprClass) {
+ const clang::ImplicitCastExpr *implicit_cast = static_cast(stmt->getCallee());
+ if (implicit_cast->getCastKind() == clang::CK_FunctionToPointerDecay) {
+ if (implicit_cast->getSubExpr()->getStmtClass() == clang::Stmt::DeclRefExprClass) {
+ const clang::DeclRefExpr *decl_ref = static_cast(implicit_cast->getSubExpr());
+ const clang::Decl *decl = decl_ref->getFoundDecl();
+ if (decl->getKind() == clang::Decl::Function) {
callee_node = callee_raw_node;
}
}
@@ -2682,7 +2680,7 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
node->data.fn_call_expr.fn_ref_expr = callee_node;
unsigned num_args = stmt->getNumArgs();
- const Expr * const* args = stmt->getArgs();
+ const clang::Expr * const* args = stmt->getArgs();
for (unsigned i = 0; i < num_args; i += 1) {
AstNode *arg_node = trans_expr(c, ResultUsedYes, scope, args[i], TransRValue);
if (arg_node == nullptr)
@@ -2698,7 +2696,7 @@ static AstNode *trans_call_expr(Context *c, ResultUsed result_used, TransScope *
return node;
}
-static AstNode *trans_member_expr(Context *c, TransScope *scope, const MemberExpr *stmt) {
+static AstNode *trans_member_expr(Context *c, TransScope *scope, const clang::MemberExpr *stmt) {
AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
if (container_node == nullptr)
return nullptr;
@@ -2713,7 +2711,7 @@ static AstNode *trans_member_expr(Context *c, TransScope *scope, const MemberExp
return node;
}
-static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const ArraySubscriptExpr *stmt) {
+static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const clang::ArraySubscriptExpr *stmt) {
AstNode *container_node = trans_expr(c, ResultUsedYes, scope, stmt->getBase(), TransRValue);
if (container_node == nullptr)
return nullptr;
@@ -2730,7 +2728,7 @@ static AstNode *trans_array_subscript_expr(Context *c, TransScope *scope, const
}
static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, TransScope *scope,
- const CStyleCastExpr *stmt, TransLRValue lrvalue)
+ const clang::CStyleCastExpr *stmt, TransLRValue lrvalue)
{
AstNode *sub_expr_node = trans_expr(c, result_used, scope, stmt->getSubExpr(), lrvalue);
if (sub_expr_node == nullptr)
@@ -2740,7 +2738,7 @@ static AstNode *trans_c_style_cast_expr(Context *c, ResultUsed result_used, Tran
}
static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scope,
- const UnaryExprOrTypeTraitExpr *stmt)
+ const clang::UnaryExprOrTypeTraitExpr *stmt)
{
AstNode *type_node = trans_qual_type(c, stmt->getTypeOfArgument(), stmt->getLocStart());
if (type_node == nullptr)
@@ -2751,14 +2749,14 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, TransScope *scop
return node;
}
-static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt *stmt) {
+static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const clang::DoStmt *stmt) {
TransScopeWhile *while_scope = trans_scope_while_create(c, parent_scope);
while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
AstNode *body_node;
TransScope *child_scope;
- if (stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) {
+ if (stmt->getBody()->getStmtClass() == clang::Stmt::CompoundStmtClass) {
// there's already a block in C, so we'll append our condition to it.
// c: do {
// c: a;
@@ -2811,11 +2809,11 @@ static AstNode *trans_do_loop(Context *c, TransScope *parent_scope, const DoStmt
return while_scope->node;
}
-static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForStmt *stmt) {
+static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const clang::ForStmt *stmt) {
AstNode *loop_block_node;
TransScopeWhile *while_scope;
TransScope *cond_scope;
- const Stmt *init_stmt = stmt->getInit();
+ const clang::Stmt *init_stmt = stmt->getInit();
if (init_stmt == nullptr) {
while_scope = trans_scope_while_create(c, parent_scope);
loop_block_node = while_scope->node;
@@ -2836,12 +2834,12 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
child_scope->node->data.block.statements.append(while_scope->node);
}
- const Stmt *cond_stmt = stmt->getCond();
+ const clang::Stmt *cond_stmt = stmt->getCond();
if (cond_stmt == nullptr) {
while_scope->node->data.while_expr.condition = trans_create_node_bool(c, true);
} else {
- if (Expr::classof(cond_stmt)) {
- const Expr *cond_expr = static_cast(cond_stmt);
+ if (clang::Expr::classof(cond_stmt)) {
+ const clang::Expr *cond_expr = static_cast(cond_stmt);
while_scope->node->data.while_expr.condition = trans_bool_expr(c, ResultUsedYes, cond_scope, cond_expr, TransRValue);
if (while_scope->node->data.while_expr.condition == nullptr)
@@ -2854,7 +2852,7 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
}
}
- const Stmt *inc_stmt = stmt->getInc();
+ const clang::Stmt *inc_stmt = stmt->getInc();
if (inc_stmt != nullptr) {
AstNode *inc_node;
TransScope *inc_scope = trans_stmt(c, cond_scope, inc_stmt, &inc_node);
@@ -2877,12 +2875,12 @@ static AstNode *trans_for_loop(Context *c, TransScope *parent_scope, const ForSt
return loop_block_node;
}
-static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const SwitchStmt *stmt) {
+static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const clang::SwitchStmt *stmt) {
TransScopeBlock *block_scope = trans_scope_block_create(c, parent_scope);
TransScopeSwitch *switch_scope;
- const DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
+ const clang::DeclStmt *var_decl_stmt = stmt->getConditionVariableDeclStmt();
if (var_decl_stmt == nullptr) {
switch_scope = trans_scope_switch_create(c, &block_scope->base);
} else {
@@ -2901,7 +2899,7 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw
switch_scope->end_label_name = end_label_name;
block_scope->node->data.block.name = end_label_name;
- const Expr *cond_expr = stmt->getCond();
+ const clang::Expr *cond_expr = stmt->getCond();
assert(cond_expr != nullptr);
AstNode *expr_node = trans_expr(c, ResultUsedYes, &block_scope->base, cond_expr, TransRValue);
@@ -2910,9 +2908,9 @@ static AstNode *trans_switch_stmt(Context *c, TransScope *parent_scope, const Sw
switch_scope->switch_node->data.switch_expr.expr = expr_node;
AstNode *body_node;
- const Stmt *body_stmt = stmt->getBody();
- if (body_stmt->getStmtClass() == Stmt::CompoundStmtClass) {
- if (trans_compound_stmt_inline(c, &switch_scope->base, (const CompoundStmt *)body_stmt,
+ const clang::Stmt *body_stmt = stmt->getBody();
+ if (body_stmt->getStmtClass() == clang::Stmt::CompoundStmtClass) {
+ if (trans_compound_stmt_inline(c, &switch_scope->base, (const clang::CompoundStmt *)body_stmt,
block_scope->node, nullptr))
{
return nullptr;
@@ -2944,7 +2942,7 @@ static TransScopeSwitch *trans_scope_switch_find(TransScope *scope) {
return nullptr;
}
-static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStmt *stmt, AstNode **out_node,
+static int trans_switch_case(Context *c, TransScope *parent_scope, const clang::CaseStmt *stmt, AstNode **out_node,
TransScope **out_scope) {
*out_node = nullptr;
@@ -2989,7 +2987,7 @@ static int trans_switch_case(Context *c, TransScope *parent_scope, const CaseStm
return ErrorNone;
}
-static int trans_switch_default(Context *c, TransScope *parent_scope, const DefaultStmt *stmt, AstNode **out_node,
+static int trans_switch_default(Context *c, TransScope *parent_scope, const clang::DefaultStmt *stmt, AstNode **out_node,
TransScope **out_scope)
{
*out_node = nullptr;
@@ -3026,25 +3024,25 @@ static int trans_switch_default(Context *c, TransScope *parent_scope, const Defa
return ErrorNone;
}
-static AstNode *trans_string_literal(Context *c, TransScope *scope, const StringLiteral *stmt) {
+static AstNode *trans_string_literal(Context *c, TransScope *scope, const clang::StringLiteral *stmt) {
switch (stmt->getKind()) {
- case StringLiteral::Ascii:
- case StringLiteral::UTF8:
+ case clang::StringLiteral::Ascii:
+ case clang::StringLiteral::UTF8:
return trans_create_node_str_lit_c(c, string_ref_to_buf(stmt->getString()));
- case StringLiteral::UTF16:
+ case clang::StringLiteral::UTF16:
emit_warning(c, stmt->getLocStart(), "TODO support UTF16 string literals");
return nullptr;
- case StringLiteral::UTF32:
+ case clang::StringLiteral::UTF32:
emit_warning(c, stmt->getLocStart(), "TODO support UTF32 string literals");
return nullptr;
- case StringLiteral::Wide:
+ case clang::StringLiteral::Wide:
emit_warning(c, stmt->getLocStart(), "TODO support wide string literals");
return nullptr;
}
zig_unreachable();
}
-static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt *stmt) {
+static AstNode *trans_break_stmt(Context *c, TransScope *scope, const clang::BreakStmt *stmt) {
TransScope *cur_scope = scope;
while (cur_scope != nullptr) {
if (cur_scope->id == TransScopeIdWhile) {
@@ -3058,7 +3056,7 @@ static AstNode *trans_break_stmt(Context *c, TransScope *scope, const BreakStmt
zig_unreachable();
}
-static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const ContinueStmt *stmt) {
+static AstNode *trans_continue_stmt(Context *c, TransScope *scope, const clang::ContinueStmt *stmt) {
return trans_create_node(c, NodeTypeContinue);
}
@@ -3071,47 +3069,47 @@ static int wrap_stmt(AstNode **out_node, TransScope **out_scope, TransScope *in_
return ErrorNone;
}
-static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
+static int trans_stmt_extra(Context *c, TransScope *scope, const clang::Stmt *stmt,
ResultUsed result_used, TransLRValue lrvalue,
AstNode **out_node, TransScope **out_child_scope,
TransScope **out_node_scope)
{
- Stmt::StmtClass sc = stmt->getStmtClass();
+ clang::Stmt::StmtClass sc = stmt->getStmtClass();
switch (sc) {
- case Stmt::ReturnStmtClass:
+ case clang::Stmt::ReturnStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_return_stmt(c, scope, (const ReturnStmt *)stmt));
- case Stmt::CompoundStmtClass:
+ trans_return_stmt(c, scope, (const clang::ReturnStmt *)stmt));
+ case clang::Stmt::CompoundStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_compound_stmt(c, scope, (const CompoundStmt *)stmt, out_node_scope));
- case Stmt::IntegerLiteralClass:
+ trans_compound_stmt(c, scope, (const clang::CompoundStmt *)stmt, out_node_scope));
+ case clang::Stmt::IntegerLiteralClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_integer_literal(c, (const IntegerLiteral *)stmt));
- case Stmt::ConditionalOperatorClass:
+ trans_integer_literal(c, (const clang::IntegerLiteral *)stmt));
+ case clang::Stmt::ConditionalOperatorClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_conditional_operator(c, result_used, scope, (const ConditionalOperator *)stmt));
- case Stmt::BinaryOperatorClass:
+ trans_conditional_operator(c, result_used, scope, (const clang::ConditionalOperator *)stmt));
+ case clang::Stmt::BinaryOperatorClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_binary_operator(c, result_used, scope, (const BinaryOperator *)stmt));
- case Stmt::CompoundAssignOperatorClass:
+ trans_binary_operator(c, result_used, scope, (const clang::BinaryOperator *)stmt));
+ case clang::Stmt::CompoundAssignOperatorClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_compound_assign_operator(c, result_used, scope, (const CompoundAssignOperator *)stmt));
- case Stmt::ImplicitCastExprClass:
+ trans_compound_assign_operator(c, result_used, scope, (const clang::CompoundAssignOperator *)stmt));
+ case clang::Stmt::ImplicitCastExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_implicit_cast_expr(c, scope, (const ImplicitCastExpr *)stmt));
- case Stmt::DeclRefExprClass:
+ trans_implicit_cast_expr(c, scope, (const clang::ImplicitCastExpr *)stmt));
+ case clang::Stmt::DeclRefExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_decl_ref_expr(c, scope, (const DeclRefExpr *)stmt, lrvalue));
- case Stmt::UnaryOperatorClass:
+ trans_decl_ref_expr(c, scope, (const clang::DeclRefExpr *)stmt, lrvalue));
+ case clang::Stmt::UnaryOperatorClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_unary_operator(c, result_used, scope, (const UnaryOperator *)stmt));
- case Stmt::DeclStmtClass:
- return trans_local_declaration(c, scope, (const DeclStmt *)stmt, out_node, out_child_scope);
- case Stmt::DoStmtClass:
- case Stmt::WhileStmtClass: {
- AstNode *while_node = sc == Stmt::DoStmtClass
- ? trans_do_loop(c, scope, (const DoStmt *)stmt)
- : trans_while_loop(c, scope, (const WhileStmt *)stmt);
+ trans_unary_operator(c, result_used, scope, (const clang::UnaryOperator *)stmt));
+ case clang::Stmt::DeclStmtClass:
+ return trans_local_declaration(c, scope, (const clang::DeclStmt *)stmt, out_node, out_child_scope);
+ case clang::Stmt::DoStmtClass:
+ case clang::Stmt::WhileStmtClass: {
+ AstNode *while_node = sc == clang::Stmt::DoStmtClass
+ ? trans_do_loop(c, scope, (const clang::DoStmt *)stmt)
+ : trans_while_loop(c, scope, (const clang::WhileStmt *)stmt);
if (while_node == nullptr)
return ErrorUnexpected;
@@ -3122,556 +3120,556 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
return wrap_stmt(out_node, out_child_scope, scope, while_node);
}
- case Stmt::IfStmtClass:
+ case clang::Stmt::IfStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_if_statement(c, scope, (const IfStmt *)stmt));
- case Stmt::CallExprClass:
+ trans_if_statement(c, scope, (const clang::IfStmt *)stmt));
+ case clang::Stmt::CallExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_call_expr(c, result_used, scope, (const CallExpr *)stmt));
- case Stmt::NullStmtClass:
+ trans_call_expr(c, result_used, scope, (const clang::CallExpr *)stmt));
+ case clang::Stmt::NullStmtClass:
*out_node = nullptr;
*out_child_scope = scope;
return ErrorNone;
- case Stmt::MemberExprClass:
+ case clang::Stmt::MemberExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_member_expr(c, scope, (const MemberExpr *)stmt));
- case Stmt::ArraySubscriptExprClass:
+ trans_member_expr(c, scope, (const clang::MemberExpr *)stmt));
+ case clang::Stmt::ArraySubscriptExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_array_subscript_expr(c, scope, (const ArraySubscriptExpr *)stmt));
- case Stmt::CStyleCastExprClass:
+ trans_array_subscript_expr(c, scope, (const clang::ArraySubscriptExpr *)stmt));
+ case clang::Stmt::CStyleCastExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_c_style_cast_expr(c, result_used, scope, (const CStyleCastExpr *)stmt, lrvalue));
- case Stmt::UnaryExprOrTypeTraitExprClass:
+ trans_c_style_cast_expr(c, result_used, scope, (const clang::CStyleCastExpr *)stmt, lrvalue));
+ case clang::Stmt::UnaryExprOrTypeTraitExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_unary_expr_or_type_trait_expr(c, scope, (const UnaryExprOrTypeTraitExpr *)stmt));
- case Stmt::ForStmtClass: {
- AstNode *node = trans_for_loop(c, scope, (const ForStmt *)stmt);
+ trans_unary_expr_or_type_trait_expr(c, scope, (const clang::UnaryExprOrTypeTraitExpr *)stmt));
+ case clang::Stmt::ForStmtClass: {
+ AstNode *node = trans_for_loop(c, scope, (const clang::ForStmt *)stmt);
return wrap_stmt(out_node, out_child_scope, scope, node);
}
- case Stmt::StringLiteralClass:
+ case clang::Stmt::StringLiteralClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_string_literal(c, scope, (const StringLiteral *)stmt));
- case Stmt::BreakStmtClass:
+ trans_string_literal(c, scope, (const clang::StringLiteral *)stmt));
+ case clang::Stmt::BreakStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_break_stmt(c, scope, (const BreakStmt *)stmt));
- case Stmt::ContinueStmtClass:
+ trans_break_stmt(c, scope, (const clang::BreakStmt *)stmt));
+ case clang::Stmt::ContinueStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_continue_stmt(c, scope, (const ContinueStmt *)stmt));
- case Stmt::ParenExprClass:
+ trans_continue_stmt(c, scope, (const clang::ContinueStmt *)stmt));
+ case clang::Stmt::ParenExprClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_expr(c, result_used, scope, ((const ParenExpr*)stmt)->getSubExpr(), lrvalue));
- case Stmt::SwitchStmtClass:
+ trans_expr(c, result_used, scope, ((const clang::ParenExpr*)stmt)->getSubExpr(), lrvalue));
+ case clang::Stmt::SwitchStmtClass:
return wrap_stmt(out_node, out_child_scope, scope,
- trans_switch_stmt(c, scope, (const SwitchStmt *)stmt));
- case Stmt::CaseStmtClass:
- return trans_switch_case(c, scope, (const CaseStmt *)stmt, out_node, out_child_scope);
- case Stmt::DefaultStmtClass:
- return trans_switch_default(c, scope, (const DefaultStmt *)stmt, out_node, out_child_scope);
- case Stmt::NoStmtClass:
+ trans_switch_stmt(c, scope, (const clang::SwitchStmt *)stmt));
+ case clang::Stmt::CaseStmtClass:
+ return trans_switch_case(c, scope, (const clang::CaseStmt *)stmt, out_node, out_child_scope);
+ case clang::Stmt::DefaultStmtClass:
+ return trans_switch_default(c, scope, (const clang::DefaultStmt *)stmt, out_node, out_child_scope);
+ case clang::Stmt::NoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C NoStmtClass");
return ErrorUnexpected;
- case Stmt::GCCAsmStmtClass:
+ case clang::Stmt::GCCAsmStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GCCAsmStmtClass");
return ErrorUnexpected;
- case Stmt::MSAsmStmtClass:
+ case clang::Stmt::MSAsmStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSAsmStmtClass");
return ErrorUnexpected;
- case Stmt::AttributedStmtClass:
+ case clang::Stmt::AttributedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AttributedStmtClass");
return ErrorUnexpected;
- case Stmt::CXXCatchStmtClass:
+ case clang::Stmt::CXXCatchStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXCatchStmtClass");
return ErrorUnexpected;
- case Stmt::CXXForRangeStmtClass:
+ case clang::Stmt::CXXForRangeStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXForRangeStmtClass");
return ErrorUnexpected;
- case Stmt::CXXTryStmtClass:
+ case clang::Stmt::CXXTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTryStmtClass");
return ErrorUnexpected;
- case Stmt::CapturedStmtClass:
+ case clang::Stmt::CapturedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CapturedStmtClass");
return ErrorUnexpected;
- case Stmt::CoreturnStmtClass:
+ case clang::Stmt::CoreturnStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoreturnStmtClass");
return ErrorUnexpected;
- case Stmt::CoroutineBodyStmtClass:
+ case clang::Stmt::CoroutineBodyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoroutineBodyStmtClass");
return ErrorUnexpected;
- case Stmt::BinaryConditionalOperatorClass:
+ case clang::Stmt::BinaryConditionalOperatorClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C BinaryConditionalOperatorClass");
return ErrorUnexpected;
- case Stmt::AddrLabelExprClass:
+ case clang::Stmt::AddrLabelExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AddrLabelExprClass");
return ErrorUnexpected;
- case Stmt::ArrayInitIndexExprClass:
+ case clang::Stmt::ArrayInitIndexExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayInitIndexExprClass");
return ErrorUnexpected;
- case Stmt::ArrayInitLoopExprClass:
+ case clang::Stmt::ArrayInitLoopExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayInitLoopExprClass");
return ErrorUnexpected;
- case Stmt::ArrayTypeTraitExprClass:
+ case clang::Stmt::ArrayTypeTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ArrayTypeTraitExprClass");
return ErrorUnexpected;
- case Stmt::AsTypeExprClass:
+ case clang::Stmt::AsTypeExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AsTypeExprClass");
return ErrorUnexpected;
- case Stmt::AtomicExprClass:
+ case clang::Stmt::AtomicExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C AtomicExprClass");
return ErrorUnexpected;
- case Stmt::BlockExprClass:
+ case clang::Stmt::BlockExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C BlockExprClass");
return ErrorUnexpected;
- case Stmt::CXXBindTemporaryExprClass:
+ case clang::Stmt::CXXBindTemporaryExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXBindTemporaryExprClass");
return ErrorUnexpected;
- case Stmt::CXXBoolLiteralExprClass:
+ case clang::Stmt::CXXBoolLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXBoolLiteralExprClass");
return ErrorUnexpected;
- case Stmt::CXXConstructExprClass:
+ case clang::Stmt::CXXConstructExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXConstructExprClass");
return ErrorUnexpected;
- case Stmt::CXXTemporaryObjectExprClass:
+ case clang::Stmt::CXXTemporaryObjectExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTemporaryObjectExprClass");
return ErrorUnexpected;
- case Stmt::CXXDefaultArgExprClass:
+ case clang::Stmt::CXXDefaultArgExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDefaultArgExprClass");
return ErrorUnexpected;
- case Stmt::CXXDefaultInitExprClass:
+ case clang::Stmt::CXXDefaultInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDefaultInitExprClass");
return ErrorUnexpected;
- case Stmt::CXXDeleteExprClass:
+ case clang::Stmt::CXXDeleteExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDeleteExprClass");
return ErrorUnexpected;
- case Stmt::CXXDependentScopeMemberExprClass:
+ case clang::Stmt::CXXDependentScopeMemberExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDependentScopeMemberExprClass");
return ErrorUnexpected;
- case Stmt::CXXFoldExprClass:
+ case clang::Stmt::CXXFoldExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXFoldExprClass");
return ErrorUnexpected;
- case Stmt::CXXInheritedCtorInitExprClass:
+ case clang::Stmt::CXXInheritedCtorInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXInheritedCtorInitExprClass");
return ErrorUnexpected;
- case Stmt::CXXNewExprClass:
+ case clang::Stmt::CXXNewExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNewExprClass");
return ErrorUnexpected;
- case Stmt::CXXNoexceptExprClass:
+ case clang::Stmt::CXXNoexceptExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNoexceptExprClass");
return ErrorUnexpected;
- case Stmt::CXXNullPtrLiteralExprClass:
+ case clang::Stmt::CXXNullPtrLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXNullPtrLiteralExprClass");
return ErrorUnexpected;
- case Stmt::CXXPseudoDestructorExprClass:
+ case clang::Stmt::CXXPseudoDestructorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXPseudoDestructorExprClass");
return ErrorUnexpected;
- case Stmt::CXXScalarValueInitExprClass:
+ case clang::Stmt::CXXScalarValueInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXScalarValueInitExprClass");
return ErrorUnexpected;
- case Stmt::CXXStdInitializerListExprClass:
+ case clang::Stmt::CXXStdInitializerListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXStdInitializerListExprClass");
return ErrorUnexpected;
- case Stmt::CXXThisExprClass:
+ case clang::Stmt::CXXThisExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXThisExprClass");
return ErrorUnexpected;
- case Stmt::CXXThrowExprClass:
+ case clang::Stmt::CXXThrowExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXThrowExprClass");
return ErrorUnexpected;
- case Stmt::CXXTypeidExprClass:
+ case clang::Stmt::CXXTypeidExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXTypeidExprClass");
return ErrorUnexpected;
- case Stmt::CXXUnresolvedConstructExprClass:
+ case clang::Stmt::CXXUnresolvedConstructExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUnresolvedConstructExprClass");
return ErrorUnexpected;
- case Stmt::CXXUuidofExprClass:
+ case clang::Stmt::CXXUuidofExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXUuidofExprClass");
return ErrorUnexpected;
- case Stmt::CUDAKernelCallExprClass:
+ case clang::Stmt::CUDAKernelCallExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CUDAKernelCallExprClass");
return ErrorUnexpected;
- case Stmt::CXXMemberCallExprClass:
+ case clang::Stmt::CXXMemberCallExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXMemberCallExprClass");
return ErrorUnexpected;
- case Stmt::CXXOperatorCallExprClass:
+ case clang::Stmt::CXXOperatorCallExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXOperatorCallExprClass");
return ErrorUnexpected;
- case Stmt::UserDefinedLiteralClass:
+ case clang::Stmt::UserDefinedLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UserDefinedLiteralClass");
return ErrorUnexpected;
- case Stmt::CXXFunctionalCastExprClass:
+ case clang::Stmt::CXXFunctionalCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXFunctionalCastExprClass");
return ErrorUnexpected;
- case Stmt::CXXConstCastExprClass:
+ case clang::Stmt::CXXConstCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXConstCastExprClass");
return ErrorUnexpected;
- case Stmt::CXXDynamicCastExprClass:
+ case clang::Stmt::CXXDynamicCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXDynamicCastExprClass");
return ErrorUnexpected;
- case Stmt::CXXReinterpretCastExprClass:
+ case clang::Stmt::CXXReinterpretCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXReinterpretCastExprClass");
return ErrorUnexpected;
- case Stmt::CXXStaticCastExprClass:
+ case clang::Stmt::CXXStaticCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CXXStaticCastExprClass");
return ErrorUnexpected;
- case Stmt::ObjCBridgedCastExprClass:
+ case clang::Stmt::ObjCBridgedCastExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBridgedCastExprClass");
return ErrorUnexpected;
- case Stmt::CharacterLiteralClass:
+ case clang::Stmt::CharacterLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CharacterLiteralClass");
return ErrorUnexpected;
- case Stmt::ChooseExprClass:
+ case clang::Stmt::ChooseExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ChooseExprClass");
return ErrorUnexpected;
- case Stmt::CompoundLiteralExprClass:
+ case clang::Stmt::CompoundLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CompoundLiteralExprClass");
return ErrorUnexpected;
- case Stmt::ConvertVectorExprClass:
+ case clang::Stmt::ConvertVectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ConvertVectorExprClass");
return ErrorUnexpected;
- case Stmt::CoawaitExprClass:
+ case clang::Stmt::CoawaitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoawaitExprClass");
return ErrorUnexpected;
- case Stmt::CoyieldExprClass:
+ case clang::Stmt::CoyieldExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C CoyieldExprClass");
return ErrorUnexpected;
- case Stmt::DependentCoawaitExprClass:
+ case clang::Stmt::DependentCoawaitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DependentCoawaitExprClass");
return ErrorUnexpected;
- case Stmt::DependentScopeDeclRefExprClass:
+ case clang::Stmt::DependentScopeDeclRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DependentScopeDeclRefExprClass");
return ErrorUnexpected;
- case Stmt::DesignatedInitExprClass:
+ case clang::Stmt::DesignatedInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DesignatedInitExprClass");
return ErrorUnexpected;
- case Stmt::DesignatedInitUpdateExprClass:
+ case clang::Stmt::DesignatedInitUpdateExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C DesignatedInitUpdateExprClass");
return ErrorUnexpected;
- case Stmt::ExprWithCleanupsClass:
+ case clang::Stmt::ExprWithCleanupsClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExprWithCleanupsClass");
return ErrorUnexpected;
- case Stmt::ExpressionTraitExprClass:
+ case clang::Stmt::ExpressionTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExpressionTraitExprClass");
return ErrorUnexpected;
- case Stmt::ExtVectorElementExprClass:
+ case clang::Stmt::ExtVectorElementExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ExtVectorElementExprClass");
return ErrorUnexpected;
- case Stmt::FloatingLiteralClass:
+ case clang::Stmt::FloatingLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C FloatingLiteralClass");
return ErrorUnexpected;
- case Stmt::FunctionParmPackExprClass:
+ case clang::Stmt::FunctionParmPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C FunctionParmPackExprClass");
return ErrorUnexpected;
- case Stmt::GNUNullExprClass:
+ case clang::Stmt::GNUNullExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GNUNullExprClass");
return ErrorUnexpected;
- case Stmt::GenericSelectionExprClass:
+ case clang::Stmt::GenericSelectionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GenericSelectionExprClass");
return ErrorUnexpected;
- case Stmt::ImaginaryLiteralClass:
+ case clang::Stmt::ImaginaryLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ImaginaryLiteralClass");
return ErrorUnexpected;
- case Stmt::ImplicitValueInitExprClass:
+ case clang::Stmt::ImplicitValueInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ImplicitValueInitExprClass");
return ErrorUnexpected;
- case Stmt::InitListExprClass:
+ case clang::Stmt::InitListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C InitListExprClass");
return ErrorUnexpected;
- case Stmt::LambdaExprClass:
+ case clang::Stmt::LambdaExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C LambdaExprClass");
return ErrorUnexpected;
- case Stmt::MSPropertyRefExprClass:
+ case clang::Stmt::MSPropertyRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSPropertyRefExprClass");
return ErrorUnexpected;
- case Stmt::MSPropertySubscriptExprClass:
+ case clang::Stmt::MSPropertySubscriptExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSPropertySubscriptExprClass");
return ErrorUnexpected;
- case Stmt::MaterializeTemporaryExprClass:
+ case clang::Stmt::MaterializeTemporaryExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass");
return ErrorUnexpected;
- case Stmt::NoInitExprClass:
+ case clang::Stmt::NoInitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass");
return ErrorUnexpected;
- case Stmt::OMPArraySectionExprClass:
+ case clang::Stmt::OMPArraySectionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPArraySectionExprClass");
return ErrorUnexpected;
- case Stmt::ObjCArrayLiteralClass:
+ case clang::Stmt::ObjCArrayLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCArrayLiteralClass");
return ErrorUnexpected;
- case Stmt::ObjCAvailabilityCheckExprClass:
+ case clang::Stmt::ObjCAvailabilityCheckExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAvailabilityCheckExprClass");
return ErrorUnexpected;
- case Stmt::ObjCBoolLiteralExprClass:
+ case clang::Stmt::ObjCBoolLiteralExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBoolLiteralExprClass");
return ErrorUnexpected;
- case Stmt::ObjCBoxedExprClass:
+ case clang::Stmt::ObjCBoxedExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCBoxedExprClass");
return ErrorUnexpected;
- case Stmt::ObjCDictionaryLiteralClass:
+ case clang::Stmt::ObjCDictionaryLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCDictionaryLiteralClass");
return ErrorUnexpected;
- case Stmt::ObjCEncodeExprClass:
+ case clang::Stmt::ObjCEncodeExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCEncodeExprClass");
return ErrorUnexpected;
- case Stmt::ObjCIndirectCopyRestoreExprClass:
+ case clang::Stmt::ObjCIndirectCopyRestoreExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIndirectCopyRestoreExprClass");
return ErrorUnexpected;
- case Stmt::ObjCIsaExprClass:
+ case clang::Stmt::ObjCIsaExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIsaExprClass");
return ErrorUnexpected;
- case Stmt::ObjCIvarRefExprClass:
+ case clang::Stmt::ObjCIvarRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCIvarRefExprClass");
return ErrorUnexpected;
- case Stmt::ObjCMessageExprClass:
+ case clang::Stmt::ObjCMessageExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCMessageExprClass");
return ErrorUnexpected;
- case Stmt::ObjCPropertyRefExprClass:
+ case clang::Stmt::ObjCPropertyRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCPropertyRefExprClass");
return ErrorUnexpected;
- case Stmt::ObjCProtocolExprClass:
+ case clang::Stmt::ObjCProtocolExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCProtocolExprClass");
return ErrorUnexpected;
- case Stmt::ObjCSelectorExprClass:
+ case clang::Stmt::ObjCSelectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCSelectorExprClass");
return ErrorUnexpected;
- case Stmt::ObjCStringLiteralClass:
+ case clang::Stmt::ObjCStringLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCStringLiteralClass");
return ErrorUnexpected;
- case Stmt::ObjCSubscriptRefExprClass:
+ case clang::Stmt::ObjCSubscriptRefExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCSubscriptRefExprClass");
return ErrorUnexpected;
- case Stmt::OffsetOfExprClass:
+ case clang::Stmt::OffsetOfExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OffsetOfExprClass");
return ErrorUnexpected;
- case Stmt::OpaqueValueExprClass:
+ case clang::Stmt::OpaqueValueExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OpaqueValueExprClass");
return ErrorUnexpected;
- case Stmt::UnresolvedLookupExprClass:
+ case clang::Stmt::UnresolvedLookupExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UnresolvedLookupExprClass");
return ErrorUnexpected;
- case Stmt::UnresolvedMemberExprClass:
+ case clang::Stmt::UnresolvedMemberExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C UnresolvedMemberExprClass");
return ErrorUnexpected;
- case Stmt::PackExpansionExprClass:
+ case clang::Stmt::PackExpansionExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PackExpansionExprClass");
return ErrorUnexpected;
- case Stmt::ParenListExprClass:
+ case clang::Stmt::ParenListExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ParenListExprClass");
return ErrorUnexpected;
- case Stmt::PredefinedExprClass:
+ case clang::Stmt::PredefinedExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PredefinedExprClass");
return ErrorUnexpected;
- case Stmt::PseudoObjectExprClass:
+ case clang::Stmt::PseudoObjectExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C PseudoObjectExprClass");
return ErrorUnexpected;
- case Stmt::ShuffleVectorExprClass:
+ case clang::Stmt::ShuffleVectorExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ShuffleVectorExprClass");
return ErrorUnexpected;
- case Stmt::SizeOfPackExprClass:
+ case clang::Stmt::SizeOfPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SizeOfPackExprClass");
return ErrorUnexpected;
- case Stmt::StmtExprClass:
+ case clang::Stmt::StmtExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C StmtExprClass");
return ErrorUnexpected;
- case Stmt::SubstNonTypeTemplateParmExprClass:
+ case clang::Stmt::SubstNonTypeTemplateParmExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmExprClass");
return ErrorUnexpected;
- case Stmt::SubstNonTypeTemplateParmPackExprClass:
+ case clang::Stmt::SubstNonTypeTemplateParmPackExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SubstNonTypeTemplateParmPackExprClass");
return ErrorUnexpected;
- case Stmt::TypeTraitExprClass:
+ case clang::Stmt::TypeTraitExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C TypeTraitExprClass");
return ErrorUnexpected;
- case Stmt::TypoExprClass:
+ case clang::Stmt::TypoExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C TypoExprClass");
return ErrorUnexpected;
- case Stmt::VAArgExprClass:
+ case clang::Stmt::VAArgExprClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C VAArgExprClass");
return ErrorUnexpected;
- case Stmt::GotoStmtClass:
+ case clang::Stmt::GotoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C GotoStmtClass");
return ErrorUnexpected;
- case Stmt::IndirectGotoStmtClass:
+ case clang::Stmt::IndirectGotoStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C IndirectGotoStmtClass");
return ErrorUnexpected;
- case Stmt::LabelStmtClass:
+ case clang::Stmt::LabelStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C LabelStmtClass");
return ErrorUnexpected;
- case Stmt::MSDependentExistsStmtClass:
+ case clang::Stmt::MSDependentExistsStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C MSDependentExistsStmtClass");
return ErrorUnexpected;
- case Stmt::OMPAtomicDirectiveClass:
+ case clang::Stmt::OMPAtomicDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPAtomicDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPBarrierDirectiveClass:
+ case clang::Stmt::OMPBarrierDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPBarrierDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPCancelDirectiveClass:
+ case clang::Stmt::OMPCancelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCancelDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPCancellationPointDirectiveClass:
+ case clang::Stmt::OMPCancellationPointDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCancellationPointDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPCriticalDirectiveClass:
+ case clang::Stmt::OMPCriticalDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPCriticalDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPFlushDirectiveClass:
+ case clang::Stmt::OMPFlushDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPFlushDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPDistributeDirectiveClass:
+ case clang::Stmt::OMPDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPDistributeParallelForDirectiveClass:
+ case clang::Stmt::OMPDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeParallelForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPDistributeParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPDistributeSimdDirectiveClass:
+ case clang::Stmt::OMPDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPDistributeSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPForDirectiveClass:
+ case clang::Stmt::OMPForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPForSimdDirectiveClass:
+ case clang::Stmt::OMPForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPParallelForDirectiveClass:
+ case clang::Stmt::OMPParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPSimdDirectiveClass:
+ case clang::Stmt::OMPSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPTargetParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetSimdDirectiveClass:
+ case clang::Stmt::OMPTargetSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetTeamsDistributeDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeParallelForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDistributeSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskLoopDirectiveClass:
+ case clang::Stmt::OMPTaskLoopDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskLoopDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskLoopSimdDirectiveClass:
+ case clang::Stmt::OMPTaskLoopSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskLoopSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTeamsDistributeDirectiveClass:
+ case clang::Stmt::OMPTeamsDistributeDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
+ case clang::Stmt::OMPTeamsDistributeParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeParallelForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
+ case clang::Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeParallelForSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTeamsDistributeSimdDirectiveClass:
+ case clang::Stmt::OMPTeamsDistributeSimdDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDistributeSimdDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPMasterDirectiveClass:
+ case clang::Stmt::OMPMasterDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPMasterDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPOrderedDirectiveClass:
+ case clang::Stmt::OMPOrderedDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPOrderedDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPParallelDirectiveClass:
+ case clang::Stmt::OMPParallelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPParallelSectionsDirectiveClass:
+ case clang::Stmt::OMPParallelSectionsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPParallelSectionsDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPSectionDirectiveClass:
+ case clang::Stmt::OMPSectionDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSectionDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPSectionsDirectiveClass:
+ case clang::Stmt::OMPSectionsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSectionsDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPSingleDirectiveClass:
+ case clang::Stmt::OMPSingleDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPSingleDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetDataDirectiveClass:
+ case clang::Stmt::OMPTargetDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetDataDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetDirectiveClass:
+ case clang::Stmt::OMPTargetDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetEnterDataDirectiveClass:
+ case clang::Stmt::OMPTargetEnterDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetEnterDataDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetExitDataDirectiveClass:
+ case clang::Stmt::OMPTargetExitDataDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetExitDataDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetParallelDirectiveClass:
+ case clang::Stmt::OMPTargetParallelDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetParallelForDirectiveClass:
+ case clang::Stmt::OMPTargetParallelForDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetParallelForDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetTeamsDirectiveClass:
+ case clang::Stmt::OMPTargetTeamsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetTeamsDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTargetUpdateDirectiveClass:
+ case clang::Stmt::OMPTargetUpdateDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTargetUpdateDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskDirectiveClass:
+ case clang::Stmt::OMPTaskDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskgroupDirectiveClass:
+ case clang::Stmt::OMPTaskgroupDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskgroupDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskwaitDirectiveClass:
+ case clang::Stmt::OMPTaskwaitDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskwaitDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTaskyieldDirectiveClass:
+ case clang::Stmt::OMPTaskyieldDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTaskyieldDirectiveClass");
return ErrorUnexpected;
- case Stmt::OMPTeamsDirectiveClass:
+ case clang::Stmt::OMPTeamsDirectiveClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C OMPTeamsDirectiveClass");
return ErrorUnexpected;
- case Stmt::ObjCAtCatchStmtClass:
+ case clang::Stmt::ObjCAtCatchStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtCatchStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCAtFinallyStmtClass:
+ case clang::Stmt::ObjCAtFinallyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtFinallyStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCAtSynchronizedStmtClass:
+ case clang::Stmt::ObjCAtSynchronizedStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtSynchronizedStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCAtThrowStmtClass:
+ case clang::Stmt::ObjCAtThrowStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtThrowStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCAtTryStmtClass:
+ case clang::Stmt::ObjCAtTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAtTryStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCAutoreleasePoolStmtClass:
+ case clang::Stmt::ObjCAutoreleasePoolStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCAutoreleasePoolStmtClass");
return ErrorUnexpected;
- case Stmt::ObjCForCollectionStmtClass:
+ case clang::Stmt::ObjCForCollectionStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C ObjCForCollectionStmtClass");
return ErrorUnexpected;
- case Stmt::SEHExceptStmtClass:
+ case clang::Stmt::SEHExceptStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHExceptStmtClass");
return ErrorUnexpected;
- case Stmt::SEHFinallyStmtClass:
+ case clang::Stmt::SEHFinallyStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHFinallyStmtClass");
return ErrorUnexpected;
- case Stmt::SEHLeaveStmtClass:
+ case clang::Stmt::SEHLeaveStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHLeaveStmtClass");
return ErrorUnexpected;
- case Stmt::SEHTryStmtClass:
+ case clang::Stmt::SEHTryStmtClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C SEHTryStmtClass");
return ErrorUnexpected;
- case Stmt::FixedPointLiteralClass:
+ case clang::Stmt::FixedPointLiteralClass:
emit_warning(c, stmt->getLocStart(), "TODO handle C FixedPointLiteralClass");
return ErrorUnexpected;
}
@@ -3679,7 +3677,7 @@ static int trans_stmt_extra(Context *c, TransScope *scope, const Stmt *stmt,
}
// Returns null if there was an error
-static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const Expr *expr,
+static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope, const clang::Expr *expr,
TransLRValue lrval)
{
AstNode *result_node;
@@ -3692,7 +3690,7 @@ static AstNode *trans_expr(Context *c, ResultUsed result_used, TransScope *scope
// Statements have no result and no concept of L or R value.
// Returns child scope, or null if there was an error
-static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, AstNode **out_node) {
+static TransScope *trans_stmt(Context *c, TransScope *scope, const clang::Stmt *stmt, AstNode **out_node) {
TransScope *child_scope;
if (trans_stmt_extra(c, scope, stmt, ResultUsedNo, TransRValue, out_node, &child_scope, nullptr)) {
return nullptr;
@@ -3700,7 +3698,7 @@ static TransScope *trans_stmt(Context *c, TransScope *scope, const Stmt *stmt, A
return child_scope;
}
-static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
+static void visit_fn_decl(Context *c, const clang::FunctionDecl *fn_decl) {
Buf *fn_name = buf_create_from_str(decl_name(fn_decl));
if (get_global(c, fn_name)) {
@@ -3717,13 +3715,13 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
proto_node->data.fn_proto.name = fn_name;
proto_node->data.fn_proto.is_extern = !fn_decl->hasBody();
- StorageClass sc = fn_decl->getStorageClass();
- if (sc == SC_None) {
+ clang::StorageClass sc = fn_decl->getStorageClass();
+ if (sc == clang::SC_None) {
proto_node->data.fn_proto.visib_mod = c->visib_mod;
proto_node->data.fn_proto.is_export = fn_decl->hasBody() ? c->want_export : false;
- } else if (sc == SC_Extern || sc == SC_Static) {
+ } else if (sc == clang::SC_Extern || sc == clang::SC_Static) {
proto_node->data.fn_proto.visib_mod = c->visib_mod;
- } else if (sc == SC_PrivateExtern) {
+ } else if (sc == clang::SC_PrivateExtern) {
emit_warning(c, fn_decl->getLocation(), "unsupported storage class: private extern");
return;
} else {
@@ -3735,7 +3733,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
for (size_t i = 0; i < proto_node->data.fn_proto.params.length; i += 1) {
AstNode *param_node = proto_node->data.fn_proto.params.at(i);
- const ParmVarDecl *param = fn_decl->getParamDecl(i);
+ const clang::ParmVarDecl *param = fn_decl->getParamDecl(i);
const char *name = decl_name(param);
Buf *proto_param_name;
@@ -3762,7 +3760,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
// actual function definition with body
c->ptr_params.clear();
- Stmt *body = fn_decl->getBody();
+ clang::Stmt *body = fn_decl->getBody();
AstNode *actual_body_node;
TransScope *result_scope = trans_stmt(c, scope, body, &actual_body_node);
if (result_scope == nullptr) {
@@ -3804,19 +3802,19 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
add_top_level_decl(c, fn_def_node->data.fn_def.fn_proto->data.fn_proto.name, fn_def_node);
}
-static AstNode *resolve_typdef_as_builtin(Context *c, const TypedefNameDecl *typedef_decl, const char *primitive_name) {
+static AstNode *resolve_typdef_as_builtin(Context *c, const clang::TypedefNameDecl *typedef_decl, const char *primitive_name) {
AstNode *node = trans_create_node_symbol_str(c, primitive_name);
c->decl_table.put(typedef_decl, node);
return node;
}
-static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl) {
+static AstNode *resolve_typedef_decl(Context *c, const clang::TypedefNameDecl *typedef_decl) {
auto existing_entry = c->decl_table.maybe_get((void*)typedef_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
}
- QualType child_qt = typedef_decl->getUnderlyingType();
+ clang::QualType child_qt = typedef_decl->getUnderlyingType();
Buf *type_name = buf_create_from_str(decl_name(typedef_decl));
if (buf_eql_str(type_name, "uint8_t")) {
@@ -3865,7 +3863,7 @@ static AstNode *resolve_typedef_decl(Context *c, const TypedefNameDecl *typedef_
return symbol_node;
}
-struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
+struct AstNode *demote_enum_to_opaque(Context *c, const clang::EnumDecl *enum_decl,
Buf *full_type_name, Buf *bare_name)
{
AstNode *opaque_node = trans_create_node_opaque(c);
@@ -3880,7 +3878,7 @@ struct AstNode *demote_enum_to_opaque(Context *c, const EnumDecl *enum_decl,
return symbol_node;
}
-static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
+static AstNode *resolve_enum_decl(Context *c, const clang::EnumDecl *enum_decl) {
auto existing_entry = c->decl_table.maybe_get((void*)enum_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
@@ -3891,7 +3889,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
Buf *bare_name = is_anonymous ? nullptr : buf_create_from_str(raw_name);
Buf *full_type_name = is_anonymous ? nullptr : buf_sprintf("enum_%s", buf_ptr(bare_name));
- const EnumDecl *enum_def = enum_decl->getDefinition();
+ const clang::EnumDecl *enum_def = enum_decl->getDefinition();
if (!enum_def) {
return demote_enum_to_opaque(c, enum_decl, full_type_name, bare_name);
}
@@ -3903,7 +3901,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
it_end = enum_def->enumerator_end();
it != it_end; ++it, field_count += 1)
{
- const EnumConstantDecl *enum_const = *it;
+ const clang::EnumConstantDecl *enum_const = *it;
if (enum_const->getInitExpr()) {
pure_enum = false;
}
@@ -3917,8 +3915,8 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
// TODO only emit this tag type if the enum tag type is not the default.
// I don't know what the default is, need to figure out how clang is deciding.
// it appears to at least be different across gcc/msvc
- if (!c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::UInt) &&
- !c_is_builtin_type(c, enum_decl->getIntegerType(), BuiltinType::Int))
+ if (!c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::UInt) &&
+ !c_is_builtin_type(c, enum_decl->getIntegerType(), clang::BuiltinType::Int))
{
enum_node->data.container_decl.init_arg_expr = tag_int_type;
}
@@ -3928,7 +3926,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
it_end = enum_def->enumerator_end();
it != it_end; ++it, i += 1)
{
- const EnumConstantDecl *enum_const = *it;
+ const clang::EnumConstantDecl *enum_const = *it;
Buf *enum_val_name = buf_create_from_str(decl_name(enum_const));
Buf *field_name;
@@ -3969,7 +3967,7 @@ static AstNode *resolve_enum_decl(Context *c, const EnumDecl *enum_decl) {
}
}
-static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_decl,
+static AstNode *demote_struct_to_opaque(Context *c, const clang::RecordDecl *record_decl,
Buf *full_type_name, Buf *bare_name)
{
AstNode *opaque_node = trans_create_node_opaque(c);
@@ -3984,7 +3982,7 @@ static AstNode *demote_struct_to_opaque(Context *c, const RecordDecl *record_dec
return symbol_node;
}
-static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
+static AstNode *resolve_record_decl(Context *c, const clang::RecordDecl *record_decl) {
auto existing_entry = c->decl_table.maybe_get((void*)record_decl->getCanonicalDecl());
if (existing_entry) {
return existing_entry->value;
@@ -4010,7 +4008,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
Buf *full_type_name = (bare_name == nullptr) ?
nullptr : buf_sprintf("%s_%s", container_kind_name, buf_ptr(bare_name));
- RecordDecl *record_def = record_decl->getDefinition();
+ clang::RecordDecl *record_def = record_decl->getDefinition();
if (record_def == nullptr) {
return demote_struct_to_opaque(c, record_decl, full_type_name, bare_name);
}
@@ -4021,7 +4019,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
it_end = record_def->field_end();
it != it_end; ++it, field_count += 1)
{
- const FieldDecl *field_decl = *it;
+ const clang::FieldDecl *field_decl = *it;
if (field_decl->isBitField()) {
emit_warning(c, field_decl->getLocation(), "%s %s demoted to opaque type - has bitfield",
@@ -4051,7 +4049,7 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
it_end = record_def->field_end();
it != it_end; ++it, i += 1)
{
- const FieldDecl *field_decl = *it;
+ const clang::FieldDecl *field_decl = *it;
AstNode *field_node = trans_create_node(c, NodeTypeStructField);
field_node->data.struct_field.name = buf_create_from_str(decl_name(field_decl));
@@ -4078,13 +4076,13 @@ static AstNode *resolve_record_decl(Context *c, const RecordDecl *record_decl) {
}
}
-static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const SourceLocation &source_loc) {
+static AstNode *trans_ap_value(Context *c, clang::APValue *ap_value, clang::QualType qt, const clang::SourceLocation &source_loc) {
switch (ap_value->getKind()) {
- case APValue::Int:
+ case clang::APValue::Int:
return trans_create_node_apint(c, ap_value->getInt());
- case APValue::Uninitialized:
+ case clang::APValue::Uninitialized:
return trans_create_node(c, NodeTypeUndefinedLiteral);
- case APValue::Array: {
+ case clang::APValue::Array: {
emit_warning(c, source_loc, "TODO add a test case for this code");
unsigned init_count = ap_value->getArrayInitializedElts();
@@ -4098,10 +4096,10 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const
init_node->data.container_init_expr.type = arr_type_node;
init_node->data.container_init_expr.kind = ContainerInitKindArray;
- QualType child_qt = qt.getTypePtr()->getAsArrayTypeUnsafe()->getElementType();
+ clang::QualType child_qt = qt.getTypePtr()->getAsArrayTypeUnsafe()->getElementType();
for (size_t i = 0; i < init_count; i += 1) {
- APValue &elem_ap_val = ap_value->getArrayInitializedElt(i);
+ clang::APValue &elem_ap_val = ap_value->getArrayInitializedElt(i);
AstNode *elem_node = trans_ap_value(c, &elem_ap_val, child_qt, source_loc);
if (elem_node == nullptr)
return nullptr;
@@ -4111,7 +4109,7 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const
return init_node;
}
- APValue &filler_ap_val = ap_value->getArrayFiller();
+ clang::APValue &filler_ap_val = ap_value->getArrayFiller();
AstNode *filler_node = trans_ap_value(c, &filler_ap_val, child_qt, source_loc);
if (filler_node == nullptr)
return nullptr;
@@ -4139,60 +4137,60 @@ static AstNode *trans_ap_value(Context *c, APValue *ap_value, QualType qt, const
return trans_create_node_bin_op(c, init_node, BinOpTypeArrayCat, rhs_node);
}
- case APValue::LValue: {
- const APValue::LValueBase lval_base = ap_value->getLValueBase();
- if (const Expr *expr = lval_base.dyn_cast()) {
+ case clang::APValue::LValue: {
+ const clang::APValue::LValueBase lval_base = ap_value->getLValueBase();
+ if (const clang::Expr *expr = lval_base.dyn_cast()) {
return trans_expr(c, ResultUsedYes, &c->global_scope->base, expr, TransRValue);
}
- //const ValueDecl *value_decl = lval_base.get();
- emit_warning(c, source_loc, "TODO handle initializer LValue ValueDecl");
+ //const clang::ValueDecl *value_decl = lval_base.get();
+ emit_warning(c, source_loc, "TODO handle initializer LValue clang::ValueDecl");
return nullptr;
}
- case APValue::Float:
+ case clang::APValue::Float:
emit_warning(c, source_loc, "unsupported initializer value kind: Float");
return nullptr;
- case APValue::ComplexInt:
+ case clang::APValue::ComplexInt:
emit_warning(c, source_loc, "unsupported initializer value kind: ComplexInt");
return nullptr;
- case APValue::ComplexFloat:
+ case clang::APValue::ComplexFloat:
emit_warning(c, source_loc, "unsupported initializer value kind: ComplexFloat");
return nullptr;
- case APValue::Vector:
+ case clang::APValue::Vector:
emit_warning(c, source_loc, "unsupported initializer value kind: Vector");
return nullptr;
- case APValue::Struct:
+ case clang::APValue::Struct:
emit_warning(c, source_loc, "unsupported initializer value kind: Struct");
return nullptr;
- case APValue::Union:
+ case clang::APValue::Union:
emit_warning(c, source_loc, "unsupported initializer value kind: Union");
return nullptr;
- case APValue::MemberPointer:
+ case clang::APValue::MemberPointer:
emit_warning(c, source_loc, "unsupported initializer value kind: MemberPointer");
return nullptr;
- case APValue::AddrLabelDiff:
+ case clang::APValue::AddrLabelDiff:
emit_warning(c, source_loc, "unsupported initializer value kind: AddrLabelDiff");
return nullptr;
}
zig_unreachable();
}
-static void visit_var_decl(Context *c, const VarDecl *var_decl) {
+static void visit_var_decl(Context *c, const clang::VarDecl *var_decl) {
Buf *name = buf_create_from_str(decl_name(var_decl));
switch (var_decl->getTLSKind()) {
- case VarDecl::TLS_None:
+ case clang::VarDecl::TLS_None:
break;
- case VarDecl::TLS_Static:
+ case clang::VarDecl::TLS_Static:
emit_warning(c, var_decl->getLocation(),
"ignoring variable '%s' - static thread local storage", buf_ptr(name));
return;
- case VarDecl::TLS_Dynamic:
+ case clang::VarDecl::TLS_Dynamic:
emit_warning(c, var_decl->getLocation(),
"ignoring variable '%s' - dynamic thread local storage", buf_ptr(name));
return;
}
- QualType qt = var_decl->getType();
+ clang::QualType qt = var_decl->getType();
AstNode *var_type = trans_qual_type(c, qt, var_decl->getLocation());
if (var_type == nullptr) {
emit_warning(c, var_decl->getLocation(), "ignoring variable '%s' - unresolved type", buf_ptr(name));
@@ -4206,7 +4204,7 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
if (is_static && !is_extern) {
AstNode *init_node;
if (var_decl->hasInit()) {
- APValue *ap_value = var_decl->evaluateValue();
+ clang::APValue *ap_value = var_decl->evaluateValue();
if (ap_value == nullptr) {
emit_warning(c, var_decl->getLocation(),
"ignoring variable '%s' - unable to evaluate initializer", buf_ptr(name));
@@ -4236,24 +4234,24 @@ static void visit_var_decl(Context *c, const VarDecl *var_decl) {
return;
}
-static bool decl_visitor(void *context, const Decl *decl) {
+static bool decl_visitor(void *context, const clang::Decl *decl) {
Context *c = (Context*)context;
switch (decl->getKind()) {
- case Decl::Function:
- visit_fn_decl(c, static_cast(decl));
+ case clang::Decl::Function:
+ visit_fn_decl(c, static_cast(decl));
break;
- case Decl::Typedef:
- resolve_typedef_decl(c, static_cast(decl));
+ case clang::Decl::Typedef:
+ resolve_typedef_decl(c, static_cast(decl));
break;
- case Decl::Enum:
- resolve_enum_decl(c, static_cast(decl));
+ case clang::Decl::Enum:
+ resolve_enum_decl(c, static_cast(decl));
break;
- case Decl::Record:
- resolve_record_decl(c, static_cast(decl));
+ case clang::Decl::Record:
+ resolve_record_decl(c, static_cast(decl));
break;
- case Decl::Var:
- visit_var_decl(c, static_cast(decl));
+ case clang::Decl::Var:
+ visit_var_decl(c, static_cast(decl));
break;
default:
emit_warning(c, decl->getLocation(), "ignoring %s decl", decl->getDeclKindName());
@@ -4674,24 +4672,24 @@ static void process_macro(Context *c, CTokenize *ctok, Buf *name, const char *ch
c->macro_table.put(name, result_node);
}
-static void process_preprocessor_entities(Context *c, ASTUnit &unit) {
+static void process_preprocessor_entities(Context *c, clang::ASTUnit &unit) {
CTokenize ctok = {{0}};
// TODO if we see #undef, delete it from the table
- for (PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) {
+ for (clang::PreprocessedEntity *entity : unit.getLocalPreprocessingEntities()) {
switch (entity->getKind()) {
- case PreprocessedEntity::InvalidKind:
- case PreprocessedEntity::InclusionDirectiveKind:
- case PreprocessedEntity::MacroExpansionKind:
+ case clang::PreprocessedEntity::InvalidKind:
+ case clang::PreprocessedEntity::InclusionDirectiveKind:
+ case clang::PreprocessedEntity::MacroExpansionKind:
continue;
- case PreprocessedEntity::MacroDefinitionKind:
+ case clang::PreprocessedEntity::MacroDefinitionKind:
{
- MacroDefinitionRecord *macro = static_cast(entity);
+ clang::MacroDefinitionRecord *macro = static_cast(entity);
const char *raw_name = macro->getName()->getNameStart();
- SourceRange range = macro->getSourceRange();
- SourceLocation begin_loc = range.getBegin();
- SourceLocation end_loc = range.getEnd();
+ clang::SourceRange range = macro->getSourceRange();
+ clang::SourceLocation begin_loc = range.getBegin();
+ clang::SourceLocation end_loc = range.getEnd();
if (begin_loc == end_loc) {
// this means it is a macro without a value
@@ -4816,9 +4814,9 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const
// to make the [start...end] argument work
clang_argv.append(nullptr);
- IntrusiveRefCntPtr diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
+ clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
- std::shared_ptr pch_container_ops = std::make_shared();
+ std::shared_ptr pch_container_ops = std::make_shared();
bool only_local_decls = true;
bool capture_diagnostics = true;
@@ -4827,13 +4825,13 @@ Error parse_h_file(ImportTableEntry *import, ZigList *errors, const
bool single_file_parse = false;
bool for_serialization = false;
const char *resources_path = buf_ptr(codegen->zig_c_headers_dir);
- std::unique_ptr err_unit;
- std::unique_ptr