From 253ecd5c11747f49575b8425a506c2fecfe26ee2 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Mon, 16 Apr 2018 03:26:10 +0300 Subject: Added ReleaseSmall mode --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 35c7462f4b..3398fd1dea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ static int usage(const char *arg0) { " --pkg-end pop current pkg\n" " --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" " --static output will be statically linked\n" " --strip exclude debug symbols\n" " --target-arch [name] specify target architecture\n" @@ -482,6 +483,8 @@ int main(int argc, char **argv) { build_mode = BuildModeFastRelease; } else if (strcmp(arg, "--release-safe") == 0) { build_mode = BuildModeSafeRelease; + } else if (strcmp(arg, "--release-small") == 0) { + build_mode = BuildModeSmallRelease; } else if (strcmp(arg, "--strip") == 0) { strip = true; } else if (strcmp(arg, "--static") == 0) { -- cgit v1.2.3 From ca4341f7ba845e7af3c6f2be52cd60c51ec6d68f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 18 Apr 2018 17:14:09 -0400 Subject: add --no-rosegment cli option this provides a workaround for #896 until valgrind adds support for clang/LLD (equivalent to gcc/gold -rosegment) --- src/all_types.hpp | 2 ++ src/link.cpp | 3 +++ src/main.cpp | 5 +++++ 3 files changed, 10 insertions(+) (limited to 'src/main.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 5a3590dd4d..88e0ba27a8 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1705,6 +1705,8 @@ struct CodeGen { ZigList error_di_types; ZigList forbidden_libs; + + bool no_rosegment_workaround; }; enum VarLinkage { diff --git a/src/link.cpp b/src/link.cpp index 3c6e27e331..d454d77aae 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -217,6 +217,9 @@ static void construct_linker_job_elf(LinkJob *lj) { lj->args.append(g->linker_script); } + if (g->no_rosegment_workaround) { + lj->args.append("--no-rosegment"); + } lj->args.append("--gc-sections"); lj->args.append("-m"); diff --git a/src/main.cpp b/src/main.cpp index 3398fd1dea..9c36f9b091 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,7 @@ static int usage(const char *arg0) { " -L[dir] alias for --library-path\n" " -rdynamic add all symbols to the dynamic symbol table\n" " -rpath [path] add directory to the runtime library search path\n" + " --no-rosegment compromise security to workaround valgrind bug\n" " -mconsole (windows) --subsystem console to the linker\n" " -mwindows (windows) --subsystem windows to the linker\n" " -framework [name] (darwin) link against framework\n" @@ -324,6 +325,7 @@ int main(int argc, char **argv) { ZigList test_exec_args = {0}; int comptime_args_end = 0; int runtime_args_start = argc; + bool no_rosegment_workaround = false; if (argc >= 2 && strcmp(argv[1], "build") == 0) { const char *zig_exe_path = arg0; @@ -507,6 +509,8 @@ int main(int argc, char **argv) { mconsole = true; } else if (strcmp(arg, "-rdynamic") == 0) { rdynamic = true; + } else if (strcmp(arg, "--no-rosegment") == 0) { + no_rosegment_workaround = true; } else if (strcmp(arg, "--each-lib-rpath") == 0) { each_lib_rpath = true; } else if (strcmp(arg, "--enable-timing-info") == 0) { @@ -844,6 +848,7 @@ int main(int argc, char **argv) { codegen_set_windows_subsystem(g, mwindows, mconsole); codegen_set_rdynamic(g, rdynamic); + g->no_rosegment_workaround = no_rosegment_workaround; if (mmacosx_version_min && mios_version_min) { fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n"); return EXIT_FAILURE; -- cgit v1.2.3 From 688ff2830d82ea36a9f022ecb7cf4c2bf2e4c586 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 7 Jun 2018 19:10:45 -0400 Subject: langref: automatic update of builtin.zig now the docs can't get out of date for this See #367 --- doc/docgen.zig | 18 +++ doc/langref.html.in | 423 +--------------------------------------------------- src/codegen.cpp | 21 ++- src/codegen.hpp | 2 + src/main.cpp | 15 ++ 5 files changed, 51 insertions(+), 428 deletions(-) (limited to 'src/main.cpp') diff --git a/doc/docgen.zig b/doc/docgen.zig index fed4bb8eba..ed0e1be273 100644 --- a/doc/docgen.zig +++ b/doc/docgen.zig @@ -300,6 +300,7 @@ const Link = struct { const Node = union(enum) { Content: []const u8, Nav, + Builtin, HeaderOpen: HeaderOpen, SeeAlso: []const SeeAlsoItem, Code: Code, @@ -356,6 +357,9 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc { _ = try eatToken(tokenizer, Token.Id.BracketClose); try nodes.append(Node.Nav); + } else if (mem.eql(u8, tag_name, "builtin")) { + _ = try eatToken(tokenizer, Token.Id.BracketClose); + try nodes.append(Node.Builtin); } else if (mem.eql(u8, tag_name, "header_open")) { _ = try eatToken(tokenizer, Token.Id.Separator); const content_token = try eatToken(tokenizer, Token.Id.TagContent); @@ -690,6 +694,9 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 { fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var, zig_exe: []const u8) !void { var code_progress_index: usize = 0; + + const builtin_code = try escapeHtml(allocator, try getBuiltinCode(allocator, zig_exe)); + for (toc.nodes) |node| { switch (node) { Node.Content => |data| { @@ -704,6 +711,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var Node.Nav => { try out.write(toc.toc); }, + Node.Builtin => { + try out.print("
{}
", builtin_code); + }, Node.HeaderOpen => |info| { try out.print("{}\n", info.n, info.url, info.name, info.n); }, @@ -1060,3 +1070,11 @@ fn exec(allocator: *mem.Allocator, args: []const []const u8) !os.ChildProcess.Ex } return result; } + +fn getBuiltinCode(allocator: *mem.Allocator, zig_exe: []const u8) ![]const u8 { + const result = try exec(allocator, []const []const u8{ + zig_exe, + "builtin", + }); + return result.stdout; +} diff --git a/doc/langref.html.in b/doc/langref.html.in index 4359cadb58..adb5470d98 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5474,425 +5474,7 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';

Example of what is imported with @import("builtin"):

- {#code_begin|syntax#} -pub const StackTrace = struct { - index: usize, - instruction_addresses: []usize, -}; - -pub const Os = enum { - freestanding, - ananas, - cloudabi, - dragonfly, - freebsd, - fuchsia, - ios, - kfreebsd, - linux, - lv2, - macosx, - netbsd, - openbsd, - solaris, - windows, - haiku, - minix, - rtems, - nacl, - cnk, - aix, - cuda, - nvcl, - amdhsa, - ps4, - elfiamcu, - tvos, - watchos, - mesa3d, - contiki, - amdpal, - zen, -}; - -pub const Arch = enum { - armv8_3a, - armv8_2a, - armv8_1a, - armv8, - armv8r, - armv8m_baseline, - armv8m_mainline, - armv7, - armv7em, - armv7m, - armv7s, - armv7k, - armv7ve, - armv6, - armv6m, - armv6k, - armv6t2, - armv5, - armv5te, - armv4t, - armebv8_3a, - armebv8_2a, - armebv8_1a, - armebv8, - armebv8r, - armebv8m_baseline, - armebv8m_mainline, - armebv7, - armebv7em, - armebv7m, - armebv7s, - armebv7k, - armebv7ve, - armebv6, - armebv6m, - armebv6k, - armebv6t2, - armebv5, - armebv5te, - armebv4t, - aarch64, - aarch64_be, - arc, - avr, - bpfel, - bpfeb, - hexagon, - mips, - mipsel, - mips64, - mips64el, - msp430, - nios2, - powerpc, - powerpc64, - powerpc64le, - r600, - amdgcn, - riscv32, - riscv64, - sparc, - sparcv9, - sparcel, - s390x, - tce, - tcele, - thumb, - thumbeb, - i386, - x86_64, - xcore, - nvptx, - nvptx64, - le32, - le64, - amdil, - amdil64, - hsail, - hsail64, - spir, - spir64, - kalimbav3, - kalimbav4, - kalimbav5, - shave, - lanai, - wasm32, - wasm64, - renderscript32, - renderscript64, -}; - -pub const Environ = enum { - unknown, - gnu, - gnuabin32, - gnuabi64, - gnueabi, - gnueabihf, - gnux32, - code16, - eabi, - eabihf, - android, - musl, - musleabi, - musleabihf, - msvc, - itanium, - cygnus, - amdopencl, - coreclr, - opencl, - simulator, -}; - -pub const ObjectFormat = enum { - unknown, - coff, - elf, - macho, - wasm, -}; - -pub const GlobalLinkage = enum { - Internal, - Strong, - Weak, - LinkOnce, -}; - -pub const AtomicOrder = enum { - Unordered, - Monotonic, - Acquire, - Release, - AcqRel, - SeqCst, -}; - -pub const AtomicRmwOp = enum { - Xchg, - Add, - Sub, - And, - Nand, - Or, - Xor, - Max, - Min, -}; - -pub const Mode = enum { - Debug, - ReleaseSafe, - ReleaseFast, - ReleaseSmall, -}; - -pub const TypeId = enum { - Type, - Void, - Bool, - NoReturn, - Int, - Float, - Pointer, - Array, - Struct, - ComptimeFloat, - ComptimeInt, - Undefined, - Null, - Nullable, - ErrorUnion, - ErrorSet, - Enum, - Union, - Fn, - Namespace, - Block, - BoundFn, - ArgTuple, - Opaque, - Promise, -}; - -pub const TypeInfo = union(TypeId) { - Type: void, - Void: void, - Bool: void, - NoReturn: void, - Int: Int, - Float: Float, - Pointer: Pointer, - Array: Array, - Struct: Struct, - ComptimeFloat: void, - ComptimeInt: void, - Undefined: void, - Null: void, - Nullable: Nullable, - ErrorUnion: ErrorUnion, - ErrorSet: ErrorSet, - Enum: Enum, - Union: Union, - Fn: Fn, - Namespace: void, - Block: void, - BoundFn: Fn, - ArgTuple: void, - Opaque: void, - Promise: Promise, - - - pub const Int = struct { - is_signed: bool, - bits: u8, - }; - - pub const Float = struct { - bits: u8, - }; - - pub const Pointer = struct { - is_const: bool, - is_volatile: bool, - alignment: u32, - child: type, - }; - - pub const Array = struct { - len: usize, - child: type, - }; - - pub const ContainerLayout = enum { - Auto, - Extern, - Packed, - }; - - pub const StructField = struct { - name: []const u8, - offset: ?usize, - field_type: type, - }; - - pub const Struct = struct { - layout: ContainerLayout, - fields: []StructField, - defs: []Definition, - }; - - pub const Nullable = struct { - child: type, - }; - - pub const ErrorUnion = struct { - error_set: type, - payload: type, - }; - - pub const Error = struct { - name: []const u8, - value: usize, - }; - - pub const ErrorSet = struct { - errors: []Error, - }; - - pub const EnumField = struct { - name: []const u8, - value: usize, - }; - - pub const Enum = struct { - layout: ContainerLayout, - tag_type: type, - fields: []EnumField, - defs: []Definition, - }; - - pub const UnionField = struct { - name: []const u8, - enum_field: ?EnumField, - field_type: type, - }; - - pub const Union = struct { - layout: ContainerLayout, - tag_type: type, - fields: []UnionField, - defs: []Definition, - }; - - pub const CallingConvention = enum { - Unspecified, - C, - Cold, - Naked, - Stdcall, - Async, - }; - - pub const FnArg = struct { - is_generic: bool, - is_noalias: bool, - arg_type: type, - }; - - pub const Fn = struct { - calling_convention: CallingConvention, - is_generic: bool, - is_var_args: bool, - return_type: type, - async_allocator_type: type, - args: []FnArg, - }; - - pub const Promise = struct { - child: type, - }; - - pub const Definition = struct { - name: []const u8, - is_pub: bool, - data: Data, - - pub const Data = union(enum) { - Type: type, - Var: type, - Fn: FnDef, - - pub const FnDef = struct { - fn_type: type, - inline_type: Inline, - calling_convention: CallingConvention, - is_var_args: bool, - is_extern: bool, - is_export: bool, - lib_name: ?[]const u8, - return_type: type, - arg_names: [][] const u8, - - pub const Inline = enum { - Auto, - Always, - Never, - }; - }; - }; - }; -}; - -pub const FloatMode = enum { - Optimized, - Strict, -}; - -pub const Endian = enum { - Big, - Little, -}; - -pub const endian = Endian.Little; -pub const is_test = true; -pub const os = Os.linux; -pub const arch = Arch.x86_64; -pub const environ = Environ.gnu; -pub const object_format = ObjectFormat.elf; -pub const mode = Mode.Debug; -pub const link_libc = false; -pub const have_error_return_tracing = true; -pub const __zig_test_fn_slice = {}; // overwritten later - {#code_end#} + {#builtin#} {#see_also|Build Mode#} {#header_close#} {#header_open|Root Source File#} @@ -6053,8 +5635,7 @@ pub fn build(b: *Builder) void { b.default_step.dependOn(&exe.step); } {#code_end#} - {#header_close#} - {#header_open|Terminal#} +

terminal

$ zig build
 $ ./test
 all your base are belong to us
diff --git a/src/codegen.cpp b/src/codegen.cpp index 7f95f335d1..fb59ca7569 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6335,13 +6335,7 @@ static const char *build_mode_to_str(BuildMode build_mode) { zig_unreachable(); } -static void define_builtin_compile_vars(CodeGen *g) { - if (g->std_package == nullptr) - return; - - const char *builtin_zig_basename = "builtin.zig"; - Buf *builtin_zig_path = buf_alloc(); - os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); +Buf *codegen_generate_builtin_source(CodeGen *g) { Buf *contents = buf_alloc(); // Modifications to this struct must be coordinated with code that does anything with @@ -6707,6 +6701,19 @@ static void define_builtin_compile_vars(CodeGen *g) { buf_appendf(contents, "pub const __zig_test_fn_slice = {}; // overwritten later\n"); + + return contents; +} + +static void define_builtin_compile_vars(CodeGen *g) { + if (g->std_package == nullptr) + return; + + const char *builtin_zig_basename = "builtin.zig"; + Buf *builtin_zig_path = buf_alloc(); + os_path_join(g->cache_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); + + Buf *contents = codegen_generate_builtin_source(g); ensure_cache_dir(g); os_write_file(builtin_zig_path, contents); diff --git a/src/codegen.hpp b/src/codegen.hpp index a7a4b748c4..b5f3374ec4 100644 --- a/src/codegen.hpp +++ b/src/codegen.hpp @@ -59,5 +59,7 @@ void codegen_add_object(CodeGen *g, Buf *object_path); void codegen_translate_c(CodeGen *g, Buf *path); +Buf *codegen_generate_builtin_source(CodeGen *g); + #endif diff --git a/src/main.cpp b/src/main.cpp index 9c36f9b091..c63a143bff 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,7 @@ static int usage(const char *arg0) { " build-exe [source] create executable from source or object files\n" " 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" " run [source] create executable and run immediately\n" " translate-c [source] convert c code to zig code\n" " targets list available compilation targets\n" @@ -214,6 +215,7 @@ static Buf *resolve_zig_lib_dir(void) { enum Cmd { CmdInvalid, CmdBuild, + CmdBuiltin, CmdRun, CmdTest, CmdVersion, @@ -664,6 +666,8 @@ int main(int argc, char **argv) { out_type = OutTypeExe; } else if (strcmp(arg, "targets") == 0) { cmd = CmdTargets; + } else if (strcmp(arg, "builtin") == 0) { + cmd = CmdBuiltin; } else { fprintf(stderr, "Unrecognized command: %s\n", arg); return usage(arg0); @@ -681,6 +685,7 @@ int main(int argc, char **argv) { return usage(arg0); } break; + case CmdBuiltin: case CmdVersion: case CmdZen: case CmdTargets: @@ -727,6 +732,16 @@ int main(int argc, char **argv) { } switch (cmd) { + case CmdBuiltin: { + Buf *zig_lib_dir_buf = resolve_zig_lib_dir(); + CodeGen *g = codegen_create(nullptr, target, out_type, build_mode, zig_lib_dir_buf); + 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))); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } case CmdRun: case CmdBuild: case CmdTranslateC: -- cgit v1.2.3 From 79120612267f55901029dd57290ee90c0a3ec987 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 17 Jun 2018 02:57:07 -0400 Subject: remove integer and float casting syntax * add `@intCast` * add `@floatCast` * add `@floatToInt` * add `@intToFloat` See #1061 --- doc/langref.html.in | 12 +- src/all_types.hpp | 36 +++++ src/codegen.cpp | 8 + src/ir.cpp | 290 +++++++++++++++++++++++++++++++++--- src/ir_print.cpp | 44 ++++++ src/main.cpp | 2 +- std/array_list.zig | 8 +- std/base64.zig | 4 +- std/crypto/blake2.zig | 10 +- std/crypto/md5.zig | 6 +- std/crypto/sha1.zig | 6 +- std/crypto/sha2.zig | 12 +- std/debug/index.zig | 8 +- std/fmt/errol/index.zig | 78 +++++----- std/fmt/index.zig | 19 +-- std/hash/crc.zig | 4 +- std/hash/siphash.zig | 6 +- std/heap.zig | 2 +- std/json.zig | 2 +- std/math/acos.zig | 4 +- std/math/asin.zig | 4 +- std/math/atan.zig | 4 +- std/math/atan2.zig | 8 +- std/math/atanh.zig | 2 +- std/math/big/int.zig | 22 +-- std/math/cbrt.zig | 6 +- std/math/ceil.zig | 4 +- std/math/complex/atan.zig | 10 +- std/math/complex/cosh.zig | 4 +- std/math/complex/exp.zig | 6 +- std/math/complex/ldexp.zig | 13 +- std/math/complex/sinh.zig | 10 +- std/math/complex/sqrt.zig | 10 +- std/math/complex/tanh.zig | 10 +- std/math/cos.zig | 4 +- std/math/cosh.zig | 2 +- std/math/exp.zig | 12 +- std/math/exp2.zig | 14 +- std/math/expm1.zig | 20 +-- std/math/floor.zig | 4 +- std/math/fma.zig | 6 +- std/math/frexp.zig | 4 +- std/math/hypot.zig | 2 +- std/math/ilogb.zig | 4 +- std/math/index.zig | 25 +++- std/math/ln.zig | 12 +- std/math/log.zig | 11 +- std/math/log10.zig | 14 +- std/math/log1p.zig | 12 +- std/math/log2.zig | 12 +- std/math/modf.zig | 8 +- std/math/pow.zig | 4 +- std/math/scalbn.zig | 4 +- std/math/sin.zig | 4 +- std/math/sinh.zig | 2 +- std/math/sqrt.zig | 2 +- std/math/tan.zig | 4 +- std/math/tanh.zig | 4 +- std/math/trunc.zig | 8 +- std/mem.zig | 2 +- std/os/child_process.zig | 2 +- std/os/darwin.zig | 11 +- std/os/file.zig | 6 +- std/os/index.zig | 16 +- std/os/linux/index.zig | 80 +++++----- std/os/linux/test.zig | 6 +- std/os/linux/vdso.zig | 4 +- std/os/time.zig | 24 +-- std/os/windows/util.zig | 9 +- std/rand/index.zig | 16 +- std/segmented_list.zig | 12 +- std/special/bootstrap.zig | 2 +- std/special/builtin.zig | 30 ++-- std/special/compiler_rt/divti3.zig | 2 +- std/special/compiler_rt/fixuint.zig | 8 +- std/special/compiler_rt/index.zig | 12 +- std/special/compiler_rt/udivmod.zig | 34 ++--- std/unicode.zig | 20 +-- std/zig/tokenizer.zig | 2 +- test/cases/cast.zig | 18 ++- test/cases/enum.zig | 2 +- test/cases/eval.zig | 8 +- test/cases/fn.zig | 2 +- test/cases/for.zig | 4 +- test/cases/struct.zig | 8 +- 85 files changed, 799 insertions(+), 413 deletions(-) (limited to 'src/main.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index 651629d8fb..35ca9a13b4 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -1355,7 +1355,7 @@ var some_integers: [100]i32 = undefined; test "modify an array" { for (some_integers) |*item, i| { - item.* = i32(i); + item.* = @intCast(i32, i); } assert(some_integers[10] == 10); assert(some_integers[99] == 99); @@ -1397,8 +1397,8 @@ var fancy_array = init: { var initial_value: [10]Point = undefined; for (initial_value) |*pt, i| { pt.* = Point{ - .x = i32(i), - .y = i32(i) * 2, + .x = @intCast(i32, i), + .y = @intCast(i32, i) * 2, }; } break :init initial_value; @@ -2410,7 +2410,7 @@ test "for basics" { var sum2: i32 = 0; for (items) |value, i| { assert(@typeOf(i) == usize); - sum2 += i32(i); + sum2 += @intCast(i32, i); } assert(sum2 == 10); } @@ -5730,7 +5730,7 @@ comptime { {#code_begin|test_err|attempt to cast negative value to unsigned integer#} comptime { const value: i32 = -1; - const unsigned = u32(value); + const unsigned = @intCast(u32, value); } {#code_end#}

At runtime crashes with the message attempt to cast negative value to unsigned integer and a stack trace.

@@ -5744,7 +5744,7 @@ comptime { {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#} comptime { const spartan_count: u16 = 300; - const byte = u8(spartan_count); + const byte = @intCast(u8, spartan_count); } {#code_end#}

At runtime crashes with the message integer cast truncated bits and a stack trace.

diff --git a/src/all_types.hpp b/src/all_types.hpp index 0d364915f9..bc2fe07c18 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1357,6 +1357,10 @@ enum BuiltinFnId { BuiltinFnIdMod, BuiltinFnIdSqrt, BuiltinFnIdTruncate, + BuiltinFnIdIntCast, + BuiltinFnIdFloatCast, + BuiltinFnIdIntToFloat, + BuiltinFnIdFloatToInt, BuiltinFnIdIntType, BuiltinFnIdSetCold, BuiltinFnIdSetRuntimeSafety, @@ -2040,6 +2044,10 @@ enum IrInstructionId { IrInstructionIdCmpxchg, IrInstructionIdFence, IrInstructionIdTruncate, + IrInstructionIdIntCast, + IrInstructionIdFloatCast, + IrInstructionIdIntToFloat, + IrInstructionIdFloatToInt, IrInstructionIdIntType, IrInstructionIdBoolNot, IrInstructionIdMemset, @@ -2632,6 +2640,34 @@ struct IrInstructionTruncate { IrInstruction *target; }; +struct IrInstructionIntCast { + IrInstruction base; + + IrInstruction *dest_type; + IrInstruction *target; +}; + +struct IrInstructionFloatCast { + IrInstruction base; + + IrInstruction *dest_type; + IrInstruction *target; +}; + +struct IrInstructionIntToFloat { + IrInstruction base; + + IrInstruction *dest_type; + IrInstruction *target; +}; + +struct IrInstructionFloatToInt { + IrInstruction base; + + IrInstruction *dest_type; + IrInstruction *target; +}; + struct IrInstructionIntType { IrInstruction base; diff --git a/src/codegen.cpp b/src/codegen.cpp index 425cdac024..4108cbbd68 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -4722,6 +4722,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdPromiseResultType: case IrInstructionIdAwaitBookkeeping: case IrInstructionIdAddImplicitReturnType: + case IrInstructionIdIntCast: + case IrInstructionIdFloatCast: + case IrInstructionIdIntToFloat: + case IrInstructionIdFloatToInt: zig_unreachable(); case IrInstructionIdReturn: @@ -6310,6 +6314,10 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCmpxchgStrong, "cmpxchgStrong", 6); create_builtin_fn(g, BuiltinFnIdFence, "fence", 1); create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2); + create_builtin_fn(g, BuiltinFnIdIntCast, "intCast", 2); + create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2); + create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2); + create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2); create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int diff --git a/src/ir.cpp b/src/ir.cpp index d008ead113..0b847fc4e4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -460,6 +460,22 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { return IrInstructionIdTruncate; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { + return IrInstructionIdIntCast; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { + return IrInstructionIdFloatCast; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { + return IrInstructionIdIntToFloat; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { + return IrInstructionIdFloatToInt; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { return IrInstructionIdIntType; } @@ -1899,10 +1915,48 @@ static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *s return &instruction->base; } -static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *dest_type, IrInstruction *target) { - IrInstruction *new_instruction = ir_build_truncate(irb, old_instruction->scope, old_instruction->source_node, dest_type, target); - ir_link_new_instruction(new_instruction, old_instruction); - return new_instruction; +static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { + IrInstructionIntCast *instruction = ir_build_instruction(irb, scope, source_node); + instruction->dest_type = dest_type; + instruction->target = target; + + ir_ref_instruction(dest_type, irb->current_basic_block); + ir_ref_instruction(target, irb->current_basic_block); + + return &instruction->base; +} + +static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { + IrInstructionFloatCast *instruction = ir_build_instruction(irb, scope, source_node); + instruction->dest_type = dest_type; + instruction->target = target; + + ir_ref_instruction(dest_type, irb->current_basic_block); + ir_ref_instruction(target, irb->current_basic_block); + + return &instruction->base; +} + +static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { + IrInstructionIntToFloat *instruction = ir_build_instruction(irb, scope, source_node); + instruction->dest_type = dest_type; + instruction->target = target; + + ir_ref_instruction(dest_type, irb->current_basic_block); + ir_ref_instruction(target, irb->current_basic_block); + + return &instruction->base; +} + +static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { + IrInstructionFloatToInt *instruction = ir_build_instruction(irb, scope, source_node); + instruction->dest_type = dest_type; + instruction->target = target; + + ir_ref_instruction(dest_type, irb->current_basic_block); + ir_ref_instruction(target, irb->current_basic_block); + + return &instruction->base; } static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { @@ -3957,6 +4011,66 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, truncate, lval); } + case BuiltinFnIdIntCast: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(irb, scope, result, lval); + } + case BuiltinFnIdFloatCast: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(irb, scope, result, lval); + } + case BuiltinFnIdIntToFloat: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(irb, scope, result, lval); + } + case BuiltinFnIdFloatToInt: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(irb, scope, result, lval); + } case BuiltinFnIdIntType: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); @@ -9948,34 +10062,37 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false); } - // explicit widening or shortening cast - if ((wanted_type->id == TypeTableEntryIdInt && - actual_type->id == TypeTableEntryIdInt) || - (wanted_type->id == TypeTableEntryIdFloat && - actual_type->id == TypeTableEntryIdFloat)) + // explicit widening conversion + if (wanted_type->id == TypeTableEntryIdInt && + actual_type->id == TypeTableEntryIdInt && + wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && + wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) { return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // explicit error set cast - if (wanted_type->id == TypeTableEntryIdErrorSet && - actual_type->id == TypeTableEntryIdErrorSet) + // small enough unsigned ints can get casted to large enough signed ints + if (wanted_type->id == TypeTableEntryIdInt && wanted_type->data.integral.is_signed && + actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed && + wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) { - return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type); + return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // explicit cast from int to float + // explicit float widening conversion if (wanted_type->id == TypeTableEntryIdFloat && - actual_type->id == TypeTableEntryIdInt) + actual_type->id == TypeTableEntryIdFloat && + wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) { - return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToFloat, false); + return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); } - // explicit cast from float to int - if (wanted_type->id == TypeTableEntryIdInt && - actual_type->id == TypeTableEntryIdFloat) + + // explicit error set cast + if (wanted_type->id == TypeTableEntryIdErrorSet && + actual_type->id == TypeTableEntryIdErrorSet) { - return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpFloatToInt, false); + return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type); } // explicit cast from [N]T to []const T @@ -17365,7 +17482,126 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc return dest_type; } - ir_build_truncate_from(&ira->new_irb, &instruction->base, dest_type_value, target); + IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, + instruction->base.source_node, dest_type_value, target); + ir_link_new_instruction(new_instruction, &instruction->base); + return dest_type; +} + +static TypeTableEntry *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { + TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); + if (type_is_invalid(dest_type)) + return ira->codegen->builtin_types.entry_invalid; + + if (dest_type->id != TypeTableEntryIdInt) { + ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->builtin_types.entry_invalid; + } + + IrInstruction *target = instruction->target->other; + if (type_is_invalid(target->value.type)) + return ira->codegen->builtin_types.entry_invalid; + + if (target->value.type->id == TypeTableEntryIdComptimeInt) { + if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { + IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, + CastOpNumLitToConcrete, false); + if (type_is_invalid(result->value.type)) + return ira->codegen->builtin_types.entry_invalid; + ir_link_new_instruction(result, &instruction->base); + return dest_type; + } else { + return ira->codegen->builtin_types.entry_invalid; + } + } + + if (target->value.type->id != TypeTableEntryIdInt) { + ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", + buf_ptr(&target->value.type->name))); + return ira->codegen->builtin_types.entry_invalid; + } + + IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); + if (type_is_invalid(result->value.type)) + return ira->codegen->builtin_types.entry_invalid; + + ir_link_new_instruction(result, &instruction->base); + return dest_type; +} + +static TypeTableEntry *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { + TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); + if (type_is_invalid(dest_type)) + return ira->codegen->builtin_types.entry_invalid; + + if (dest_type->id != TypeTableEntryIdFloat) { + ir_add_error(ira, instruction->dest_type, + buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); + return ira->codegen->builtin_types.entry_invalid; + } + + IrInstruction *target = instruction->target->other; + if (type_is_invalid(target->value.type)) + return ira->codegen->builtin_types.entry_invalid; + + if (target->value.type->id == TypeTableEntryIdComptimeInt || + target->value.type->id == TypeTableEntryIdComptimeFloat) + { + if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { + CastOp op; + if (target->value.type->id == TypeTableEntryIdComptimeInt) { + op = CastOpIntToFloat; + } else { + op = CastOpNumLitToConcrete; + } + IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); + if (type_is_invalid(result->value.type)) + return ira->codegen->builtin_types.entry_invalid; + ir_link_new_instruction(result, &instruction->base); + return dest_type; + } else { + return ira->codegen->builtin_types.entry_invalid; + } + } + + if (target->value.type->id != TypeTableEntryIdFloat) { + ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", + buf_ptr(&target->value.type->name))); + return ira->codegen->builtin_types.entry_invalid; + } + + IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); + if (type_is_invalid(result->value.type)) + return ira->codegen->builtin_types.entry_invalid; + ir_link_new_instruction(result, &instruction->base); + return dest_type; +} + +static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { + TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); + if (type_is_invalid(dest_type)) + return ira->codegen->builtin_types.entry_invalid; + + IrInstruction *target = instruction->target->other; + if (type_is_invalid(target->value.type)) + return ira->codegen->builtin_types.entry_invalid; + + IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); + ir_link_new_instruction(result, &instruction->base); + return dest_type; +} + +static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { + TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other); + if (type_is_invalid(dest_type)) + return ira->codegen->builtin_types.entry_invalid; + + IrInstruction *target = instruction->target->other; + if (type_is_invalid(target->value.type)) + return ira->codegen->builtin_types.entry_invalid; + + IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); + ir_link_new_instruction(result, &instruction->base); return dest_type; } @@ -19899,6 +20135,14 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); case IrInstructionIdTruncate: return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); + case IrInstructionIdIntCast: + return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); + case IrInstructionIdFloatCast: + return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); + case IrInstructionIdIntToFloat: + return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); + case IrInstructionIdFloatToInt: + return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); case IrInstructionIdIntType: return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); case IrInstructionIdBoolNot: @@ -20242,6 +20486,10 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdPromiseResultType: case IrInstructionIdSqrt: case IrInstructionIdAtomicLoad: + case IrInstructionIdIntCast: + case IrInstructionIdFloatCast: + case IrInstructionIdIntToFloat: + case IrInstructionIdFloatToInt: return false; case IrInstructionIdAsm: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 43907fa9d4..b5722c52fa 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -648,6 +648,38 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction) fprintf(irp->f, ")"); } +static void ir_print_int_cast(IrPrint *irp, IrInstructionIntCast *instruction) { + fprintf(irp->f, "@intCast("); + ir_print_other_instruction(irp, instruction->dest_type); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->target); + fprintf(irp->f, ")"); +} + +static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instruction) { + fprintf(irp->f, "@floatCast("); + ir_print_other_instruction(irp, instruction->dest_type); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->target); + fprintf(irp->f, ")"); +} + +static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) { + fprintf(irp->f, "@intToFloat("); + ir_print_other_instruction(irp, instruction->dest_type); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->target); + fprintf(irp->f, ")"); +} + +static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruction) { + fprintf(irp->f, "@floatToInt("); + ir_print_other_instruction(irp, instruction->dest_type); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->target); + fprintf(irp->f, ")"); +} + static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) { fprintf(irp->f, "@IntType("); ir_print_other_instruction(irp, instruction->is_signed); @@ -1417,6 +1449,18 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdTruncate: ir_print_truncate(irp, (IrInstructionTruncate *)instruction); break; + case IrInstructionIdIntCast: + ir_print_int_cast(irp, (IrInstructionIntCast *)instruction); + break; + case IrInstructionIdFloatCast: + ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction); + break; + case IrInstructionIdIntToFloat: + ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction); + break; + case IrInstructionIdFloatToInt: + ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction); + break; case IrInstructionIdIntType: ir_print_int_type(irp, (IrInstructionIntType *)instruction); break; diff --git a/src/main.cpp b/src/main.cpp index c63a143bff..0fe12bb0cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,7 +34,7 @@ static int usage(const char *arg0) { " --assembly [source] add assembly file to build\n" " --cache-dir [path] override the cache directory\n" " --color [auto|off|on] enable or disable colored error messages\n" - " --emit [filetype] emit a specific file format as compilation output\n" + " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n" " --enable-timing-info print timing diagnostics\n" " --libc-include-dir [path] directory where libc stdlib.h resides\n" " --name [name] override output name\n" diff --git a/std/array_list.zig b/std/array_list.zig index fd1d5cbe26..b71f5be6ab 100644 --- a/std/array_list.zig +++ b/std/array_list.zig @@ -185,23 +185,23 @@ test "basic ArrayList test" { { var i: usize = 0; while (i < 10) : (i += 1) { - list.append(i32(i + 1)) catch unreachable; + list.append(@intCast(i32, i + 1)) catch unreachable; } } { var i: usize = 0; while (i < 10) : (i += 1) { - assert(list.items[i] == i32(i + 1)); + assert(list.items[i] == @intCast(i32, i + 1)); } } for (list.toSlice()) |v, i| { - assert(v == i32(i + 1)); + assert(v == @intCast(i32, i + 1)); } for (list.toSliceConst()) |v, i| { - assert(v == i32(i + 1)); + assert(v == @intCast(i32, i + 1)); } assert(list.pop() == 10); diff --git a/std/base64.zig b/std/base64.zig index d27bcbd201..45c8e22c7e 100644 --- a/std/base64.zig +++ b/std/base64.zig @@ -99,7 +99,7 @@ pub const Base64Decoder = struct { assert(!result.char_in_alphabet[c]); assert(c != pad_char); - result.char_to_index[c] = u8(i); + result.char_to_index[c] = @intCast(u8, i); result.char_in_alphabet[c] = true; } @@ -284,7 +284,7 @@ pub const Base64DecoderUnsafe = struct { }; for (alphabet_chars) |c, i| { assert(c != pad_char); - result.char_to_index[c] = u8(i); + result.char_to_index[c] = @intCast(u8, i); } return result; } diff --git a/std/crypto/blake2.zig b/std/crypto/blake2.zig index f0a9766c00..947133e4cf 100644 --- a/std/crypto/blake2.zig +++ b/std/crypto/blake2.zig @@ -79,7 +79,7 @@ fn Blake2s(comptime out_len: usize) type { mem.copy(u32, d.h[0..], iv[0..]); // No key plus default parameters - d.h[0] ^= 0x01010000 ^ u32(out_len >> 3); + d.h[0] ^= 0x01010000 ^ @intCast(u32, out_len >> 3); d.t = 0; d.buf_len = 0; } @@ -110,7 +110,7 @@ fn Blake2s(comptime out_len: usize) type { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); } pub fn final(d: *Self, out: []u8) void { @@ -144,7 +144,7 @@ fn Blake2s(comptime out_len: usize) type { } v[12] ^= @truncate(u32, d.t); - v[13] ^= u32(d.t >> 32); + v[13] ^= @intCast(u32, d.t >> 32); if (last) v[14] = ~v[14]; const rounds = comptime []RoundParam{ @@ -345,7 +345,7 @@ fn Blake2b(comptime out_len: usize) type { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); } pub fn final(d: *Self, out: []u8) void { @@ -377,7 +377,7 @@ fn Blake2b(comptime out_len: usize) type { } v[12] ^= @truncate(u64, d.t); - v[13] ^= u64(d.t >> 64); + v[13] ^= @intCast(u64, d.t >> 64); if (last) v[14] = ~v[14]; const rounds = comptime []RoundParam{ diff --git a/std/crypto/md5.zig b/std/crypto/md5.zig index c0d1732d37..23fe2313a0 100644 --- a/std/crypto/md5.zig +++ b/std/crypto/md5.zig @@ -78,7 +78,7 @@ pub const Md5 = struct { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); // Md5 uses the bottom 64-bits for length padding d.total_len +%= b.len; @@ -103,9 +103,9 @@ pub const Md5 = struct { // Append message length. var i: usize = 1; var len = d.total_len >> 5; - d.buf[56] = u8(d.total_len & 0x1f) << 3; + d.buf[56] = @intCast(u8, d.total_len & 0x1f) << 3; while (i < 8) : (i += 1) { - d.buf[56 + i] = u8(len & 0xff); + d.buf[56 + i] = @intCast(u8, len & 0xff); len >>= 8; } diff --git a/std/crypto/sha1.zig b/std/crypto/sha1.zig index 9e46fc9239..5c91590c88 100644 --- a/std/crypto/sha1.zig +++ b/std/crypto/sha1.zig @@ -78,7 +78,7 @@ pub const Sha1 = struct { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); d.total_len += b.len; } @@ -102,9 +102,9 @@ pub const Sha1 = struct { // Append message length. var i: usize = 1; var len = d.total_len >> 5; - d.buf[63] = u8(d.total_len & 0x1f) << 3; + d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3; while (i < 8) : (i += 1) { - d.buf[63 - i] = u8(len & 0xff); + d.buf[63 - i] = @intCast(u8, len & 0xff); len >>= 8; } diff --git a/std/crypto/sha2.zig b/std/crypto/sha2.zig index d1375d73e8..d1b915835c 100644 --- a/std/crypto/sha2.zig +++ b/std/crypto/sha2.zig @@ -131,7 +131,7 @@ fn Sha2_32(comptime params: Sha2Params32) type { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); d.total_len += b.len; } @@ -155,9 +155,9 @@ fn Sha2_32(comptime params: Sha2Params32) type { // Append message length. var i: usize = 1; var len = d.total_len >> 5; - d.buf[63] = u8(d.total_len & 0x1f) << 3; + d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3; while (i < 8) : (i += 1) { - d.buf[63 - i] = u8(len & 0xff); + d.buf[63 - i] = @intCast(u8, len & 0xff); len >>= 8; } @@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type { // Copy any remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); d.total_len += b.len; } @@ -496,9 +496,9 @@ fn Sha2_64(comptime params: Sha2Params64) type { // Append message length. var i: usize = 1; var len = d.total_len >> 5; - d.buf[127] = u8(d.total_len & 0x1f) << 3; + d.buf[127] = @intCast(u8, d.total_len & 0x1f) << 3; while (i < 16) : (i += 1) { - d.buf[127 - i] = u8(len & 0xff); + d.buf[127 - i] = @intCast(u8, len & 0xff); len >>= 8; } diff --git a/std/debug/index.zig b/std/debug/index.zig index fb1dac537c..198e0f90f6 100644 --- a/std/debug/index.zig +++ b/std/debug/index.zig @@ -554,7 +554,7 @@ const LineNumberProgram = struct { const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name); errdefer self.file_entries.allocator.free(file_name); return LineInfo{ - .line = if (self.prev_line >= 0) usize(self.prev_line) else 0, + .line = if (self.prev_line >= 0) @intCast(usize, self.prev_line) else 0, .column = self.prev_column, .file_name = file_name, .allocator = self.file_entries.allocator, @@ -1070,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 { var operand: u64 = undefined; - if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; + if (@shlWithOverflow(u64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo; result |= operand; @@ -1089,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 { var operand: i64 = undefined; - if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo; + if (@shlWithOverflow(i64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo; result |= operand; shift += 7; if ((byte & 0b10000000) == 0) { - if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift)); + if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << @intCast(u6, shift)); return result; } } diff --git a/std/fmt/errol/index.zig b/std/fmt/errol/index.zig index a906b714ab..a5fb692857 100644 --- a/std/fmt/errol/index.zig +++ b/std/fmt/errol/index.zig @@ -29,11 +29,11 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro switch (mode) { RoundMode.Decimal => { if (float_decimal.exp >= 0) { - round_digit = precision + usize(float_decimal.exp); + round_digit = precision + @intCast(usize, float_decimal.exp); } else { // if a small negative exp, then adjust we need to offset by the number // of leading zeros that will occur. - const min_exp_required = usize(-float_decimal.exp); + const min_exp_required = @intCast(usize, -float_decimal.exp); if (precision > min_exp_required) { round_digit = precision - min_exp_required; } @@ -107,16 +107,16 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { // normalize the midpoint const e = math.frexp(val).exponent; - var exp = i16(math.floor(307 + f64(e) * 0.30103)); + var exp = @floatToInt(i16, math.floor(307 + @intToFloat(f64, e) * 0.30103)); if (exp < 20) { exp = 20; - } else if (usize(exp) >= lookup_table.len) { - exp = i16(lookup_table.len - 1); + } else if (@intCast(usize, exp) >= lookup_table.len) { + exp = @intCast(i16, lookup_table.len - 1); } - var mid = lookup_table[usize(exp)]; + var mid = lookup_table[@intCast(usize, exp)]; mid = hpProd(mid, val); - const lten = lookup_table[usize(exp)].val; + const lten = lookup_table[@intCast(usize, exp)].val; exp -= 307; @@ -168,25 +168,25 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal { // the 0-index for this extra digit. var buf_index: usize = 1; while (true) { - var hdig = u8(math.floor(high.val)); - if ((high.val == f64(hdig)) and (high.off < 0)) hdig -= 1; + var hdig = @floatToInt(u8, math.floor(high.val)); + if ((high.val == @intToFloat(f64, hdig)) and (high.off < 0)) hdig -= 1; - var ldig = u8(math.floor(low.val)); - if ((low.val == f64(ldig)) and (low.off < 0)) ldig -= 1; + var ldig = @floatToInt(u8, math.floor(low.val)); + if ((low.val == @intToFloat(f64, ldig)) and (low.off < 0)) ldig -= 1; if (ldig != hdig) break; buffer[buf_index] = hdig + '0'; buf_index += 1; - high.val -= f64(hdig); - low.val -= f64(ldig); + high.val -= @intToFloat(f64, hdig); + low.val -= @intToFloat(f64, ldig); hpMul10(&high); hpMul10(&low); } const tmp = (high.val + low.val) / 2.0; - var mdig = u8(math.floor(tmp + 0.5)); - if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1; + var mdig = @floatToInt(u8, math.floor(tmp + 0.5)); + if ((@intToFloat(f64, mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1; buffer[buf_index] = mdig + '0'; buf_index += 1; @@ -304,7 +304,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { assert((val > 9.007199254740992e15) and val < (3.40282366920938e38)); - var mid = u128(val); + var mid = @floatToInt(u128, val); var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0); var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0); @@ -314,11 +314,11 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { low -= 1; } - var l64 = u64(low % pow19); - const lf = u64((low / pow19) % pow19); + var l64 = @intCast(u64, low % pow19); + const lf = @intCast(u64, (low / pow19) % pow19); - var h64 = u64(high % pow19); - const hf = u64((high / pow19) % pow19); + var h64 = @intCast(u64, high % pow19); + const hf = @intCast(u64, (high / pow19) % pow19); if (lf != hf) { l64 = lf; @@ -348,7 +348,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { return FloatDecimal{ .digits = buffer[0..buf_index], - .exp = i32(buf_index) + mi, + .exp = @intCast(i32, buf_index) + mi, }; } @@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal { fn errolFixed(val: f64, buffer: []u8) FloatDecimal { assert((val >= 16.0) and (val < 9.007199254740992e15)); - const u = u64(val); - const n = f64(u); + const u = @floatToInt(u64, val); + const n = @intToFloat(f64, u); var mid = val - n; var lo = ((fpprev(val) - n) + mid) / 2.0; var hi = ((fpnext(val) - n) + mid) / 2.0; var buf_index = u64toa(u, buffer); - var exp = i32(buf_index); + var exp = @intCast(i32, buf_index); var j = buf_index; buffer[j] = 0; if (mid != 0.0) { while (mid != 0.0) { lo *= 10.0; - const ldig = i32(lo); - lo -= f64(ldig); + const ldig = @floatToInt(i32, lo); + lo -= @intToFloat(f64, ldig); mid *= 10.0; - const mdig = i32(mid); - mid -= f64(mdig); + const mdig = @floatToInt(i32, mid); + mid -= @intToFloat(f64, mdig); hi *= 10.0; - const hdig = i32(hi); - hi -= f64(hdig); + const hdig = @floatToInt(i32, hi); + hi -= @intToFloat(f64, hdig); - buffer[j] = u8(mdig + '0'); + buffer[j] = @intCast(u8, mdig + '0'); j += 1; if (hdig != ldig or j > 50) break; @@ -452,7 +452,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { var buf_index: usize = 0; if (value < kTen8) { - const v = u32(value); + const v = @intCast(u32, value); if (v < 10000) { const d1: u32 = (v / 100) << 1; const d2: u32 = (v % 100) << 1; @@ -507,8 +507,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { buf_index += 1; } } else if (value < kTen16) { - const v0: u32 = u32(value / kTen8); - const v1: u32 = u32(value % kTen8); + const v0: u32 = @intCast(u32, value / kTen8); + const v1: u32 = @intCast(u32, value % kTen8); const b0: u32 = v0 / 10000; const c0: u32 = v0 % 10000; @@ -578,11 +578,11 @@ fn u64toa(value_param: u64, buffer: []u8) usize { buffer[buf_index] = c_digits_lut[d8 + 1]; buf_index += 1; } else { - const a = u32(value / kTen16); // 1 to 1844 + const a = @intCast(u32, value / kTen16); // 1 to 1844 value %= kTen16; if (a < 10) { - buffer[buf_index] = '0' + u8(a); + buffer[buf_index] = '0' + @intCast(u8, a); buf_index += 1; } else if (a < 100) { const i: u32 = a << 1; @@ -591,7 +591,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize { buffer[buf_index] = c_digits_lut[i + 1]; buf_index += 1; } else if (a < 1000) { - buffer[buf_index] = '0' + u8(a / 100); + buffer[buf_index] = '0' + @intCast(u8, a / 100); buf_index += 1; const i: u32 = (a % 100) << 1; @@ -612,8 +612,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize { buf_index += 1; } - const v0 = u32(value / kTen8); - const v1 = u32(value % kTen8); + const v0 = @intCast(u32, value / kTen8); + const v1 = @intCast(u32, value % kTen8); const b0: u32 = v0 / 10000; const c0: u32 = v0 % 10000; diff --git a/std/fmt/index.zig b/std/fmt/index.zig index 90d3a559c4..f4dfa0e324 100644 --- a/std/fmt/index.zig +++ b/std/fmt/index.zig @@ -5,6 +5,7 @@ const assert = debug.assert; const mem = std.mem; const builtin = @import("builtin"); const errol = @import("errol/index.zig"); +const lossyCast = std.math.lossyCast; const max_int_digits = 65; @@ -463,7 +464,7 @@ pub fn formatFloatDecimal( errol.roundToPrecision(&float_decimal, precision, errol.RoundMode.Decimal); // exp < 0 means the leading is always 0 as errol result is normalized. - var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0; + var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0; // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); @@ -492,7 +493,7 @@ pub fn formatFloatDecimal( // Zero-fill until we reach significant digits or run out of precision. if (float_decimal.exp <= 0) { - const zero_digit_count = usize(-float_decimal.exp); + const zero_digit_count = @intCast(usize, -float_decimal.exp); const zeros_to_print = math.min(zero_digit_count, precision); var i: usize = 0; @@ -521,7 +522,7 @@ pub fn formatFloatDecimal( } } else { // exp < 0 means the leading is always 0 as errol result is normalized. - var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0; + var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0; // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this. var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len); @@ -547,7 +548,7 @@ pub fn formatFloatDecimal( // Zero-fill until we reach significant digits or run out of precision. if (float_decimal.exp < 0) { - const zero_digit_count = usize(-float_decimal.exp); + const zero_digit_count = @intCast(usize, -float_decimal.exp); var i: usize = 0; while (i < zero_digit_count) : (i += 1) { @@ -578,7 +579,7 @@ pub fn formatBytes( 1024 => math.min(math.log2(value) / 10, mags_iec.len - 1), else => unreachable, }; - const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude)); + const new_value = lossyCast(f64, value) / math.pow(f64, lossyCast(f64, radix), lossyCast(f64, magnitude)); const suffix = switch (radix) { 1000 => mags_si[magnitude], 1024 => mags_iec[magnitude], @@ -628,15 +629,15 @@ fn formatIntSigned( if (value < 0) { const minus_sign: u8 = '-'; try output(context, (*[1]u8)(&minus_sign)[0..]); - const new_value = uint(-(value + 1)) + 1; + const new_value = @intCast(uint, -(value + 1)) + 1; const new_width = if (width == 0) 0 else (width - 1); return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); } else if (width == 0) { - return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output); + return formatIntUnsigned(@intCast(uint, value), base, uppercase, width, context, Errors, output); } else { const plus_sign: u8 = '+'; try output(context, (*[1]u8)(&plus_sign)[0..]); - const new_value = uint(value); + const new_value = @intCast(uint, value); const new_width = if (width == 0) 0 else (width - 1); return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output); } @@ -660,7 +661,7 @@ fn formatIntUnsigned( while (true) { const digit = a % base; index -= 1; - buf[index] = digitToChar(u8(digit), uppercase); + buf[index] = digitToChar(@intCast(u8, digit), uppercase); a /= base; if (a == 0) break; } diff --git a/std/hash/crc.zig b/std/hash/crc.zig index ec831cdc2e..c455140785 100644 --- a/std/hash/crc.zig +++ b/std/hash/crc.zig @@ -26,7 +26,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type { var tables: [8][256]u32 = undefined; for (tables[0]) |*e, i| { - var crc = u32(i); + var crc = @intCast(u32, i); var j: usize = 0; while (j < 8) : (j += 1) { if (crc & 1 == 1) { @@ -122,7 +122,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type { var table: [16]u32 = undefined; for (table) |*e, i| { - var crc = u32(i * 16); + var crc = @intCast(u32, i * 16); var j: usize = 0; while (j < 8) : (j += 1) { if (crc & 1 == 1) { diff --git a/std/hash/siphash.zig b/std/hash/siphash.zig index 8a90308a46..cdad77e59e 100644 --- a/std/hash/siphash.zig +++ b/std/hash/siphash.zig @@ -81,7 +81,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize) // Remainder for next pass. mem.copy(u8, d.buf[d.buf_len..], b[off..]); - d.buf_len += u8(b[off..].len); + d.buf_len += @intCast(u8, b[off..].len); d.msg_len +%= @truncate(u8, b.len); } @@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" { var buffer: [64]u8 = undefined; for (vectors) |vector, i| { - buffer[i] = u8(i); + buffer[i] = @intCast(u8, i); const expected = mem.readInt(vector, u64, Endian.Little); debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); @@ -312,7 +312,7 @@ test "siphash128-2-4 sanity" { var buffer: [64]u8 = undefined; for (vectors) |vector, i| { - buffer[i] = u8(i); + buffer[i] = @intCast(u8, i); const expected = mem.readInt(vector, u128, Endian.Little); debug.assert(siphash.hash(test_key, buffer[0..i]) == expected); diff --git a/std/heap.zig b/std/heap.zig index 172bc24118..2a2c8c0b59 100644 --- a/std/heap.zig +++ b/std/heap.zig @@ -408,7 +408,7 @@ fn testAllocator(allocator: *mem.Allocator) !void { for (slice) |*item, i| { item.* = try allocator.create(i32); - item.*.* = i32(i); + item.*.* = @intCast(i32, i); } for (slice) |item, i| { diff --git a/std/json.zig b/std/json.zig index 8bbee981e3..2930cd21bb 100644 --- a/std/json.zig +++ b/std/json.zig @@ -180,7 +180,7 @@ pub const StreamingParser = struct { pub fn fromInt(x: var) State { debug.assert(x == 0 or x == 1); const T = @TagType(State); - return State(T(x)); + return State(@intCast(T, x)); } }; diff --git a/std/math/acos.zig b/std/math/acos.zig index 284f73fc91..54844e8f6e 100644 --- a/std/math/acos.zig +++ b/std/math/acos.zig @@ -95,12 +95,12 @@ fn acos64(x: f64) f64 { const pio2_lo: f64 = 6.12323399573676603587e-17; const ux = @bitCast(u64, x); - const hx = u32(ux >> 32); + const hx = @intCast(u32, ux >> 32); const ix = hx & 0x7FFFFFFF; // |x| >= 1 or nan if (ix >= 0x3FF00000) { - const lx = u32(ux & 0xFFFFFFFF); + const lx = @intCast(u32, ux & 0xFFFFFFFF); // acos(1) = 0, acos(-1) = pi if ((ix - 0x3FF00000) | lx == 0) { diff --git a/std/math/asin.zig b/std/math/asin.zig index 2ee3aa6048..30b3a57e32 100644 --- a/std/math/asin.zig +++ b/std/math/asin.zig @@ -87,12 +87,12 @@ fn asin64(x: f64) f64 { const pio2_lo: f64 = 6.12323399573676603587e-17; const ux = @bitCast(u64, x); - const hx = u32(ux >> 32); + const hx = @intCast(u32, ux >> 32); const ix = hx & 0x7FFFFFFF; // |x| >= 1 or nan if (ix >= 0x3FF00000) { - const lx = u32(ux & 0xFFFFFFFF); + const lx = @intCast(u32, ux & 0xFFFFFFFF); // asin(1) = +-pi/2 with inexact if ((ix - 0x3FF00000) | lx == 0) { diff --git a/std/math/atan.zig b/std/math/atan.zig index 7eceef98e3..6ca94dd84a 100644 --- a/std/math/atan.zig +++ b/std/math/atan.zig @@ -138,7 +138,7 @@ fn atan64(x_: f64) f64 { var x = x_; var ux = @bitCast(u64, x); - var ix = u32(ux >> 32); + var ix = @intCast(u32, ux >> 32); const sign = ix >> 31; ix &= 0x7FFFFFFF; @@ -159,7 +159,7 @@ fn atan64(x_: f64) f64 { // |x| < 2^(-27) if (ix < 0x3E400000) { if (ix < 0x00100000) { - math.forceEval(f32(x)); + math.forceEval(@floatCast(f32, x)); } return x; } diff --git a/std/math/atan2.zig b/std/math/atan2.zig index f0a8e67c46..b3e45ba045 100644 --- a/std/math/atan2.zig +++ b/std/math/atan2.zig @@ -124,12 +124,12 @@ fn atan2_64(y: f64, x: f64) f64 { } var ux = @bitCast(u64, x); - var ix = u32(ux >> 32); - var lx = u32(ux & 0xFFFFFFFF); + var ix = @intCast(u32, ux >> 32); + var lx = @intCast(u32, ux & 0xFFFFFFFF); var uy = @bitCast(u64, y); - var iy = u32(uy >> 32); - var ly = u32(uy & 0xFFFFFFFF); + var iy = @intCast(u32, uy >> 32); + var ly = @intCast(u32, uy & 0xFFFFFFFF); // x = 1.0 if ((ix -% 0x3FF00000) | lx == 0) { diff --git a/std/math/atanh.zig b/std/math/atanh.zig index 8ca0cc85bc..4ae8a66bc0 100644 --- a/std/math/atanh.zig +++ b/std/math/atanh.zig @@ -62,7 +62,7 @@ fn atanh_64(x: f64) f64 { if (e < 0x3FF - 32) { // underflow if (e == 0) { - math.forceEval(f32(y)); + math.forceEval(@floatCast(f32, y)); } } // |x| < 0.5 diff --git a/std/math/big/int.zig b/std/math/big/int.zig index 5e15cfb895..21d9347c01 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -135,7 +135,7 @@ pub const Int = struct { self.positive = value >= 0; self.len = 0; - var w_value: UT = if (value < 0) UT(-value) else UT(value); + var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value); if (info.bits <= Limb.bit_count) { self.limbs[0] = Limb(w_value); @@ -198,7 +198,7 @@ pub const Int = struct { var r: UT = 0; if (@sizeOf(UT) <= @sizeOf(Limb)) { - r = UT(self.limbs[0]); + r = @intCast(UT, self.limbs[0]); } else { for (self.limbs[0..self.len]) |_, ri| { const limb = self.limbs[self.len - ri - 1]; @@ -210,7 +210,7 @@ pub const Int = struct { if (!T.is_signed) { return if (self.positive) r else error.NegativeIntoUnsigned; } else { - return if (self.positive) T(r) else -T(r); + return if (self.positive) @intCast(T, r) else -@intCast(T, r); } }, else => { @@ -295,7 +295,7 @@ pub const Int = struct { for (self.limbs[0..self.len]) |limb| { var shift: usize = 0; while (shift < Limb.bit_count) : (shift += base_shift) { - const r = u8((limb >> Log2Limb(shift)) & Limb(base - 1)); + const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1)); const ch = try digitToChar(r, base); try digits.append(ch); } @@ -329,7 +329,7 @@ pub const Int = struct { var r_word = r.limbs[0]; var i: usize = 0; while (i < digits_per_limb) : (i += 1) { - const ch = try digitToChar(u8(r_word % base), base); + const ch = try digitToChar(@intCast(u8, r_word % base), base); r_word /= base; try digits.append(ch); } @@ -340,7 +340,7 @@ pub const Int = struct { var r_word = q.limbs[0]; while (r_word != 0) { - const ch = try digitToChar(u8(r_word % base), base); + const ch = try digitToChar(@intCast(u8, r_word % base), base); r_word /= base; try digits.append(ch); } @@ -801,7 +801,7 @@ pub const Int = struct { q.limbs[i - t - 1] = @maxValue(Limb); } else { const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]); - const z = Limb(num / DoubleLimb(y.limbs[t])); + const z = @intCast(Limb, num / DoubleLimb(y.limbs[t])); q.limbs[i - t - 1] = if (z > @maxValue(Limb)) @maxValue(Limb) else Limb(z); } @@ -860,7 +860,7 @@ pub const Int = struct { debug.assert(r.len >= a.len + (shift / Limb.bit_count) + 1); const limb_shift = shift / Limb.bit_count + 1; - const interior_limb_shift = Log2Limb(shift % Limb.bit_count); + const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count); var carry: Limb = 0; var i: usize = 0; @@ -869,7 +869,7 @@ pub const Int = struct { const dst_i = src_i + limb_shift; const src_digit = a[src_i]; - r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift)); + r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); carry = (src_digit << interior_limb_shift); } @@ -898,7 +898,7 @@ pub const Int = struct { debug.assert(r.len >= a.len - (shift / Limb.bit_count)); const limb_shift = shift / Limb.bit_count; - const interior_limb_shift = Log2Limb(shift % Limb.bit_count); + const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count); var carry: Limb = 0; var i: usize = 0; @@ -908,7 +908,7 @@ pub const Int = struct { const src_digit = a[src_i]; r[dst_i] = carry | (src_digit >> interior_limb_shift); - carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift)); + carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift)); } } diff --git a/std/math/cbrt.zig b/std/math/cbrt.zig index cd3b71ca8a..c067c5155a 100644 --- a/std/math/cbrt.zig +++ b/std/math/cbrt.zig @@ -54,7 +54,7 @@ fn cbrt32(x: f32) f32 { r = t * t * t; t = t * (f64(x) + x + r) / (x + r + r); - return f32(t); + return @floatCast(f32, t); } fn cbrt64(x: f64) f64 { @@ -69,7 +69,7 @@ fn cbrt64(x: f64) f64 { const P4: f64 = 0.145996192886612446982; var u = @bitCast(u64, x); - var hx = u32(u >> 32) & 0x7FFFFFFF; + var hx = @intCast(u32, u >> 32) & 0x7FFFFFFF; // cbrt(nan, inf) = itself if (hx >= 0x7FF00000) { @@ -79,7 +79,7 @@ fn cbrt64(x: f64) f64 { // cbrt to ~5bits if (hx < 0x00100000) { u = @bitCast(u64, x * 0x1.0p54); - hx = u32(u >> 32) & 0x7FFFFFFF; + hx = @intCast(u32, u >> 32) & 0x7FFFFFFF; // cbrt(0) is itself if (hx == 0) { diff --git a/std/math/ceil.zig b/std/math/ceil.zig index a189bb66d2..1c429504e8 100644 --- a/std/math/ceil.zig +++ b/std/math/ceil.zig @@ -20,7 +20,7 @@ pub fn ceil(x: var) @typeOf(x) { fn ceil32(x: f32) f32 { var u = @bitCast(u32, x); - var e = i32((u >> 23) & 0xFF) - 0x7F; + var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; var m: u32 = undefined; // TODO: Shouldn't need this explicit check. @@ -31,7 +31,7 @@ fn ceil32(x: f32) f32 { if (e >= 23) { return x; } else if (e >= 0) { - m = u32(0x007FFFFF) >> u5(e); + m = u32(0x007FFFFF) >> @intCast(u5, e); if (u & m == 0) { return x; } diff --git a/std/math/complex/atan.zig b/std/math/complex/atan.zig index 9bfe5fe724..de60f2546d 100644 --- a/std/math/complex/atan.zig +++ b/std/math/complex/atan.zig @@ -4,7 +4,7 @@ const math = std.math; const cmath = math.complex; const Complex = cmath.Complex; -pub fn atan(z: var) Complex(@typeOf(z.re)) { +pub fn atan(z: var) @typeOf(z) { const T = @typeOf(z.re); return switch (T) { f32 => atan32(z), @@ -25,11 +25,11 @@ fn redupif32(x: f32) f32 { t -= 0.5; } - const u = f32(i32(t)); + const u = @intToFloat(f32, @floatToInt(i32, t)); return ((x - u * DP1) - u * DP2) - t * DP3; } -fn atan32(z: *const Complex(f32)) Complex(f32) { +fn atan32(z: Complex(f32)) Complex(f32) { const maxnum = 1.0e38; const x = z.re; @@ -74,11 +74,11 @@ fn redupif64(x: f64) f64 { t -= 0.5; } - const u = f64(i64(t)); + const u = @intToFloat(f64, @floatToInt(i64, t)); return ((x - u * DP1) - u * DP2) - t * DP3; } -fn atan64(z: *const Complex(f64)) Complex(f64) { +fn atan64(z: Complex(f64)) Complex(f64) { const maxnum = 1.0e308; const x = z.re; diff --git a/std/math/complex/cosh.zig b/std/math/complex/cosh.zig index c2f9a47b8d..a2e31631ea 100644 --- a/std/math/complex/cosh.zig +++ b/std/math/complex/cosh.zig @@ -83,12 +83,12 @@ fn cosh64(z: *const Complex(f64)) Complex(f64) { const y = z.im; const fx = @bitCast(u64, x); - const hx = u32(fx >> 32); + const hx = @intCast(u32, fx >> 32); const lx = @truncate(u32, fx); const ix = hx & 0x7fffffff; const fy = @bitCast(u64, y); - const hy = u32(fy >> 32); + const hy = @intCast(u32, fy >> 32); const ly = @truncate(u32, fy); const iy = hy & 0x7fffffff; diff --git a/std/math/complex/exp.zig b/std/math/complex/exp.zig index 44c354f246..48fb132d97 100644 --- a/std/math/complex/exp.zig +++ b/std/math/complex/exp.zig @@ -6,7 +6,7 @@ const Complex = cmath.Complex; const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; -pub fn exp(z: var) Complex(@typeOf(z.re)) { +pub fn exp(z: var) @typeOf(z) { const T = @typeOf(z.re); return switch (T) { @@ -16,7 +16,7 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) { }; } -fn exp32(z: *const Complex(f32)) Complex(f32) { +fn exp32(z: Complex(f32)) Complex(f32) { @setFloatMode(this, @import("builtin").FloatMode.Strict); const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.72283955 @@ -63,7 +63,7 @@ fn exp32(z: *const Complex(f32)) Complex(f32) { } } -fn exp64(z: *const Complex(f64)) Complex(f64) { +fn exp64(z: Complex(f64)) Complex(f64) { const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2 diff --git a/std/math/complex/ldexp.zig b/std/math/complex/ldexp.zig index a56c2ef2eb..e919ef6bec 100644 --- a/std/math/complex/ldexp.zig +++ b/std/math/complex/ldexp.zig @@ -4,7 +4,7 @@ const math = std.math; const cmath = math.complex; const Complex = cmath.Complex; -pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) { +pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) { const T = @typeOf(z.re); return switch (T) { @@ -20,11 +20,12 @@ fn frexp_exp32(x: f32, expt: *i32) f32 { const exp_x = math.exp(x - kln2); const hx = @bitCast(u32, exp_x); - expt.* = i32(hx >> 23) - (0x7f + 127) + k; + // TODO zig should allow this cast implicitly because it should know the value is in range + expt.* = @intCast(i32, hx >> 23) - (0x7f + 127) + k; return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23)); } -fn ldexp_cexp32(z: *const Complex(f32), expt: i32) Complex(f32) { +fn ldexp_cexp32(z: Complex(f32), expt: i32) Complex(f32) { var ex_expt: i32 = undefined; const exp_x = frexp_exp32(z.re, &ex_expt); const exptf = expt + ex_expt; @@ -45,16 +46,16 @@ fn frexp_exp64(x: f64, expt: *i32) f64 { const exp_x = math.exp(x - kln2); const fx = @bitCast(u64, x); - const hx = u32(fx >> 32); + const hx = @intCast(u32, fx >> 32); const lx = @truncate(u32, fx); - expt.* = i32(hx >> 20) - (0x3ff + 1023) + k; + expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k; const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20); return @bitCast(f64, (u64(high_word) << 32) | lx); } -fn ldexp_cexp64(z: *const Complex(f64), expt: i32) Complex(f64) { +fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) { var ex_expt: i32 = undefined; const exp_x = frexp_exp64(z.re, &ex_expt); const exptf = i64(expt + ex_expt); diff --git a/std/math/complex/sinh.zig b/std/math/complex/sinh.zig index 3d196bfd50..ab23c5c74d 100644 --- a/std/math/complex/sinh.zig +++ b/std/math/complex/sinh.zig @@ -6,7 +6,7 @@ const Complex = cmath.Complex; const ldexp_cexp = @import("ldexp.zig").ldexp_cexp; -pub fn sinh(z: var) Complex(@typeOf(z.re)) { +pub fn sinh(z: var) @typeOf(z) { const T = @typeOf(z.re); return switch (T) { f32 => sinh32(z), @@ -15,7 +15,7 @@ pub fn sinh(z: var) Complex(@typeOf(z.re)) { }; } -fn sinh32(z: *const Complex(f32)) Complex(f32) { +fn sinh32(z: Complex(f32)) Complex(f32) { const x = z.re; const y = z.im; @@ -78,17 +78,17 @@ fn sinh32(z: *const Complex(f32)) Complex(f32) { return Complex(f32).new((x * x) * (y - y), (x + x) * (y - y)); } -fn sinh64(z: *const Complex(f64)) Complex(f64) { +fn sinh64(z: Complex(f64)) Complex(f64) { const x = z.re; const y = z.im; const fx = @bitCast(u64, x); - const hx = u32(fx >> 32); + const hx = @intCast(u32, fx >> 32); const lx = @truncate(u32, fx); const ix = hx & 0x7fffffff; const fy = @bitCast(u64, y); - const hy = u32(fy >> 32); + const hy = @intCast(u32, fy >> 32); const ly = @truncate(u32, fy); const iy = hy & 0x7fffffff; diff --git a/std/math/complex/sqrt.zig b/std/math/complex/sqrt.zig index caa3bd2868..47367816f7 100644 --- a/std/math/complex/sqrt.zig +++ b/std/math/complex/sqrt.zig @@ -49,10 +49,16 @@ fn sqrt32(z: Complex(f32)) Complex(f32) { if (dx >= 0) { const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5); - return Complex(f32).new(f32(t), f32(dy / (2.0 * t))); + return Complex(f32).new( + @floatCast(f32, t), + @floatCast(f32, dy / (2.0 * t)), + ); } else { const t = math.sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5); - return Complex(f32).new(f32(math.fabs(y) / (2.0 * t)), f32(math.copysign(f64, t, y))); + return Complex(f32).new( + @floatCast(f32, math.fabs(y) / (2.0 * t)), + @floatCast(f32, math.copysign(f64, t, y)), + ); } } diff --git a/std/math/complex/tanh.zig b/std/math/complex/tanh.zig index 1d754838a3..e48d438783 100644 --- a/std/math/complex/tanh.zig +++ b/std/math/complex/tanh.zig @@ -4,7 +4,7 @@ const math = std.math; const cmath = math.complex; const Complex = cmath.Complex; -pub fn tanh(z: var) Complex(@typeOf(z.re)) { +pub fn tanh(z: var) @typeOf(z) { const T = @typeOf(z.re); return switch (T) { f32 => tanh32(z), @@ -13,7 +13,7 @@ pub fn tanh(z: var) Complex(@typeOf(z.re)) { }; } -fn tanh32(z: *const Complex(f32)) Complex(f32) { +fn tanh32(z: Complex(f32)) Complex(f32) { const x = z.re; const y = z.im; @@ -51,12 +51,14 @@ fn tanh32(z: *const Complex(f32)) Complex(f32) { return Complex(f32).new((beta * rho * s) / den, t / den); } -fn tanh64(z: *const Complex(f64)) Complex(f64) { +fn tanh64(z: Complex(f64)) Complex(f64) { const x = z.re; const y = z.im; const fx = @bitCast(u64, x); - const hx = u32(fx >> 32); + // TODO: zig should allow this conversion implicitly because it can notice that the value necessarily + // fits in range. + const hx = @intCast(u32, fx >> 32); const lx = @truncate(u32, fx); const ix = hx & 0x7fffffff; diff --git a/std/math/cos.zig b/std/math/cos.zig index 5e5ec4f1cb..71d5e4a8f6 100644 --- a/std/math/cos.zig +++ b/std/math/cos.zig @@ -55,7 +55,7 @@ fn cos32(x_: f32) f32 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; @@ -106,7 +106,7 @@ fn cos64(x_: f64) f64 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; diff --git a/std/math/cosh.zig b/std/math/cosh.zig index fa46219986..52beafb642 100644 --- a/std/math/cosh.zig +++ b/std/math/cosh.zig @@ -49,7 +49,7 @@ fn cosh32(x: f32) f32 { fn cosh64(x: f64) f64 { const u = @bitCast(u64, x); - const w = u32(u >> 32); + const w = @intCast(u32, u >> 32); const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); // TODO: Shouldn't need this explicit check. diff --git a/std/math/exp.zig b/std/math/exp.zig index 76dc47d04b..d6185d4f0b 100644 --- a/std/math/exp.zig +++ b/std/math/exp.zig @@ -29,7 +29,7 @@ fn exp32(x_: f32) f32 { var x = x_; var hx = @bitCast(u32, x); - const sign = i32(hx >> 31); + const sign = @intCast(i32, hx >> 31); hx &= 0x7FFFFFFF; if (math.isNan(x)) { @@ -63,12 +63,12 @@ fn exp32(x_: f32) f32 { if (hx > 0x3EB17218) { // |x| > 1.5 * ln2 if (hx > 0x3F851592) { - k = i32(invln2 * x + half[usize(sign)]); + k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]); } else { k = 1 - sign - sign; } - const fk = f32(k); + const fk = @intToFloat(f32, k); hi = x - fk * ln2hi; lo = fk * ln2lo; x = hi - lo; @@ -110,7 +110,7 @@ fn exp64(x_: f64) f64 { var x = x_; var ux = @bitCast(u64, x); var hx = ux >> 32; - const sign = i32(hx >> 31); + const sign = @intCast(i32, hx >> 31); hx &= 0x7FFFFFFF; if (math.isNan(x)) { @@ -148,12 +148,12 @@ fn exp64(x_: f64) f64 { if (hx > 0x3EB17218) { // |x| >= 1.5 * ln2 if (hx > 0x3FF0A2B2) { - k = i32(invln2 * x + half[usize(sign)]); + k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]); } else { k = 1 - sign - sign; } - const dk = f64(k); + const dk = @intToFloat(f64, k); hi = x - dk * ln2hi; lo = dk * ln2lo; x = hi - lo; diff --git a/std/math/exp2.zig b/std/math/exp2.zig index 62a3eb85b6..90ea088181 100644 --- a/std/math/exp2.zig +++ b/std/math/exp2.zig @@ -38,8 +38,8 @@ const exp2ft = []const f64{ fn exp2_32(x: f32) f32 { @setFloatMode(this, @import("builtin").FloatMode.Strict); - const tblsiz = u32(exp2ft.len); - const redux: f32 = 0x1.8p23 / f32(tblsiz); + const tblsiz = @intCast(u32, exp2ft.len); + const redux: f32 = 0x1.8p23 / @intToFloat(f32, tblsiz); const P1: f32 = 0x1.62e430p-1; const P2: f32 = 0x1.ebfbe0p-3; const P3: f32 = 0x1.c6b348p-5; @@ -89,7 +89,7 @@ fn exp2_32(x: f32) f32 { var r: f64 = exp2ft[i0]; const t: f64 = r * z; r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4); - return f32(r * uk); + return @floatCast(f32, r * uk); } const exp2dt = []f64{ @@ -355,8 +355,8 @@ const exp2dt = []f64{ fn exp2_64(x: f64) f64 { @setFloatMode(this, @import("builtin").FloatMode.Strict); - const tblsiz = u32(exp2dt.len / 2); - const redux: f64 = 0x1.8p52 / f64(tblsiz); + const tblsiz = @intCast(u32, exp2dt.len / 2); + const redux: f64 = 0x1.8p52 / @intToFloat(f64, tblsiz); const P1: f64 = 0x1.62e42fefa39efp-1; const P2: f64 = 0x1.ebfbdff82c575p-3; const P3: f64 = 0x1.c6b08d704a0a6p-5; @@ -364,7 +364,7 @@ fn exp2_64(x: f64) f64 { const P5: f64 = 0x1.5d88003875c74p-10; const ux = @bitCast(u64, x); - const ix = u32(ux >> 32) & 0x7FFFFFFF; + const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF; // TODO: This should be handled beneath. if (math.isNan(x)) { @@ -386,7 +386,7 @@ fn exp2_64(x: f64) f64 { if (ux >> 63 != 0) { // underflow if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) { - math.forceEval(f32(-0x1.0p-149 / x)); + math.forceEval(@floatCast(f32, -0x1.0p-149 / x)); } if (x <= -1075) { return 0; diff --git a/std/math/expm1.zig b/std/math/expm1.zig index 11af1b215f..438e44ccce 100644 --- a/std/math/expm1.zig +++ b/std/math/expm1.zig @@ -78,8 +78,8 @@ fn expm1_32(x_: f32) f32 { kf += 0.5; } - k = i32(kf); - const t = f32(k); + k = @floatToInt(i32, kf); + const t = @intToFloat(f32, k); hi = x - t * ln2_hi; lo = t * ln2_lo; } @@ -123,7 +123,7 @@ fn expm1_32(x_: f32) f32 { } } - const twopk = @bitCast(f32, u32((0x7F +% k) << 23)); + const twopk = @bitCast(f32, @intCast(u32, (0x7F +% k) << 23)); if (k < 0 or k > 56) { var y = x - e + 1.0; @@ -136,7 +136,7 @@ fn expm1_32(x_: f32) f32 { return y - 1.0; } - const uf = @bitCast(f32, u32(0x7F -% k) << 23); + const uf = @bitCast(f32, @intCast(u32, 0x7F -% k) << 23); if (k < 23) { return (x - e + (1 - uf)) * twopk; } else { @@ -158,7 +158,7 @@ fn expm1_64(x_: f64) f64 { var x = x_; const ux = @bitCast(u64, x); - const hx = u32(ux >> 32) & 0x7FFFFFFF; + const hx = @intCast(u32, ux >> 32) & 0x7FFFFFFF; const sign = ux >> 63; if (math.isNegativeInf(x)) { @@ -207,8 +207,8 @@ fn expm1_64(x_: f64) f64 { kf += 0.5; } - k = i32(kf); - const t = f64(k); + k = @floatToInt(i32, kf); + const t = @intToFloat(f64, k); hi = x - t * ln2_hi; lo = t * ln2_lo; } @@ -219,7 +219,7 @@ fn expm1_64(x_: f64) f64 { // |x| < 2^(-54) else if (hx < 0x3C900000) { if (hx < 0x00100000) { - math.forceEval(f32(x)); + math.forceEval(@floatCast(f32, x)); } return x; } else { @@ -252,7 +252,7 @@ fn expm1_64(x_: f64) f64 { } } - const twopk = @bitCast(f64, u64(0x3FF +% k) << 52); + const twopk = @bitCast(f64, @intCast(u64, 0x3FF +% k) << 52); if (k < 0 or k > 56) { var y = x - e + 1.0; @@ -265,7 +265,7 @@ fn expm1_64(x_: f64) f64 { return y - 1.0; } - const uf = @bitCast(f64, u64(0x3FF -% k) << 52); + const uf = @bitCast(f64, @intCast(u64, 0x3FF -% k) << 52); if (k < 20) { return (x - e + (1 - uf)) * twopk; } else { diff --git a/std/math/floor.zig b/std/math/floor.zig index 7d5364787f..79d1097d08 100644 --- a/std/math/floor.zig +++ b/std/math/floor.zig @@ -20,7 +20,7 @@ pub fn floor(x: var) @typeOf(x) { fn floor32(x: f32) f32 { var u = @bitCast(u32, x); - const e = i32((u >> 23) & 0xFF) - 0x7F; + const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; var m: u32 = undefined; // TODO: Shouldn't need this explicit check. @@ -33,7 +33,7 @@ fn floor32(x: f32) f32 { } if (e >= 0) { - m = u32(0x007FFFFF) >> u5(e); + m = u32(0x007FFFFF) >> @intCast(u5, e); if (u & m == 0) { return x; } diff --git a/std/math/fma.zig b/std/math/fma.zig index 3e9214f35b..21faf4118d 100644 --- a/std/math/fma.zig +++ b/std/math/fma.zig @@ -17,10 +17,10 @@ fn fma32(x: f32, y: f32, z: f32) f32 { const e = (u >> 52) & 0x7FF; if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) { - return f32(xy_z); + return @floatCast(f32, xy_z); } else { // TODO: Handle inexact case with double-rounding - return f32(xy_z); + return @floatCast(f32, xy_z); } } @@ -124,7 +124,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 { var sum = dd_add(a, b); if (sum.lo != 0) { var uhii = @bitCast(u64, sum.hi); - const bits_lost = -i32((uhii >> 52) & 0x7FF) - scale + 1; + const bits_lost = -@intCast(i32, (uhii >> 52) & 0x7FF) - scale + 1; if ((bits_lost != 1) == (uhii & 1 != 0)) { const uloi = @bitCast(u64, sum.lo); uhii += 1 - (((uhii ^ uloi) >> 62) & 2); diff --git a/std/math/frexp.zig b/std/math/frexp.zig index b58af0a9bc..dfc790fdd9 100644 --- a/std/math/frexp.zig +++ b/std/math/frexp.zig @@ -30,7 +30,7 @@ fn frexp32(x: f32) frexp32_result { var result: frexp32_result = undefined; var y = @bitCast(u32, x); - const e = i32(y >> 23) & 0xFF; + const e = @intCast(i32, y >> 23) & 0xFF; if (e == 0) { if (x != 0) { @@ -67,7 +67,7 @@ fn frexp64(x: f64) frexp64_result { var result: frexp64_result = undefined; var y = @bitCast(u64, x); - const e = i32(y >> 52) & 0x7FF; + const e = @intCast(i32, y >> 52) & 0x7FF; if (e == 0) { if (x != 0) { diff --git a/std/math/hypot.zig b/std/math/hypot.zig index 494df22ba6..f834f422e6 100644 --- a/std/math/hypot.zig +++ b/std/math/hypot.zig @@ -49,7 +49,7 @@ fn hypot32(x: f32, y: f32) f32 { yy *= 0x1.0p-90; } - return z * math.sqrt(f32(f64(x) * x + f64(y) * y)); + return z * math.sqrt(@floatCast(f32, f64(x) * x + f64(y) * y)); } fn sq(hi: *f64, lo: *f64, x: f64) void { diff --git a/std/math/ilogb.zig b/std/math/ilogb.zig index f1f33aff55..a24f580a32 100644 --- a/std/math/ilogb.zig +++ b/std/math/ilogb.zig @@ -23,7 +23,7 @@ const fp_ilogb0 = fp_ilogbnan; fn ilogb32(x: f32) i32 { var u = @bitCast(u32, x); - var e = i32((u >> 23) & 0xFF); + var e = @intCast(i32, (u >> 23) & 0xFF); // TODO: We should be able to merge this with the lower check. if (math.isNan(x)) { @@ -59,7 +59,7 @@ fn ilogb32(x: f32) i32 { fn ilogb64(x: f64) i32 { var u = @bitCast(u64, x); - var e = i32((u >> 52) & 0x7FF); + var e = @intCast(i32, (u >> 52) & 0x7FF); if (math.isNan(x)) { return @maxValue(i32); diff --git a/std/math/index.zig b/std/math/index.zig index 99e5b4ecf1..176293be74 100644 --- a/std/math/index.zig +++ b/std/math/index.zig @@ -227,7 +227,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T { /// A negative shift amount results in a right shift. pub fn shl(comptime T: type, a: T, shift_amt: var) T { const abs_shift_amt = absCast(shift_amt); - const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt); + const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt); if (@typeOf(shift_amt).is_signed) { if (shift_amt >= 0) { @@ -251,7 +251,7 @@ test "math.shl" { /// A negative shift amount results in a lefft shift. pub fn shr(comptime T: type, a: T, shift_amt: var) T { const abs_shift_amt = absCast(shift_amt); - const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt); + const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt); if (@typeOf(shift_amt).is_signed) { if (shift_amt >= 0) { @@ -473,9 +473,9 @@ fn testRem() void { /// Result is an unsigned integer. pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) { const uint = @IntType(false, @typeOf(x).bit_count); - if (x >= 0) return uint(x); + if (x >= 0) return @intCast(uint, x); - return uint(-(x + 1)) + 1; + return @intCast(uint, -(x + 1)) + 1; } test "math.absCast" { @@ -499,7 +499,7 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) { if (x == -@minValue(int)) return @minValue(int); - return -int(x); + return -@intCast(int, x); } test "math.negateCast" { @@ -522,7 +522,7 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) { } else if (@minValue(@typeOf(x)) < @minValue(T) and x < @minValue(T)) { return error.Overflow; } else { - return T(x); + return @intCast(T, x); } } @@ -565,7 +565,7 @@ test "math.floorPowerOfTwo" { pub fn log2_int(comptime T: type, x: T) Log2Int(T) { assert(x != 0); - return Log2Int(T)(T.bit_count - 1 - @clz(x)); + return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x)); } pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { @@ -597,3 +597,14 @@ fn testFloorPowerOfTwo() void { assert(floorPowerOfTwo(u4, 8) == 8); assert(floorPowerOfTwo(u4, 9) == 8); } + +pub fn lossyCast(comptime T: type, value: var) T { + switch (@typeInfo(@typeOf(value))) { + builtin.TypeId.Int => return @intToFloat(T, value), + builtin.TypeId.Float => return @floatCast(T, value), + builtin.TypeId.ComptimeInt => return T(value), + builtin.TypeId.ComptimeFloat => return T(value), + else => @compileError("bad type"), + } +} + diff --git a/std/math/ln.zig b/std/math/ln.zig index 3fd75977b9..e78cc379e0 100644 --- a/std/math/ln.zig +++ b/std/math/ln.zig @@ -71,7 +71,7 @@ pub fn ln_32(x_: f32) f32 { // x into [sqrt(2) / 2, sqrt(2)] ix += 0x3F800000 - 0x3F3504F3; - k += i32(ix >> 23) - 0x7F; + k += @intCast(i32, ix >> 23) - 0x7F; ix = (ix & 0x007FFFFF) + 0x3F3504F3; x = @bitCast(f32, ix); @@ -83,7 +83,7 @@ pub fn ln_32(x_: f32) f32 { const t2 = z * (Lg1 + w * Lg3); const R = t2 + t1; const hfsq = 0.5 * f * f; - const dk = f32(k); + const dk = @intToFloat(f32, k); return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; } @@ -103,7 +103,7 @@ pub fn ln_64(x_: f64) f64 { var x = x_; var ix = @bitCast(u64, x); - var hx = u32(ix >> 32); + var hx = @intCast(u32, ix >> 32); var k: i32 = 0; if (hx < 0x00100000 or hx >> 31 != 0) { @@ -119,7 +119,7 @@ pub fn ln_64(x_: f64) f64 { // subnormal, scale x k -= 54; x *= 0x1.0p54; - hx = u32(@bitCast(u64, ix) >> 32); + hx = @intCast(u32, @bitCast(u64, ix) >> 32); } else if (hx >= 0x7FF00000) { return x; } else if (hx == 0x3FF00000 and ix << 32 == 0) { @@ -128,7 +128,7 @@ pub fn ln_64(x_: f64) f64 { // x into [sqrt(2) / 2, sqrt(2)] hx += 0x3FF00000 - 0x3FE6A09E; - k += i32(hx >> 20) - 0x3FF; + k += @intCast(i32, hx >> 20) - 0x3FF; hx = (hx & 0x000FFFFF) + 0x3FE6A09E; ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); x = @bitCast(f64, ix); @@ -141,7 +141,7 @@ pub fn ln_64(x_: f64) f64 { const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); const R = t2 + t1; - const dk = f64(k); + const dk = @intToFloat(f64, k); return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi; } diff --git a/std/math/log.zig b/std/math/log.zig index 2c876081d8..20b6d055e8 100644 --- a/std/math/log.zig +++ b/std/math/log.zig @@ -13,22 +13,23 @@ pub fn log(comptime T: type, base: T, x: T) T { return math.ln(x); } + const float_base = math.lossyCast(f64, base); switch (@typeId(T)) { TypeId.ComptimeFloat => { - return @typeOf(1.0)(math.ln(f64(x)) / math.ln(f64(base))); + return @typeOf(1.0)(math.ln(f64(x)) / math.ln(float_base)); }, TypeId.ComptimeInt => { - return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(f64(base)))); + return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(float_base))); }, builtin.TypeId.Int => { // TODO implement integer log without using float math - return T(math.floor(math.ln(f64(x)) / math.ln(f64(base)))); + return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base))); }, builtin.TypeId.Float => { switch (T) { - f32 => return f32(math.ln(f64(x)) / math.ln(f64(base))), - f64 => return math.ln(x) / math.ln(f64(base)), + f32 => return @floatCast(f32, math.ln(f64(x)) / math.ln(float_base)), + f64 => return math.ln(x) / math.ln(float_base), else => @compileError("log not implemented for " ++ @typeName(T)), } }, diff --git a/std/math/log10.zig b/std/math/log10.zig index c444add9ac..a93ce48fb7 100644 --- a/std/math/log10.zig +++ b/std/math/log10.zig @@ -28,7 +28,7 @@ pub fn log10(x: var) @typeOf(x) { return @typeOf(1)(math.floor(log10_64(f64(x)))); }, TypeId.Int => { - return T(math.floor(log10_64(f64(x)))); + return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x)))); }, else => @compileError("log10 not implemented for " ++ @typeName(T)), } @@ -71,7 +71,7 @@ pub fn log10_32(x_: f32) f32 { // x into [sqrt(2) / 2, sqrt(2)] ix += 0x3F800000 - 0x3F3504F3; - k += i32(ix >> 23) - 0x7F; + k += @intCast(i32, ix >> 23) - 0x7F; ix = (ix & 0x007FFFFF) + 0x3F3504F3; x = @bitCast(f32, ix); @@ -89,7 +89,7 @@ pub fn log10_32(x_: f32) f32 { u &= 0xFFFFF000; hi = @bitCast(f32, u); const lo = f - hi - hfsq + s * (hfsq + R); - const dk = f32(k); + const dk = @intToFloat(f32, k); return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi; } @@ -109,7 +109,7 @@ pub fn log10_64(x_: f64) f64 { var x = x_; var ix = @bitCast(u64, x); - var hx = u32(ix >> 32); + var hx = @intCast(u32, ix >> 32); var k: i32 = 0; if (hx < 0x00100000 or hx >> 31 != 0) { @@ -125,7 +125,7 @@ pub fn log10_64(x_: f64) f64 { // subnormal, scale x k -= 54; x *= 0x1.0p54; - hx = u32(@bitCast(u64, x) >> 32); + hx = @intCast(u32, @bitCast(u64, x) >> 32); } else if (hx >= 0x7FF00000) { return x; } else if (hx == 0x3FF00000 and ix << 32 == 0) { @@ -134,7 +134,7 @@ pub fn log10_64(x_: f64) f64 { // x into [sqrt(2) / 2, sqrt(2)] hx += 0x3FF00000 - 0x3FE6A09E; - k += i32(hx >> 20) - 0x3FF; + k += @intCast(i32, hx >> 20) - 0x3FF; hx = (hx & 0x000FFFFF) + 0x3FE6A09E; ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); x = @bitCast(f64, ix); @@ -157,7 +157,7 @@ pub fn log10_64(x_: f64) f64 { // val_hi + val_lo ~ log10(1 + f) + k * log10(2) var val_hi = hi * ivln10hi; - const dk = f64(k); + const dk = @intToFloat(f64, k); const y = dk * log10_2hi; var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi; diff --git a/std/math/log1p.zig b/std/math/log1p.zig index 57efdaf51c..7d3be6bb49 100644 --- a/std/math/log1p.zig +++ b/std/math/log1p.zig @@ -68,7 +68,7 @@ fn log1p_32(x: f32) f32 { const uf = 1 + x; var iu = @bitCast(u32, uf); iu += 0x3F800000 - 0x3F3504F3; - k = i32(iu >> 23) - 0x7F; + k = @intCast(i32, iu >> 23) - 0x7F; // correction to avoid underflow in c / u if (k < 25) { @@ -90,7 +90,7 @@ fn log1p_32(x: f32) f32 { const t2 = z * (Lg1 + w * Lg3); const R = t2 + t1; const hfsq = 0.5 * f * f; - const dk = f32(k); + const dk = @intToFloat(f32, k); return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; } @@ -107,7 +107,7 @@ fn log1p_64(x: f64) f64 { const Lg7: f64 = 1.479819860511658591e-01; var ix = @bitCast(u64, x); - var hx = u32(ix >> 32); + var hx = @intCast(u32, ix >> 32); var k: i32 = 1; var c: f64 = undefined; var f: f64 = undefined; @@ -145,9 +145,9 @@ fn log1p_64(x: f64) f64 { if (k != 0) { const uf = 1 + x; const hu = @bitCast(u64, uf); - var iu = u32(hu >> 32); + var iu = @intCast(u32, hu >> 32); iu += 0x3FF00000 - 0x3FE6A09E; - k = i32(iu >> 20) - 0x3FF; + k = @intCast(i32, iu >> 20) - 0x3FF; // correction to avoid underflow in c / u if (k < 54) { @@ -170,7 +170,7 @@ fn log1p_64(x: f64) f64 { const t1 = w * (Lg2 + w * (Lg4 + w * Lg6)); const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7))); const R = t2 + t1; - const dk = f64(k); + const dk = @intToFloat(f64, k); return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi; } diff --git a/std/math/log2.zig b/std/math/log2.zig index 2530519941..858f6ffa02 100644 --- a/std/math/log2.zig +++ b/std/math/log2.zig @@ -75,7 +75,7 @@ pub fn log2_32(x_: f32) f32 { // x into [sqrt(2) / 2, sqrt(2)] ix += 0x3F800000 - 0x3F3504F3; - k += i32(ix >> 23) - 0x7F; + k += @intCast(i32, ix >> 23) - 0x7F; ix = (ix & 0x007FFFFF) + 0x3F3504F3; x = @bitCast(f32, ix); @@ -93,7 +93,7 @@ pub fn log2_32(x_: f32) f32 { u &= 0xFFFFF000; hi = @bitCast(f32, u); const lo = f - hi - hfsq + s * (hfsq + R); - return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k); + return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @intToFloat(f32, k); } pub fn log2_64(x_: f64) f64 { @@ -109,7 +109,7 @@ pub fn log2_64(x_: f64) f64 { var x = x_; var ix = @bitCast(u64, x); - var hx = u32(ix >> 32); + var hx = @intCast(u32, ix >> 32); var k: i32 = 0; if (hx < 0x00100000 or hx >> 31 != 0) { @@ -125,7 +125,7 @@ pub fn log2_64(x_: f64) f64 { // subnormal, scale x k -= 54; x *= 0x1.0p54; - hx = u32(@bitCast(u64, x) >> 32); + hx = @intCast(u32, @bitCast(u64, x) >> 32); } else if (hx >= 0x7FF00000) { return x; } else if (hx == 0x3FF00000 and ix << 32 == 0) { @@ -134,7 +134,7 @@ pub fn log2_64(x_: f64) f64 { // x into [sqrt(2) / 2, sqrt(2)] hx += 0x3FF00000 - 0x3FE6A09E; - k += i32(hx >> 20) - 0x3FF; + k += @intCast(i32, hx >> 20) - 0x3FF; hx = (hx & 0x000FFFFF) + 0x3FE6A09E; ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF); x = @bitCast(f64, ix); @@ -159,7 +159,7 @@ pub fn log2_64(x_: f64) f64 { var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi; // spadd(val_hi, val_lo, y) - const y = f64(k); + const y = @intToFloat(f64, k); const ww = y + val_hi; val_lo += (y - ww) + val_hi; val_hi = ww; diff --git a/std/math/modf.zig b/std/math/modf.zig index a6606ce34c..b6dd78f022 100644 --- a/std/math/modf.zig +++ b/std/math/modf.zig @@ -29,7 +29,7 @@ fn modf32(x: f32) modf32_result { var result: modf32_result = undefined; const u = @bitCast(u32, x); - const e = i32((u >> 23) & 0xFF) - 0x7F; + const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F; const us = u & 0x80000000; // TODO: Shouldn't need this. @@ -57,7 +57,7 @@ fn modf32(x: f32) modf32_result { return result; } - const mask = u32(0x007FFFFF) >> u5(e); + const mask = u32(0x007FFFFF) >> @intCast(u5, e); if (u & mask == 0) { result.ipart = x; result.fpart = @bitCast(f32, us); @@ -74,7 +74,7 @@ fn modf64(x: f64) modf64_result { var result: modf64_result = undefined; const u = @bitCast(u64, x); - const e = i32((u >> 52) & 0x7FF) - 0x3FF; + const e = @intCast(i32, (u >> 52) & 0x7FF) - 0x3FF; const us = u & (1 << 63); if (math.isInf(x)) { @@ -101,7 +101,7 @@ fn modf64(x: f64) modf64_result { return result; } - const mask = u64(@maxValue(u64) >> 12) >> u6(e); + const mask = u64(@maxValue(u64) >> 12) >> @intCast(u6, e); if (u & mask == 0) { result.ipart = x; result.fpart = @bitCast(f64, us); diff --git a/std/math/pow.zig b/std/math/pow.zig index dfe4fc09d6..7fc334c06b 100644 --- a/std/math/pow.zig +++ b/std/math/pow.zig @@ -146,7 +146,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { var xe = r2.exponent; var x1 = r2.significand; - var i = i32(yi); + var i = @floatToInt(i32, yi); while (i != 0) : (i >>= 1) { if (i & 1 == 1) { a1 *= x1; @@ -171,7 +171,7 @@ pub fn pow(comptime T: type, x: T, y: T) T { fn isOddInteger(x: f64) bool { const r = math.modf(x); - return r.fpart == 0.0 and i64(r.ipart) & 1 == 1; + return r.fpart == 0.0 and @floatToInt(i64, r.ipart) & 1 == 1; } test "math.pow" { diff --git a/std/math/scalbn.zig b/std/math/scalbn.zig index deb5d989d2..f72c7e866f 100644 --- a/std/math/scalbn.zig +++ b/std/math/scalbn.zig @@ -37,7 +37,7 @@ fn scalbn32(x: f32, n_: i32) f32 { } } - const u = u32(n +% 0x7F) << 23; + const u = @intCast(u32, n +% 0x7F) << 23; return y * @bitCast(f32, u); } @@ -67,7 +67,7 @@ fn scalbn64(x: f64, n_: i32) f64 { } } - const u = u64(n +% 0x3FF) << 52; + const u = @intCast(u64, n +% 0x3FF) << 52; return y * @bitCast(f64, u); } diff --git a/std/math/sin.zig b/std/math/sin.zig index 21c324e444..3796d74812 100644 --- a/std/math/sin.zig +++ b/std/math/sin.zig @@ -60,7 +60,7 @@ fn sin32(x_: f32) f32 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; @@ -112,7 +112,7 @@ fn sin64(x_: f64) f64 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; diff --git a/std/math/sinh.zig b/std/math/sinh.zig index 85c9ae979b..bb3af280ab 100644 --- a/std/math/sinh.zig +++ b/std/math/sinh.zig @@ -57,7 +57,7 @@ fn sinh64(x: f64) f64 { @setFloatMode(this, @import("builtin").FloatMode.Strict); const u = @bitCast(u64, x); - const w = u32(u >> 32); + const w = @intCast(u32, u >> 32); const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); if (x == 0.0 or math.isNan(x)) { diff --git a/std/math/sqrt.zig b/std/math/sqrt.zig index 7a3ddb3b96..599008acff 100644 --- a/std/math/sqrt.zig +++ b/std/math/sqrt.zig @@ -99,7 +99,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) { } const ResultType = @IntType(false, T.bit_count / 2); - return ResultType(res); + return @intCast(ResultType, res); } test "math.sqrt_int" { diff --git a/std/math/tan.zig b/std/math/tan.zig index f578cf8156..ff3ed06186 100644 --- a/std/math/tan.zig +++ b/std/math/tan.zig @@ -53,7 +53,7 @@ fn tan32(x_: f32) f32 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; @@ -102,7 +102,7 @@ fn tan64(x_: f64) f64 { } var y = math.floor(x * m4pi); - var j = i64(y); + var j = @floatToInt(i64, y); if (j & 1 == 1) { j += 1; diff --git a/std/math/tanh.zig b/std/math/tanh.zig index c1f5a0ca46..6204b2a374 100644 --- a/std/math/tanh.zig +++ b/std/math/tanh.zig @@ -68,7 +68,7 @@ fn tanh32(x: f32) f32 { fn tanh64(x: f64) f64 { const u = @bitCast(u64, x); - const w = u32(u >> 32); + const w = @intCast(u32, u >> 32); const ax = @bitCast(f64, u & (@maxValue(u64) >> 1)); var t: f64 = undefined; @@ -100,7 +100,7 @@ fn tanh64(x: f64) f64 { } // |x| is subnormal else { - math.forceEval(f32(x)); + math.forceEval(@floatCast(f32, x)); t = x; } diff --git a/std/math/trunc.zig b/std/math/trunc.zig index 54aa6943f7..92d5bfebc5 100644 --- a/std/math/trunc.zig +++ b/std/math/trunc.zig @@ -19,7 +19,7 @@ pub fn trunc(x: var) @typeOf(x) { fn trunc32(x: f32) f32 { const u = @bitCast(u32, x); - var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9; + var e = @intCast(i32, ((u >> 23) & 0xFF)) - 0x7F + 9; var m: u32 = undefined; if (e >= 23 + 9) { @@ -29,7 +29,7 @@ fn trunc32(x: f32) f32 { e = 1; } - m = u32(@maxValue(u32)) >> u5(e); + m = u32(@maxValue(u32)) >> @intCast(u5, e); if (u & m == 0) { return x; } else { @@ -40,7 +40,7 @@ fn trunc32(x: f32) f32 { fn trunc64(x: f64) f64 { const u = @bitCast(u64, x); - var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12; + var e = @intCast(i32, ((u >> 52) & 0x7FF)) - 0x3FF + 12; var m: u64 = undefined; if (e >= 52 + 12) { @@ -50,7 +50,7 @@ fn trunc64(x: f64) f64 { e = 1; } - m = u64(@maxValue(u64)) >> u6(e); + m = u64(@maxValue(u64)) >> @intCast(u6, e); if (u & m == 0) { return x; } else { diff --git a/std/mem.zig b/std/mem.zig index 10b3eb8fef..b02589b0dd 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -334,7 +334,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T { builtin.Endian.Little => { const ShiftType = math.Log2Int(T); for (bytes) |b, index| { - result = result | (T(b) << ShiftType(index * 8)); + result = result | (T(b) << @intCast(ShiftType, index * 8)); } }, } diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 1e3a732498..3a0fa7f461 100644 --- a/std/os/child_process.zig +++ b/std/os/child_process.zig @@ -413,7 +413,7 @@ pub const ChildProcess = struct { } // we are the parent - const pid = i32(pid_result); + const pid = @intCast(i32, pid_result); if (self.stdin_behavior == StdIo.Pipe) { self.stdin = os.File.openHandle(stdin_pipe[1]); } else { diff --git a/std/os/darwin.zig b/std/os/darwin.zig index a835959103..15e5608343 100644 --- a/std/os/darwin.zig +++ b/std/os/darwin.zig @@ -290,7 +290,7 @@ pub fn WIFSIGNALED(x: i32) bool { /// Get the errno from a syscall return value, or 0 for no error. pub fn getErrno(r: usize) usize { const signed_r = @bitCast(isize, r); - return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0; + return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; } pub fn close(fd: i32) usize { @@ -339,7 +339,14 @@ pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) 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), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset); + const ptr_result = c.mmap( + @ptrCast(*c_void, address), + length, + @bitCast(c_int, @intCast(c_uint, prot)), + @bitCast(c_int, c_uint(flags)), + fd, + offset, + ); const isize_result = @bitCast(isize, @ptrToInt(ptr_result)); return errnoWrap(isize_result); } diff --git a/std/os/file.zig b/std/os/file.zig index 7e05501831..055f185121 100644 --- a/std/os/file.zig +++ b/std/os/file.zig @@ -266,7 +266,7 @@ pub const File = struct { pub fn getEndPos(self: *File) !usize { if (is_posix) { const stat = try os.posixFStat(self.handle); - return usize(stat.size); + return @intCast(usize, stat.size); } else if (is_windows) { var file_size: windows.LARGE_INTEGER = undefined; if (windows.GetFileSizeEx(self.handle, &file_size) == 0) { @@ -277,7 +277,7 @@ pub const File = struct { } if (file_size < 0) return error.Overflow; - return math.cast(usize, u64(file_size)); + return math.cast(usize, @intCast(u64, file_size)); } else { @compileError("TODO support getEndPos on this OS"); } @@ -343,7 +343,7 @@ pub const File = struct { } else if (is_windows) { var index: usize = 0; while (index < buffer.len) { - const want_read_count = windows.DWORD(math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index)); + const want_read_count = @intCast(windows.DWORD, math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index)); var amt_read: windows.DWORD = undefined; if (windows.ReadFile(self.handle, @ptrCast(*c_void, buffer.ptr + index), want_read_count, &amt_read, null) == 0) { const err = windows.GetLastError(); diff --git a/std/os/index.zig b/std/os/index.zig index fb4605fce0..f1c3ab2128 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -126,7 +126,7 @@ pub fn getRandomBytes(buf: []u8) !void { } defer _ = windows.CryptReleaseContext(hCryptProv, 0); - if (windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr) == 0) { + if (windows.CryptGenRandom(hCryptProv, @intCast(windows.DWORD, buf.len), buf.ptr) == 0) { const err = windows.GetLastError(); return switch (err) { else => unexpectedErrorWindows(err), @@ -343,7 +343,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 { else => return unexpectedErrorPosix(err), } } - return i32(result); + return @intCast(i32, result); } } @@ -586,7 +586,7 @@ pub fn getCwd(allocator: *Allocator) ![]u8 { errdefer allocator.free(buf); while (true) { - const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr); + const result = windows.GetCurrentDirectoryA(@intCast(windows.WORD, buf.len), buf.ptr); if (result == 0) { const err = windows.GetLastError(); @@ -2019,7 +2019,7 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 { const rc = posix.socket(domain, socket_type, protocol); const err = posix.getErrno(rc); switch (err) { - 0 => return i32(rc), + 0 => return @intCast(i32, rc), posix.EACCES => return PosixSocketError.PermissionDenied, posix.EAFNOSUPPORT => return PosixSocketError.AddressFamilyNotSupported, posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable, @@ -2183,7 +2183,7 @@ pub fn posixAccept(fd: i32, addr: *posix.sockaddr, flags: u32) PosixAcceptError! const rc = posix.accept4(fd, addr, &sockaddr_size, flags); const err = posix.getErrno(rc); switch (err) { - 0 => return i32(rc), + 0 => return @intCast(i32, rc), posix.EINTR => continue, else => return unexpectedErrorPosix(err), @@ -2226,7 +2226,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 { const rc = posix.epoll_create1(flags); const err = posix.getErrno(rc); switch (err) { - 0 => return i32(rc), + 0 => return @intCast(i32, rc), else => return unexpectedErrorPosix(err), posix.EINVAL => return LinuxEpollCreateError.InvalidSyscall, @@ -2296,7 +2296,7 @@ pub fn linuxEpollCtl(epfd: i32, op: u32, fd: i32, event: *linux.epoll_event) Lin pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize { while (true) { - const rc = posix.epoll_wait(epfd, events.ptr, u32(events.len), timeout); + const rc = posix.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout); const err = posix.getErrno(rc); switch (err) { 0 => return rc, @@ -2661,7 +2661,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread posix.EAGAIN => return SpawnThreadError.SystemResources, posix.EPERM => unreachable, posix.EINVAL => unreachable, - else => return unexpectedErrorPosix(usize(err)), + 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 diff --git a/std/os/linux/index.zig b/std/os/linux/index.zig index 0e77371ec2..65aa659c82 100644 --- a/std/os/linux/index.zig +++ b/std/os/linux/index.zig @@ -642,7 +642,7 @@ pub fn WIFEXITED(s: i32) bool { return WTERMSIG(s) == 0; } pub fn WIFSTOPPED(s: i32) bool { - return (u16)(((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00; + return @intCast(u16, ((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00; } pub fn WIFSIGNALED(s: i32) bool { return (unsigned(s) & 0xffff) -% 1 < 0xff; @@ -658,11 +658,11 @@ pub const winsize = extern struct { /// Get the errno from a syscall return value, or 0 for no error. pub fn getErrno(r: usize) usize { const signed_r = @bitCast(isize, r); - return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0; + return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0; } pub fn dup2(old: i32, new: i32) usize { - return syscall2(SYS_dup2, usize(old), usize(new)); + return syscall2(SYS_dup2, @intCast(usize, old), @intCast(usize, new)); } // TODO https://github.com/ziglang/zig/issues/265 @@ -693,12 +693,12 @@ pub fn getcwd(buf: [*]u8, size: usize) usize { } pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize { - return syscall3(SYS_getdents, usize(fd), @ptrToInt(dirp), count); + return syscall3(SYS_getdents, @intCast(usize, fd), @ptrToInt(dirp), count); } pub fn isatty(fd: i32) bool { var wsz: winsize = undefined; - return syscall3(SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; + return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0; } // TODO https://github.com/ziglang/zig/issues/265 @@ -727,7 +727,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize { } pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize { - return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset)); + return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset)); } pub fn munmap(address: usize, length: usize) usize { @@ -735,7 +735,7 @@ pub fn munmap(address: usize, length: usize) usize { } pub fn read(fd: i32, buf: [*]u8, count: usize) usize { - return syscall3(SYS_read, usize(fd), @ptrToInt(buf), count); + return syscall3(SYS_read, @intCast(usize, fd), @ptrToInt(buf), count); } // TODO https://github.com/ziglang/zig/issues/265 @@ -749,7 +749,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize { } pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize { - return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset); + return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset); } // TODO https://github.com/ziglang/zig/issues/265 @@ -766,11 +766,11 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize { } pub fn write(fd: i32, buf: [*]const u8, count: usize) usize { - return syscall3(SYS_write, usize(fd), @ptrToInt(buf), count); + return syscall3(SYS_write, @intCast(usize, fd), @ptrToInt(buf), count); } pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize { - return syscall4(SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset); + return syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset); } // TODO https://github.com/ziglang/zig/issues/265 @@ -790,7 +790,7 @@ pub fn create(path: [*]const u8, perm: usize) usize { // TODO https://github.com/ziglang/zig/issues/265 pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize { - return syscall4(SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode); + return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode); } /// See also `clone` (from the arch-specific include) @@ -804,11 +804,11 @@ pub fn clone2(flags: usize, child_stack_ptr: usize) usize { } pub fn close(fd: i32) usize { - return syscall1(SYS_close, usize(fd)); + return syscall1(SYS_close, @intCast(usize, fd)); } pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize { - return syscall3(SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos); + return syscall3(SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos); } pub fn exit(status: i32) noreturn { @@ -817,11 +817,11 @@ pub fn exit(status: i32) noreturn { } pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize { - return syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags)); + return syscall3(SYS_getrandom, @ptrToInt(buf), count, @intCast(usize, flags)); } pub fn kill(pid: i32, sig: i32) usize { - return syscall2(SYS_kill, @bitCast(usize, isize(pid)), usize(sig)); + return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @intCast(usize, sig)); } // TODO https://github.com/ziglang/zig/issues/265 @@ -999,8 +999,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len; pub fn raise(sig: i32) usize { var set: sigset_t = undefined; blockAppSignals(&set); - const tid = i32(syscall0(SYS_gettid)); - const ret = syscall2(SYS_tkill, usize(tid), usize(sig)); + const tid = @intCast(i32, syscall0(SYS_gettid)); + const ret = syscall2(SYS_tkill, @intCast(usize, tid), @intCast(usize, sig)); restoreSignals(&set); return ret; } @@ -1019,12 +1019,12 @@ fn restoreSignals(set: *sigset_t) void { pub fn sigaddset(set: *sigset_t, sig: u6) void { const s = sig - 1; - (set.*)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1)); + (set.*)[@intCast(usize, s) / usize.bit_count] |= @intCast(usize, 1) << (s & (usize.bit_count - 1)); } pub fn sigismember(set: *const sigset_t, sig: u6) bool { const s = sig - 1; - return ((set.*)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0; + return ((set.*)[@intCast(usize, s) / usize.bit_count] & (@intCast(usize, 1) << (s & (usize.bit_count - 1)))) != 0; } pub const in_port_t = u16; @@ -1057,11 +1057,11 @@ pub const iovec = extern struct { }; pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { - return syscall3(SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len)); + return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); } pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { - return syscall3(SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len)); + return syscall3(SYS_getpeername, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len)); } pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { @@ -1069,47 +1069,47 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize { } pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize { - return syscall5(SYS_setsockopt, usize(fd), level, optname, usize(optval), @ptrToInt(optlen)); + return syscall5(SYS_setsockopt, @intCast(usize, fd), level, optname, @intCast(usize, optval), @ptrToInt(optlen)); } pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize { - return syscall5(SYS_getsockopt, usize(fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); + return syscall5(SYS_getsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen)); } pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize { - return syscall3(SYS_sendmsg, usize(fd), @ptrToInt(msg), flags); + return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags); } pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize { - return syscall3(SYS_connect, usize(fd), @ptrToInt(addr), usize(len)); + return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len)); } pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize { - return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags); + return syscall3(SYS_recvmsg, @intCast(usize, fd), @ptrToInt(msg), flags); } pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize { - return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); + return syscall6(SYS_recvfrom, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen)); } pub fn shutdown(fd: i32, how: i32) usize { - return syscall2(SYS_shutdown, usize(fd), usize(how)); + return syscall2(SYS_shutdown, @intCast(usize, fd), @intCast(usize, how)); } pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize { - return syscall3(SYS_bind, usize(fd), @ptrToInt(addr), usize(len)); + return syscall3(SYS_bind, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len)); } pub fn listen(fd: i32, backlog: u32) usize { - return syscall2(SYS_listen, usize(fd), backlog); + return syscall2(SYS_listen, @intCast(usize, fd), backlog); } pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize { - return syscall6(SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen)); + return syscall6(SYS_sendto, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen)); } pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize { - return syscall4(SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(*fd[0])); + return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(*fd[0])); } pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { @@ -1117,11 +1117,11 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize { } pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize { - return syscall4(SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags); + return syscall4(SYS_accept4, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len), flags); } pub fn fstat(fd: i32, stat_buf: *Stat) usize { - return syscall2(SYS_fstat, usize(fd), @ptrToInt(stat_buf)); + return syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf)); } // TODO https://github.com/ziglang/zig/issues/265 @@ -1214,15 +1214,15 @@ pub fn epoll_create1(flags: usize) usize { } pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize { - return syscall4(SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev)); + return syscall4(SYS_epoll_ctl, @intCast(usize, epoll_fd), @intCast(usize, op), @intCast(usize, fd), @ptrToInt(ev)); } pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize { - return syscall4(SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout)); + return syscall4(SYS_epoll_wait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout)); } pub fn timerfd_create(clockid: i32, flags: u32) usize { - return syscall2(SYS_timerfd_create, usize(clockid), usize(flags)); + return syscall2(SYS_timerfd_create, @intCast(usize, clockid), @intCast(usize, flags)); } pub const itimerspec = extern struct { @@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct { }; pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize { - return syscall2(SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value)); + return syscall2(SYS_timerfd_gettime, @intCast(usize, fd), @ptrToInt(curr_value)); } pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize { - return syscall4(SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value)); + return syscall4(SYS_timerfd_settime, @intCast(usize, fd), @intCast(usize, flags), @ptrToInt(new_value), @ptrToInt(old_value)); } pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330; @@ -1345,7 +1345,7 @@ pub const cap_user_data_t = extern struct { }; pub fn unshare(flags: usize) usize { - return syscall1(SYS_unshare, usize(flags)); + return syscall1(SYS_unshare, @intCast(usize, flags)); } pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize { diff --git a/std/os/linux/test.zig b/std/os/linux/test.zig index 948a3ac96b..e7dae3a584 100644 --- a/std/os/linux/test.zig +++ b/std/os/linux/test.zig @@ -21,7 +21,7 @@ test "timer" { .it_value = time_interval, }; - err = linux.timerfd_settime(i32(timer_fd), 0, &new_time, null); + err = linux.timerfd_settime(@intCast(i32, timer_fd), 0, &new_time, null); assert(err == 0); var event = linux.epoll_event{ @@ -29,12 +29,12 @@ test "timer" { .data = linux.epoll_data{ .ptr = 0 }, }; - err = linux.epoll_ctl(i32(epoll_fd), linux.EPOLL_CTL_ADD, i32(timer_fd), &event); + err = linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event); assert(err == 0); const events_one: linux.epoll_event = undefined; var events = []linux.epoll_event{events_one} ** 8; // TODO implicit cast from *[N]T to [*]T - err = linux.epoll_wait(i32(epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); + err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1); } diff --git a/std/os/linux/vdso.zig b/std/os/linux/vdso.zig index cbd0cd1df5..a78e3370e6 100644 --- a/std/os/linux/vdso.zig +++ b/std/os/linux/vdso.zig @@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { var i: usize = 0; while (i < hashtab[1]) : (i += 1) { - if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue; - if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue; + if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue; + if (0 == (u32(1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue; if (0 == syms[i].st_shndx) continue; if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue; if (maybe_versym) |versym| { diff --git a/std/os/time.zig b/std/os/time.zig index ffb506cd7d..73ba5bba82 100644 --- a/std/os/time.zig +++ b/std/os/time.zig @@ -14,12 +14,12 @@ pub const epoch = @import("epoch.zig"); pub fn sleep(seconds: usize, nanoseconds: usize) void { switch (builtin.os) { Os.linux, Os.macosx, Os.ios => { - posixSleep(u63(seconds), u63(nanoseconds)); + posixSleep(@intCast(u63, seconds), @intCast(u63, nanoseconds)); }, Os.windows => { const ns_per_ms = ns_per_s / ms_per_s; const milliseconds = seconds * ms_per_s + nanoseconds / ns_per_ms; - windows.Sleep(windows.DWORD(milliseconds)); + windows.Sleep(@intCast(windows.DWORD, milliseconds)); }, else => @compileError("Unsupported OS"), } @@ -83,8 +83,8 @@ fn milliTimestampDarwin() u64 { var tv: darwin.timeval = undefined; var err = darwin.gettimeofday(&tv, null); debug.assert(err == 0); - const sec_ms = u64(tv.tv_sec) * ms_per_s; - const usec_ms = @divFloor(u64(tv.tv_usec), us_per_s / ms_per_s); + const sec_ms = @intCast(u64, tv.tv_sec) * ms_per_s; + const usec_ms = @divFloor(@intCast(u64, tv.tv_usec), us_per_s / ms_per_s); return u64(sec_ms) + u64(usec_ms); } @@ -95,8 +95,8 @@ fn milliTimestampPosix() u64 { var ts: posix.timespec = undefined; const err = posix.clock_gettime(posix.CLOCK_REALTIME, &ts); debug.assert(err == 0); - const sec_ms = u64(ts.tv_sec) * ms_per_s; - const nsec_ms = @divFloor(u64(ts.tv_nsec), ns_per_s / ms_per_s); + const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s; + const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s); return sec_ms + nsec_ms; } @@ -162,13 +162,13 @@ pub const Timer = struct { var freq: i64 = undefined; var err = windows.QueryPerformanceFrequency(&freq); if (err == windows.FALSE) return error.TimerUnsupported; - self.frequency = u64(freq); + self.frequency = @intCast(u64, freq); self.resolution = @divFloor(ns_per_s, self.frequency); var start_time: i64 = undefined; err = windows.QueryPerformanceCounter(&start_time); debug.assert(err != windows.FALSE); - self.start_time = u64(start_time); + self.start_time = @intCast(u64, start_time); }, Os.linux => { //On Linux, seccomp can do arbitrary things to our ability to call @@ -184,12 +184,12 @@ pub const Timer = struct { posix.EINVAL => return error.TimerUnsupported, else => return std.os.unexpectedErrorPosix(errno), } - self.resolution = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); + self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); result = posix.clock_gettime(monotonic_clock_id, &ts); errno = posix.getErrno(result); if (errno != 0) return std.os.unexpectedErrorPosix(errno); - self.start_time = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); + self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); }, Os.macosx, Os.ios => { darwin.mach_timebase_info(&self.frequency); @@ -236,7 +236,7 @@ pub const Timer = struct { var result: i64 = undefined; var err = windows.QueryPerformanceCounter(&result); debug.assert(err != windows.FALSE); - return u64(result); + return @intCast(u64, result); } fn clockDarwin() u64 { @@ -247,7 +247,7 @@ pub const Timer = struct { var ts: posix.timespec = undefined; var result = posix.clock_gettime(monotonic_clock_id, &ts); debug.assert(posix.getErrno(result) == 0); - return u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec); + return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); } }; diff --git a/std/os/windows/util.zig b/std/os/windows/util.zig index 88a9e7952e..cb4788ba17 100644 --- a/std/os/windows/util.zig +++ b/std/os/windows/util.zig @@ -42,7 +42,7 @@ pub const WriteError = error{ }; pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void { - if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) { + if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), @intCast(u32, bytes.len), null, null) == 0) { const err = windows.GetLastError(); return switch (err) { windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources, @@ -68,7 +68,12 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool { const size = @sizeOf(windows.FILE_NAME_INFO); var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH); - if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo, @ptrCast(*c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0) { + if (windows.GetFileInformationByHandleEx( + handle, + windows.FileNameInfo, + @ptrCast(*c_void, &name_info_bytes[0]), + @intCast(u32, name_info_bytes.len), + ) == 0) { return true; } diff --git a/std/rand/index.zig b/std/rand/index.zig index 3a1a559cd9..13694f4c09 100644 --- a/std/rand/index.zig +++ b/std/rand/index.zig @@ -55,16 +55,16 @@ pub const Random = struct { if (T.is_signed) { const uint = @IntType(false, T.bit_count); if (start >= 0 and end >= 0) { - return T(r.range(uint, uint(start), uint(end))); + return @intCast(T, r.range(uint, @intCast(uint, start), @intCast(uint, end))); } else if (start < 0 and end < 0) { // Can't overflow because the range is over signed ints return math.negateCast(r.range(uint, math.absCast(end), math.absCast(start)) + 1) catch unreachable; } else if (start < 0 and end >= 0) { - const end_uint = uint(end); + const end_uint = @intCast(uint, end); const total_range = math.absCast(start) + end_uint; const value = r.range(uint, 0, total_range); const result = if (value < end_uint) x: { - break :x T(value); + break :x @intCast(T, value); } else if (value == end_uint) x: { break :x start; } else x: { @@ -213,9 +213,9 @@ pub const Pcg = struct { self.s = l *% default_multiplier +% (self.i | 1); const xor_s = @truncate(u32, ((l >> 18) ^ l) >> 27); - const rot = u32(l >> 59); + const rot = @intCast(u32, l >> 59); - return (xor_s >> u5(rot)) | (xor_s << u5((0 -% rot) & 31)); + return (xor_s >> @intCast(u5, rot)) | (xor_s << @intCast(u5, (0 -% rot) & 31)); } fn seed(self: *Pcg, init_s: u64) void { @@ -322,7 +322,7 @@ pub const Xoroshiro128 = struct { inline for (table) |entry| { var b: usize = 0; while (b < 64) : (b += 1) { - if ((entry & (u64(1) << u6(b))) != 0) { + if ((entry & (u64(1) << @intCast(u6, b))) != 0) { s0 ^= self.s[0]; s1 ^= self.s[1]; } @@ -667,13 +667,13 @@ test "Random range" { } fn testRange(r: *Random, start: i32, end: i32) void { - const count = usize(end - start); + const count = @intCast(usize, end - start); var values_buffer = []bool{false} ** 20; const values = values_buffer[0..count]; var i: usize = 0; while (i < count) { const value = r.range(i32, start, end); - const index = usize(value - start); + const index = @intCast(usize, value - start); if (!values[index]) { i += 1; values[index] = true; diff --git a/std/segmented_list.zig b/std/segmented_list.zig index 9f10f4d44a..6e3f32e9d6 100644 --- a/std/segmented_list.zig +++ b/std/segmented_list.zig @@ -104,7 +104,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type } pub fn deinit(self: *Self) void { - self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0); + self.freeShelves(@intCast(ShelfIndex, self.dynamic_segments.len), 0); self.allocator.free(self.dynamic_segments); self.* = undefined; } @@ -158,7 +158,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type /// Only grows capacity, or retains current capacity pub fn growCapacity(self: *Self, new_capacity: usize) !void { const new_cap_shelf_count = shelfCount(new_capacity); - const old_shelf_count = ShelfIndex(self.dynamic_segments.len); + const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len); if (new_cap_shelf_count > old_shelf_count) { self.dynamic_segments = try self.allocator.realloc([*]T, self.dynamic_segments, new_cap_shelf_count); var i = old_shelf_count; @@ -175,7 +175,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type /// Only shrinks capacity or retains current capacity pub fn shrinkCapacity(self: *Self, new_capacity: usize) void { if (new_capacity <= prealloc_item_count) { - const len = ShelfIndex(self.dynamic_segments.len); + const len = @intCast(ShelfIndex, self.dynamic_segments.len); self.freeShelves(len, 0); self.allocator.free(self.dynamic_segments); self.dynamic_segments = [][*]T{}; @@ -183,7 +183,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type } const new_cap_shelf_count = shelfCount(new_capacity); - const old_shelf_count = ShelfIndex(self.dynamic_segments.len); + const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len); assert(new_cap_shelf_count <= old_shelf_count); if (new_cap_shelf_count == old_shelf_count) { return; @@ -338,7 +338,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { { var i: usize = 0; while (i < 100) : (i += 1) { - try list.push(i32(i + 1)); + try list.push(@intCast(i32, i + 1)); assert(list.len == i + 1); } } @@ -346,7 +346,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void { { var i: usize = 0; while (i < 100) : (i += 1) { - assert(list.at(i).* == i32(i + 1)); + assert(list.at(i).* == @intCast(i32, i + 1)); } } diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index dd37f1edb6..5c8a330a92 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -80,7 +80,7 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 { var env_count: usize = 0; while (c_envp[env_count] != null) : (env_count += 1) {} const envp = @ptrCast([*][*]u8, c_envp)[0..env_count]; - return callMainWithArgs(usize(c_argc), c_argv, envp); + return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp); } fn callMain() u8 { diff --git a/std/special/builtin.zig b/std/special/builtin.zig index e97b0a89e4..07e735d931 100644 --- a/std/special/builtin.zig +++ b/std/special/builtin.zig @@ -135,9 +135,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { const mask = if (T == f32) 0xff else 0x7ff; var ux = @bitCast(uint, x); var uy = @bitCast(uint, y); - var ex = i32((ux >> digits) & mask); - var ey = i32((uy >> digits) & mask); - const sx = if (T == f32) u32(ux & 0x80000000) else i32(ux >> bits_minus_1); + var ex = @intCast(i32, (ux >> digits) & mask); + var ey = @intCast(i32, (uy >> digits) & mask); + const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1); var i: uint = undefined; if (uy << 1 == 0 or isNan(uint, uy) or ex == mask) @@ -156,7 +156,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { ex -= 1; i <<= 1; }) {} - ux <<= log2uint(@bitCast(u32, -ex + 1)); + ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1)); } else { ux &= @maxValue(uint) >> exp_bits; ux |= 1 << digits; @@ -167,7 +167,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { ey -= 1; i <<= 1; }) {} - uy <<= log2uint(@bitCast(u32, -ey + 1)); + uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1)); } else { uy &= @maxValue(uint) >> exp_bits; uy |= 1 << digits; @@ -199,12 +199,12 @@ fn generic_fmod(comptime T: type, x: T, y: T) T { ux -%= 1 << digits; ux |= uint(@bitCast(u32, ex)) << digits; } else { - ux >>= log2uint(@bitCast(u32, -ex + 1)); + ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1)); } if (T == f32) { ux |= sx; } else { - ux |= uint(sx) << bits_minus_1; + ux |= @intCast(uint, sx) << bits_minus_1; } return @bitCast(T, ux); } @@ -227,8 +227,8 @@ export fn sqrt(x: f64) f64 { const sign: u32 = 0x80000000; const u = @bitCast(u64, x); - var ix0 = u32(u >> 32); - var ix1 = u32(u & 0xFFFFFFFF); + var ix0 = @intCast(u32, u >> 32); + var ix1 = @intCast(u32, u & 0xFFFFFFFF); // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan if (ix0 & 0x7FF00000 == 0x7FF00000) { @@ -245,7 +245,7 @@ export fn sqrt(x: f64) f64 { } // normalize x - var m = i32(ix0 >> 20); + var m = @intCast(i32, ix0 >> 20); if (m == 0) { // subnormal while (ix0 == 0) { @@ -259,9 +259,9 @@ export fn sqrt(x: f64) f64 { while (ix0 & 0x00100000 == 0) : (i += 1) { ix0 <<= 1; } - m -= i32(i) - 1; - ix0 |= ix1 >> u5(32 - i); - ix1 <<= u5(i); + m -= @intCast(i32, i) - 1; + ix0 |= ix1 >> @intCast(u5, 32 - i); + ix1 <<= @intCast(u5, i); } // unbias exponent @@ -345,10 +345,10 @@ export fn sqrt(x: f64) f64 { // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same // behaviour at least. - var iix0 = i32(ix0); + var iix0 = @intCast(i32, ix0); iix0 = iix0 +% (m << 20); - const uz = (u64(iix0) << 32) | ix1; + const uz = (@intCast(u64, iix0) << 32) | ix1; return @bitCast(f64, uz); } diff --git a/std/special/compiler_rt/divti3.zig b/std/special/compiler_rt/divti3.zig index 60460ea62d..712cccba82 100644 --- a/std/special/compiler_rt/divti3.zig +++ b/std/special/compiler_rt/divti3.zig @@ -13,7 +13,7 @@ pub extern fn __divti3(a: i128, b: i128) i128 { const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null); const s = s_a ^ s_b; - return (i128(r) ^ s) -% s; + return (@bitCast(i128, r) ^ s) -% s; } pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void { diff --git a/std/special/compiler_rt/fixuint.zig b/std/special/compiler_rt/fixuint.zig index bd9b2fc395..48d63ed914 100644 --- a/std/special/compiler_rt/fixuint.zig +++ b/std/special/compiler_rt/fixuint.zig @@ -32,14 +32,14 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t const aAbs: rep_t = aRep & absMask; const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1); - const exponent = i32(aAbs >> significandBits) - exponentBias; + const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias; const significand: rep_t = (aAbs & significandMask) | implicitBit; // If either the value or the exponent is negative, the result is zero. if (sign == -1 or exponent < 0) return 0; // If the value is too large for the integer type, saturate. - if (c_uint(exponent) >= fixuint_t.bit_count) return ~fixuint_t(0); + if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~fixuint_t(0); // If 0 <= exponent < significandBits, right shift to get the result. // Otherwise, shift left. @@ -47,11 +47,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t // TODO this is a workaround for the mysterious "integer cast truncated bits" // happening on the next line @setRuntimeSafety(false); - return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent)); + return @intCast(fixuint_t, significand >> @intCast(Log2Int(rep_t), significandBits - exponent)); } else { // TODO this is a workaround for the mysterious "integer cast truncated bits" // happening on the next line @setRuntimeSafety(false); - return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits); + return @intCast(fixuint_t, significand) << @intCast(Log2Int(fixuint_t), exponent - significandBits); } } diff --git a/std/special/compiler_rt/index.zig b/std/special/compiler_rt/index.zig index f952730353..dc95aa23f2 100644 --- a/std/special/compiler_rt/index.zig +++ b/std/special/compiler_rt/index.zig @@ -292,7 +292,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 { @setRuntimeSafety(is_test); const d = __udivsi3(a, b); - rem.* = u32(i32(a) -% (i32(d) * i32(b))); + rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b))); return d; } @@ -316,12 +316,12 @@ extern fn __udivsi3(n: u32, d: u32) u32 { sr += 1; // 1 <= sr <= n_uword_bits - 1 // Not a special case - var q: u32 = n << u5(n_uword_bits - sr); - var r: u32 = n >> u5(sr); + var q: u32 = n << @intCast(u5, n_uword_bits - sr); + var r: u32 = n >> @intCast(u5, sr); var carry: u32 = 0; while (sr > 0) : (sr -= 1) { // r:q = ((r:q) << 1) | carry - r = (r << 1) | (q >> u5(n_uword_bits - 1)); + r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1)); q = (q << 1) | carry; // carry = 0; // if (r.all >= d.all) @@ -329,8 +329,8 @@ extern fn __udivsi3(n: u32, d: u32) u32 { // r.all -= d.all; // carry = 1; // } - const s = i32(d -% r -% 1) >> u5(n_uword_bits - 1); - carry = u32(s & 1); + const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1); + carry = @intCast(u32, s & 1); r -= d & @bitCast(u32, s); } q = (q << 1) | carry; diff --git a/std/special/compiler_rt/udivmod.zig b/std/special/compiler_rt/udivmod.zig index 894dd02239..e6b4ee0482 100644 --- a/std/special/compiler_rt/udivmod.zig +++ b/std/special/compiler_rt/udivmod.zig @@ -71,7 +71,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: r[high] = n[high] & (d[high] - 1); rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 } - return n[high] >> Log2SingleInt(@ctz(d[high])); + return n[high] >> @intCast(Log2SingleInt, @ctz(d[high])); } // K K // --- @@ -88,10 +88,10 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: // 1 <= sr <= SingleInt.bit_count - 1 // q.all = a << (DoubleInt.bit_count - sr); q[low] = 0; - q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); + q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); // r.all = a >> sr; - r[high] = n[high] >> Log2SingleInt(sr); - r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); + r[high] = n[high] >> @intCast(Log2SingleInt, sr); + r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); } else { // d[low] != 0 if (d[high] == 0) { @@ -107,8 +107,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: return a; } sr = @ctz(d[low]); - q[high] = n[high] >> Log2SingleInt(sr); - q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); + q[high] = n[high] >> @intCast(Log2SingleInt, sr); + q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 } // K X @@ -126,15 +126,15 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: } else if (sr < SingleInt.bit_count) { // 2 <= sr <= SingleInt.bit_count - 1 q[low] = 0; - q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); - r[high] = n[high] >> Log2SingleInt(sr); - r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); + q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); + r[high] = n[high] >> @intCast(Log2SingleInt, sr); + r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); } else { // SingleInt.bit_count + 1 <= sr <= DoubleInt.bit_count - 1 - q[low] = n[low] << Log2SingleInt(DoubleInt.bit_count - sr); - q[high] = (n[high] << Log2SingleInt(DoubleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr - SingleInt.bit_count)); + q[low] = n[low] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr); + q[high] = (n[high] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count)); r[high] = 0; - r[low] = n[high] >> Log2SingleInt(sr - SingleInt.bit_count); + r[low] = n[high] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count); } } else { // K X @@ -158,9 +158,9 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: r[high] = 0; r[low] = n[high]; } else { - r[high] = n[high] >> Log2SingleInt(sr); - r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr)); - q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr); + r[high] = n[high] >> @intCast(Log2SingleInt, sr); + r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); + q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr); } } } @@ -184,8 +184,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: // carry = 1; // } r_all = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 - const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1); - carry = u32(s & 1); + const s: SignedDoubleInt = @intCast(SignedDoubleInt, b -% r_all -% 1) >> (DoubleInt.bit_count - 1); + carry = @intCast(u32, s & 1); r_all -= b & @bitCast(DoubleInt, s); r = @ptrCast(*[2]SingleInt, &r_all).*; // TODO issue #421 } diff --git a/std/unicode.zig b/std/unicode.zig index ec808ca4fe..9c329acc68 100644 --- a/std/unicode.zig +++ b/std/unicode.zig @@ -35,22 +35,22 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 { // - Increasing the initial shift by 6 each time // - Each time after the first shorten the shifted // value to a max of 0b111111 (63) - 1 => out[0] = u8(c), // Can just do 0 + codepoint for initial range + 1 => out[0] = @intCast(u8, c), // Can just do 0 + codepoint for initial range 2 => { - out[0] = u8(0b11000000 | (c >> 6)); - out[1] = u8(0b10000000 | (c & 0b111111)); + out[0] = @intCast(u8, 0b11000000 | (c >> 6)); + out[1] = @intCast(u8, 0b10000000 | (c & 0b111111)); }, 3 => { if (0xd800 <= c and c <= 0xdfff) return error.Utf8CannotEncodeSurrogateHalf; - out[0] = u8(0b11100000 | (c >> 12)); - out[1] = u8(0b10000000 | ((c >> 6) & 0b111111)); - out[2] = u8(0b10000000 | (c & 0b111111)); + out[0] = @intCast(u8, 0b11100000 | (c >> 12)); + out[1] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111)); + out[2] = @intCast(u8, 0b10000000 | (c & 0b111111)); }, 4 => { - out[0] = u8(0b11110000 | (c >> 18)); - out[1] = u8(0b10000000 | ((c >> 12) & 0b111111)); - out[2] = u8(0b10000000 | ((c >> 6) & 0b111111)); - out[3] = u8(0b10000000 | (c & 0b111111)); + out[0] = @intCast(u8, 0b11110000 | (c >> 18)); + out[1] = @intCast(u8, 0b10000000 | ((c >> 12) & 0b111111)); + out[2] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111)); + out[3] = @intCast(u8, 0b10000000 | (c & 0b111111)); }, else => unreachable, } diff --git a/std/zig/tokenizer.zig b/std/zig/tokenizer.zig index 4534529f36..79f1871b64 100644 --- a/std/zig/tokenizer.zig +++ b/std/zig/tokenizer.zig @@ -1128,7 +1128,7 @@ pub const Tokenizer = struct { // check utf8-encoded character. const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1; if (self.index + length > self.buffer.len) { - return u3(self.buffer.len - self.index); + return @intCast(u3, self.buffer.len - self.index); } const bytes = self.buffer[self.index .. self.index + length]; switch (length) { diff --git a/test/cases/cast.zig b/test/cases/cast.zig index 4c216010eb..7035740c54 100644 --- a/test/cases/cast.zig +++ b/test/cases/cast.zig @@ -343,7 +343,7 @@ fn testPeerErrorAndArray2(x: u8) error![]const u8 { test "explicit cast float number literal to integer if no fraction component" { const x = i32(1e4); assert(x == 10000); - const y = i32(f32(1e4)); + const y = @floatToInt(i32, f32(1e4)); assert(y == 10000); } @@ -398,3 +398,19 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" { const x: [*]const ?[*]const u8 = &window_name; assert(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name")); } + +test "@intCast comptime_int" { + const result = @intCast(i32, 1234); + assert(@typeOf(result) == i32); + assert(result == 1234); +} + +test "@floatCast comptime_int and comptime_float" { + const result = @floatCast(f32, 1234); + assert(@typeOf(result) == f32); + assert(result == 1234.0); + + const result2 = @floatCast(f32, 1234.0); + assert(@typeOf(result) == f32); + assert(result == 1234.0); +} diff --git a/test/cases/enum.zig b/test/cases/enum.zig index 5c78d73092..6a02a47784 100644 --- a/test/cases/enum.zig +++ b/test/cases/enum.zig @@ -99,7 +99,7 @@ test "int to enum" { testIntToEnumEval(3); } fn testIntToEnumEval(x: i32) void { - assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three); + assert(IntToEnumNumber(@intCast(u3, x)) == IntToEnumNumber.Three); } const IntToEnumNumber = enum { Zero, diff --git a/test/cases/eval.zig b/test/cases/eval.zig index 08d3f3a841..6c919e17a6 100644 --- a/test/cases/eval.zig +++ b/test/cases/eval.zig @@ -5,7 +5,7 @@ const builtin = @import("builtin"); test "compile time recursion" { assert(some_data.len == 21); } -var some_data: [usize(fibonacci(7))]u8 = undefined; +var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined; fn fibonacci(x: i32) i32 { if (x <= 1) return 1; return fibonacci(x - 1) + fibonacci(x - 2); @@ -356,7 +356,7 @@ const global_array = x: { test "compile-time downcast when the bits fit" { comptime { const spartan_count: u16 = 255; - const byte = u8(spartan_count); + const byte = @intCast(u8, spartan_count); assert(byte == 255); } } @@ -440,7 +440,7 @@ test "binary math operator in partially inlined function" { var b: [16]u8 = undefined; for (b) |*r, i| - r.* = u8(i + 1); + r.* = @intCast(u8, i + 1); copyWithPartialInline(s[0..], b[0..]); assert(s[0] == 0x1020304); @@ -480,7 +480,7 @@ fn generateTable(comptime T: type) [1010]T { var res: [1010]T = undefined; var i: usize = 0; while (i < 1010) : (i += 1) { - res[i] = T(i); + res[i] = @intCast(T, i); } return res; } diff --git a/test/cases/fn.zig b/test/cases/fn.zig index 12f22bfc35..47f7d5e688 100644 --- a/test/cases/fn.zig +++ b/test/cases/fn.zig @@ -80,7 +80,7 @@ test "function pointers" { fn4, }; for (fns) |f, i| { - assert(f() == u32(i) + 5); + assert(f() == @intCast(u32, i) + 5); } } fn fn1() u32 { diff --git a/test/cases/for.zig b/test/cases/for.zig index bdbab312f6..59d90c1b85 100644 --- a/test/cases/for.zig +++ b/test/cases/for.zig @@ -46,7 +46,7 @@ test "basic for loop" { buf_index += 1; } for (array) |item, index| { - buffer[buf_index] = u8(index); + buffer[buf_index] = @intCast(u8, index); buf_index += 1; } const unknown_size: []const u8 = array; @@ -55,7 +55,7 @@ test "basic for loop" { buf_index += 1; } for (unknown_size) |item, index| { - buffer[buf_index] = u8(index); + buffer[buf_index] = @intCast(u8, index); buf_index += 1; } diff --git a/test/cases/struct.zig b/test/cases/struct.zig index 6952611a8c..94a2ba6336 100644 --- a/test/cases/struct.zig +++ b/test/cases/struct.zig @@ -365,14 +365,14 @@ test "runtime struct initialization of bitfield" { .y = x1, }; const s2 = Nibbles{ - .x = u4(x2), - .y = u4(x2), + .x = @intCast(u4, x2), + .y = @intCast(u4, x2), }; assert(s1.x == x1); assert(s1.y == x1); - assert(s2.x == u4(x2)); - assert(s2.y == u4(x2)); + assert(s2.x == @intCast(u4, x2)); + assert(s2.y == @intCast(u4, x2)); } var x1 = u4(1); -- cgit v1.2.3 From 03f66825d6b6922da250cdb99c2996455541e0f9 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 29 Jun 2018 23:28:42 +0200 Subject: support --emit in 'test' command Support the `--emit` switch in `zig --emit asm test file.zig`. The command fails because no tests run (no executable is created) but it emits the requested file. That seems like a good tradeoff. --- src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 0fe12bb0cb..a409778a78 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -924,6 +924,8 @@ int main(int argc, char **argv) { codegen_print_timing_report(g, stdout); return EXIT_SUCCESS; } else if (cmd == CmdTest) { + codegen_set_emit_file_type(g, emit_file_type); + ZigTarget native; get_native_target(&native); -- cgit v1.2.3 From 574e31f0a046aa6e6fad73fff2cbbb3617fe1bae Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 10 Jul 2018 20:18:43 -0400 Subject: self-hosted: first passing test * introduce std.atomic.Int * add src-self-hosted/test.zig which is tested by the main test suite - it fully utilizes the multithreaded async/await event loop so the tests should Go Fast * `stage2/bin/zig build-obj test.zig` is able to spit out an error if 2 exported functions collide * ability for `zig test` to accept `--object` and `--assembly` arguments * std.build: TestStep supports addLibPath and addObjectFile --- CMakeLists.txt | 1 + build.zig | 152 ++++++++++++++++++++--------------- src-self-hosted/errmsg.zig | 18 +++-- src-self-hosted/introspect.zig | 5 ++ src-self-hosted/main.zig | 36 ++++----- src-self-hosted/module.zig | 98 +++++++++++++++++++---- src-self-hosted/test.zig | 176 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 10 ++- std/atomic/index.zig | 2 + std/atomic/int.zig | 19 +++++ std/build.zig | 22 ++++++ 11 files changed, 432 insertions(+), 107 deletions(-) create mode 100644 src-self-hosted/test.zig create mode 100644 std/atomic/int.zig (limited to 'src/main.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb0ec2058..559b3b6964 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -431,6 +431,7 @@ set(ZIG_CPP_SOURCES set(ZIG_STD_FILES "array_list.zig" "atomic/index.zig" + "atomic/int.zig" "atomic/queue_mpmc.zig" "atomic/queue_mpsc.zig" "atomic/stack.zig" diff --git a/build.zig b/build.zig index fd154c7504..273048d458 100644 --- a/build.zig +++ b/build.zig @@ -35,70 +35,27 @@ pub fn build(b: *Builder) !void { "BUILD_INFO", }); var index: usize = 0; - const cmake_binary_dir = nextValue(&index, build_info); - const cxx_compiler = nextValue(&index, build_info); - const llvm_config_exe = nextValue(&index, build_info); - const lld_include_dir = nextValue(&index, build_info); - const lld_libraries = nextValue(&index, build_info); - const std_files = nextValue(&index, build_info); - const c_header_files = nextValue(&index, build_info); - const dia_guids_lib = nextValue(&index, build_info); + var ctx = Context{ + .cmake_binary_dir = nextValue(&index, build_info), + .cxx_compiler = nextValue(&index, build_info), + .llvm_config_exe = nextValue(&index, build_info), + .lld_include_dir = nextValue(&index, build_info), + .lld_libraries = nextValue(&index, build_info), + .std_files = nextValue(&index, build_info), + .c_header_files = nextValue(&index, build_info), + .dia_guids_lib = nextValue(&index, build_info), + .llvm = undefined, + }; + ctx.llvm = try findLLVM(b, ctx.llvm_config_exe); - const llvm = findLLVM(b, llvm_config_exe) catch unreachable; + var test_stage2 = b.addTest("src-self-hosted/test.zig"); + test_stage2.setBuildMode(builtin.Mode.Debug); var exe = b.addExecutable("zig", "src-self-hosted/main.zig"); exe.setBuildMode(mode); - // This is for finding /lib/libz.a on alpine linux. - // TODO turn this into -Dextra-lib-path=/lib option - exe.addLibPath("/lib"); - - exe.addIncludeDir("src"); - exe.addIncludeDir(cmake_binary_dir); - addCppLib(b, exe, cmake_binary_dir, "zig_cpp"); - if (lld_include_dir.len != 0) { - exe.addIncludeDir(lld_include_dir); - var it = mem.split(lld_libraries, ";"); - while (it.next()) |lib| { - exe.addObjectFile(lib); - } - } else { - addCppLib(b, exe, cmake_binary_dir, "embedded_lld_wasm"); - addCppLib(b, exe, cmake_binary_dir, "embedded_lld_elf"); - addCppLib(b, exe, cmake_binary_dir, "embedded_lld_coff"); - addCppLib(b, exe, cmake_binary_dir, "embedded_lld_lib"); - } - dependOnLib(exe, llvm); - - if (exe.target.getOs() == builtin.Os.linux) { - const libstdcxx_path_padded = try b.exec([][]const u8{ - cxx_compiler, - "-print-file-name=libstdc++.a", - }); - const libstdcxx_path = mem.split(libstdcxx_path_padded, "\r\n").next().?; - if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) { - warn( - \\Unable to determine path to libstdc++.a - \\On Fedora, install libstdc++-static and try again. - \\ - ); - return error.RequiredLibraryNotFound; - } - exe.addObjectFile(libstdcxx_path); - - exe.linkSystemLibrary("pthread"); - } else if (exe.target.isDarwin()) { - exe.linkSystemLibrary("c++"); - } - - if (dia_guids_lib.len != 0) { - exe.addObjectFile(dia_guids_lib); - } - - if (exe.target.getOs() != builtin.Os.windows) { - exe.linkSystemLibrary("xml2"); - } - exe.linkSystemLibrary("c"); + try configureStage2(b, test_stage2, ctx); + try configureStage2(b, exe, ctx); b.default_step.dependOn(&exe.step); @@ -110,12 +67,16 @@ pub fn build(b: *Builder) !void { exe.setVerboseLink(verbose_link_exe); b.installArtifact(exe); - installStdLib(b, std_files); - installCHeaders(b, c_header_files); + installStdLib(b, ctx.std_files); + installCHeaders(b, ctx.c_header_files); const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter"); const with_lldb = b.option(bool, "with-lldb", "Run tests in LLDB to get a backtrace if one fails") orelse false; + const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests"); + test_stage2_step.dependOn(&test_stage2.step); + test_step.dependOn(test_stage2_step); + test_step.dependOn(docs_step); test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", with_lldb)); @@ -133,7 +94,7 @@ pub fn build(b: *Builder) !void { test_step.dependOn(tests.addGenHTests(b, test_filter)); } -fn dependOnLib(lib_exe_obj: *std.build.LibExeObjStep, dep: *const LibraryDep) void { +fn dependOnLib(lib_exe_obj: var, dep: *const LibraryDep) void { for (dep.libdirs.toSliceConst()) |lib_dir| { lib_exe_obj.addLibPath(lib_dir); } @@ -148,7 +109,7 @@ fn dependOnLib(lib_exe_obj: *std.build.LibExeObjStep, dep: *const LibraryDep) vo } } -fn addCppLib(b: *Builder, lib_exe_obj: *std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void { +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, cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable); } @@ -254,3 +215,68 @@ fn nextValue(index: *usize, build_info: []const u8) []const u8 { } } } + +fn configureStage2(b: *Builder, exe: var, ctx: Context) !void { + // This is for finding /lib/libz.a on alpine linux. + // TODO turn this into -Dextra-lib-path=/lib option + exe.addLibPath("/lib"); + + exe.addIncludeDir("src"); + exe.addIncludeDir(ctx.cmake_binary_dir); + 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, ";"); + while (it.next()) |lib| { + exe.addObjectFile(lib); + } + } else { + addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_wasm"); + addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_elf"); + addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_coff"); + addCppLib(b, exe, ctx.cmake_binary_dir, "embedded_lld_lib"); + } + dependOnLib(exe, ctx.llvm); + + if (exe.target.getOs() == builtin.Os.linux) { + const libstdcxx_path_padded = try b.exec([][]const u8{ + ctx.cxx_compiler, + "-print-file-name=libstdc++.a", + }); + const libstdcxx_path = mem.split(libstdcxx_path_padded, "\r\n").next().?; + if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) { + warn( + \\Unable to determine path to libstdc++.a + \\On Fedora, install libstdc++-static and try again. + \\ + ); + return error.RequiredLibraryNotFound; + } + exe.addObjectFile(libstdcxx_path); + + exe.linkSystemLibrary("pthread"); + } else if (exe.target.isDarwin()) { + exe.linkSystemLibrary("c++"); + } + + if (ctx.dia_guids_lib.len != 0) { + exe.addObjectFile(ctx.dia_guids_lib); + } + + if (exe.target.getOs() != builtin.Os.windows) { + exe.linkSystemLibrary("xml2"); + } + exe.linkSystemLibrary("c"); +} + +const Context = struct { + cmake_binary_dir: []const u8, + cxx_compiler: []const u8, + llvm_config_exe: []const u8, + lld_include_dir: []const u8, + lld_libraries: []const u8, + std_files: []const u8, + c_header_files: []const u8, + dia_guids_lib: []const u8, + llvm: LibraryDep, +}; diff --git a/src-self-hosted/errmsg.zig b/src-self-hosted/errmsg.zig index b6fd78d8f6..a92b5145ce 100644 --- a/src-self-hosted/errmsg.zig +++ b/src-self-hosted/errmsg.zig @@ -11,11 +11,15 @@ pub const Color = enum { On, }; +pub const Span = struct { + first: ast.TokenIndex, + last: ast.TokenIndex, +}; + pub const Msg = struct { path: []const u8, text: []u8, - first_token: TokenIndex, - last_token: TokenIndex, + span: Span, tree: *ast.Tree, }; @@ -39,8 +43,10 @@ pub fn createFromParseError( .tree = tree, .path = path, .text = text_buf.toOwnedSlice(), - .first_token = loc_token, - .last_token = loc_token, + .span = Span{ + .first = loc_token, + .last = loc_token, + }, }); errdefer allocator.destroy(msg); @@ -48,8 +54,8 @@ pub fn createFromParseError( } pub fn printToStream(stream: var, msg: *const Msg, color_on: bool) !void { - const first_token = msg.tree.tokens.at(msg.first_token); - const last_token = msg.tree.tokens.at(msg.last_token); + const first_token = msg.tree.tokens.at(msg.span.first); + const last_token = msg.tree.tokens.at(msg.span.last); const start_loc = msg.tree.tokenLocationPtr(0, first_token); const end_loc = msg.tree.tokenLocationPtr(first_token.end, last_token); if (!color_on) { diff --git a/src-self-hosted/introspect.zig b/src-self-hosted/introspect.zig index 74084b48c6..ecd04c4467 100644 --- a/src-self-hosted/introspect.zig +++ b/src-self-hosted/introspect.zig @@ -53,3 +53,8 @@ pub fn resolveZigLibDir(allocator: *mem.Allocator) ![]u8 { return error.ZigLibDirNotFound; }; } + +/// Caller must free result +pub fn resolveZigCacheDir(allocator: *mem.Allocator) ![]u8 { + return std.mem.dupe(allocator, u8, "zig-cache"); +} diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index fe94a4460a..d7ead0ba32 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -481,29 +481,29 @@ fn buildOutputType(allocator: *Allocator, args: []const []const u8, out_type: Mo module.link_out_file = flags.single("out-file"); try module.build(); - const process_build_events_handle = try async processBuildEvents(module, true); + const process_build_events_handle = try async processBuildEvents(module, color); defer cancel process_build_events_handle; loop.run(); } -async fn processBuildEvents(module: *Module, watch: bool) void { - while (watch) { - // TODO directly awaiting async should guarantee memory allocation elision - const build_event = await (async module.events.get() catch unreachable); +async fn processBuildEvents(module: *Module, color: errmsg.Color) void { + // TODO directly awaiting async should guarantee memory allocation elision + const build_event = await (async module.events.get() catch unreachable); - switch (build_event) { - Module.Event.Ok => { - std.debug.warn("Build succeeded\n"); - return; - }, - Module.Event.Error => |err| { - std.debug.warn("build failed: {}\n", @errorName(err)); - @panic("TODO error return trace"); - }, - Module.Event.Fail => |errs| { - @panic("TODO print compile error messages"); - }, - } + switch (build_event) { + Module.Event.Ok => { + std.debug.warn("Build succeeded\n"); + return; + }, + Module.Event.Error => |err| { + std.debug.warn("build failed: {}\n", @errorName(err)); + @panic("TODO error return trace"); + }, + Module.Event.Fail => |msgs| { + for (msgs) |msg| { + errmsg.printToFile(&stderr_file, msg, color) catch os.exit(1); + } + }, } } diff --git a/src-self-hosted/module.zig b/src-self-hosted/module.zig index 24be228eb8..44954e4cd1 100644 --- a/src-self-hosted/module.zig +++ b/src-self-hosted/module.zig @@ -89,12 +89,9 @@ pub const Module = struct { /// the build is complete. build_group: event.Group(BuildError!void), - const BuildErrorsList = std.SegmentedList(BuildErrorDesc, 1); + compile_errors: event.Locked(CompileErrList), - pub const BuildErrorDesc = struct { - code: BuildError, - text: []const u8, - }; + const CompileErrList = std.ArrayList(*errmsg.Msg); // TODO handle some of these earlier and report them in a way other than error codes pub const BuildError = error{ @@ -131,11 +128,12 @@ pub const Module = struct { NoStdHandles, Overflow, NotSupported, + BufferTooSmall, }; pub const Event = union(enum) { Ok, - Fail: []errmsg.Msg, + Fail: []*errmsg.Msg, Error: BuildError, }; @@ -249,6 +247,7 @@ pub const Module = struct { .link_out_file = null, .exported_symbol_names = event.Locked(Decl.Table).init(loop, Decl.Table.init(loop.allocator)), .build_group = event.Group(BuildError!void).init(loop), + .compile_errors = event.Locked(CompileErrList).init(loop, CompileErrList.init(loop.allocator)), }); } @@ -288,7 +287,17 @@ pub const Module = struct { await (async self.events.put(Event{ .Error = err }) catch unreachable); return; }; - await (async self.events.put(Event.Ok) catch unreachable); + const compile_errors = blk: { + const held = await (async self.compile_errors.acquire() catch unreachable); + defer held.release(); + break :blk held.value.toOwnedSlice(); + }; + + if (compile_errors.len == 0) { + await (async self.events.put(Event.Ok) catch unreachable); + } else { + await (async self.events.put(Event{ .Fail = compile_errors }) catch unreachable); + } // for now we stop after 1 return; } @@ -310,10 +319,13 @@ pub const Module = struct { }; errdefer self.a().free(source_code); - var parsed_file = ParsedFile{ - .tree = try std.zig.parse(self.a(), source_code), + const parsed_file = try self.a().create(ParsedFile{ + .tree = undefined, .realpath = root_src_real_path, - }; + }); + errdefer self.a().destroy(parsed_file); + + parsed_file.tree = try std.zig.parse(self.a(), source_code); errdefer parsed_file.tree.deinit(); const tree = &parsed_file.tree; @@ -337,7 +349,7 @@ pub const Module = struct { const name = if (fn_proto.name_token) |name_token| tree.tokenSlice(name_token) else { @panic("TODO add compile error"); //try self.addCompileError( - // &parsed_file, + // parsed_file, // fn_proto.fn_token, // fn_proto.fn_token + 1, // "missing function name", @@ -357,7 +369,7 @@ pub const Module = struct { }); errdefer self.a().destroy(fn_decl); - try decl_group.call(addTopLevelDecl, self, tree, &fn_decl.base); + try decl_group.call(addTopLevelDecl, self, parsed_file, &fn_decl.base); }, ast.Node.Id.TestDecl => @panic("TODO"), else => unreachable, @@ -367,20 +379,56 @@ pub const Module = struct { try await (async self.build_group.wait() catch unreachable); } - async fn addTopLevelDecl(self: *Module, tree: *ast.Tree, decl: *Decl) !void { - const is_export = decl.isExported(tree); + async fn addTopLevelDecl(self: *Module, parsed_file: *ParsedFile, decl: *Decl) !void { + const is_export = decl.isExported(&parsed_file.tree); if (is_export) { - try self.build_group.call(verifyUniqueSymbol, self, decl); + try self.build_group.call(verifyUniqueSymbol, self, parsed_file, decl); } } - async fn verifyUniqueSymbol(self: *Module, decl: *Decl) !void { + fn addCompileError(self: *Module, parsed_file: *ParsedFile, span: errmsg.Span, comptime fmt: []const u8, args: ...) !void { + const text = try std.fmt.allocPrint(self.loop.allocator, fmt, args); + errdefer self.loop.allocator.free(text); + + try self.build_group.call(addCompileErrorAsync, self, parsed_file, span.first, span.last, text); + } + + async fn addCompileErrorAsync( + self: *Module, + parsed_file: *ParsedFile, + first_token: ast.TokenIndex, + last_token: ast.TokenIndex, + text: []u8, + ) !void { + const msg = try self.loop.allocator.create(errmsg.Msg{ + .path = parsed_file.realpath, + .text = text, + .span = errmsg.Span{ + .first = first_token, + .last = last_token, + }, + .tree = &parsed_file.tree, + }); + errdefer self.loop.allocator.destroy(msg); + + const compile_errors = await (async self.compile_errors.acquire() catch unreachable); + defer compile_errors.release(); + + try compile_errors.value.append(msg); + } + + async fn verifyUniqueSymbol(self: *Module, parsed_file: *ParsedFile, decl: *Decl) !void { const exported_symbol_names = await (async self.exported_symbol_names.acquire() catch unreachable); defer exported_symbol_names.release(); if (try exported_symbol_names.value.put(decl.name, decl)) |other_decl| { - @panic("TODO report compile error"); + try self.addCompileError( + parsed_file, + decl.getSpan(), + "exported symbol collision: '{}'", + decl.name, + ); } } @@ -503,6 +551,22 @@ pub const Decl = struct { } } + pub fn getSpan(base: *const Decl) errmsg.Span { + switch (base.id) { + Id.Fn => { + const fn_decl = @fieldParentPtr(Fn, "base", base); + const fn_proto = fn_decl.fn_proto; + const start = fn_proto.fn_token; + const end = fn_proto.name_token orelse start; + return errmsg.Span{ + .first = start, + .last = end + 1, + }; + }, + else => @panic("TODO"), + } + } + pub const Resolution = enum { Unresolved, InProgress, diff --git a/src-self-hosted/test.zig b/src-self-hosted/test.zig new file mode 100644 index 0000000000..7ce7cf6ee3 --- /dev/null +++ b/src-self-hosted/test.zig @@ -0,0 +1,176 @@ +const std = @import("std"); +const mem = std.mem; +const builtin = @import("builtin"); +const Target = @import("target.zig").Target; +const Module = @import("module.zig").Module; +const introspect = @import("introspect.zig"); +const assertOrPanic = std.debug.assertOrPanic; +const errmsg = @import("errmsg.zig"); + +test "compile errors" { + var ctx: TestContext = undefined; + try ctx.init(); + defer ctx.deinit(); + + try ctx.testCompileError( + \\export fn entry() void {} + \\export fn entry() void {} + , file1, 2, 8, "exported symbol collision: 'entry'"); + + try ctx.run(); +} + +const file1 = "1.zig"; + +const TestContext = struct { + loop: std.event.Loop, + zig_lib_dir: []u8, + direct_allocator: std.heap.DirectAllocator, + arena: std.heap.ArenaAllocator, + zig_cache_dir: []u8, + file_index: std.atomic.Int(usize), + group: std.event.Group(error!void), + any_err: error!void, + + const tmp_dir_name = "stage2_test_tmp"; + + fn init(self: *TestContext) !void { + self.* = TestContext{ + .any_err = {}, + .direct_allocator = undefined, + .arena = undefined, + .loop = undefined, + .zig_lib_dir = undefined, + .zig_cache_dir = undefined, + .group = undefined, + .file_index = std.atomic.Int(usize).init(0), + }; + + self.direct_allocator = std.heap.DirectAllocator.init(); + errdefer self.direct_allocator.deinit(); + + self.arena = std.heap.ArenaAllocator.init(&self.direct_allocator.allocator); + errdefer self.arena.deinit(); + + // TODO faster allocator for coroutines that is thread-safe/lock-free + try self.loop.initMultiThreaded(&self.direct_allocator.allocator); + errdefer self.loop.deinit(); + + self.group = std.event.Group(error!void).init(&self.loop); + errdefer self.group.cancelAll(); + + self.zig_lib_dir = try introspect.resolveZigLibDir(&self.arena.allocator); + errdefer self.arena.allocator.free(self.zig_lib_dir); + + self.zig_cache_dir = try introspect.resolveZigCacheDir(&self.arena.allocator); + errdefer self.arena.allocator.free(self.zig_cache_dir); + + try std.os.makePath(&self.arena.allocator, tmp_dir_name); + errdefer std.os.deleteTree(&self.arena.allocator, tmp_dir_name) catch {}; + } + + fn deinit(self: *TestContext) void { + std.os.deleteTree(&self.arena.allocator, tmp_dir_name) catch {}; + self.arena.allocator.free(self.zig_cache_dir); + self.arena.allocator.free(self.zig_lib_dir); + self.loop.deinit(); + self.arena.deinit(); + self.direct_allocator.deinit(); + } + + fn run(self: *TestContext) !void { + const handle = try self.loop.call(waitForGroup, self); + defer cancel handle; + self.loop.run(); + return self.any_err; + } + + async fn waitForGroup(self: *TestContext) void { + self.any_err = await (async self.group.wait() catch unreachable); + } + + fn testCompileError( + self: *TestContext, + source: []const u8, + path: []const u8, + line: usize, + column: usize, + msg: []const u8, + ) !void { + var file_index_buf: [20]u8 = undefined; + const file_index = try std.fmt.bufPrint(file_index_buf[0..], "{}", self.file_index.next()); + const file1_path = try std.os.path.join(&self.arena.allocator, tmp_dir_name, file_index, file1); + + if (std.os.path.dirname(file1_path)) |dirname| { + try std.os.makePath(&self.arena.allocator, dirname); + } + + // TODO async I/O + try std.io.writeFile(&self.arena.allocator, file1_path, source); + + var module = try Module.create( + &self.loop, + "test", + file1_path, + Target.Native, + Module.Kind.Obj, + builtin.Mode.Debug, + self.zig_lib_dir, + self.zig_cache_dir, + ); + errdefer module.destroy(); + + try module.build(); + + try self.group.call(getModuleEvent, module, source, path, line, column, msg); + } + + async fn getModuleEvent( + module: *Module, + source: []const u8, + path: []const u8, + line: usize, + column: usize, + text: []const u8, + ) !void { + defer module.destroy(); + const build_event = await (async module.events.get() catch unreachable); + + switch (build_event) { + Module.Event.Ok => { + @panic("build incorrectly succeeded"); + }, + Module.Event.Error => |err| { + @panic("build incorrectly failed"); + }, + Module.Event.Fail => |msgs| { + assertOrPanic(msgs.len != 0); + for (msgs) |msg| { + if (mem.endsWith(u8, msg.path, path) and mem.eql(u8, msg.text, text)) { + const first_token = msg.tree.tokens.at(msg.span.first); + const last_token = msg.tree.tokens.at(msg.span.first); + const start_loc = msg.tree.tokenLocationPtr(0, first_token); + if (start_loc.line + 1 == line and start_loc.column + 1 == column) { + return; + } + } + } + std.debug.warn( + "\n=====source:=======\n{}\n====expected:========\n{}:{}:{}: error: {}\n", + source, + path, + line, + column, + text, + ); + std.debug.warn("\n====found:========\n"); + var stderr = try std.io.getStdErr(); + for (msgs) |msg| { + try errmsg.printToFile(&stderr, msg, errmsg.Color.Auto); + } + std.debug.warn("============\n"); + return error.TestFailed; + }, + } + } +}; diff --git a/src/main.cpp b/src/main.cpp index a409778a78..5f96953f21 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -891,15 +891,19 @@ int main(int argc, char **argv) { add_package(g, cur_pkg, g->root_package); - if (cmd == CmdBuild || cmd == CmdRun) { - codegen_set_emit_file_type(g, emit_file_type); - + if (cmd == CmdBuild || cmd == CmdRun || cmd == CmdTest) { for (size_t i = 0; i < objects.length; i += 1) { codegen_add_object(g, buf_create_from_str(objects.at(i))); } for (size_t i = 0; i < asm_files.length; i += 1) { codegen_add_assembly(g, buf_create_from_str(asm_files.at(i))); } + } + + + if (cmd == CmdBuild || cmd == CmdRun) { + codegen_set_emit_file_type(g, emit_file_type); + codegen_build(g); codegen_link(g, out_file); if (timing_info) diff --git a/std/atomic/index.zig b/std/atomic/index.zig index c0ea5be183..cf344a8231 100644 --- a/std/atomic/index.zig +++ b/std/atomic/index.zig @@ -1,9 +1,11 @@ pub const Stack = @import("stack.zig").Stack; pub const QueueMpsc = @import("queue_mpsc.zig").QueueMpsc; pub const QueueMpmc = @import("queue_mpmc.zig").QueueMpmc; +pub const Int = @import("int.zig").Int; test "std.atomic" { _ = @import("stack.zig"); _ = @import("queue_mpsc.zig"); _ = @import("queue_mpmc.zig"); + _ = @import("int.zig"); } diff --git a/std/atomic/int.zig b/std/atomic/int.zig new file mode 100644 index 0000000000..7042bca78d --- /dev/null +++ b/std/atomic/int.zig @@ -0,0 +1,19 @@ +const builtin = @import("builtin"); +const AtomicOrder = builtin.AtomicOrder; + +/// Thread-safe, lock-free integer +pub fn Int(comptime T: type) type { + return struct { + value: T, + + pub const Self = this; + + pub fn init(init_val: T) Self { + return Self{ .value = init_val }; + } + + pub fn next(self: *Self) T { + return @atomicRmw(T, &self.value, builtin.AtomicRmwOp.Add, 1, AtomicOrder.SeqCst); + } + }; +} diff --git a/std/build.zig b/std/build.zig index 24fa85383a..cea760e8a2 100644 --- a/std/build.zig +++ b/std/build.zig @@ -1596,6 +1596,8 @@ pub const TestStep = struct { target: Target, exec_cmd_args: ?[]const ?[]const u8, include_dirs: ArrayList([]const u8), + lib_paths: ArrayList([]const u8), + object_files: ArrayList([]const u8), pub fn init(builder: *Builder, root_src: []const u8) TestStep { const step_name = builder.fmt("test {}", root_src); @@ -1611,9 +1613,15 @@ pub const TestStep = struct { .target = Target{ .Native = {} }, .exec_cmd_args = null, .include_dirs = ArrayList([]const u8).init(builder.allocator), + .lib_paths = ArrayList([]const u8).init(builder.allocator), + .object_files = ArrayList([]const u8).init(builder.allocator), }; } + pub fn addLibPath(self: *TestStep, path: []const u8) void { + self.lib_paths.append(path) catch unreachable; + } + pub fn setVerbose(self: *TestStep, value: bool) void { self.verbose = value; } @@ -1638,6 +1646,10 @@ pub const TestStep = struct { self.filter = text; } + pub fn addObjectFile(self: *TestStep, path: []const u8) void { + self.object_files.append(path) catch unreachable; + } + pub fn setTarget(self: *TestStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void { self.target = Target{ .Cross = CrossTarget{ @@ -1699,6 +1711,11 @@ pub const TestStep = struct { try zig_args.append(self.name_prefix); } + for (self.object_files.toSliceConst()) |object_file| { + try zig_args.append("--object"); + try zig_args.append(builder.pathFromRoot(object_file)); + } + { var it = self.link_libs.iterator(); while (true) { @@ -1734,6 +1751,11 @@ pub const TestStep = struct { try zig_args.append(rpath); } + for (self.lib_paths.toSliceConst()) |lib_path| { + try zig_args.append("--library-path"); + try zig_args.append(lib_path); + } + for (builder.lib_paths.toSliceConst()) |lib_path| { try zig_args.append("--library-path"); try zig_args.append(lib_path); -- cgit v1.2.3