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 e192dbbf76d018ea950992b252fed27a00a87e2f..144c8571c430ab0ac51dff2ff25424632f0906c7 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 f6fe72891d6a221ae411cf5ab7216ceae29b79b1..3fc6772b31d70355bf128f2b04ecfcd10a2ec202 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 e2576f53359ed3066e7ff4f72cbd39ee9937fa7f..b73fda59d1352325b4d7eecf7bf4fdb888d90837 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 fd8e3db2fae23fae491d0dd8179786e8d0c29f01..81f49089be13055598b6d58259c7a57762b79ac6 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 1aab4c32def93d41b8b7284e2867fa68c10763d1..6c61bcc0484189377321ce92ecd305078345cbba 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 b69a93733cbe88f1738d3785e75844db43142c59..1e4981353bc0d47e21c7c5027cd62038eb835de9 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 133ce1c69c483fbeb6d148e87bcc2d68c5f64d44..f04ad1604e3d46f82f73f655de960b1fbebb3448 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 d61768b1983164ca64873859186d8db3dc678060..55ed01046d030a859e3a0c5cbe16e32369590ea5 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 9f2687a5b371a5ee43c07d6b5a90062783cf8360..0e9c2d96557c1eac8f770fbb54861eedd21e26c2 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 46e0d134680112e4b925823595ee3d66628fa9f5..01978e1909dde0aa4d8df71c59cfcfb666da945b 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 43965e8293acd09964a18b8849df757a518d2bf6..d5228db6047851418ee71c349aa8960d964d87e0 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 6838704084cfa9296260cfea20cbc1d40aec4d48..9dac6aa5661f3a164d978cbcb9e281b9b4043cd6 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 5d48ea893ebfe35b2648dc8caac11529cb33aa0e..f272ac71eaff04e6841b098820f452df9e5eadea 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 723581cbefab3399de5012ca33174fca060c453d..54173fa38ad167114693d6a595eac7f92e250a4c 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 78d543583d8160d9e271334c3f4dc5da54681af6..75abe3bbdec268660d4d95484a1c2eccd4c2ce5c 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 5142920687105dcd534c109aaa163a39995b1813..f14cf477862b60ffaa4294fd53fb600f375084c6 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 dd875eeaf9d70140fdf693e938f26809bbfe9b84..37582d49c1b35132138493192dc151504039143b 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);
+ 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);
}
- for (threads) |t|
- t.wait();
-
- std.debug.assertOrPanic(context.data == thread_count * TestContext.incr_count);
}
diff --git a/test/tests.zig b/test/tests.zig
index 1ca06b4b3452f73f173ea05c999ee130785c5e1b..73d4644d18395cbf79bc3b8ea9ebc5ce975a6225 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);
}
}
}
--
2.54.0
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 d676e7a6c5280465f1644a76421a40b631144cd6..3d3c501df35788d0c6b2ed2f926b08940851cace 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 2d8494eb0b6db4fe27a6622a008d27d2774701c0..3e8af0524fb24fef4f578203893fee18682430f0 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);
--
2.54.0
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 c00c7c1d412e31ed49571a87d4214e046b8601b9..d60892432ee3322a5bc8d9ef6c24601d961a6d6f 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 0e552fde7ef5fd047aa1c3c806362336a7952d11..fc49fad410b6423f3fa481d534f5b400c1c90ef5 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 562765b354d5a68b23fa696d67a68ab63b32763e..0362bb4ef83f604764f16b97ba5198804788542c 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 0742cbfe6507f7deada6b82ce15aac847ab2d84e..1403ab860dd9deb0bf5049136a2f70a239f34669 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 720b2796510518b7895cce7eca7e5c5c13707529..0d31731b551e6dd730aaf379c989dc3a8f098244 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 43d3b5a784e0d3ee4bf32a79036247bf2e9c5f94..b14c073a9e4c8fccd35a897b15f9e41a59e6f60c 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 fa3134390252917c54b0eb6ca16ad24d33896e91..8a05594b301bfcbe80f7400053bb5a950d0666e5 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 e6dca4eff77e1b8c634b117635f9551316193b91..9431c614b92eeed292e15af6fa0039d30475d757 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 6c61bcc0484189377321ce92ecd305078345cbba..183c434dc574fdf1a78c6910b5e52c2145054346 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 1e4981353bc0d47e21c7c5027cd62038eb835de9..503fa0c0ceb4fc4dbceadb86cde1e4705c0ad2d4 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 90f5bec656314860926fa62c811fc9ff5c2700c2..6f58594190126c5d8da9d9a9a5b5f8fe3bd8e961 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 445f943594cd24f9ba73df3e053ea91b41a7ff3e..838bd0c166fdfb58866b3dd28e85552d91517904 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 f04ad1604e3d46f82f73f655de960b1fbebb3448..f8cdae6208906a949ff3fcce6660cba2bbe9fc2c 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 7e77b3e6e2de0fda045efc267e58910b22ef6be0..097f2beddcd3901aa4785f1956930400cec45452 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 0e9c2d96557c1eac8f770fbb54861eedd21e26c2..7f6b5d953ba375c92667cd8e95288c2d544728ef 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 46b247fa7eadf63e725260de9f911cc055085017..fd2ce1e965fa44382a4f4ac83ddfc34d6401ec50 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 46625cd34b78f83fe2c614b6af7ea4dd541e2eb2..c8701aeda60d2d69c80bcfc4aa4e4ca1753c2349 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 c3db55b5a67cebf94d7bd3238c859bc6852538bf..7021cac70752ed4c2c96e695c90d2069021efc5d 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 fb5f6fd5da62cd402f856c1c87c08aebd4ab0c14..a403d80453ab14ac498d21cbe0405b2b91cc334b 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 0aa896ff1be209a37c522af72f08b1031a64502d..9f33bee9057541534a2ca721cdd194091afca884 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 75abe3bbdec268660d4d95484a1c2eccd4c2ce5c..0d0e07bfa353ca1c6203b90e74ff8aa41e015260 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 a216484d7d669ba61a7f8ce0f012960866f01209..783464c620709cd4bd0470bbf9b284e213fd653d 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 73d4644d18395cbf79bc3b8ea9ebc5ce975a6225..548496fa2f6dac4151b53d563ad1f2c3cd9436b8 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;
--
2.54.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 d99165a6de51df7388639a8c60dc2738907f13a5..a41a5f808ba3a08c4606bfee5ab2255aff36669d 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 1c5d111c5ae69d919d4ba90cdcd986ee53007cf1..18d2daf0c2e894ebfb51fb691c272ea16b4d9508 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 1403ab860dd9deb0bf5049136a2f70a239f34669..f6ee9a0513d029474685786181d6103ff232b93e 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 6f58594190126c5d8da9d9a9a5b5f8fe3bd8e961..5246d973398fd1f4bf2b1e308ebe0b47f38c8432 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 bec3816d881afb0dfdba4cded2d086c5a5669e83..26ae4ef089626223bdabebfa20a7005f4eb81d09 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 9f33bee9057541534a2ca721cdd194091afca884..7aa85823692825ff14e8fdb9c910f88ea71c9850 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 0d0e07bfa353ca1c6203b90e74ff8aa41e015260..451c0a3436644feffdd72b97a6b775d394edb14d 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 4d3d3d6a8b53b6107d92e8ddc654be4ceaaef67c..0b960fa2da73db41b4401eaf33c63653007bf727 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();
--
2.54.0
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 3fc6772b31d70355bf128f2b04ecfcd10a2ec202..c4c9e13cfb4c2427c9261d76d2c33ac588b6408e 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 99378eb7a85298401f4bbea50a9d1088fe502f0f..ff961a704448aa8b4bac7e13574b2a9fd47c14bd 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 da5265a59416758ff5a6f2dc85b02465a86da1b2..f558fa44b0647266cdce174f95658b3199117bf1 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 b73fda59d1352325b4d7eecf7bf4fdb888d90837..de2222afb741ea18c9425991d45dd8d28db18ebc 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 3d3c501df35788d0c6b2ed2f926b08940851cace..3cbbdc810307581a0ca990285fee5b8da1e49885 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 a1fd450b65f6a07739a1b7d9fa48a8e91f52afc4..e19aa6dda832b21d2a5a4cd1588ee36a4f72dce5 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 e545a4c4184d3f6587b5ead0c453fe3c54e8ef11..1fa00b34fd67197765d831982b974ac3e489f6d2 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 0000000000000000000000000000000000000000..53c5d0138179bfb715034a90050c298e6a42d433
--- /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();
+}
+
--
2.54.0
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 ff961a704448aa8b4bac7e13574b2a9fd47c14bd..d92d337c695c2cbf679f4f40653cdd335515e37e 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 65f6b5abb7e233c50efaa99a84b00e89a2086e4c..e5a4890914bc03bf3f337429e386963819bd9fd7 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 26dca1198bf73ec570e5039f93a78ad32ccb867f..b5b0e97b534348fa9a2afdb308fe2d72d2addccf 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);
--
2.54.0
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 de2222afb741ea18c9425991d45dd8d28db18ebc..226a1377961ac5acac729e654fcb5dec7764f25a 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 53c5d0138179bfb715034a90050c298e6a42d433..c97ee0e3d66af06d2d5edd9dda70ef75b659b92c 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();
}
-
--
2.54.0
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 144c8571c430ab0ac51dff2ff25424632f0906c7..e3ba0e3956aa001cbaa3235c2fb54a9598f5bad9 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#}
--
2.54.0
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 13f2a964d038ed4e9b94ffe6357554eb2e939442..02020ddd73d2be53e9e0adb15dc32f5aabedb0ff 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};"
+ // );
}
--
2.54.0
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 7aa85823692825ff14e8fdb9c910f88ea71c9850..37f75483a63fa34431a427ad464e30653740f740 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;
}
};
--
2.54.0
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 37f75483a63fa34431a427ad464e30653740f740..871f9dd701f993b6ba3e497640e93bc108886753 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)) |_| {
--
2.54.0
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 c8701aeda60d2d69c80bcfc4aa4e4ca1753c2349..81d90def6eaf2aa13c7b92ac6a6e7f35ce04de0a 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 0bee0ddaf0c2f8fe146d08e011c7c2b6550b8859..9a0687ec694f1e1111f1116a792bace531748a9d 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
+}
--
2.54.0
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 e5c6ab553466fc91e55c04fa133e0820acc06046..0000000000000000000000000000000000000000
--- 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.
--
2.54.0
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 4dd6a1dcfa620c3796801b895101402d2f5c66d6..a093bfbfd9f232fd9d38ffd77b3756fa783ed408 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 c4c9e13cfb4c2427c9261d76d2c33ac588b6408e..5af4e71157d580bfa70c6767f0c37ad3b89ccae7 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 ff961a704448aa8b4bac7e13574b2a9fd47c14bd..96f1faaaa962f6db8558e885950263561aa20c1f 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 f558fa44b0647266cdce174f95658b3199117bf1..977378251001dd26389a6eeeff110d806f64e241 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 994ba5f5b139fe32e884a69f7837784c3dddc5a5..34a7faa2a5192043a4d2890b5539da2ae3603491 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 de2222afb741ea18c9425991d45dd8d28db18ebc..d8fc077efcba30bd87db242e55117dd5feb664c8 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 3cbbdc810307581a0ca990285fee5b8da1e49885..02b2b12230cf44422f06e157c3b2122e4bfaa7d2 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 81bd469d1c084bbd4c2b21c41c0608c0b4dd785d..1c1af87c51f66c10a04e0f5f551f60c158944363 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 d43bfabf6de6a11321ffc84f52e70f0a0439f860..3acd605748b2553b686dda423d648731331a81dd 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 1574e95571d2f652fd7429831b2f60942a2b0ae3..17f36699b3bb21b41efbce5fc520fcdc3e141cf7 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 838bd0c166fdfb58866b3dd28e85552d91517904..b4ef84950958c08550589f9381eae70b528eb560 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 fd2ce1e965fa44382a4f4ac83ddfc34d6401ec50..1403f8e831dc5cc694dd184a7e898ed35af33fd2 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 80d1e46bb6cb069874d79f251f726b15e7cfbc5d..ef3988460fd955fb9711e344ca9d30379f3f4930 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 26ae4ef089626223bdabebfa20a7005f4eb81d09..178a5f6c6f08c777deb9391227096eee77cc100c 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 451c0a3436644feffdd72b97a6b775d394edb14d..68b3409757b96669af07fd60888904c6cd040cc3 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 0000000000000000000000000000000000000000..c54d274c5def8f9f959d769398a0153d82b69dca
--- /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 f14cf477862b60ffaa4294fd53fb600f375084c6..bd9148d1b10f1f9462dc6153b6edeb6bfb77c85d 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 129bde913fd2d2976914c72733b69530826c3b92..0e84f67481a484d565504a8f2fb9035be2163eb7 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 30d9ca5d702d5959011c34d94f51807c6717ffd6..acd1eada066370f0e69788eabd2eced814b9e411 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 8d2555ddddb390f928c6440024cfe008f58f6744..3cc8e5f31e0248e1392a5584772a3b784c62b858 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);
+}
--
2.54.0
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 a093bfbfd9f232fd9d38ffd77b3756fa783ed408..4dd6a1dcfa620c3796801b895101402d2f5c66d6 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 d8fc077efcba30bd87db242e55117dd5feb664c8..5e282160d6b028f0bcc29a539f9956216eb6494d 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 6f1cdfb677b6636a225eb4bf1f44b5e7898f66c6..4bd8f2dccaf38eaa1a474db9157d2c59387df0e7 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 593f7f309fcaa519fb161c09c4ddf465314f5d58..58221a99eafc22ae7222e3e63afa2853c2da52e0 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 81f49089be13055598b6d58259c7a57762b79ac6..73a1d75d42924cc6c2a006fd93432b04dbe8ae3d 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 5246d973398fd1f4bf2b1e308ebe0b47f38c8432..07efcec30df84e97d01bafe7749a55331129b5f0 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 ef3988460fd955fb9711e344ca9d30379f3f4930..2a632440045ebfdd929e4a86259c2113597b58b5 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 68b3409757b96669af07fd60888904c6cd040cc3..d17b6f4f409681a99dd76034620991db66bf6422 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 c54d274c5def8f9f959d769398a0153d82b69dca..0000000000000000000000000000000000000000
--- 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 0e84f67481a484d565504a8f2fb9035be2163eb7..97699e0cc5bf2958f723308ec42cf358db0b635c 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 548496fa2f6dac4151b53d563ad1f2c3cd9436b8..fc188f55509c889d61de684ec562055dbf40d92f 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);
}
}
--
2.54.0
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 4dd6a1dcfa620c3796801b895101402d2f5c66d6..d6bd8a6c2e379980358e4c9c0d62b3dfabac1e40 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 5e282160d6b028f0bcc29a539f9956216eb6494d..71696694264304bff97fd05cdde3c9553c2f9f7f 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 3f19905835d8a16162aee213818b716345c3126c..8e9ed8b8dbfabc6dbc555e5ff8779440d9002a72 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 66b9552c5fff674ace0f921e153d65ab3fbba259..ce8443de02c3ed5a773b898f9e0cdca51650b8cb 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 0000000000000000000000000000000000000000..9e62a7c5c660bf61450a3fa4268a2ecafae62c82
--- /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 97699e0cc5bf2958f723308ec42cf358db0b635c..6dcc90b37204ae72c2369599cc04d4f2bdd264f6 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());
}
--
2.54.0
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 b90f58ff51326e1629812a4dbed9a29c00c72b56..5c7c5b8a186e43b7d3a205b91469b03aa2099b65 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 8b2a7e4c101280abce8709368457263692a02d43..14e470055303e07ca2e2561c2afd2382101ec287 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 682e10c3618e8a938691d7af73ddd849872a2a93..edcb9dc579bd2d1028f388e5a0120f1106058cb2 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 1348396f598d3c049bbaebcedf12419afb0b49be..0dbbded80275e020b00d30d21ec6a7838e94590d 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 0253912d377d64f095941e091792f39a0a9735cd..a1e2747df574e0a9884f2b063ab5e743d3562321 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 97a79bed39396b2999b338a5e22d33033c5d7d35..fd0fe434cb1fec4daff2ea63e371c2ba4ddaef1e 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 178a5f6c6f08c777deb9391227096eee77cc100c..48d1cb930cdc0c72fd3174ba31fcb8ea2c7786a9 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 2651310c98c995e3f0349beb391672714881076a..6635b76976ceb9c39e1b0d2af53a24cc3b10e82f 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 a0315b451194f62309f889e31b5b18c5a61da874..f5e0b78eec70a11b20ac9fccbf4f70cccafffaff 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 d17b6f4f409681a99dd76034620991db66bf6422..8e9876c36b2df041b4dfbedc3890a7d76ccdc179 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 5a5b1b77720002035aa2577137e646dcce27807e..266a77b97c898d7d70cd1b713e1711ca8d0d72a3 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 0980e8c2d8c2c706519026ee3f0bb392f684837d..745da4dd8040114993fcca62d07cf35de56b9445 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 fac941cbde5be8bcbf0164b06d30d693b9e5b8d7..670c410509e994e6bb15760fb1c5493d355d2ceb 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);
}
--
2.54.0
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 | 103 +++++++++++++++++-----------------------------------
1 file changed, 34 insertions(+), 69 deletions(-)
diff --git a/std/mem.zig b/std/mem.zig
index aac07ece7d47884dfae07c16e1c2248a57374165..a6cbae744fc7e6e2f15bbd10e3e1ff6cf7e32840 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;
- }
- }
-
- const buf = try allocator.alloc(u8, total_strings_len);
- errdefer allocator.free(buf);
+pub const SplitIterator = struct {
+ buffer: []const u8,
+ index: ?usize,
+ delimiter: []const u8,
- 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 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];
}
- 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;
- }
+ /// 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 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" {
--
2.54.0
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 c5de05e372ab1ff73b1f1f2507f659e829226741..f010430e14e4a7520a3065a4a6ebb321a5b120c5 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;
--
2.54.0
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 70d50f9843344c8b97df412f6ce7fe82c96d6999..2f0afa09b76ec25b141b7775e2558d6d74f17418 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(
--
2.54.0
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 5af4e71157d580bfa70c6767f0c37ad3b89ccae7..842c9ae9046d57f164b60fa67c1f7504c022c183 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 f010430e14e4a7520a3065a4a6ebb321a5b120c5..3bfd7cdfc59b1e0321f744c25b7c86adc0bd3dcf 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 02b2b12230cf44422f06e157c3b2122e4bfaa7d2..00d358552a937f302b2f628380fcd184107bb5fe 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 e19aa6dda832b21d2a5a4cd1588ee36a4f72dce5..75da24d1a9188a21e24237ad0dec80e3c5630118 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 7c13f5b6fa5eaa576538829c7482d067262743c1..7de43b45f44ce8017af8e86d2cdda926bbbba945 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 61ddcd81355653c60e45c6ffdd401051a8b7c033..27f685a96e194b784506c23e745485e4db4f3e1d 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 3e8af0524fb24fef4f578203893fee18682430f0..0d1ecfab5b2fa086ed30c1ad25ee3fb7fdbf619f 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,
--
2.54.0
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 | 92 ++++++++++++++++++++++++++++------------------------
1 file changed, 49 insertions(+), 43 deletions(-)
diff --git a/std/heap.zig b/std/heap.zig
index 1403f8e831dc5cc694dd184a7e898ed35af33fd2..8a5ebf134c75804dfdc9e66ed8d1189a666f97d0 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 fn init(buffer: []u8) ThreadSafeFixedBufferAllocator {
- return ThreadSafeFixedBufferAllocator{
- .allocator = Allocator{
- .allocFn = alloc,
- .reallocFn = realloc,
- .freeFn = free,
- },
- .buffer = buffer,
- .end_index = 0,
+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,
+ };
+ }
+
+ 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) {
--
2.54.0
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 d6bd8a6c2e379980358e4c9c0d62b3dfabac1e40..ed79f99901f820ac364be6288c2b8e6d3aca42c7 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 14e470055303e07ca2e2561c2afd2382101ec287..7aaf5ebdc7bd1d2ef594783cef2632e522e9f1c6 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 99e6ecc17a7c54b16326907d26abe75fd0cb06a3..7bbd233a75287170d9df66a6fd1c8d9c96d0f0d7 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 de551cf7f703ab6a82a55f44ecd9f7365e222dc2..4be6d5393261b2a033ebaf4d3d8ace026af6d226 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 00d358552a937f302b2f628380fcd184107bb5fe..efda2b321bf814e63f4ebe478a568bbd9014624c 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 ddad9c989cc4af01a7ed57e043d03dc229747508..e2535d639337558dd2af34ec1d76a9275820f330 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 183c434dc574fdf1a78c6910b5e52c2145054346..bdc86c0981ab43ee2d9111692bdcf013e4896cb2 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 503fa0c0ceb4fc4dbceadb86cde1e4705c0ad2d4..4d0d5075e048061798d93cf666a5293c17203f12 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 bc0bdb1bd371a8bc4b26621bd8cd0e3d3a03c0a2..cfe8ea95f88ae41570715657477f8cddfa0fb6b0 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 6de0d20cdbffb1ca4194f5eb5947e60816a69e09..f8d3d5e04de45ae015109e35af84273a8955d607 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 ab2d8e7c34a6c857b271659f8ce9377aba02503e..7ccd94c179bfe61695e6eb37ec8fc8826161cb3c 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 2b71c26749b2cbb632d1c668777570ee22f8556c..371655f1e58c5401eeaccd59f2650ea487a9fd70 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 5ec1e79756715b4244d465d94ca7b34a1babb0d4..d964f4c03d023c93d0647c2e5da1766c7c5d24a6 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 0d7a4d672d64bf85e2e7c06d698a79d5c7a74235..64adb17c454a46b1c8e3017fac4c6f51c5e0f635 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 3fa24272e5ecdc49b9b346e911f46f94b9b78395..258cdf7320580d5feabbdb8b110eb5057ba4924b 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 daccb56808bf30eb5959aa5e921264bf8280fb75..9349569f97aa271c8ebc970442926fdc2cdc79d7 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 a8aaf21279492a2ba8781238568ffe25a4a5690e..abd2eac48fc8fe7ac80b922a626c91d5b77ee5f0 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 a1e2747df574e0a9884f2b063ab5e743d3562321..7e5be9acefa57d6f817066542e29e942e17958f9 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 4d1995131853f061ea1823c9933b716a319ab084..66026b1f29005e12039f449a8b20fcc3d6449622 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 f8cdae6208906a949ff3fcce6660cba2bbe9fc2c..4af9bf612b6b2337455015072743cfa119ad79ab 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 fd0fe434cb1fec4daff2ea63e371c2ba4ddaef1e..0e7482ec60743a8a7e52cf4b1dc7c45f904b96e8 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 55ed01046d030a859e3a0c5cbe16e32369590ea5..66acac5ad7376ec1595aa8e7cb45d94ed3138798 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 7f6b5d953ba375c92667cd8e95288c2d544728ef..25e79640cb1d4ad1ec93828ca7279dde2cdd8726 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 01978e1909dde0aa4d8df71c59cfcfb666da945b..d6a246cee5340d31ce751f885166419057cde156 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 d5228db6047851418ee71c349aa8960d964d87e0..b92bf4198269931222f3dd4c5594c50dde7aeb29 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 9dac6aa5661f3a164d978cbcb9e281b9b4043cd6..48461c3d815ccef39bbe8118fe53b5b96ba9cbf3 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 f272ac71eaff04e6841b098820f452df9e5eadea..26ccd12b73362bb3a6b0a0fe4d44e56b89e3a1bb 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 6097a12c23e8f5e99a2b8359ad78a02f33c72324..05b028112f3038706fdcc38013f2331961f51cea 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 9c5966f89bbe29d3ed14b6613ea27543304dcc40..78f960367a546336c325ea976169d413bd76bc07 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 c4bd92884a9734aff9f9c3b9cf340efa23d1145e..9bea358bf15db81fa8639fc271d477294d262586 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 9bb18f14b3556e1895cd965eaef3a972eb903dad..6876b636f67852d58cb42e276a5356a4d419b98c 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 ee269502726e3c61cea5b6b79bf2c62e4cf14476..c9a6128d35b7dab34fd21986b63dad3df5f54880 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 a63a549814fbc17262a5adfb596db1a7cf5d9b56..716f04ff342f034cc9b1615caaf5f29ee23e8d3e 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 8a5ebf134c75804dfdc9e66ed8d1189a666f97d0..e7088150a821b11d11250ced23836b27f2ba9a83 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 2a632440045ebfdd929e4a86259c2113597b58b5..9d9b7ee8d62576616905d60c486597256c372c66 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 81d90def6eaf2aa13c7b92ac6a6e7f35ce04de0a..d7e8507f9bc57094b1a6d75c63354b17ed03aabf 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 9a0687ec694f1e1111f1116a792bace531748a9d..fb6e0ae7e9bb94424b31f649687bb2120e39c43d 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 4d07d7b89d809ed7d7d06ede3ec650fa09cceb6d..d8f28560e57174e25394fc0205e761f6b6090151 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 9e19ec592a42feeeb3d07cdb9820b1bc903d7d29..edc50be8cb3e3ef1b4a1639b7524f06fd57fa3d2 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 f08c01e874c122c402b911078d4d61fc82c97499..a09168786ba0bc73cc9e31c24e6636bbb83ecc96 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 7021cac70752ed4c2c96e695c90d2069021efc5d..86e5cd056ef61503814464c5a6db4b04ae5ba211 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 54844e8f6e4fe0131d8213462bdbfd6ec49b4e77..734f7a8651679d7503e23f615588cf53ebab7633 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 9be323e1f64a85aa46b0895b31c4a2cc5a6f6fc5..a9c4a908ef15aaf72ffab1c852e34218f97c18d4 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 30b3a57e3287e3de57d80b9f19b35f29eefd35e3..c9dbdf704f0b051f64723855ca0aa7f1c2deb0d3 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 98892bcbcbdd4f2ec5bf00cfd35ede4d69164fa9..05bd8d008ec9c3e63665c06202c2f4e2c8f28660 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 6ca94dd84ae4a3a5b68e0a7abf3b9d9bd184b724..72d17b4db2b25825dbedf64280b352dbf7249c41 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 a7757132d79fcebad24bfd9673a25808ba408d12..6e1f67cfbba5642c51184a4668e5eade684211bc 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 c97855c234fa2155994d3ec1699370c833968ff6..f2feab02070e3df5cf4ce95bbc5440a2066386ce 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 cda2e1419fe0c9527b49674abbd1dadf528a907c..f21e5df8aa4f0aa37f2c1bcf057b65caf6e5992d 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 c067c5155a8545a550658c5cda75e44a02b771eb..957e026af45e65267728ae6e566bd2453502849d 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 8a5221d8626b75d8103ab5799817639dc5e462d1..5c6b98b2ca96f18d84b7bc54a009da59fcc79c9d 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 4cd095c46bf65ea9ddf7c10f175c85218dc27c7c..245d67d4c57fa8684cfae99b5274f5ff8a68da5c 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 a5760b4ace73d5d08e8f7409d9b26e4860f32990..1b314bc31a80e76c1d8af410ed32b59693405dcd 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 8dd91b283655fc5efd5269af4f4946b1444530aa..0e4c0121f4dc13867a0a644f18b838043905161e 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 f24512ac73abaa6abddc4ad644dde2e9c9ce6750..be117a59401b685d92f024b6bae8fc8fca640a62 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 584a3a1a9b0fab7d71ed37e21ab517672fc26610..cf802ea206418a66c2dac3992340612b860c0686 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 0c4dc2b6e497b143756b2e32b6310fd157443c83..0386a636b0e50bb245aa62fc3e83974c861b07ad 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 de60f2546d4c8fe0ff0a751329e3b8410549d52f..8e60e58e43faca85af9d85657a3e63cc9a658c2e 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 f70c74176502dfb427aad554947bf24dad31141c..5b18fe1992f7d92da57a787f412eefac1f996346 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 ad3e8b50365746d1308709bb177b47ad2d775bd5..143543f9e7e81058f08c4f0dd573319eb9761a88 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 96e4ffcdb0c60a6fc908eac54061836d2fadefd4..658d19c3b6ecac46dac8c0d42ba036daac5f3ce5 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 91875a0c47e8bd389ead0a82d1010837045323d0..5ce10b03f8396caf592252a401c8ac7be5663f25 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 0473f653b6253ba81fc019ff2165a8e8efcde38e..9ded698d088eda5fe4b2a99f16cc4866a4a1e60d 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 171c4c5829484c8ea1a2d9bb9cb82d8caf873e79..ffbf14d83e68fa926d0cb62fc66b38ecfa02c546 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 a4a1d1664fae8ac188682d3af31f8735a2a402c4..360bb7d21ea624610c4c6cc08de89bec534fc6a7 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 edf68653b698894b4edc9dbe66abe64342fea4c3..bd625626c8790ff428e25455253005895a6ddad8 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 b6c4cc046eb673cb95ef19948f533385907a2de2..d31006129e2f7edfd515a9414e5b379d3aa8eb4b 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 d32b771d3b4ddefd9499d7e78920269c3a406794..9d54ab0969691673589e893068f84faca065112b 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 dc19a0ba1bf4c78cf28644a88556befd57eb5dbf..469ea6067a3f3900e0f15616e215c2026ea28fad 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 47367816f79549e6eb2af0df15b96cad0eb9ca35..60f6061baab09f6e2e2d390cb0ca9342c5661d51 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 4ea5182fa7836720eae8856cf0eca23a7c0a6e4f..db345805985b9e64d672d8178d4ef1cc3ea4bc1b 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 e48d438783e7089deabed9d974bdddb203bed261..03ab431312686e155dd18354bde966c6daeb0ed2 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 4c6e333d6c39bbbf129e18b543a2163119b80df1..dbf8f6e1ef911e8431d4d7565b095243c5c49b07 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 b6a2fbffe68bf8c11379fe8d8e65b11e87149bac..7783ddc09be9139600d781882ab7b1ba2b5a5517 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 77e02855fd3c17fd9ac7d4caaeac2e67288b488f..57c5eef828484700c4c3810a8f028b91aadb8587 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 3d8e5d692e851760227ac08c070e93ad1f357c8f..ba0001a09adb8aaa62a2c66f7c2917dc14a6bd59 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 6729417f602c8e3ba9ab6403946558cb2ce83e1b..ba00ec2561966b2f23e6343ff55e772a76ded387 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 443010ac7fe138211e957bae648c9e19e16d84e7..9fad5644c36de1077b4e3abf3c97b48490617726 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 6ce462b10ff4ca8d894722dc8ea831c6faeba7dd..c7c12e37bad38c4429177ba69c97d3630a469682 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 21faf4118d6706e7cfb2d5965aeaa083ed875c25..b084cf3cbde2f106774e1d82d0c113caa6c9a28d 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 dfc790fdd9386392c062fe0bf6247fccabd76d5c..35f3e081a9036a721de24dad3f191ef623a531f9 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 a63657a621936fbc3bcc46646fd17f1caec52e5e..dea11e0a61053af2a0d06c35f23c94b6bcdf0967 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 e6bdb14012c0689ae71e808094d2421b45830cc9..e7b64853570c99e99daa0c23052fcae3ebe4a104 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 f37de2505b2488085dfde68eaa1d919384511eab..ccfac030386ae99230b499224607a3f6df206736 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 bdfdff8f9fdf615e625a798af18eb0d8047fe62a..bf1c9ac63c5bb795d93e0bce2becf36fc5f3f18d 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 93f66cc8702e67b22370666d469464e17c2fb7b2..e34e9c597194f3e1de9d954e954e70eae098e51e 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 a2cb85b4f77116f8ae98e3f4189e171312278bce..641da9e620ed1a2400da1df61b6006682ab2ab62 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 cc088e46a07f2c93005a08c7ad856287520deee6..2c57aea7a9af84b3e65d838a8ce228d7862b6b05 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 a560fee8ecf42438a780edf6d01032cc071d42c1..257ce8054ffcd9ee6d6b7b78749a224a6847da67 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 20b6d055e8ad0f8fcfe915afd17f8adc28077017..21cffcc07884bd5cd046a42f8fb4aa186b0d15bf 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 2b53d8a6ae1376ef94f570f9a71c02f968d643e2..8055f712801aba0fa6829d22804271b95d1aa624 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 903fceac058a126106b34fe39c25725547b74a76..257e7b90d458cd770b48eef4d3d081cdbde22ed1 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 555c0bdf181cbf79a2373cce59d1708f5b6cd1f1..1bb51bf9f9c0c5f8ac5b9b5d77cd149b4223baf6 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 0f619f25bcc9c9078dd4ea8fc838fd692caf38a6..2dadda76a91355caab53686372732dd5a20af952 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 39a2bfa9f7dd0c8b91679d4ad032106f505ae9c7..f037f66d7e0491fc7fa882d35865e5652e1d1473 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 13c09b192ea69064a2f22b451814e565865e93ef..9c2a4a49658ab4f67afe62e05d99727007bad098 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 4fe35365c8e78bcf18a6a965d5f886df53d4c275..7346b703c9c54422b19d57f65111136f1e207542 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 f72c7e866f1e078cc92c9e174eaa037b03254c72..d37a8659a945849d014a4cd6e79d39a14b508e6c 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 8c6829dfcd7906b9fc0b77fe008acb4c413931a0..728f651aece35456ae9ba7fa11a612cd1c2f33f7 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 15b2f9f17af8e9a11dd49b1eaad3747b859be27e..5ade6636c73a81fda1f973bfa84e27c398f4bf5f 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 733b89754a7210b1b6d034f64cb3e295ec132b16..95924ba55a8ca473c1883c82845f3b2b02c21a80 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 4300f20f5a8c3026fbae49403ed59fe6c64702a1..9996b44b20c83f6f057066fc8a77ad07ac29e561 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 a71a17e62531df3de2e056a56ecf2f63b1005d0a..ec4309232082cd76f56fe9220838f16548618ee6 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 faeb2641cc24f71d1bc4936abf74f5a4e8b9f32a..a35449a0536aa58888c0b7e0b2eaa86f8be42909 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 bb309a1e24b93996e24d6328d1752c8149d7d321..8c91ccc568d1b5c9ab8a5561efbc31f4430be960 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 a6cbae744fc7e6e2f15bbd10e3e1ff6cf7e32840..1c7523bf13b4bdecc9246ac7727da7e6f45d8e3c 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 4d195a6a12ac53f8a8e31151dbe5b4b352b0d62c..3f8ea762a6e6c611bdac60d27f0fe514f0ca80c6 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 c9d9e971c9f78562820d30fd4d29fb7c30e68ef3..7fca5f4dcdb6ca349cf13f260e0772cc66aa09fa 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 54173fa38ad167114693d6a595eac7f92e250a4c..a13b1c06c7b25dc5b38bb50dd0998444b0ea4a08 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 6635b76976ceb9c39e1b0d2af53a24cc3b10e82f..1da0b3492bcae6e5f8df75900f354eba1c5c31bc 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 8e9876c36b2df041b4dfbedc3890a7d76ccdc179..f52c12c2b68f52916768f76c2488361535a229e7 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 4de26012c7b12e8ed0a82b98b68fed57c6babf73..40fb7823d2c9f00ff29f83c7738464579a91f152 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 266a77b97c898d7d70cd1b713e1711ca8d0d72a3..5ba345fceb892a921a5daa6842eaf2fe64df85c9 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 bd9148d1b10f1f9462dc6153b6edeb6bfb77c85d..b2a4d966518477291333ae4ecd422f5fbbacd892 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 4b11a69376ff1799ed7cfb58be566f6dcdd749d2..638fb41ff164acb877b619b74aadea84e503ce83 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 c335063e64f2dc46c091306c7d754099510be349..12dd763aeecf85883071c2e2721afb2a9481be16 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 beb7f3aae997713a1da886b2d03904aa5ec23da8..27e60dca6ab02dba5a4f44902ed1dc2837690a6a 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 d786e0becd23a8842190b01e046f10606681e23e..26b7fa48f59909e5b67073f1be48b94f8f1c73a2 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 f29f51b7cf4c47906b4a02834e18f0f491847cfa..86a6724fee6113aae6849bd01acf65105b726b1b 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 eef5a9b812be0d08505f078707a4f341df09209d..e1c1babae7fee43c79cc1e6a44cbd0cf21fc271d 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 99696070116a383fd3c76f07c2af03f4a1db98e5..050a799823a100f42ed0acb9ec0c8cee40e5297d 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 72bcf452d255f23c36a5c2c30ba93d8aba2a29b1..a55245210b28d952243eba3d9bd1d0f05fa9cc20 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 147f46534aaf33b5e4425c4cde4951ccf71769f8..5cb9bef1d9cf0237a6678980638978e0165ad39f 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 5bb3a31a3f4ab88a6c1d448692f3eae9993f7751..5fbcd206edeb8d1f660993f301cb7577a87c4f07 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 6676bddbeeabe290f71c4647ca951290f984bac8..0b0936d1e234373c7f88c1d9fa4b3b6ef8105a1e 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 ef8e50e38ea9e299adc8424857d973a0954a6fb7..276670421b9c45664c9445fadc9b7b5c098a231a 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 d5c0ba5c2a3744af130430fe392f9928ada68bc1..a05c15e5361c0c20f56cd43751ae8db992af8c75 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 d693143b18ceb1d7d10e0a458d2b108beb8a785d..32410e2deee95388e22ea72fd151edc5c32c8e19 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 58ccbc58323da26144c643d6e7dde16c117d5a4b..a31bcb7d6f11993aceee9c3d5c57d224a4c94586 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 7a3cc7f46c74120481d914eb8bc8468154f1c22d..7b37e4e09fcf72247691626d34745ba2edaf0d99 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 520009486aa555e19d49b312ab430a70b159d25f..be461a1c916bf73d02b57befb82bcacd6ca0518e 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 e59d09f8de9532787e3125494576c9766f7074e9..67eeb70520cd7df29cbb1a5094ff0afeb51613f4 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 db6e32e23dffaba8e13cf2d88751faa4b4453f71..c006473fb95b606788538c9384730f6a884bf53f 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 7f7b083d19d93224703fc2b583713bbdddb64422..8241900692e086800fc57ee369e379913f176a1a 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 e4e6c1736db530c53c227c25a43940cef46675fe..e2089822d2bc53dc59adc78594c28b0f90348ad8 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 614c648dfe9cba6c4678cd065adbca99d46723e9..4aee84d2d20f5d95819b1ba3415d6ae648a1c9cd 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 43ad527f53d003375cd3af059807678cd038c2fa..4cb27cbb8a9bdf2652de702e36fe6b1f6f9eb5b1 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 6b1b9b7bd242e397da8fb35e26813b47d172faab..0d47641c092af8fbfd0b8931da7df0b8faed3be5 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 f47fcb3c86457069977d07a05474566262dfca11..e7096369122ad0026d4180d9f47b83796cfc6949 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 9128ac6c08da5bd7e6d98d7275caa702b6ede926..833e4779ddc634eb775b4396a6f4573be56e00c0 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 25dc595052307004dcb8da0310979e1df03337e0..4914342c31832830e64a1cb7dd6329d26ae17bf3 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 ecb8eac60a8ac6b9c66caeba34d5f34e05e3153d..a6aa115307310eaca87e082bedbbac2af538bf40 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 da2ccc8b355ee9ca7f4c31c40f92d9b86ad97586..53e3e48bdb6a8cd96aec7ecfb5a4dc098bdd37e1 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 8533c750708bfc91fe4b856e2c8ba65d1eef69d3..5b4e195870ac15079e469147f463fe53cee20086 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 06f54cde037e7cda6a1b439b822b7de915535874..52e4786903e5c9605de536b5149caeb81256581d 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 e2c79378e223b604c9e7108ed40f67db347092e0..974f3e4be3e2c55a9c0ed04d47ef52655e2e8253 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 7f84c1f963066697745a8645fd96d37c51544791..3a9780706694e37bcba71f919c622810d247f1da 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 8e67fee108519a23d0705346d09afaaf41f8695b..09f3eabb3e60a79f7de5d115b270a7ca39584cd8 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 4bbfc2b290b46088ac16a971c440deb925e21a56..3df94db58907d0f1d27ca181e399d10698ce0342 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 6b3671323f58111940a422fac913e7dc8e4d0ed8..00144a8839b8a89df8eadbb6bdc5cb55a9e967a5 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 413ff20a797fbd7ad923e67ddbaeba14c39b318d..92c580e20f19724b8728505f7cdd5c8e167339f3 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 34b9dda1ea21affaa37906dec26186a7583ed78c..5e6924f290949edb1465f0bc82ed35651bb0c250 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 f6b370c26ea62d0168fb31e1368fd7dd8adbb013..0c7880f34627d432a896131a146ca8702fb28fa4 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 27fdeb2030b6152a51b6a8b602741c356272d1a2..747bb08573c1d6322417b5b8550631ad2ca1bad9 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 37582d49c1b35132138493192dc151504039143b..16bcd7adafe49dffdd1c26c0c30a5c7b4ec6b67f 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 0000000000000000000000000000000000000000..ade6e8b0dd4ffd79381376a3a7787e08e0266f50
--- /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 2e542bcb19c2fa1ebf979ff0301f0fef7c089fda..fccdf513b90527565b38a5f77e0132be6dd8a0fa 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 bb2099fb75fbc448abdcf202f5b92d5fce610cd4..f6ac4ed98cf00019b3da9250ddfbb3a1079e907f 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 2b60fb9b00ea4810c8017e5283e453584f8a2989..7ad842e4b6d47e451ff65e8f174df49e8a568714 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 4941fe2cc2164be031e94b50d2ba0583911c694f..e71babe4e80c4e1878d50b80ec5fbd033feb4458 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 745da4dd8040114993fcca62d07cf35de56b9445..1520b3bde0da9812ec41d4732a1d46859d16f8fc 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 aa7a93ad848210b088ab33ab63d284c1e7a1ae56..dbd705ddc46908c3ee3fd690a93621b18078f8d9 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 98c805908b724e01907d24ba540a8434ebe91007..d4d9661ead4987cae4f28d90057b749d8cbc9bb6 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 118330520986bfc055fb640fa2793c239f9703f6..99b828e53cb4b5a0dd33df2e3fc1872efde432b6 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 48701c58362181a187436e997128208878f42b99..845d80777aae7fa5478841a3de2e77751d3c8cfc 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 fa3c5f29a603a337e94eb4cfc0d74070e48f6726..daa463fd451df90e7d2cd2e85077fce536ac500d 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 3290688358feac2159cdc205227bdb9ed91c1f72..610acc06c21196c5163fa1fbe5e500594f614c31 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 19030255e4f71fe2330e0027a194c8e815ebcf20..9607d2e3ef3cfa5551683e49e16fcbccc8f07082 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 97787ace84f20f45d2b01d1f5239ae773d2970a2..3897a3eab7902a00fef022e2b1cd0fd5df4152c5 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 2d7241526f429e138e577a22c589a849eb1926d4..dfc22790052ed9cf52e842eda2f2f0880b26ae0a 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 8084538e03c02f5a6621b51ed8b0c52666cefaac..beffa0f73a110c86f82de0930f3039785aec932c 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 69a7e70f7dbb3b424c0740300703b12654acc807..9dc1d111eae88b8040563377e73c0edf32128285 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 a83e7653e27ac6604a725fb6fbf8b898434145d5..3aa1db2ea01fe0ea428f3b896cfa68220ee6be0b 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 2e67f4473fecd47e54015be00e94350dfce83101..f1d61baa3af106e89913386bd95acd56e1c04514 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 2d452da15610e28f13c2a5d9811791435f0b757b..91c994d7c0aa7288ce5eb65797d801962fac287b 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 fbc932781ab9662e8820a0621940306cf0dfbe9e..48cf1ae2a6c09189cf3a4d627424ecf98fa2fd40 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 e9dfd5d2ce031b532534d0b7ff6196a92f748ec5..d5ea3f66fe2a978492b85295677bce3cf662a31a 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 0483e3828cde39dc0d245c4aa7690ee3ceb2c5ac..d1bb8d7053008d1b9b249fef623d1f790feeb133 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 766ad9e15761335b3ce42fed34ba788349deddba..b1f0b6b605c1d15cbb45e16f855a5f9dc3510956 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 67ba6a231f33d4ffa50f63e77b86c5bee7cd947f..d4491bfc2748f02859e6787d3ded44394aeae451 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 cb37fe67fe84a4dda7e46952ac4200d989fa3791..159ec52d43f8d4f06a3a3a8d3133430162b757cc 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 ce20480c63325f23c4ae2bdb5218807887d00f58..dd2a135b5668ab3394bbec5d7c44015f1d843212 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 e29c5c4acf5a31a97ef06afdf1c5c4c6ececc83b..10c002f6bad608844c4ff21076d930826ff86106 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 14ee212ce07cb45cfcfcd27b0202e67d4ca808df..3794a965c6d15e0fa6462a88cdee1a3f1fe1a241 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 863da4bdb831b9015d67a9fcf5284733b9c33e91..7fadf7f23055ea977d81f1caa0ab151a04ac5de3 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 27f685a96e194b784506c23e745485e4db4f3e1d..8ed03f49367177888a5445abeb610fda11cf2e6e 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 5b9b70a558017b04cc2a0e805963bb5c05ae445e..57044d8aae620c194f09ac50bf536357f218beff 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 6ca2a301eca5218568e8f9f375f026351a9ac708..29f77bf67c1248c4c585a98fd6adeaeb4a5b4162 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 a2327c506011df0892e72279bb8b5f2fc2c86b19..be977bbfcef433f2b902f31b300d05f2ff75305d 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 6c6c60311e67bf3a0b8f45c0e0d71106927c36a3..0bb9125e7c8bbf7bed2708eaef4d290295485d70 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 9de138ef78cd40707c66ae7ea208b44f4ca5fbfd..899aeea67dd7e87285464e9378f813056047a8f2 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 49af1ceae78eef7a5566e589d9d39abd027d7d40..2e022a3427b65058c82e86a2445c385bedbc7907 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 c7e38712bcdf5b8e7ff0a4eb8d8eba7692ec768c..265ddd9d6c081af0e23ff4fcbcac19ad5fdd4fb9 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 0d1ecfab5b2fa086ed30c1ad25ee3fb7fdbf619f..5976761f77b56ff13d5dc41f8a0bf1105df67921 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 ed2487c02081d059431989d21c31c5511a69bc54..6026a49d1253e0055096af8c86cc781cf60b9158 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 3011bc41d0746b316f816e94c3374bbc8b554a5f..3f78c8029018a564d1cdf37c597949ac7cd44476 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 0af076d40acfd848a05f6785243eeaecd2b56351..030693ac59a3fa7b1bbcd2fb89c5ed9e88470b05 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 b6d1ef24c42f58b3d349192267d494d64538d1ef..b10dd14fa4e63fdf8ccc1d20fc860e6310272fcf 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 a0928634a7c3180411f22137ddffd2dffce30a13..637f9b88ae47eb82e76791e4cd0c10fb70efbbe4 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 58d1b8fd734f5e5d2047430cb80fb425f6a7e3af..a61b9dcfb40ad6ea644ffe6fd03253cbc4971f7f 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 736e4c219ddc6f4e9d5c286fbd93c9c48df6d2ee..9a8c6848e2710f389281ed8205ebb7984616bbb7 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 d062311b2e9fe2d44c9b243d00ad32ff6a0fb9ad..77a3dfd2215887ba3cafb0f391cc0393b18ac70f 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 bf657fc86a9c720d1be79b352aee94dc8031e150..b1780f93d658f6e4f84c08f7439493e532a66ae9 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 bc61e11df7a212a53315e05d910a879fb5553ff3..821079df79afbbab98c783f60251df135249b865 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 9d6a5a499799273335bc8c5d1dd3142131d5b1ff..0b88cc4497f7c658ca69c6065740fcbb62646839 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 3cc8e5f31e0248e1392a5584772a3b784c62b858..91cab78bc72219d98588ddfcdaffc26632ddd759 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 fe3e0cc02093840810993eaacaeb9a1b6d5414f4..32feaced1030101d6517e41278f04376bf94ecf2 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 b9ae2d27cdb773017cd221a5badf73aea1fb10d3..1e01a5a8a219000418a2094e5224173efdcfaebe 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 e2f86a05ba442a2bf0469e47e49fb616282d9d4a..8c9b86b260a499a3fd79baeb7580666adafbcf38 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 14692cb1ea1b901922822b9c7f868c3ba2356345..a65bed020c5e8116bc6d7979769b117f3049a1e3 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 1142d89ab5576746ef57667357de59931fcb97f9..47b19700ee680dc3176b3d1be3eeee5638ec1e25 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 f7f8bb523bf4b218df8140b5220d443e97b91de1..2b63284720749ce8ef3ababa910497bd807896c2 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 54c3dda8493026f9547acf5570ee0fe64e4e87e3..3787382aea802cd88b5bb363582bad364bf6e0d3 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 181113f6bf1922cf635a675b1d660efabf4ab358..15e4114c2d1f1b3d08c36003ebc2287cd4f73e89 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 acbe6b245978a018a846f77b9fdcb976b77cfee7..2c1cf06268f748924641c057f04e0eaeede36fdf 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 f4c142e0f75576884c6e259bd67c9fc640b9edd2..55efc85b97175675ff9e9e67539573283e9222d9 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 ddaea4c24299dd75828a27861205e0a5568d55cb..58a6c817591f29846a88c1b1871c64b631685490 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 cc29e43485b2848c53e82d8963802b26aa04d719..13fa84d0fa395265404f7ef7bdf5eb3fbaab4285 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 92ae2baa152d5f9f4bffbf67d8402a6ea58899cf..a045f482a2810791ae6ba4e228b2ca92c311edc4 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 4cc479f31c4aee69e6f88757f65d78e1388ed94e..991d742cece1f834c05c07b0fabcbc5ccc42a828 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 15780a7c4456461fe28ff31bf3d098aef60f1dea..52c6579654a8933ff7e8e3b72e9c1b8f922f3064 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 4ac971397e0498888fd7c19aac2e773ed16d21f0..1059bf28f8b275dae6d09028b2cfd207180f1fd2 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 6ac1919f0d5a17100ba3409c8523b43eadb8590c..3593eabb5a8d74f221c8607580d4856c74518721 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 4ca031e2e11b9beeb27d3e2cb2171e0a744d989c..da965915caed95b90a889d702fd536b087738c47 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 0e3a7a03ae078bf43dc7f8c2cb66fbfda66860eb..a0bee3a3ee5b0f07c1ea53109e6cbc8b4fa002e4 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 b7904bc7fbca8f21ad3ba7800a0f5235a84b3fa5..c195b64cbf66eb0003c8df8c5c577f2a92b87dfc 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 ed48875eb46629628b6201aa1a3f4df7d7ca677a..9c700f6260ae019e4f7a7ccc54e0037a0d2953b5 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 f3bb17b282a66e857379d4846c0f9098b39a9421..ce0ad795b48151321c685aa1329bdb814c55317a 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 333e217d493bdc3d13800861bc13533f13be8773..4c233576cd44c9389ccd52b5803dc473568254a3 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 7443319336b0c66a63eb94bd4a287858f5e86118..fd5aebc87e0a144d8e9cac2acb6be2dad8a51ddd 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 c8e8feb11ea661cb5711ebccd19ed0a599ce495f..0a4e2cfb92c02696eb5bd990fce9f57aacbc82d8 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 1f782a3bb3a3c9ba1e5b43c7a3fce0556b6f05e6..cc93b57f06248f16e5daecea3c9af4b8de53ebbf 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 c97ee0e3d66af06d2d5edd9dda70ef75b659b92c..7cead12b65bf0f5d5f63c3890b5e25d3ed48639f 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 431d3f4eb1033606614c9abe35898951ea8a5f69..972279194689fa120c70f4cb4fa41cf6e4dc97c3 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 579b4e4db8529cdbf8819249228a7dfe876f9aec..29ad90ed17cfb6bcc299dc9b419b7d357a69b593 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 7577868aff5414a5d27e1983ff0137bb577dc038..f7c238ee8d9515e7109203a5ae335b16bbb49909 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 196311a2836b208d6beb25b57ee95569e8348ae7..4805fc9896e68985afbeba5ef26c40fa3183ff6c 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 52863d5fa4937982e850cebcc84731cb9bc683a4..f5bcd59ecffd49d01c1ce9bc621924acd60dff28 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 356a106418bb4a9aff021e78a27659137c8c5e63..191bdc9b4f9d7b99eed1eef61a86c1b7481ea1a0 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);
}
--
2.54.0
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 efda2b321bf814e63f4ebe478a568bbd9014624c..d87486bbdd1e554a8cef1370fe54fcfe91de39b4 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 acd1eada066370f0e69788eabd2eced814b9e411..de01a5ac45584841f5810c6b4d8cfb39b47f3c87 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 670c410509e994e6bb15760fb1c5493d355d2ceb..800ddc1ccdb2f16789931bad79fb53297101bedf 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;
--
2.54.0
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 7aaf5ebdc7bd1d2ef594783cef2632e522e9f1c6..1bd0805bb9f4bf614a4e20dcbc7563ddd13c43ef 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 e3ba0e3956aa001cbaa3235c2fb54a9598f5bad9..2cd35c2f4ef3fe518e7777b8f4a6d3ec1c28ed46 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 {
--
2.54.0
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 f6ac4ed98cf00019b3da9250ddfbb3a1079e907f..ea32634566e94547bc2503f2f03d757d5d2a6c28 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 783464c620709cd4bd0470bbf9b284e213fd653d..ae3e00eb4b8ec86f2853a8e99ce056ccdab684c8 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 7ad842e4b6d47e451ff65e8f174df49e8a568714..93d5ce3437e7c4a38c1cc085f47205970bd5246b 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 e55a0beb93e0fe68b18f5621cea05f1f6afa3b0d..66aba75e1bc8629a31ed90cd0c78ac24886270c5 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 e71babe4e80c4e1878d50b80ec5fbd033feb4458..08ffa28fce59c7e1da8b82ecfdc881a42358c063 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,
--
2.54.0
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 1bd0805bb9f4bf614a4e20dcbc7563ddd13c43ef..45f6dc268441051bf4f76aa4aa66a29ead8793e3 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,
--
2.54.0
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 842c9ae9046d57f164b60fa67c1f7504c022c183..908c0e327c60e00249f737016f8a52e06179b6c9 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 83a576554a48c7ed8e03807353465a8e9da2ec9f..0c493ebda17bbe105e88f47f052675e0ee55ef49 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 3bfd7cdfc59b1e0321f744c25b7c86adc0bd3dcf..e45280b0d1a32e08e9cdb3619949a756181c7601 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();
}
--
2.54.0
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 e45280b0d1a32e08e9cdb3619949a756181c7601..4868576b4980986ce61094b1d04db751e1b4c391 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 7de43b45f44ce8017af8e86d2cdda926bbbba945..821328b7a6df540598017e5782accb0bb0ad1374 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 0b88cc4497f7c658ca69c6065740fcbb62646839..36e81e11ed3748ac9d24c856566ffb54823a26d6 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();
+}
--
2.54.0
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 0c493ebda17bbe105e88f47f052675e0ee55ef49..970d1cc3820cb12f32e961fb8e1c2def78c99c11 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 265ddd9d6c081af0e23ff4fcbcac19ad5fdd4fb9..7d9dae7bdd38ac942b1b7297773c69a80a2d2525 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;
+}
--
2.54.0
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 2cd35c2f4ef3fe518e7777b8f4a6d3ec1c28ed46..dfea8e1e0410245c12c629cc31eb8073141a1138 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#}
--
2.54.0
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 dfea8e1e0410245c12c629cc31eb8073141a1138..779eb6a31b9ce1be9f651e63559a81f4cd2ef3ef 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 d87486bbdd1e554a8cef1370fe54fcfe91de39b4..5d4013b4b91e9c06096d89c900dee7a9845c4a6b 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 de01a5ac45584841f5810c6b4d8cfb39b47f3c87..b47cdf2ed1a113412bd501b1e27563ef0e0d850b 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 c195b64cbf66eb0003c8df8c5c577f2a92b87dfc..568346369f41275e05cd0da8cdcde95a78b3b723 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);
+}
--
2.54.0
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 | 248 ++++++++++++++++++++----------
src/parser.cpp | 8 +
src/tokenizer.cpp | 19 ++-
src/tokenizer.hpp | 1 +
test/stage1/behavior/pointers.zig | 6 +
7 files changed, 216 insertions(+), 81 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 908c0e327c60e00249f737016f8a52e06179b6c9..fd66b77ad21e6b736db4e2a61eea781d613e1314 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 970d1cc3820cb12f32e961fb8e1c2def78c99c11..e561050e0dd2a2cbc606969124f531e1f1864b0b 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 5d4013b4b91e9c06096d89c900dee7a9845c4a6b..76277f541b5836ae38e51c2e9644310cfb17e4f2 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) {
+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 *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;
+ 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,44 +20809,63 @@ 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_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) {
- Error err;
+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;
- // We explicitly check for the size, so we can use get_src_ptr_type
- if (get_src_ptr_type(dest_type) == nullptr) {
- ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
+ 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 ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
+ 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 (!type_has_bits(dest_type)) {
+ }
+
+ if (get_codegen_ptr_type(dest_type) != nullptr) {
ir_add_error(ira, dest_type_value,
- buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name)));
+ buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_instruction;
}
- IrInstruction *target = instruction->target->child;
- if (type_is_invalid(target->value.type))
+ 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))
@@ -20815,19 +20876,48 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
if (!val)
return ira->codegen->invalid_instruction;
- IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
+ 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, instruction->base.scope,
- instruction->base.source_node, nullptr, casted_int);
- result->value.type = dest_type;
+ 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;
+ ZigType *dest_type = ir_resolve_type(ira, dest_type_value);
+ if (type_is_invalid(dest_type))
+ return ira->codegen->invalid_instruction;
+
+ // We explicitly check for the size, so we can use get_src_ptr_type
+ if (get_src_ptr_type(dest_type) == nullptr) {
+ ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+ if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
+ return ira->codegen->invalid_instruction;
+ if (!type_has_bits(dest_type)) {
+ ir_add_error(ira, dest_type_value,
+ buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name)));
+ return ira->codegen->invalid_instruction;
+ }
+
+
+ IrInstruction *target = instruction->target->child;
+ if (type_is_invalid(target->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return ir_analyze_int_to_ptr(ira, &instruction->base, target, dest_type);
+}
+
static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
IrInstructionDeclRef *instruction)
{
diff --git a/src/parser.cpp b/src/parser.cpp
index 1c1af87c51f66c10a04e0f5f551f60c158944363..160a7268b043dcfe774d535a65e384f495cc9544 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 3acd605748b2553b686dda423d648731331a81dd..9ff6ed3bbe4192d6c4c08173fb04819abcf09ccd 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 17f36699b3bb21b41efbce5fc520fcdc3e141cf7..62117b577938e9e51071125a4b1cd183b56adb4e 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 47b19700ee680dc3176b3d1be3eeee5638ec1e25..6969e151df63aaff921a9412b88824528dfc8ab2 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;
+}
--
2.54.0
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 76277f541b5836ae38e51c2e9644310cfb17e4f2..30350d75de593f7b574f7deb27f77181e691bc92 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 6969e151df63aaff921a9412b88824528dfc8ab2..79832bc3162095ce3b59b1b2fee58a56f64759c1 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);
+}
--
2.54.0
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 ade6e8b0dd4ffd79381376a3a7787e08e0266f50..bece76ee5ca8d69f4be1be54bfefc7b9d3378f31 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,
--
2.54.0
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 4868576b4980986ce61094b1d04db751e1b4c391..192c0f051938200e7ad1afb9889784abe22c0577 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:
--
2.54.0
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 779eb6a31b9ce1be9f651e63559a81f4cd2ef3ef..82ec13c9bb4deaeadd5fd41bcb8a405ea6039c1c 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 160a7268b043dcfe774d535a65e384f495cc9544..3a6ce0464737c4ebcd1c81e7f38e60c8b1c6e95a 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) {
--
2.54.0
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 e9756b404d00ce27866eac75d70018a4672578e1..8b64d75c11f9d39bcdaa2c5d659524b2803d91a2 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 |
--
2.54.0
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 ae3e00eb4b8ec86f2853a8e99ce056ccdab684c8..867dd1159202b77e492085bb54b6eb1e238f0302 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 93d5ce3437e7c4a38c1cc085f47205970bd5246b..5b7b7aa2a91837e59025fe2923f61a57aaa929eb 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 08ffa28fce59c7e1da8b82ecfdc881a42358c063..877e4e8db377951f352e90a2c3e2a67aff91a053 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,
});
}
--
2.54.0
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 e561050e0dd2a2cbc606969124f531e1f1864b0b..691579200e8307f7c5727d481f3581b77f28e56e 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 977378251001dd26389a6eeeff110d806f64e241..1e4f2f2ce75e8acf11f544de3f863832a2a1b264 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 34a7faa2a5192043a4d2890b5539da2ae3603491..7b57841205ac0f08797b081a33d64133f869849e 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 d37002d8c7251b428c20e94a52021dd2e632c134..1652156eeed63e6449d36c42a0b37b47a93c98b9 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 02fa3b24be9585936a655035b3776ccc1d4af105..b06a28d12d850bac25d00eb41a34c72402110c82 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 13f2a964d038ed4e9b94ffe6357554eb2e939442..746fa60b18aff7d89534f269fd318e76b863cde7 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;
--
2.54.0
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 691579200e8307f7c5727d481f3581b77f28e56e..af6200cc8261eab2606accffc571a2018b6a98db 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 4868576b4980986ce61094b1d04db751e1b4c391..605ea59b06b890ded5ca1311bb58ee36da70885b 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 30350d75de593f7b574f7deb27f77181e691bc92..bc37ac9b54886fb861ac8afe9f29398b4f327071 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 b06a28d12d850bac25d00eb41a34c72402110c82..63f04dae6c0f2ce8b98168f789b8a7c4cc8018b4 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 79832bc3162095ce3b59b1b2fee58a56f64759c1..63e4c314b14a23c0f77c4466127b2c995b82c379 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 746fa60b18aff7d89534f269fd318e76b863cde7..b87b962edc768a7a8fcd0d4c5699f360acee299c 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;
\\}
);
--
2.54.0
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 8a05594b301bfcbe80f7400053bb5a950d0666e5..790b51b7bec02d183cab175700ed1df7a9458352 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 605ea59b06b890ded5ca1311bb58ee36da70885b..142e8174f5149994d80baced11557927f0b65e73 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 bc37ac9b54886fb861ac8afe9f29398b4f327071..36ea50ed5213a3e7ced75658cb761ac7881bb2dc 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 05b028112f3038706fdcc38013f2331961f51cea..b09fe21032c31fcda99173d2f1959dc1bc68086a 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 3f8ea762a6e6c611bdac60d27f0fe514f0ca80c6..652e2d39ec1137b1c9cc34b92aa819730a25d818 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 ade6e8b0dd4ffd79381376a3a7787e08e0266f50..f3ce69659d772161667ca44238659de199951bd5 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 ce0ad795b48151321c685aa1329bdb814c55317a..dc185cc96038650ef5f0e29a8fdb4f82717c80a9 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();
--
2.54.0
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 36ea50ed5213a3e7ced75658cb761ac7881bb2dc..5ec397b0b2751804854f7cc1cd4906f85ec18599 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 63e4c314b14a23c0f77c4466127b2c995b82c379..4375a6971fce957533bdfd1a18f02deeef700533 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();
}
--
2.54.0
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 5ec397b0b2751804854f7cc1cd4906f85ec18599..91c85032344a8753b1e1000beae80e2a747480fc 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 4375a6971fce957533bdfd1a18f02deeef700533..3f62bd1cec8dab9f7d5b4539e11da573b43c9b19 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);
+}
--
2.54.0
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 91c85032344a8753b1e1000beae80e2a747480fc..1f0edc910d657f6a590aadc40cec3019f1b406b3 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();
--
2.54.0
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 af6200cc8261eab2606accffc571a2018b6a98db..ab2afba56116f5ec9125a424407a596354eab27c 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 1e4f2f2ce75e8acf11f544de3f863832a2a1b264..c8141b02ff11039f0f44d30fc38c63817b585b0d 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 1f0edc910d657f6a590aadc40cec3019f1b406b3..64e08ef7eafd62c7745ad91e0a379acc51d9f26a 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 b47cdf2ed1a113412bd501b1e27563ef0e0d850b..63850bb888393b44decb724064082c91227f888e 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 {
--
2.54.0
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 64e08ef7eafd62c7745ad91e0a379acc51d9f26a..00d82c9224f2a61dfad3cbc07c17409d6110f085 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 3f62bd1cec8dab9f7d5b4539e11da573b43c9b19..8d87fe2a208f28a3ce4086562eb9e46a0bba8726 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');
+}
--
2.54.0
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 00d82c9224f2a61dfad3cbc07c17409d6110f085..50b5661e12a3fec471d829aa6db07a9539b76bb5 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 63850bb888393b44decb724064082c91227f888e..8f8e2a0bdff71d6adaa58e1f886d2f9d64031b71 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 {};
--
2.54.0
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 | 14 +++--
src/analyze.cpp | 45 +++++++++++-----
src/ir.cpp | 99 ++++++++++++++++++++++++----------
test/compile_errors.zig | 114 ++++++++++++++++++++++++----------------
4 files changed, 182 insertions(+), 90 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index fd66b77ad21e6b736db4e2a61eea781d613e1314..230dba9a423802966b67ab09e9aa375e282d485d 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;
- bool is_const;
- bool is_volatile;
AstNode *op_expr;
+ Token *allow_zero_token;
+ bool is_const;
+ bool is_volatile;
};
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 ab2afba56116f5ec9125a424407a596354eab27c..900def52d4b97ffe5c96682bb7ca4369d33daa83 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 50b5661e12a3fec471d829aa6db07a9539b76bb5..19bec193d56bb1b3d9086457a23c520eae253872 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 8f8e2a0bdff71d6adaa58e1f886d2f9d64031b71..c51a65cadfd5889af56c9c38faaa7db6c0df48d9 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(
--
2.54.0
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 970d1cc3820cb12f32e961fb8e1c2def78c99c11..b3b4c36cf1bc8e20aec9e20a9a15ac971b2828f2 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:
--
2.54.0
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 ed79f99901f820ac364be6288c2b8e6d3aca42c7..41fa44374efb0bcccfa376fe2efa707df10e47ee 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 0000000000000000000000000000000000000000..5f7f73c44f48786467e0439f175feae169cb3106
--- /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 0000000000000000000000000000000000000000..f374a67433941259bc14d1bf477f47216903e7a0
--- /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 3df94db58907d0f1d27ca181e399d10698ce0342..6715df1805e25a9f24fe25c2fbb5fc5685b28c83 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 5cb2f615688f2c1aa192b10358bf46a6a646f2a0..b385090a93e733ff1c8d8ca4a7a1635ad8253e53 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 c4bf2db7333b8e911fbe4d2d467dcfb9be0a7f16..429372c3f191501c53a921b0c1508b3d0b42db63 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 {
--
2.54.0
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 9fad5644c36de1077b4e3abf3c97b48490617726..a605f4f33f048cdd4cff4bd481fce035b9d39fb5 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 ccfac030386ae99230b499224607a3f6df206736..20648139b81a7daba5579bbc66aa251524b01838 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 62f5ef7c0da91c8c9c485501e41f605c9660c97a..fb7a3489c5bad18a84da9cd2f0517e8a41d1ea5b 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 e34e9c597194f3e1de9d954e954e70eae098e51e..b1e3f7795eb81e328954ae227878dfac8d6bcf7b 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 641da9e620ed1a2400da1df61b6006682ab2ab62..e8b03a1e346d06e06b981863d0e8bd63130464fb 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 2cbcbee81b974159a0bf5ca99bc81faa3b159a43..d3ad43da2371930e9504e1189ad01c780b147d5c 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)),
};
}
--
2.54.0
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 7cead12b65bf0f5d5f63c3890b5e25d3ed48639f..5e3e44610998411d0d19c582eba3d353ec890a2a 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();
+}
--
2.54.0
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 5e3e44610998411d0d19c582eba3d353ec890a2a..b0d287145469043b46cd9c1b846d4167d9d8866e 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();
+}
--
2.54.0
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 41fa44374efb0bcccfa376fe2efa707df10e47ee..8e80c65dbdff712f28ac2b090bcd8496a96c1a58 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 05b028112f3038706fdcc38013f2331961f51cea..efb1c41f920a4074b623f07037523d44456a4013 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 0000000000000000000000000000000000000000..b83cdbbbb250d14453b39041677925e3c0ba971b
--- /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));
+ }
+ }
+}
--
2.54.0
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 d8f28560e57174e25394fc0205e761f6b6090151..5a28d9ab4154d7ef180bc37ef6e19b442349f646 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);
}
--
2.54.0
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 b47cdf2ed1a113412bd501b1e27563ef0e0d850b..b895e2c2d15d59346450b7910076085913842de2 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",
+ );
}
--
2.54.0
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 19bec193d56bb1b3d9086457a23c520eae253872..f064adb1280dbd8ed3bfa1458d19f6423c7629b4 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 c51a65cadfd5889af56c9c38faaa7db6c0df48d9..71ee4901ff539dc7f6bb94f715d24573420a0091 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 {
--
2.54.0
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 230dba9a423802966b67ab09e9aa375e282d485d..bafe316c3dcb2f6651233d2565eb848cf79f4a65 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 900def52d4b97ffe5c96682bb7ca4369d33daa83..6a8090a8437318580cbdef43d0907850228e470f 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 c8141b02ff11039f0f44d30fc38c63817b585b0d..50e841baa1bc203af68a982d02d6c0382c34652e 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 142e8174f5149994d80baced11557927f0b65e73..dbb13ca885d3134150ff178067843128efbec94a 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 f064adb1280dbd8ed3bfa1458d19f6423c7629b4..dfbc36e02cb04e2837367eec324a395af7bc417a 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 821328b7a6df540598017e5782accb0bb0ad1374..12cac64b3af2a86266759e1ec3f0fdf309f33eef 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);
--
2.54.0
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 934b8a4f4a83007b3e27e51ced31175dc35b0c13..5e94a83a3a5b97fac22688be4d79e2bfab01082c 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
--
2.54.0
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 5d4013b4b91e9c06096d89c900dee7a9845c4a6b..03dea10b100993043be833b1c2977fdc4ce68f97 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 b895e2c2d15d59346450b7910076085913842de2..6a2ded1844d525e72aa9ab8223634d3ab9e8a927 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();
--
2.54.0
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 | 42 ++++++++++++++++++++---------------------
test/compile_errors.zig | 37 ++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index dfbc36e02cb04e2837367eec324a395af7bc417a..89528db1857b26d100bdce42a9a8eec129634e75 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8683,6 +8683,18 @@ 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) {
+ 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_ptr_type->data.pointer.child_type;
+ 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);
@@ -8693,18 +8705,6 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
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)
- 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_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_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 71ee4901ff539dc7f6bb94f715d24573420a0091..630386aa4f3cac0513c8e3a8270fe1b0ceb577f4 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'",
--
2.54.0
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 6a8090a8437318580cbdef43d0907850228e470f..90ce3d3371c333d8a9c7e50bb670b232bbc7a560 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 630386aa4f3cac0513c8e3a8270fe1b0ceb577f4..ac8d413d2cab871c4cfecbda8d20c28ccddf0caf 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 {
--
2.54.0
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 45f6dc268441051bf4f76aa4aa66a29ead8793e3..082f308a573ec68ea3a328da4b4677837b6abfa1 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 45cfa989428ac25b9b5d2e6b1b4d04aec1638d11..1c671b61e2273738e20560377f411168b916b06a 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 e55d8ccda6f512f9cf9b63c46fb59be0fff432b2..de956f15250a32a7d88e16150118f3e2a12d6b8c 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 0362bb4ef83f604764f16b97ba5198804788542c..dc1b0dc943bfd75bf302ff6b194187bcbe079c51 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 778d3fae0762e3ffe51890e43f57a9c6f73be8c9..704e83c3c6b3c489c4163a7b4503790926ae516c 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 b14c073a9e4c8fccd35a897b15f9e41a59e6f60c..9a84ad256e26e9a40ae41c9951765348aef3eac7 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 36381b820d6b806a4d624da7f03cd37f17239734..121242b5059f2cc097f5a7b193d3f4a55afae4a8 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 790b51b7bec02d183cab175700ed1df7a9458352..7d611bb78793a286110ff4cb1e21de372ba3bdb1 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 9431c614b92eeed292e15af6fa0039d30475d757..d9d4c3d1d95ec56238be1d16361465eea37c7c87 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 89528db1857b26d100bdce42a9a8eec129634e75..7c46b21717606dd456cfaffd525d82749925daa7 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 716f04ff342f034cc9b1615caaf5f29ee23e8d3e..4519890bb75b06ce289d46a45cb4f0d43f375f8e 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 ac8d413d2cab871c4cfecbda8d20c28ccddf0caf..5e9b691641d27d3eebb04691516e8dfc05457351 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 8d87fe2a208f28a3ce4086562eb9e46a0bba8726..eed7a765d7230c7e6c895d17d774c925de767eb1 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();
+}
--
2.54.0
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 90ce3d3371c333d8a9c7e50bb670b232bbc7a560..55deafb3a8c83af50053a8722596e27a7548b790 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 50e841baa1bc203af68a982d02d6c0382c34652e..845fb6253413f29d083a6beecbc7546fbc2b8570 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 dbb13ca885d3134150ff178067843128efbec94a..bae9abe06d8c6d72868730a5c49f59f3bd151879 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 6fea79518c239a8cb054eb38f653196f984b070f..b1434c68717219e0f4e9d889776559fd7ddd08dc 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 a87b12351ac2f3f3215b0748da0f6b3b8a99d3e0..99d1cadf56bf500b6e226c64877da1d99bbc4550 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
--
2.54.0
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 82ec13c9bb4deaeadd5fd41bcb8a405ea6039c1c..e5a60b0bc172c4bbb68e9ce622f9bf63aa8d0a38 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
--
2.54.0
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 7c46b21717606dd456cfaffd525d82749925daa7..6e190adf6faf58e4f4c601f7b79de166312e34de 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 5e9b691641d27d3eebb04691516e8dfc05457351..ab9eda3f1580b3ef41c4879366e3ec3e66ffb02e 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 dc185cc96038650ef5f0e29a8fdb4f82717c80a9..52e03c2d7372c7ba5fcf7d267156571701ce514a 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);
}
--
2.54.0
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 6e190adf6faf58e4f4c601f7b79de166312e34de..7c46b21717606dd456cfaffd525d82749925daa7 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 ab9eda3f1580b3ef41c4879366e3ec3e66ffb02e..a2fd90119743639e8c1bc78e1073a1425dde3e0a 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 52e03c2d7372c7ba5fcf7d267156571701ce514a..dc185cc96038650ef5f0e29a8fdb4f82717c80a9 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);
}
--
2.54.0
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 55deafb3a8c83af50053a8722596e27a7548b790..1917784511d2cb5fceb46d9d2716a5378ade5256 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 7c46b21717606dd456cfaffd525d82749925daa7..707eac0181826d7edf59d5585c7bd38073ceee65 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 63f04dae6c0f2ce8b98168f789b8a7c4cc8018b4..42a7ab436d26334c8d38508dfed65984c12d9777 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 a2fd90119743639e8c1bc78e1073a1425dde3e0a..1f641a90525f0c98c0ae8419ad1312cb3c549c40 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 b87b962edc768a7a8fcd0d4c5699f360acee299c..7385427dbec92ef2b36a897ad579a7bb1ed377dc 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;
--
2.54.0
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 704e83c3c6b3c489c4163a7b4503790926ae516c..5cb95682abeeaf857294e8d36383c9e97a94b387 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 d9d4c3d1d95ec56238be1d16361465eea37c7c87..d8c0f7b5c87c7d11277eb1f4722a35c217bb2287 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 {
--
2.54.0
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 b83cdbbbb250d14453b39041677925e3c0ba971b..de9619efe2b131eb43ba52484c9c3cf4f8efebbd 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 5a28d9ab4154d7ef180bc37ef6e19b442349f646..dd053e7635eeec8f673769e791d84c9c1f2ba326 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)) };
}
};
--
2.54.0
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 5f7f73c44f48786467e0439f175feae169cb3106..09413b23287cf4e16e6fc37c977a62636e7c67f7 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 f374a67433941259bc14d1bf477f47216903e7a0..099b737976380c94bab03376292c15282dca436e 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);
--
2.54.0
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 c64ce807b62ed77e9dd0869f26ead6574b5f4e51..3e883abbabd52cc2fee19f6797361edcdbf471d0 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)),
--
2.54.0
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 edcb9dc579bd2d1028f388e5a0120f1106058cb2..d3a461bcd9346973a63a8c11373745a84efd158a 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;
}
--
2.54.0
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 568346369f41275e05cd0da8cdcde95a78b3b723..099b6c3359bc330c7fec7901d364cbab79f27896 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);
+}
--
2.54.0
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 e5a60b0bc172c4bbb68e9ce622f9bf63aa8d0a38..1341bf1be52b162f0a7e8862861f83cf50a433c9 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 e2a96da7c3e830a83f06d5979ef2fa0d499dc40b..794949358660bb08a2c0efa1846caa86a6f3d238 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 845fb6253413f29d083a6beecbc7546fbc2b8570..7ded651e9568cfd4b67a8e8c91f6d4397d848374 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 c9262038e08864ae80cf9b0fbce588760b83eb11..92cdd8c891e402a4ef11f57547d7d2e4bd1ec852 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 d7e8507f9bc57094b1a6d75c63354b17ed03aabf..6c70834b5270d0c2cb1d336ea77cb9f7b5c430d6 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 1c7523bf13b4bdecc9246ac7727da7e6f45d8e3c..39b9701754a90be90259961a2e47635e05c0401c 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 1fa00b34fd67197765d831982b974ac3e489f6d2..df311637fa09d422788e9d6f1aa62ece3f022d1c 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 0000000000000000000000000000000000000000..ff9ab419f87855d4916fc7b38f8d408fabcf638b
--- /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);
+}
--
2.54.0
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 bafe316c3dcb2f6651233d2565eb848cf79f4a65..6fbd987b9edddcef6cf7d5f502128a6430fb07f2 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 794949358660bb08a2c0efa1846caa86a6f3d238..12e245bd72442be7226e5bb881f51cbdf192d70e 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 7ded651e9568cfd4b67a8e8c91f6d4397d848374..956ef473092650498a56afc11ee178ebc4468bea 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 d2662b10d26e3443f0b593d1b156dc78e281a5ff..d2b2836b0c985d306c14f28b63fec8fc5580de96 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 92cdd8c891e402a4ef11f57547d7d2e4bd1ec852..0fcbb60fe8a323d8df8ad3c57b0b8ac9b117515d 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 0a7c614812b424c817c98b1b8ce2919a6f56df5c..0b85ad2c55f742fa55b08a53b04ba107797dc34d 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 e7108cb36a09123dc2f02cd203f57781638d51e8..9ef4af41625854e2c9f5d59bb8227c1fda2d5629 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(
--
2.54.0
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 12e245bd72442be7226e5bb881f51cbdf192d70e..9941104bc4a3338e8140b34f636117d8504cea2f 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;
--
2.54.0
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 8e80c65dbdff712f28ac2b090bcd8496a96c1a58..db5f50908c0e058a2610b620b764f97b08c55f77 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 64aa729469e3d3cacbb796a4ea25973b9ad174db..42556beaed46bf5ab707491ba1b0884a065095cd 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 73a1d75d42924cc6c2a006fd93432b04dbe8ae3d..78446f9e98378138bfc42037f4a9ff9d554f1b95 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 0000000000000000000000000000000000000000..b6b728f5cf1592668f6f70b0a86f947bc7d9ad50
--- /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");
+}
--
2.54.0
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 b6b728f5cf1592668f6f70b0a86f947bc7d9ad50..46ced0e1361119c34aeb7cbff8cd5a313a2e7355 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,
--
2.54.0
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 710314d1cb7dfbde07241a73e289bfef38db06a8..7d618466b2de8d5312127e75c38a8a867d1c0394 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