authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 14:51:23-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-18 14:51:23-04:00
logc757984879687e465c6470fc1347cf0f14e46dcc
tree9827a65bfcc0041a279d8a75b567cba83f9c5b16
parent84a700f97240eb2d4c65554d9be43bae9fa6d4ae
parent1ca90b585692c9611c64412844d2f3a7b3e11340

Merge remote-tracking branch 'origin/master' into llvm7


110 files changed, 1812 insertions(+), 882 deletions(-)

CMakeLists.txt+2-1
......@@ -30,7 +30,7 @@ if(GIT_EXE)
3030 message("WARNING: Tag does not match configured Zig version")
3131 endif()
3232 else()
33 set(ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}.${ZIG_GIT_REV}")
33 set(ZIG_VERSION "${ZIG_VERSION}+${ZIG_GIT_REV}")
3434 endif()
3535endif()
3636message("Configuring zig version ${ZIG_VERSION}")
......@@ -438,6 +438,7 @@ set(ZIG_STD_FILES
438438 "debug/failing_allocator.zig"
439439 "debug/index.zig"
440440 "dwarf.zig"
441 "dynamic_library.zig"
441442 "elf.zig"
442443 "empty.zig"
443444 "event.zig"
doc/langref.html.in+198-58
......@@ -370,17 +370,17 @@ pub fn main() void {
370370 <tr>
371371 <td><code>f32</code></td>
372372 <td><code>float</code></td>
373 <td>32-bit floating point (23-bit mantissa)</td>
373 <td>32-bit floating point (23-bit mantissa) IEEE-754-2008 binary32</td>
374374 </tr>
375375 <tr>
376376 <td><code>f64</code></td>
377377 <td><code>double</code></td>
378 <td>64-bit floating point (52-bit mantissa)</td>
378 <td>64-bit floating point (52-bit mantissa) IEEE-754-2008 binary64</td>
379379 </tr>
380380 <tr>
381381 <td><code>f128</code></td>
382382 <td>(none)</td>
383 <td>128-bit floating point (112-bit mantissa)</td>
383 <td>128-bit floating point (112-bit mantissa) IEEE-754-2008 binary128</td>
384384 </tr>
385385 <tr>
386386 <td><code>bool</code></td>
......@@ -407,6 +407,16 @@ pub fn main() void {
407407 <td>(none)</td>
408408 <td>an error code</td>
409409 </tr>
410 <tr>
411 <td><code>comptime_int</code></td>
412 <td>(none)</td>
413 <td>Only allowed for {#link|comptime#}-known values. The type of integer literals.</td>
414 </tr>
415 <tr>
416 <td><code>comptime_float</code></td>
417 <td>(none)</td>
418 <td>Only allowed for {#link|comptime#}-known values. The type of float literals.</td>
419 </tr>
410420 </table>
411421 </div>
412422 {#see_also|Integers|Floats|void|Errors#}
......@@ -642,7 +652,18 @@ fn divide(a: i32, b: i32) i32 {
642652 {#header_close#}
643653 {#header_close#}
644654 {#header_open|Floats#}
655 <p>Zig has the following floating point types:</p>
656 <ul>
657 <li><code>f32</code> - IEEE-754-2008 binary32</li>
658 <li><code>f64</code> - IEEE-754-2008 binary64</li>
659 <li><code>f128</code> - IEEE-754-2008 binary128</li>
660 <li><code>c_longdouble</code> - matches <code>long double</code> for the target C ABI</li>
661 </ul>
645662 {#header_open|Float Literals#}
663 <p>
664 Float literals have type <code>comptime_float</code> which is guaranteed to hold at least all possible values
665 that the largest other floating point type can hold. Float literals implicitly cast to any other type.
666 </p>
646667 {#code_begin|syntax#}
647668const floating_point = 123.0E+77;
648669const another_float = 123.0;
......@@ -1334,7 +1355,7 @@ var some_integers: [100]i32 = undefined;
13341355
13351356test "modify an array" {
13361357 for (some_integers) |*item, i| {
1337 item.* = i32(i);
1358 item.* = @intCast(i32, i);
13381359 }
13391360 assert(some_integers[10] == 10);
13401361 assert(some_integers[99] == 99);
......@@ -1376,8 +1397,8 @@ var fancy_array = init: {
13761397 var initial_value: [10]Point = undefined;
13771398 for (initial_value) |*pt, i| {
13781399 pt.* = Point{
1379 .x = i32(i),
1380 .y = i32(i) * 2,
1400 .x = @intCast(i32, i),
1401 .y = @intCast(i32, i) * 2,
13811402 };
13821403 }
13831404 break :init initial_value;
......@@ -1630,7 +1651,7 @@ fn foo(bytes: []u8) u32 {
16301651 <pre><code class="zig">@ptrCast(*u32, f32(12.34)).*</code></pre>
16311652 <p>Instead, use {#link|@bitCast#}:
16321653 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
1633 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
1654 <p>As an added benefit, the <code>@bitCast</code> version works at compile-time.</p>
16341655 {#see_also|Slices|Memory#}
16351656 {#header_close#}
16361657 {#header_close#}
......@@ -2389,7 +2410,7 @@ test "for basics" {
23892410 var sum2: i32 = 0;
23902411 for (items) |value, i| {
23912412 assert(@typeOf(i) == usize);
2392 sum2 += i32(i);
2413 sum2 += @intCast(i32, i);
23932414 }
23942415 assert(sum2 == 10);
23952416}
......@@ -2797,39 +2818,30 @@ fn foo() void { }
27972818 {#code_end#}
27982819 {#header_open|Pass-by-value Parameters#}
27992820 <p>
2800 In Zig, structs, unions, and enums with payloads cannot be passed by value
2801 to a function.
2821 In Zig, structs, unions, and enums with payloads can be passed directly to a function:
28022822 </p>
2803 {#code_begin|test_err|not copyable; cannot pass by value#}
2804const Foo = struct {
2823 {#code_begin|test#}
2824const Point = struct {
28052825 x: i32,
2826 y: i32,
28062827};
28072828
2808fn bar(foo: Foo) void {}
2809
2810test "pass aggregate type by value to function" {
2811 bar(Foo {.x = 12,});
2829fn foo(point: Point) i32 {
2830 return point.x + point.y;
28122831}
2813 {#code_end#}
2814 <p>
2815 Instead, one must use <code>*const</code>. Zig allows implicitly casting something
2816 to a const pointer to it:
2817 </p>
2818 {#code_begin|test#}
2819const Foo = struct {
2820 x: i32,
2821};
28222832
2823fn bar(foo: *const Foo) void {}
2833const assert = @import("std").debug.assert;
28242834
2825test "implicitly cast to const pointer" {
2826 bar(Foo {.x = 12,});
2835test "pass aggregate type by non-copy value to function" {
2836 assert(foo(Point{ .x = 1, .y = 2 }) == 3);
28272837}
28282838 {#code_end#}
28292839 <p>
2830 However,
2831 the C ABI does allow passing structs and unions by value. So functions which
2832 use the C calling convention may pass structs and unions by value.
2840 In this case, the value may be passed by reference, or by value, whichever way
2841 Zig decides will be faster.
2842 </p>
2843 <p>
2844 For extern functions, Zig follows the C ABI for passing structs and unions by value.
28332845 </p>
28342846 {#header_close#}
28352847 {#header_open|Function Reflection#}
......@@ -3539,13 +3551,91 @@ const optional_value: ?i32 = null;
35393551 <p>TODO: ptrcast builtin</p>
35403552 <p>TODO: explain number literals vs concrete types</p>
35413553 {#header_close#}
3554
35423555 {#header_open|void#}
3543 <p>TODO: assigning void has no codegen</p>
3544 <p>TODO: hashmap with void becomes a set</p>
3545 <p>TODO: difference between c_void and void</p>
3546 <p>TODO: void is the default return value of functions</p>
3547 <p>TODO: functions require assigning the return value</p>
3556 <p>
3557 <code>void</code> represents a type that has no value. Code that makes use of void values is
3558 not included in the final generated code:
3559 </p>
3560 {#code_begin|syntax#}
3561export fn entry() void {
3562 var x: void = {};
3563 var y: void = {};
3564 x = y;
3565}
3566 {#code_end#}
3567 <p>When this turns into LLVM IR, there is no code generated in the body of <code>entry</code>,
3568 even in debug mode. For example, on x86_64:</p>
3569 <pre><code>0000000000000010 &lt;entry&gt;:
3570 10: 55 push %rbp
3571 11: 48 89 e5 mov %rsp,%rbp
3572 14: 5d pop %rbp
3573 15: c3 retq </code></pre>
3574 <p>These assembly instructions do not have any code associated with the void values -
3575 they only perform the function call prologue and epilog.</p>
3576 <p>
3577 <code>void</code> can be useful for instantiating generic types. For example, given a
3578 <code>Map(Key, Value)</code>, one can pass <code>void</code> for the <code>Value</code>
3579 type to make it into a <code>Set</code>:
3580 </p>
3581 {#code_begin|test#}
3582const std = @import("std");
3583const assert = std.debug.assert;
3584
3585test "turn HashMap into a set with void" {
3586 var map = std.HashMap(i32, void, hash_i32, eql_i32).init(std.debug.global_allocator);
3587 defer map.deinit();
3588
3589 _ = try map.put(1, {});
3590 _ = try map.put(2, {});
3591
3592 assert(map.contains(2));
3593 assert(!map.contains(3));
3594
3595 _ = map.remove(2);
3596 assert(!map.contains(2));
3597}
3598
3599fn hash_i32(x: i32) u32 {
3600 return @bitCast(u32, x);
3601}
3602
3603fn eql_i32(a: i32, b: i32) bool {
3604 return a == b;
3605}
3606 {#code_end#}
3607 <p>Note that this is different than using a dummy value for the hash map value.
3608 By using <code>void</code> as the type of the value, the hash map entry type has no value field, and
3609 thus the hash map takes up less space. Further, all the code that deals with storing and loading the
3610 value is deleted, as seen above.
3611 </p>
3612 <p>
3613 <code>void</code> is distinct from <code>c_void</code>, which is defined like this:
3614 <code>pub const c_void = @OpaqueType();</code>.
3615 <code>void</code> has a known size of 0 bytes, and <code>c_void</code> has an unknown, but non-zero, size.
3616 </p>
3617 <p>
3618 Expressions of type <code>void</code> are the only ones whose value can be ignored. For example:
3619 </p>
3620 {#code_begin|test_err|expression value is ignored#}
3621test "ignoring expression value" {
3622 foo();
3623}
3624
3625fn foo() i32 {
3626 return 1234;
3627}
3628 {#code_end#}
3629 <p>However, if the expression has type <code>void</code>:</p>
3630 {#code_begin|test#}
3631test "ignoring expression value" {
3632 foo();
3633}
3634
3635fn foo() void {}
3636 {#code_end#}
35483637 {#header_close#}
3638
35493639 {#header_open|this#}
35503640 <p>TODO: example of this referring to Self struct</p>
35513641 <p>TODO: example of this referring to recursion function</p>
......@@ -4548,6 +4638,19 @@ comptime {
45484638 </p>
45494639 {#see_also|Alignment#}
45504640 {#header_close#}
4641
4642 {#header_open|@boolToInt#}
4643 <pre><code class="zig">@boolToInt(value: bool) u1</code></pre>
4644 <p>
4645 Converts <code>true</code> to <code>u1(1)</code> and <code>false</code> to
4646 <code>u1(0)</code>.
4647 </p>
4648 <p>
4649 If the value is known at compile-time, the return type is <code>comptime_int</code>
4650 instead of <code>u1</code>.
4651 </p>
4652 {#header_close#}
4653
45514654 {#header_open|@cDefine#}
45524655 <pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre>
45534656 <p>
......@@ -4822,21 +4925,6 @@ test "main" {
48224925 Creates a symbol in the output object file.
48234926 </p>
48244927 {#header_close#}
4825 {#header_open|@tagName#}
4826 <pre><code class="zig">@tagName(value: var) []const u8</code></pre>
4827 <p>
4828 Converts an enum value or union value to a slice of bytes representing the name.
4829 </p>
4830 {#header_close#}
4831 {#header_open|@TagType#}
4832 <pre><code class="zig">@TagType(T: type) type</code></pre>
4833 <p>
4834 For an enum, returns the integer type that is used to store the enumeration value.
4835 </p>
4836 <p>
4837 For a union, returns the enum type that is used to store the tag value.
4838 </p>
4839 {#header_close#}
48404928 {#header_open|@errorName#}
48414929 <pre><code class="zig">@errorName(err: error) []u8</code></pre>
48424930 <p>
......@@ -4871,6 +4959,12 @@ test "main" {
48714959 </p>
48724960 {#see_also|Compile Variables#}
48734961 {#header_close#}
4962
4963 {#header_open|@field#}
4964 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre>
4965 <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p>
4966 {#header_close#}
4967
48744968 {#header_open|@fieldParentPtr#}
48754969 <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,
48764970 field_ptr: *T) *ParentType</code></pre>
......@@ -4878,6 +4972,23 @@ test "main" {
48784972 Given a pointer to a field, returns the base pointer of a struct.
48794973 </p>
48804974 {#header_close#}
4975
4976 {#header_open|@floatCast#}
4977 <pre><code class="zig">@floatCast(comptime DestType: type, value: var) DestType</code></pre>
4978 <p>
4979 Convert from one float type to another. This cast is safe, but may cause the
4980 numeric value to lose precision.
4981 </p>
4982 {#header_close#}
4983
4984 {#header_open|@floatToInt#}
4985 <pre><code class="zig">@floatToInt(comptime DestType: type, float: var) DestType</code></pre>
4986 <p>
4987 Converts the integer part of a floating point number to the destination type.
4988 To convert the other way, use {#link|@intToFloat#}. This cast is always safe.
4989 </p>
4990 {#header_close#}
4991
48814992 {#header_open|@frameAddress#}
48824993 <pre><code class="zig">@frameAddress()</code></pre>
48834994 <p>
......@@ -4932,12 +5043,30 @@ fn add(a: i32, b: i32) i32 { return a + b; }
49325043 </p>
49335044 {#see_also|@noInlineCall#}
49345045 {#header_close#}
5046
5047 {#header_open|@intCast#}
5048 <pre><code class="zig">@intCast(comptime DestType: type, int: var) DestType</code></pre>
5049 <p>
5050 Converts an integer to another integer while keeping the same numerical value.
5051 Attempting to convert a number which is out of range of the destination type results in
5052 {#link|Undefined Behavior#}.
5053 </p>
5054 {#header_close#}
5055
5056 {#header_open|@intToFloat#}
5057 <pre><code class="zig">@intToFloat(comptime DestType: type, int: var) DestType</code></pre>
5058 <p>
5059 Converts an integer to the closest floating point representation. To convert the other way, use {#link|@floatToInt#}. This cast is always safe.
5060 </p>
5061 {#header_close#}
5062
49355063 {#header_open|@intToPtr#}
49365064 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) DestType</code></pre>
49375065 <p>
49385066 Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}.
49395067 </p>
49405068 {#header_close#}
5069
49415070 {#header_open|@IntType#}
49425071 <pre><code class="zig">@IntType(comptime is_signed: bool, comptime bit_count: u8) type</code></pre>
49435072 <p>
......@@ -4975,10 +5104,6 @@ fn add(a: i32, b: i32) i32 { return a + b; }
49755104 It does not include functions, variables, or constants.
49765105 </p>
49775106 {#header_close#}
4978 {#header_open|@field#}
4979 <pre><code class="zig">@field(lhs: var, comptime field_name: []const u8) (field)</code></pre>
4980 <p>Preforms field access equivalent to <code>lhs.-&gtfield_name-&lt</code>.</p>
4981 {#header_close#}
49825107 {#header_open|@memberType#}
49835108 <pre><code class="zig">@memberType(comptime T: type, comptime index: usize) type</code></pre>
49845109 <p>Returns the field type of a struct or union.</p>
......@@ -5358,6 +5483,21 @@ pub const FloatMode = enum {
53585483 If no overflow or underflow occurs, returns <code>false</code>.
53595484 </p>
53605485 {#header_close#}
5486 {#header_open|@tagName#}
5487 <pre><code class="zig">@tagName(value: var) []const u8</code></pre>
5488 <p>
5489 Converts an enum value or union value to a slice of bytes representing the name.
5490 </p>
5491 {#header_close#}
5492 {#header_open|@TagType#}
5493 <pre><code class="zig">@TagType(T: type) type</code></pre>
5494 <p>
5495 For an enum, returns the integer type that is used to store the enumeration value.
5496 </p>
5497 <p>
5498 For a union, returns the enum type that is used to store the tag value.
5499 </p>
5500 {#header_close#}
53615501 {#header_open|@truncate#}
53625502 <pre><code class="zig">@truncate(comptime T: type, integer) T</code></pre>
53635503 <p>
......@@ -5718,7 +5858,7 @@ comptime {
57185858 {#code_begin|test_err|attempt to cast negative value to unsigned integer#}
57195859comptime {
57205860 const value: i32 = -1;
5721 const unsigned = u32(value);
5861 const unsigned = @intCast(u32, value);
57225862}
57235863 {#code_end#}
57245864 <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p>
......@@ -5732,7 +5872,7 @@ comptime {
57325872 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#}
57335873comptime {
57345874 const spartan_count: u16 = 300;
5735 const byte = u8(spartan_count);
5875 const byte = @intCast(u8, spartan_count);
57365876}
57375877 {#code_end#}
57385878 <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p>
......@@ -6653,7 +6793,7 @@ hljs.registerLanguage("zig", function(t) {
66536793 a = t.IR + "\\s*\\(",
66546794 c = {
66556795 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong resume cancel await async orelse",
6656 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
6796 built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
66576797 literal: "true false null undefined"
66586798 },
66596799 n = [e, t.CLCM, t.CBCM, s, r];
example/hello_world/hello_libc.zig+1-1
......@@ -8,7 +8,7 @@ const c = @cImport({
88const msg = c"Hello, world!\n";
99
1010export fn main(argc: c_int, argv: **u8) c_int {
11 if (c.printf(msg) != c_int(c.strlen(msg))) return -1;
11 if (c.printf(msg) != @intCast(c_int, c.strlen(msg))) return -1;
1212
1313 return 0;
1414}
src-self-hosted/main.zig+55-8
......@@ -700,6 +700,36 @@ const args_fmt_spec = []Flag{
700700 }),
701701};
702702
703const Fmt = struct {
704 seen: std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8),
705 queue: std.LinkedList([]const u8),
706 any_error: bool,
707
708 // file_path must outlive Fmt
709 fn addToQueue(self: *Fmt, file_path: []const u8) !void {
710 const new_node = try self.seen.allocator.construct(std.LinkedList([]const u8).Node{
711 .prev = undefined,
712 .next = undefined,
713 .data = file_path,
714 });
715
716 if (try self.seen.put(file_path, {})) |_| return;
717
718 self.queue.append(new_node);
719 }
720
721 fn addDirToQueue(self: *Fmt, file_path: []const u8) !void {
722 var dir = try std.os.Dir.open(self.seen.allocator, file_path);
723 defer dir.close();
724 while (try dir.next()) |entry| {
725 if (entry.kind == std.os.Dir.Entry.Kind.Directory or mem.endsWith(u8, entry.name, ".zig")) {
726 const full_path = try os.path.join(self.seen.allocator, file_path, entry.name);
727 try self.addToQueue(full_path);
728 }
729 }
730 }
731};
732
703733fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
704734 var flags = try Args.parse(allocator, args_fmt_spec, args);
705735 defer flags.deinit();
......@@ -728,21 +758,38 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
728758 }
729759 };
730760
731 var fmt_errors = false;
761 var fmt = Fmt{
762 .seen = std.HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator),
763 .queue = std.LinkedList([]const u8).init(),
764 .any_error = false,
765 };
766
732767 for (flags.positionals.toSliceConst()) |file_path| {
768 try fmt.addToQueue(file_path);
769 }
770
771 while (fmt.queue.popFirst()) |node| {
772 const file_path = node.data;
773
733774 var file = try os.File.openRead(allocator, file_path);
734775 defer file.close();
735776
736 const source_code = io.readFileAlloc(allocator, file_path) catch |err| {
737 try stderr.print("unable to open '{}': {}\n", file_path, err);
738 fmt_errors = true;
739 continue;
777 const source_code = io.readFileAlloc(allocator, file_path) catch |err| switch (err) {
778 error.IsDir => {
779 try fmt.addDirToQueue(file_path);
780 continue;
781 },
782 else => {
783 try stderr.print("unable to open '{}': {}\n", file_path, err);
784 fmt.any_error = true;
785 continue;
786 },
740787 };
741788 defer allocator.free(source_code);
742789
743790 var tree = std.zig.parse(allocator, source_code) catch |err| {
744791 try stderr.print("error parsing file '{}': {}\n", file_path, err);
745 fmt_errors = true;
792 fmt.any_error = true;
746793 continue;
747794 };
748795 defer tree.deinit();
......@@ -755,7 +802,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
755802 try errmsg.printToFile(&stderr_file, msg, color);
756803 }
757804 if (tree.errors.len != 0) {
758 fmt_errors = true;
805 fmt.any_error = true;
759806 continue;
760807 }
761808
......@@ -769,7 +816,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
769816 }
770817 }
771818
772 if (fmt_errors) {
819 if (fmt.any_error) {
773820 os.exit(1);
774821 }
775822}
src/all_types.hpp+44
......@@ -1357,6 +1357,11 @@ enum BuiltinFnId {
13571357 BuiltinFnIdMod,
13581358 BuiltinFnIdSqrt,
13591359 BuiltinFnIdTruncate,
1360 BuiltinFnIdIntCast,
1361 BuiltinFnIdFloatCast,
1362 BuiltinFnIdIntToFloat,
1363 BuiltinFnIdFloatToInt,
1364 BuiltinFnIdBoolToInt,
13601365 BuiltinFnIdIntType,
13611366 BuiltinFnIdSetCold,
13621367 BuiltinFnIdSetRuntimeSafety,
......@@ -2038,6 +2043,11 @@ enum IrInstructionId {
20382043 IrInstructionIdCmpxchg,
20392044 IrInstructionIdFence,
20402045 IrInstructionIdTruncate,
2046 IrInstructionIdIntCast,
2047 IrInstructionIdFloatCast,
2048 IrInstructionIdIntToFloat,
2049 IrInstructionIdFloatToInt,
2050 IrInstructionIdBoolToInt,
20412051 IrInstructionIdIntType,
20422052 IrInstructionIdBoolNot,
20432053 IrInstructionIdMemset,
......@@ -2630,6 +2640,40 @@ struct IrInstructionTruncate {
26302640 IrInstruction *target;
26312641};
26322642
2643struct IrInstructionIntCast {
2644 IrInstruction base;
2645
2646 IrInstruction *dest_type;
2647 IrInstruction *target;
2648};
2649
2650struct IrInstructionFloatCast {
2651 IrInstruction base;
2652
2653 IrInstruction *dest_type;
2654 IrInstruction *target;
2655};
2656
2657struct IrInstructionIntToFloat {
2658 IrInstruction base;
2659
2660 IrInstruction *dest_type;
2661 IrInstruction *target;
2662};
2663
2664struct IrInstructionFloatToInt {
2665 IrInstruction base;
2666
2667 IrInstruction *dest_type;
2668 IrInstruction *target;
2669};
2670
2671struct IrInstructionBoolToInt {
2672 IrInstruction base;
2673
2674 IrInstruction *target;
2675};
2676
26332677struct IrInstructionIntType {
26342678 IrInstruction base;
26352679
src/analyze.cpp+5-7
......@@ -1022,6 +1022,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
10221022 ensure_complete_type(g, fn_type_id->return_type);
10231023 if (type_is_invalid(fn_type_id->return_type))
10241024 return g->builtin_types.entry_invalid;
1025 assert(fn_type_id->return_type->id != TypeTableEntryIdOpaque);
10251026 } else {
10261027 zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447");
10271028 }
......@@ -1135,7 +1136,10 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
11351136 gen_param_info->src_index = i;
11361137 gen_param_info->gen_index = SIZE_MAX;
11371138
1138 type_ensure_zero_bits_known(g, type_entry);
1139 ensure_complete_type(g, type_entry);
1140 if (type_is_invalid(type_entry))
1141 return g->builtin_types.entry_invalid;
1142
11391143 if (type_has_bits(type_entry)) {
11401144 TypeTableEntry *gen_type;
11411145 if (handle_is_ptr(type_entry)) {
......@@ -1546,12 +1550,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
15461550 case TypeTableEntryIdUnion:
15471551 case TypeTableEntryIdFn:
15481552 case TypeTableEntryIdPromise:
1549 ensure_complete_type(g, type_entry);
1550 if (calling_convention_allows_zig_types(fn_type_id.cc) && !type_is_copyable(g, type_entry)) {
1551 add_node_error(g, param_node->data.param_decl.type,
1552 buf_sprintf("type '%s' is not copyable; cannot pass by value", buf_ptr(&type_entry->name)));
1553 return g->builtin_types.entry_invalid;
1554 }
15551553 break;
15561554 }
15571555 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];
src/codegen.cpp+16-31
......@@ -326,17 +326,6 @@ static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char
326326 return addLLVMAttr(fn_val, param_index + 1, attr_name);
327327}
328328
329//static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) {
330// return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val);
331//}
332
333static void addLLVMCallsiteAttr(LLVMValueRef call_instr, unsigned param_index, const char *attr_name) {
334 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
335 assert(kind_id != 0);
336 LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), kind_id, 0);
337 LLVMAddCallSiteAttribute(call_instr, param_index + 1, llvm_attr);
338}
339
340329static bool is_symbol_available(CodeGen *g, Buf *name) {
341330 return g->exported_symbol_names.maybe_get(name) == nullptr && g->external_prototypes.maybe_get(name) == nullptr;
342331}
......@@ -585,11 +574,6 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
585574 if (param_type->id == TypeTableEntryIdPointer) {
586575 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull");
587576 }
588 // Note: byval is disabled on windows due to an LLVM bug:
589 // https://github.com/ziglang/zig/issues/536
590 if (is_byval && g->zig_target.os != OsWindows) {
591 addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval");
592 }
593577 }
594578
595579 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry);
......@@ -3053,15 +3037,6 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr
30533037 }
30543038
30553039
3056 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {
3057 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
3058 // Note: byval is disabled on windows due to an LLVM bug:
3059 // https://github.com/ziglang/zig/issues/536
3060 if (gen_info->is_byval && g->zig_target.os != OsWindows) {
3061 addLLVMCallsiteAttr(result, (unsigned)gen_info->gen_index, "byval");
3062 }
3063 }
3064
30653040 if (instruction->is_async) {
30663041 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, instruction->tmp_ptr, err_union_payload_index, "");
30673042 LLVMBuildStore(g->builder, result, payload_ptr);
......@@ -4658,6 +4633,11 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
46584633 case IrInstructionIdPromiseResultType:
46594634 case IrInstructionIdAwaitBookkeeping:
46604635 case IrInstructionIdAddImplicitReturnType:
4636 case IrInstructionIdIntCast:
4637 case IrInstructionIdFloatCast:
4638 case IrInstructionIdIntToFloat:
4639 case IrInstructionIdFloatToInt:
4640 case IrInstructionIdBoolToInt:
46614641 zig_unreachable();
46624642
46634643 case IrInstructionIdReturn:
......@@ -6246,6 +6226,11 @@ static void define_builtin_fns(CodeGen *g) {
62466226 create_builtin_fn(g, BuiltinFnIdCmpxchgStrong, "cmpxchgStrong", 6);
62476227 create_builtin_fn(g, BuiltinFnIdFence, "fence", 1);
62486228 create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2);
6229 create_builtin_fn(g, BuiltinFnIdIntCast, "intCast", 2);
6230 create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2);
6231 create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2);
6232 create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2);
6233 create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1);
62496234 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
62506235 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
62516236 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
......@@ -6683,7 +6668,7 @@ static void define_builtin_compile_vars(CodeGen *g) {
66836668 int err;
66846669 Buf *abs_full_path = buf_alloc();
66856670 if ((err = os_path_real(builtin_zig_path, abs_full_path))) {
6686 fprintf(stderr, "unable to open '%s': %s", buf_ptr(builtin_zig_path), err_str(err));
6671 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err));
66876672 exit(1);
66886673 }
66896674
......@@ -6851,11 +6836,11 @@ static ImportTableEntry *add_special_code(CodeGen *g, PackageTableEntry *package
68516836 Buf *abs_full_path = buf_alloc();
68526837 int err;
68536838 if ((err = os_path_real(&path_to_code_src, abs_full_path))) {
6854 zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err));
6839 zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
68556840 }
68566841 Buf *import_code = buf_alloc();
68576842 if ((err = os_fetch_file_path(abs_full_path, import_code, false))) {
6858 zig_panic("unable to open '%s': %s", buf_ptr(&path_to_code_src), err_str(err));
6843 zig_panic("unable to open '%s': %s\n", buf_ptr(&path_to_code_src), err_str(err));
68596844 }
68606845
68616846 return add_source_file(g, package, abs_full_path, import_code);
......@@ -6939,13 +6924,13 @@ static void gen_root_source(CodeGen *g) {
69396924 Buf *abs_full_path = buf_alloc();
69406925 int err;
69416926 if ((err = os_path_real(rel_full_path, abs_full_path))) {
6942 fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err));
6927 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err));
69436928 exit(1);
69446929 }
69456930
69466931 Buf *source_code = buf_alloc();
69476932 if ((err = os_fetch_file_path(rel_full_path, source_code, true))) {
6948 fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err));
6933 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(rel_full_path), err_str(err));
69496934 exit(1);
69506935 }
69516936
......@@ -7289,7 +7274,7 @@ static void gen_h_file(CodeGen *g) {
72897274
72907275 FILE *out_h = fopen(buf_ptr(g->out_h_path), "wb");
72917276 if (!out_h)
7292 zig_panic("unable to open %s: %s", buf_ptr(g->out_h_path), strerror(errno));
7277 zig_panic("unable to open %s: %s\n", buf_ptr(g->out_h_path), strerror(errno));
72937278
72947279 Buf *export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name)));
72957280 buf_upcase(export_macro);
src/ir.cpp+366-50
......@@ -460,6 +460,26 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) {
460460 return IrInstructionIdTruncate;
461461}
462462
463static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) {
464 return IrInstructionIdIntCast;
465}
466
467static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) {
468 return IrInstructionIdFloatCast;
469}
470
471static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) {
472 return IrInstructionIdIntToFloat;
473}
474
475static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) {
476 return IrInstructionIdFloatToInt;
477}
478
479static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) {
480 return IrInstructionIdBoolToInt;
481}
482
463483static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) {
464484 return IrInstructionIdIntType;
465485}
......@@ -1899,10 +1919,57 @@ static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *s
18991919 return &instruction->base;
19001920}
19011921
1902static IrInstruction *ir_build_truncate_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *dest_type, IrInstruction *target) {
1903 IrInstruction *new_instruction = ir_build_truncate(irb, old_instruction->scope, old_instruction->source_node, dest_type, target);
1904 ir_link_new_instruction(new_instruction, old_instruction);
1905 return new_instruction;
1922static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {
1923 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node);
1924 instruction->dest_type = dest_type;
1925 instruction->target = target;
1926
1927 ir_ref_instruction(dest_type, irb->current_basic_block);
1928 ir_ref_instruction(target, irb->current_basic_block);
1929
1930 return &instruction->base;
1931}
1932
1933static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {
1934 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node);
1935 instruction->dest_type = dest_type;
1936 instruction->target = target;
1937
1938 ir_ref_instruction(dest_type, irb->current_basic_block);
1939 ir_ref_instruction(target, irb->current_basic_block);
1940
1941 return &instruction->base;
1942}
1943
1944static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {
1945 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node);
1946 instruction->dest_type = dest_type;
1947 instruction->target = target;
1948
1949 ir_ref_instruction(dest_type, irb->current_basic_block);
1950 ir_ref_instruction(target, irb->current_basic_block);
1951
1952 return &instruction->base;
1953}
1954
1955static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) {
1956 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node);
1957 instruction->dest_type = dest_type;
1958 instruction->target = target;
1959
1960 ir_ref_instruction(dest_type, irb->current_basic_block);
1961 ir_ref_instruction(target, irb->current_basic_block);
1962
1963 return &instruction->base;
1964}
1965
1966static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) {
1967 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node);
1968 instruction->target = target;
1969
1970 ir_ref_instruction(target, irb->current_basic_block);
1971
1972 return &instruction->base;
19061973}
19071974
19081975static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) {
......@@ -3957,6 +4024,76 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
39574024 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value);
39584025 return ir_lval_wrap(irb, scope, truncate, lval);
39594026 }
4027 case BuiltinFnIdIntCast:
4028 {
4029 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4030 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4031 if (arg0_value == irb->codegen->invalid_instruction)
4032 return arg0_value;
4033
4034 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4035 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4036 if (arg1_value == irb->codegen->invalid_instruction)
4037 return arg1_value;
4038
4039 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value);
4040 return ir_lval_wrap(irb, scope, result, lval);
4041 }
4042 case BuiltinFnIdFloatCast:
4043 {
4044 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4045 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4046 if (arg0_value == irb->codegen->invalid_instruction)
4047 return arg0_value;
4048
4049 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4050 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4051 if (arg1_value == irb->codegen->invalid_instruction)
4052 return arg1_value;
4053
4054 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value);
4055 return ir_lval_wrap(irb, scope, result, lval);
4056 }
4057 case BuiltinFnIdIntToFloat:
4058 {
4059 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4060 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4061 if (arg0_value == irb->codegen->invalid_instruction)
4062 return arg0_value;
4063
4064 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4065 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4066 if (arg1_value == irb->codegen->invalid_instruction)
4067 return arg1_value;
4068
4069 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value);
4070 return ir_lval_wrap(irb, scope, result, lval);
4071 }
4072 case BuiltinFnIdFloatToInt:
4073 {
4074 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4075 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4076 if (arg0_value == irb->codegen->invalid_instruction)
4077 return arg0_value;
4078
4079 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4080 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4081 if (arg1_value == irb->codegen->invalid_instruction)
4082 return arg1_value;
4083
4084 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value);
4085 return ir_lval_wrap(irb, scope, result, lval);
4086 }
4087 case BuiltinFnIdBoolToInt:
4088 {
4089 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4090 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4091 if (arg0_value == irb->codegen->invalid_instruction)
4092 return arg0_value;
4093
4094 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
4095 return ir_lval_wrap(irb, scope, result, lval);
4096 }
39604097 case BuiltinFnIdIntType:
39614098 {
39624099 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
......@@ -9941,41 +10078,37 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
994110078 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false);
994210079 }
994310080
9944 // explicit cast from bool to int
10081 // explicit widening conversion
994510082 if (wanted_type->id == TypeTableEntryIdInt &&
9946 actual_type->id == TypeTableEntryIdBool)
9947 {
9948 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBoolToInt, false);
9949 }
9950
9951 // explicit widening or shortening cast
9952 if ((wanted_type->id == TypeTableEntryIdInt &&
9953 actual_type->id == TypeTableEntryIdInt) ||
9954 (wanted_type->id == TypeTableEntryIdFloat &&
9955 actual_type->id == TypeTableEntryIdFloat))
10083 actual_type->id == TypeTableEntryIdInt &&
10084 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed &&
10085 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count)
995610086 {
995710087 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
995810088 }
995910089
9960 // explicit error set cast
9961 if (wanted_type->id == TypeTableEntryIdErrorSet &&
9962 actual_type->id == TypeTableEntryIdErrorSet)
10090 // small enough unsigned ints can get casted to large enough signed ints
10091 if (wanted_type->id == TypeTableEntryIdInt && wanted_type->data.integral.is_signed &&
10092 actual_type->id == TypeTableEntryIdInt && !actual_type->data.integral.is_signed &&
10093 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count)
996310094 {
9964 return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type);
10095 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
996510096 }
996610097
9967 // explicit cast from int to float
10098 // explicit float widening conversion
996810099 if (wanted_type->id == TypeTableEntryIdFloat &&
9969 actual_type->id == TypeTableEntryIdInt)
10100 actual_type->id == TypeTableEntryIdFloat &&
10101 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count)
997010102 {
9971 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpIntToFloat, false);
10103 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type);
997210104 }
997310105
9974 // explicit cast from float to int
9975 if (wanted_type->id == TypeTableEntryIdInt &&
9976 actual_type->id == TypeTableEntryIdFloat)
10106
10107 // explicit error set cast
10108 if (wanted_type->id == TypeTableEntryIdErrorSet &&
10109 actual_type->id == TypeTableEntryIdErrorSet)
997710110 {
9978 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpFloatToInt, false);
10111 return ir_analyze_err_set_cast(ira, source_instr, value, wanted_type);
997910112 }
998010113
998110114 // explicit cast from [N]T to []const T
......@@ -10463,13 +10596,6 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ
1046310596 zig_unreachable();
1046410597}
1046510598
10466static IrInstruction *ir_implicit_byval_const_ref_cast(IrAnalyze *ira, IrInstruction *inst) {
10467 if (type_is_copyable(ira->codegen, inst->value.type))
10468 return inst;
10469 TypeTableEntry *const_ref_type = get_pointer_to_type(ira->codegen, inst->value.type, true);
10470 return ir_implicit_cast(ira, inst, const_ref_type);
10471}
10472
1047310599static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) {
1047410600 TypeTableEntry *type_entry = ptr->value.type;
1047510601 if (type_is_invalid(type_entry)) {
......@@ -12283,7 +12409,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1228312409 IrInstruction *casted_arg;
1228412410 if (is_var_args) {
1228512411 arg_part_of_generic_id = true;
12286 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
12412 casted_arg = arg;
1228712413 } else {
1228812414 if (param_decl_node->data.param_decl.var_token == nullptr) {
1228912415 AstNode *param_type_node = param_decl_node->data.param_decl.type;
......@@ -12296,7 +12422,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
1229612422 return false;
1229712423 } else {
1229812424 arg_part_of_generic_id = true;
12299 casted_arg = ir_implicit_byval_const_ref_cast(ira, arg);
12425 casted_arg = arg;
1230012426 }
1230112427 }
1230212428
......@@ -12515,9 +12641,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1251512641
1251612642 size_t next_proto_i = 0;
1251712643 if (first_arg_ptr) {
12518 IrInstruction *first_arg;
1251912644 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12520 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12645
12646 bool first_arg_known_bare = false;
12647 if (fn_type_id->next_param_index >= 1) {
12648 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12649 if (type_is_invalid(param_type))
12650 return ira->codegen->builtin_types.entry_invalid;
12651 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12652 }
12653
12654 IrInstruction *first_arg;
12655 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1252112656 first_arg = first_arg_ptr;
1252212657 } else {
1252312658 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12667,9 +12802,18 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1266712802 size_t next_proto_i = 0;
1266812803
1266912804 if (first_arg_ptr) {
12670 IrInstruction *first_arg;
1267112805 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12672 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
12806
12807 bool first_arg_known_bare = false;
12808 if (fn_type_id->next_param_index >= 1) {
12809 TypeTableEntry *param_type = fn_type_id->param_info[next_proto_i].type;
12810 if (type_is_invalid(param_type))
12811 return ira->codegen->builtin_types.entry_invalid;
12812 first_arg_known_bare = param_type->id != TypeTableEntryIdPointer;
12813 }
12814
12815 IrInstruction *first_arg;
12816 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
1267312817 first_arg = first_arg_ptr;
1267412818 } else {
1267512819 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12802,10 +12946,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1280212946 return ira->codegen->builtin_types.entry_invalid;
1280312947 }
1280412948 if (inst_fn_type_id.async_allocator_type == nullptr) {
12805 IrInstruction *casted_inst = ir_implicit_byval_const_ref_cast(ira, uncasted_async_allocator_inst);
12806 if (type_is_invalid(casted_inst->value.type))
12807 return ira->codegen->builtin_types.entry_invalid;
12808 inst_fn_type_id.async_allocator_type = casted_inst->value.type;
12949 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type;
1280912950 }
1281012951 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type);
1281112952 if (type_is_invalid(async_allocator_inst->value.type))
......@@ -12866,9 +13007,16 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1286613007 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count);
1286713008 size_t next_arg_index = 0;
1286813009 if (first_arg_ptr) {
12869 IrInstruction *first_arg;
1287013010 assert(first_arg_ptr->value.type->id == TypeTableEntryIdPointer);
12871 if (handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) {
13011
13012 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
13013 if (type_is_invalid(param_type))
13014 return ira->codegen->builtin_types.entry_invalid;
13015
13016 IrInstruction *first_arg;
13017 if (param_type->id == TypeTableEntryIdPointer &&
13018 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type))
13019 {
1287213020 first_arg = first_arg_ptr;
1287313021 } else {
1287413022 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr);
......@@ -12876,10 +13024,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
1287613024 return ira->codegen->builtin_types.entry_invalid;
1287713025 }
1287813026
12879 TypeTableEntry *param_type = fn_type_id->param_info[next_arg_index].type;
12880 if (type_is_invalid(param_type))
12881 return ira->codegen->builtin_types.entry_invalid;
12882
1288313027 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type);
1288413028 if (type_is_invalid(casted_arg->value.type))
1288513029 return ira->codegen->builtin_types.entry_invalid;
......@@ -17354,10 +17498,162 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc
1735417498 return dest_type;
1735517499 }
1735617500
17357 ir_build_truncate_from(&ira->new_irb, &instruction->base, dest_type_value, target);
17501 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope,
17502 instruction->base.source_node, dest_type_value, target);
17503 ir_link_new_instruction(new_instruction, &instruction->base);
1735817504 return dest_type;
1735917505}
1736017506
17507static TypeTableEntry *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) {
17508 TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other);
17509 if (type_is_invalid(dest_type))
17510 return ira->codegen->builtin_types.entry_invalid;
17511
17512 if (dest_type->id != TypeTableEntryIdInt) {
17513 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name)));
17514 return ira->codegen->builtin_types.entry_invalid;
17515 }
17516
17517 IrInstruction *target = instruction->target->other;
17518 if (type_is_invalid(target->value.type))
17519 return ira->codegen->builtin_types.entry_invalid;
17520
17521 if (target->value.type->id == TypeTableEntryIdComptimeInt) {
17522 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) {
17523 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type,
17524 CastOpNumLitToConcrete, false);
17525 if (type_is_invalid(result->value.type))
17526 return ira->codegen->builtin_types.entry_invalid;
17527 ir_link_new_instruction(result, &instruction->base);
17528 return dest_type;
17529 } else {
17530 return ira->codegen->builtin_types.entry_invalid;
17531 }
17532 }
17533
17534 if (target->value.type->id != TypeTableEntryIdInt) {
17535 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'",
17536 buf_ptr(&target->value.type->name)));
17537 return ira->codegen->builtin_types.entry_invalid;
17538 }
17539
17540 IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type);
17541 if (type_is_invalid(result->value.type))
17542 return ira->codegen->builtin_types.entry_invalid;
17543
17544 ir_link_new_instruction(result, &instruction->base);
17545 return dest_type;
17546}
17547
17548static TypeTableEntry *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) {
17549 TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other);
17550 if (type_is_invalid(dest_type))
17551 return ira->codegen->builtin_types.entry_invalid;
17552
17553 if (dest_type->id != TypeTableEntryIdFloat) {
17554 ir_add_error(ira, instruction->dest_type,
17555 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name)));
17556 return ira->codegen->builtin_types.entry_invalid;
17557 }
17558
17559 IrInstruction *target = instruction->target->other;
17560 if (type_is_invalid(target->value.type))
17561 return ira->codegen->builtin_types.entry_invalid;
17562
17563 if (target->value.type->id == TypeTableEntryIdComptimeInt ||
17564 target->value.type->id == TypeTableEntryIdComptimeFloat)
17565 {
17566 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) {
17567 CastOp op;
17568 if (target->value.type->id == TypeTableEntryIdComptimeInt) {
17569 op = CastOpIntToFloat;
17570 } else {
17571 op = CastOpNumLitToConcrete;
17572 }
17573 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false);
17574 if (type_is_invalid(result->value.type))
17575 return ira->codegen->builtin_types.entry_invalid;
17576 ir_link_new_instruction(result, &instruction->base);
17577 return dest_type;
17578 } else {
17579 return ira->codegen->builtin_types.entry_invalid;
17580 }
17581 }
17582
17583 if (target->value.type->id != TypeTableEntryIdFloat) {
17584 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'",
17585 buf_ptr(&target->value.type->name)));
17586 return ira->codegen->builtin_types.entry_invalid;
17587 }
17588
17589 IrInstruction *result = ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type);
17590 if (type_is_invalid(result->value.type))
17591 return ira->codegen->builtin_types.entry_invalid;
17592 ir_link_new_instruction(result, &instruction->base);
17593 return dest_type;
17594}
17595
17596static TypeTableEntry *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) {
17597 TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other);
17598 if (type_is_invalid(dest_type))
17599 return ira->codegen->builtin_types.entry_invalid;
17600
17601 IrInstruction *target = instruction->target->other;
17602 if (type_is_invalid(target->value.type))
17603 return ira->codegen->builtin_types.entry_invalid;
17604
17605 if (target->value.type->id != TypeTableEntryIdInt && target->value.type->id != TypeTableEntryIdComptimeInt) {
17606 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'",
17607 buf_ptr(&target->value.type->name)));
17608 return ira->codegen->builtin_types.entry_invalid;
17609 }
17610
17611 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false);
17612 ir_link_new_instruction(result, &instruction->base);
17613 return dest_type;
17614}
17615
17616static TypeTableEntry *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) {
17617 TypeTableEntry *dest_type = ir_resolve_type(ira, instruction->dest_type->other);
17618 if (type_is_invalid(dest_type))
17619 return ira->codegen->builtin_types.entry_invalid;
17620
17621 IrInstruction *target = instruction->target->other;
17622 if (type_is_invalid(target->value.type))
17623 return ira->codegen->builtin_types.entry_invalid;
17624
17625 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false);
17626 ir_link_new_instruction(result, &instruction->base);
17627 return dest_type;
17628}
17629
17630static TypeTableEntry *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) {
17631 IrInstruction *target = instruction->target->other;
17632 if (type_is_invalid(target->value.type))
17633 return ira->codegen->builtin_types.entry_invalid;
17634
17635 if (target->value.type->id != TypeTableEntryIdBool) {
17636 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'",
17637 buf_ptr(&target->value.type->name)));
17638 return ira->codegen->builtin_types.entry_invalid;
17639 }
17640
17641 if (instr_is_comptime(target)) {
17642 bool is_true;
17643 if (!ir_resolve_bool(ira, target, &is_true))
17644 return ira->codegen->builtin_types.entry_invalid;
17645
17646 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
17647 bigint_init_unsigned(&out_val->data.x_bigint, is_true ? 1 : 0);
17648 return ira->codegen->builtin_types.entry_num_lit_int;
17649 }
17650
17651 TypeTableEntry *u1_type = get_int_type(ira->codegen, false, 1);
17652 IrInstruction *result = ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false);
17653 ir_link_new_instruction(result, &instruction->base);
17654 return u1_type;
17655}
17656
1736117657static TypeTableEntry *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) {
1736217658 IrInstruction *is_signed_value = instruction->is_signed->other;
1736317659 bool is_signed;
......@@ -18380,6 +18676,11 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc
1838018676 fn_type_id.return_type = ir_resolve_type(ira, return_type_value);
1838118677 if (type_is_invalid(fn_type_id.return_type))
1838218678 return ira->codegen->builtin_types.entry_invalid;
18679 if (fn_type_id.return_type->id == TypeTableEntryIdOpaque) {
18680 ir_add_error(ira, instruction->return_type,
18681 buf_sprintf("return type cannot be opaque"));
18682 return ira->codegen->builtin_types.entry_invalid;
18683 }
1838318684
1838418685 if (fn_type_id.cc == CallingConventionAsync) {
1838518686 if (instruction->async_allocator_type_value == nullptr) {
......@@ -19888,6 +20189,16 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1988820189 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction);
1988920190 case IrInstructionIdTruncate:
1989020191 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction);
20192 case IrInstructionIdIntCast:
20193 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction);
20194 case IrInstructionIdFloatCast:
20195 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction);
20196 case IrInstructionIdIntToFloat:
20197 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction);
20198 case IrInstructionIdFloatToInt:
20199 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction);
20200 case IrInstructionIdBoolToInt:
20201 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction);
1989120202 case IrInstructionIdIntType:
1989220203 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction);
1989320204 case IrInstructionIdBoolNot:
......@@ -20231,6 +20542,11 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2023120542 case IrInstructionIdPromiseResultType:
2023220543 case IrInstructionIdSqrt:
2023320544 case IrInstructionIdAtomicLoad:
20545 case IrInstructionIdIntCast:
20546 case IrInstructionIdFloatCast:
20547 case IrInstructionIdIntToFloat:
20548 case IrInstructionIdFloatToInt:
20549 case IrInstructionIdBoolToInt:
2023420550 return false;
2023520551
2023620552 case IrInstructionIdAsm:
src/ir_print.cpp+53
......@@ -648,6 +648,44 @@ static void ir_print_truncate(IrPrint *irp, IrInstructionTruncate *instruction)
648648 fprintf(irp->f, ")");
649649}
650650
651static void ir_print_int_cast(IrPrint *irp, IrInstructionIntCast *instruction) {
652 fprintf(irp->f, "@intCast(");
653 ir_print_other_instruction(irp, instruction->dest_type);
654 fprintf(irp->f, ", ");
655 ir_print_other_instruction(irp, instruction->target);
656 fprintf(irp->f, ")");
657}
658
659static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instruction) {
660 fprintf(irp->f, "@floatCast(");
661 ir_print_other_instruction(irp, instruction->dest_type);
662 fprintf(irp->f, ", ");
663 ir_print_other_instruction(irp, instruction->target);
664 fprintf(irp->f, ")");
665}
666
667static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) {
668 fprintf(irp->f, "@intToFloat(");
669 ir_print_other_instruction(irp, instruction->dest_type);
670 fprintf(irp->f, ", ");
671 ir_print_other_instruction(irp, instruction->target);
672 fprintf(irp->f, ")");
673}
674
675static void ir_print_float_to_int(IrPrint *irp, IrInstructionFloatToInt *instruction) {
676 fprintf(irp->f, "@floatToInt(");
677 ir_print_other_instruction(irp, instruction->dest_type);
678 fprintf(irp->f, ", ");
679 ir_print_other_instruction(irp, instruction->target);
680 fprintf(irp->f, ")");
681}
682
683static void ir_print_bool_to_int(IrPrint *irp, IrInstructionBoolToInt *instruction) {
684 fprintf(irp->f, "@boolToInt(");
685 ir_print_other_instruction(irp, instruction->target);
686 fprintf(irp->f, ")");
687}
688
651689static void ir_print_int_type(IrPrint *irp, IrInstructionIntType *instruction) {
652690 fprintf(irp->f, "@IntType(");
653691 ir_print_other_instruction(irp, instruction->is_signed);
......@@ -1417,6 +1455,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14171455 case IrInstructionIdTruncate:
14181456 ir_print_truncate(irp, (IrInstructionTruncate *)instruction);
14191457 break;
1458 case IrInstructionIdIntCast:
1459 ir_print_int_cast(irp, (IrInstructionIntCast *)instruction);
1460 break;
1461 case IrInstructionIdFloatCast:
1462 ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction);
1463 break;
1464 case IrInstructionIdIntToFloat:
1465 ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction);
1466 break;
1467 case IrInstructionIdFloatToInt:
1468 ir_print_float_to_int(irp, (IrInstructionFloatToInt *)instruction);
1469 break;
1470 case IrInstructionIdBoolToInt:
1471 ir_print_bool_to_int(irp, (IrInstructionBoolToInt *)instruction);
1472 break;
14201473 case IrInstructionIdIntType:
14211474 ir_print_int_type(irp, (IrInstructionIntType *)instruction);
14221475 break;
src/link.cpp+2-2
......@@ -208,7 +208,7 @@ static Buf *get_dynamic_linker_path(CodeGen *g) {
208208static void construct_linker_job_elf(LinkJob *lj) {
209209 CodeGen *g = lj->codegen;
210210
211 if (lj->link_in_crt) {
211 if (g->libc_link_lib != nullptr) {
212212 find_libc_lib_path(g);
213213 }
214214
......@@ -432,7 +432,7 @@ static bool zig_lld_link(ZigLLVM_ObjectFormatType oformat, const char **args, si
432432static void construct_linker_job_coff(LinkJob *lj) {
433433 CodeGen *g = lj->codegen;
434434
435 if (lj->link_in_crt) {
435 if (g->libc_link_lib != nullptr) {
436436 find_libc_lib_path(g);
437437 }
438438
src/main.cpp+1-1
......@@ -34,7 +34,7 @@ static int usage(const char *arg0) {
3434 " --assembly [source] add assembly file to build\n"
3535 " --cache-dir [path] override the cache directory\n"
3636 " --color [auto|off|on] enable or disable colored error messages\n"
37 " --emit [filetype] emit a specific file format as compilation output\n"
37 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"
3838 " --enable-timing-info print timing diagnostics\n"
3939 " --libc-include-dir [path] directory where libc stdlib.h resides\n"
4040 " --name [name] override output name\n"
src/os.cpp+19-2
......@@ -989,12 +989,29 @@ int os_self_exe_path(Buf *out_path) {
989989 }
990990
991991#elif defined(ZIG_OS_DARWIN)
992 // How long is the executable's path?
992993 uint32_t u32_len = 0;
993994 int ret1 = _NSGetExecutablePath(nullptr, &u32_len);
994995 assert(ret1 != 0);
995 buf_resize(out_path, u32_len);
996 int ret2 = _NSGetExecutablePath(buf_ptr(out_path), &u32_len);
996
997 Buf *tmp = buf_alloc_fixed(u32_len);
998
999 // Fill the executable path.
1000 int ret2 = _NSGetExecutablePath(buf_ptr(tmp), &u32_len);
9971001 assert(ret2 == 0);
1002
1003 // According to libuv project, PATH_MAX*2 works around a libc bug where
1004 // the resolved path is sometimes bigger than PATH_MAX.
1005 buf_resize(out_path, PATH_MAX*2);
1006 char *real_path = realpath(buf_ptr(tmp), buf_ptr(out_path));
1007 if (!real_path) {
1008 buf_init_from_buf(out_path, tmp);
1009 return 0;
1010 }
1011
1012 // Resize out_path for the correct length.
1013 buf_resize(out_path, strlen(buf_ptr(out_path)));
1014
9981015 return 0;
9991016#elif defined(ZIG_OS_LINUX)
10001017 buf_resize(out_path, 256);
src/target.cpp+35-15
......@@ -685,21 +685,41 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
685685uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
686686 switch (target->os) {
687687 case OsFreestanding:
688 switch (id) {
689 case CIntTypeShort:
690 case CIntTypeUShort:
691 return 16;
692 case CIntTypeInt:
693 case CIntTypeUInt:
694 return 32;
695 case CIntTypeLong:
696 case CIntTypeULong:
697 return get_arch_pointer_bit_width(target->arch.arch);
698 case CIntTypeLongLong:
699 case CIntTypeULongLong:
700 return 64;
701 case CIntTypeCount:
702 zig_unreachable();
688 switch (target->arch.arch) {
689 case ZigLLVM_msp430:
690 switch (id) {
691 case CIntTypeShort:
692 case CIntTypeUShort:
693 return 16;
694 case CIntTypeInt:
695 case CIntTypeUInt:
696 return 16;
697 case CIntTypeLong:
698 case CIntTypeULong:
699 return 32;
700 case CIntTypeLongLong:
701 case CIntTypeULongLong:
702 return 64;
703 case CIntTypeCount:
704 zig_unreachable();
705 }
706 default:
707 switch (id) {
708 case CIntTypeShort:
709 case CIntTypeUShort:
710 return 16;
711 case CIntTypeInt:
712 case CIntTypeUInt:
713 return 32;
714 case CIntTypeLong:
715 case CIntTypeULong:
716 return get_arch_pointer_bit_width(target->arch.arch);
717 case CIntTypeLongLong:
718 case CIntTypeULongLong:
719 return 64;
720 case CIntTypeCount:
721 zig_unreachable();
722 }
703723 }
704724 case OsLinux:
705725 case OsMacOSX:
std/array_list.zig+17-17
......@@ -29,36 +29,36 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
2929 };
3030 }
3131
32 pub fn deinit(self: *const Self) void {
32 pub fn deinit(self: Self) void {
3333 self.allocator.free(self.items);
3434 }
3535
36 pub fn toSlice(self: *const Self) []align(A) T {
36 pub fn toSlice(self: Self) []align(A) T {
3737 return self.items[0..self.len];
3838 }
3939
40 pub fn toSliceConst(self: *const Self) []align(A) const T {
40 pub fn toSliceConst(self: Self) []align(A) const T {
4141 return self.items[0..self.len];
4242 }
4343
44 pub fn at(self: *const Self, n: usize) T {
44 pub fn at(self: Self, n: usize) T {
4545 return self.toSliceConst()[n];
4646 }
4747
4848 /// Sets the value at index `i`, or returns `error.OutOfBounds` if
4949 /// the index is not in range.
50 pub fn setOrError(self: *const Self, i: usize, item: *const T) !void {
50 pub fn setOrError(self: Self, i: usize, item: T) !void {
5151 if (i >= self.len) return error.OutOfBounds;
52 self.items[i] = item.*;
52 self.items[i] = item;
5353 }
5454
5555 /// Sets the value at index `i`, asserting that the value is in range.
56 pub fn set(self: *const Self, i: usize, item: *const T) void {
56 pub fn set(self: *Self, i: usize, item: T) void {
5757 assert(i < self.len);
58 self.items[i] = item.*;
58 self.items[i] = item;
5959 }
6060
61 pub fn count(self: *const Self) usize {
61 pub fn count(self: Self) usize {
6262 return self.len;
6363 }
6464
......@@ -81,12 +81,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
8181 return result;
8282 }
8383
84 pub fn insert(self: *Self, n: usize, item: *const T) !void {
84 pub fn insert(self: *Self, n: usize, item: T) !void {
8585 try self.ensureCapacity(self.len + 1);
8686 self.len += 1;
8787
8888 mem.copy(T, self.items[n + 1 .. self.len], self.items[n .. self.len - 1]);
89 self.items[n] = item.*;
89 self.items[n] = item;
9090 }
9191
9292 pub fn insertSlice(self: *Self, n: usize, items: []align(A) const T) !void {
......@@ -97,9 +97,9 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type {
9797 mem.copy(T, self.items[n .. n + items.len], items);
9898 }
9999
100 pub fn append(self: *Self, item: *const T) !void {
100 pub fn append(self: *Self, item: T) !void {
101101 const new_item_ptr = try self.addOne();
102 new_item_ptr.* = item.*;
102 new_item_ptr.* = item;
103103 }
104104
105105 pub fn appendSlice(self: *Self, items: []align(A) const T) !void {
......@@ -185,23 +185,23 @@ test "basic ArrayList test" {
185185 {
186186 var i: usize = 0;
187187 while (i < 10) : (i += 1) {
188 list.append(i32(i + 1)) catch unreachable;
188 list.append(@intCast(i32, i + 1)) catch unreachable;
189189 }
190190 }
191191
192192 {
193193 var i: usize = 0;
194194 while (i < 10) : (i += 1) {
195 assert(list.items[i] == i32(i + 1));
195 assert(list.items[i] == @intCast(i32, i + 1));
196196 }
197197 }
198198
199199 for (list.toSlice()) |v, i| {
200 assert(v == i32(i + 1));
200 assert(v == @intCast(i32, i + 1));
201201 }
202202
203203 for (list.toSliceConst()) |v, i| {
204 assert(v == i32(i + 1));
204 assert(v == @intCast(i32, i + 1));
205205 }
206206
207207 assert(list.pop() == 10);
std/base64.zig+2-2
......@@ -99,7 +99,7 @@ pub const Base64Decoder = struct {
9999 assert(!result.char_in_alphabet[c]);
100100 assert(c != pad_char);
101101
102 result.char_to_index[c] = u8(i);
102 result.char_to_index[c] = @intCast(u8, i);
103103 result.char_in_alphabet[c] = true;
104104 }
105105
......@@ -284,7 +284,7 @@ pub const Base64DecoderUnsafe = struct {
284284 };
285285 for (alphabet_chars) |c, i| {
286286 assert(c != pad_char);
287 result.char_to_index[c] = u8(i);
287 result.char_to_index[c] = @intCast(u8, i);
288288 }
289289 return result;
290290 }
std/build.zig+1-1
......@@ -234,7 +234,7 @@ pub const Builder = struct {
234234 defer wanted_steps.deinit();
235235
236236 if (step_names.len == 0) {
237 try wanted_steps.append(&self.default_step);
237 try wanted_steps.append(self.default_step);
238238 } else {
239239 for (step_names) |step_name| {
240240 const s = try self.getTopLevelStepByName(step_name);
std/crypto/blake2.zig+5-5
......@@ -79,7 +79,7 @@ fn Blake2s(comptime out_len: usize) type {
7979 mem.copy(u32, d.h[0..], iv[0..]);
8080
8181 // No key plus default parameters
82 d.h[0] ^= 0x01010000 ^ u32(out_len >> 3);
82 d.h[0] ^= 0x01010000 ^ @intCast(u32, out_len >> 3);
8383 d.t = 0;
8484 d.buf_len = 0;
8585 }
......@@ -110,7 +110,7 @@ fn Blake2s(comptime out_len: usize) type {
110110
111111 // Copy any remainder for next pass.
112112 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
113 d.buf_len += u8(b[off..].len);
113 d.buf_len += @intCast(u8, b[off..].len);
114114 }
115115
116116 pub fn final(d: *Self, out: []u8) void {
......@@ -144,7 +144,7 @@ fn Blake2s(comptime out_len: usize) type {
144144 }
145145
146146 v[12] ^= @truncate(u32, d.t);
147 v[13] ^= u32(d.t >> 32);
147 v[13] ^= @intCast(u32, d.t >> 32);
148148 if (last) v[14] = ~v[14];
149149
150150 const rounds = comptime []RoundParam{
......@@ -345,7 +345,7 @@ fn Blake2b(comptime out_len: usize) type {
345345
346346 // Copy any remainder for next pass.
347347 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
348 d.buf_len += u8(b[off..].len);
348 d.buf_len += @intCast(u8, b[off..].len);
349349 }
350350
351351 pub fn final(d: *Self, out: []u8) void {
......@@ -377,7 +377,7 @@ fn Blake2b(comptime out_len: usize) type {
377377 }
378378
379379 v[12] ^= @truncate(u64, d.t);
380 v[13] ^= u64(d.t >> 64);
380 v[13] ^= @intCast(u64, d.t >> 64);
381381 if (last) v[14] = ~v[14];
382382
383383 const rounds = comptime []RoundParam{
std/crypto/md5.zig+3-3
......@@ -78,7 +78,7 @@ pub const Md5 = struct {
7878
7979 // Copy any remainder for next pass.
8080 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
81 d.buf_len += u8(b[off..].len);
81 d.buf_len += @intCast(u8, b[off..].len);
8282
8383 // Md5 uses the bottom 64-bits for length padding
8484 d.total_len +%= b.len;
......@@ -103,9 +103,9 @@ pub const Md5 = struct {
103103 // Append message length.
104104 var i: usize = 1;
105105 var len = d.total_len >> 5;
106 d.buf[56] = u8(d.total_len & 0x1f) << 3;
106 d.buf[56] = @intCast(u8, d.total_len & 0x1f) << 3;
107107 while (i < 8) : (i += 1) {
108 d.buf[56 + i] = u8(len & 0xff);
108 d.buf[56 + i] = @intCast(u8, len & 0xff);
109109 len >>= 8;
110110 }
111111
std/crypto/sha1.zig+3-3
......@@ -78,7 +78,7 @@ pub const Sha1 = struct {
7878
7979 // Copy any remainder for next pass.
8080 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
81 d.buf_len += u8(b[off..].len);
81 d.buf_len += @intCast(u8, b[off..].len);
8282
8383 d.total_len += b.len;
8484 }
......@@ -102,9 +102,9 @@ pub const Sha1 = struct {
102102 // Append message length.
103103 var i: usize = 1;
104104 var len = d.total_len >> 5;
105 d.buf[63] = u8(d.total_len & 0x1f) << 3;
105 d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3;
106106 while (i < 8) : (i += 1) {
107 d.buf[63 - i] = u8(len & 0xff);
107 d.buf[63 - i] = @intCast(u8, len & 0xff);
108108 len >>= 8;
109109 }
110110
std/crypto/sha2.zig+6-6
......@@ -131,7 +131,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
131131
132132 // Copy any remainder for next pass.
133133 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
134 d.buf_len += u8(b[off..].len);
134 d.buf_len += @intCast(u8, b[off..].len);
135135
136136 d.total_len += b.len;
137137 }
......@@ -155,9 +155,9 @@ fn Sha2_32(comptime params: Sha2Params32) type {
155155 // Append message length.
156156 var i: usize = 1;
157157 var len = d.total_len >> 5;
158 d.buf[63] = u8(d.total_len & 0x1f) << 3;
158 d.buf[63] = @intCast(u8, d.total_len & 0x1f) << 3;
159159 while (i < 8) : (i += 1) {
160 d.buf[63 - i] = u8(len & 0xff);
160 d.buf[63 - i] = @intCast(u8, len & 0xff);
161161 len >>= 8;
162162 }
163163
......@@ -472,7 +472,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
472472
473473 // Copy any remainder for next pass.
474474 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
475 d.buf_len += u8(b[off..].len);
475 d.buf_len += @intCast(u8, b[off..].len);
476476
477477 d.total_len += b.len;
478478 }
......@@ -496,9 +496,9 @@ fn Sha2_64(comptime params: Sha2Params64) type {
496496 // Append message length.
497497 var i: usize = 1;
498498 var len = d.total_len >> 5;
499 d.buf[127] = u8(d.total_len & 0x1f) << 3;
499 d.buf[127] = @intCast(u8, d.total_len & 0x1f) << 3;
500500 while (i < 16) : (i += 1) {
501 d.buf[127 - i] = u8(len & 0xff);
501 d.buf[127 - i] = @intCast(u8, len & 0xff);
502502 len >>= 8;
503503 }
504504
std/debug/index.zig+5-4
......@@ -554,7 +554,7 @@ const LineNumberProgram = struct {
554554 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
555555 errdefer self.file_entries.allocator.free(file_name);
556556 return LineInfo{
557 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
557 .line = if (self.prev_line >= 0) @intCast(usize, self.prev_line) else 0,
558558 .column = self.prev_column,
559559 .file_name = file_name,
560560 .allocator = self.file_entries.allocator,
......@@ -639,6 +639,7 @@ const ParseFormValueError = error{
639639 Unexpected,
640640 InvalidDebugInfo,
641641 EndOfFile,
642 IsDir,
642643 OutOfMemory,
643644};
644645
......@@ -1069,7 +1070,7 @@ fn readULeb128(in_stream: var) !u64 {
10691070
10701071 var operand: u64 = undefined;
10711072
1072 if (@shlWithOverflow(u64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1073 if (@shlWithOverflow(u64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
10731074
10741075 result |= operand;
10751076
......@@ -1088,13 +1089,13 @@ fn readILeb128(in_stream: var) !i64 {
10881089
10891090 var operand: i64 = undefined;
10901091
1091 if (@shlWithOverflow(i64, byte & 0b01111111, u6(shift), &operand)) return error.InvalidDebugInfo;
1092 if (@shlWithOverflow(i64, byte & 0b01111111, @intCast(u6, shift), &operand)) return error.InvalidDebugInfo;
10921093
10931094 result |= operand;
10941095 shift += 7;
10951096
10961097 if ((byte & 0b10000000) == 0) {
1097 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << u6(shift));
1098 if (shift < @sizeOf(i64) * 8 and (byte & 0b01000000) != 0) result |= -(i64(1) << @intCast(u6, shift));
10981099 return result;
10991100 }
11001101 }
std/dynamic_library.zig created+156
......@@ -0,0 +1,156 @@
1const std = @import("index.zig");
2const mem = std.mem;
3const elf = std.elf;
4const cstr = std.cstr;
5const linux = std.os.linux;
6
7pub const DynLib = struct {
8 allocator: *mem.Allocator,
9 elf_lib: ElfLib,
10 fd: i32,
11 map_addr: usize,
12 map_size: usize,
13
14 /// Trusts the file
15 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
16 const fd = try std.os.posixOpen(allocator, path, 0, linux.O_RDONLY | linux.O_CLOEXEC);
17 errdefer std.os.close(fd);
18
19 const size = @intCast(usize, (try std.os.posixFStat(fd)).size);
20
21 const addr = linux.mmap(
22 null,
23 size,
24 linux.PROT_READ | linux.PROT_EXEC,
25 linux.MAP_PRIVATE | linux.MAP_LOCKED,
26 fd,
27 0,
28 );
29 errdefer _ = linux.munmap(addr, size);
30
31 const bytes = @intToPtr([*]align(std.os.page_size) u8, addr)[0..size];
32
33 return DynLib{
34 .allocator = allocator,
35 .elf_lib = try ElfLib.init(bytes),
36 .fd = fd,
37 .map_addr = addr,
38 .map_size = size,
39 };
40 }
41
42 pub fn close(self: *DynLib) void {
43 _ = linux.munmap(self.map_addr, self.map_size);
44 std.os.close(self.fd);
45 self.* = undefined;
46 }
47
48 pub fn lookup(self: *DynLib, name: []const u8) ?usize {
49 return self.elf_lib.lookup("", name);
50 }
51};
52
53pub const ElfLib = struct {
54 strings: [*]u8,
55 syms: [*]elf.Sym,
56 hashtab: [*]linux.Elf_Symndx,
57 versym: ?[*]u16,
58 verdef: ?*elf.Verdef,
59 base: usize,
60
61 // Trusts the memory
62 pub fn init(bytes: []align(@alignOf(elf.Ehdr)) u8) !ElfLib {
63 const eh = @ptrCast(*elf.Ehdr, bytes.ptr);
64 if (!mem.eql(u8, eh.e_ident[0..4], "\x7fELF")) return error.NotElfFile;
65 if (eh.e_type != elf.ET_DYN) return error.NotDynamicLibrary;
66
67 const elf_addr = @ptrToInt(bytes.ptr);
68 var ph_addr: usize = elf_addr + eh.e_phoff;
69
70 var base: usize = @maxValue(usize);
71 var maybe_dynv: ?[*]usize = null;
72 {
73 var i: usize = 0;
74 while (i < eh.e_phnum) : ({
75 i += 1;
76 ph_addr += eh.e_phentsize;
77 }) {
78 const ph = @intToPtr(*elf.Phdr, ph_addr);
79 switch (ph.p_type) {
80 elf.PT_LOAD => base = elf_addr + ph.p_offset - ph.p_vaddr,
81 elf.PT_DYNAMIC => maybe_dynv = @intToPtr([*]usize, elf_addr + ph.p_offset),
82 else => {},
83 }
84 }
85 }
86 const dynv = maybe_dynv orelse return error.MissingDynamicLinkingInformation;
87 if (base == @maxValue(usize)) return error.BaseNotFound;
88
89 var maybe_strings: ?[*]u8 = null;
90 var maybe_syms: ?[*]elf.Sym = null;
91 var maybe_hashtab: ?[*]linux.Elf_Symndx = null;
92 var maybe_versym: ?[*]u16 = null;
93 var maybe_verdef: ?*elf.Verdef = null;
94
95 {
96 var i: usize = 0;
97 while (dynv[i] != 0) : (i += 2) {
98 const p = base + dynv[i + 1];
99 switch (dynv[i]) {
100 elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p),
101 elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p),
102 elf.DT_HASH => maybe_hashtab = @intToPtr([*]linux.Elf_Symndx, p),
103 elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p),
104 elf.DT_VERDEF => maybe_verdef = @intToPtr(*elf.Verdef, p),
105 else => {},
106 }
107 }
108 }
109
110 return ElfLib{
111 .base = base,
112 .strings = maybe_strings orelse return error.ElfStringSectionNotFound,
113 .syms = maybe_syms orelse return error.ElfSymSectionNotFound,
114 .hashtab = maybe_hashtab orelse return error.ElfHashTableNotFound,
115 .versym = maybe_versym,
116 .verdef = maybe_verdef,
117 };
118 }
119
120 /// Returns the address of the symbol
121 pub fn lookup(self: *const ElfLib, vername: []const u8, name: []const u8) ?usize {
122 const maybe_versym = if (self.verdef == null) null else self.versym;
123
124 const OK_TYPES = (1 << elf.STT_NOTYPE | 1 << elf.STT_OBJECT | 1 << elf.STT_FUNC | 1 << elf.STT_COMMON);
125 const OK_BINDS = (1 << elf.STB_GLOBAL | 1 << elf.STB_WEAK | 1 << elf.STB_GNU_UNIQUE);
126
127 var i: usize = 0;
128 while (i < self.hashtab[1]) : (i += 1) {
129 if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
130 if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
131 if (0 == self.syms[i].st_shndx) continue;
132 if (!mem.eql(u8, name, cstr.toSliceConst(self.strings + self.syms[i].st_name))) continue;
133 if (maybe_versym) |versym| {
134 if (!checkver(self.verdef.?, versym[i], vername, self.strings))
135 continue;
136 }
137 return self.base + self.syms[i].st_value;
138 }
139
140 return null;
141 }
142};
143
144fn checkver(def_arg: *elf.Verdef, vsym_arg: i32, vername: []const u8, strings: [*]u8) bool {
145 var def = def_arg;
146 const vsym = @bitCast(u32, vsym_arg) & 0x7fff;
147 while (true) {
148 if (0 == (def.vd_flags & elf.VER_FLG_BASE) and (def.vd_ndx & 0x7fff) == vsym)
149 break;
150 if (def.vd_next == 0)
151 return false;
152 def = @intToPtr(*elf.Verdef, @ptrToInt(def) + def.vd_next);
153 }
154 const aux = @intToPtr(*elf.Verdaux, @ptrToInt(def) + def.vd_aux);
155 return mem.eql(u8, vername, cstr.toSliceConst(strings + aux.vda_name));
156}
std/elf.zig+15
......@@ -305,6 +305,21 @@ pub const STT_ARM_16BIT = STT_HIPROC;
305305pub const VER_FLG_BASE = 0x1;
306306pub const VER_FLG_WEAK = 0x2;
307307
308/// An unknown type.
309pub const ET_NONE = 0;
310
311/// A relocatable file.
312pub const ET_REL = 1;
313
314/// An executable file.
315pub const ET_EXEC = 2;
316
317/// A shared object.
318pub const ET_DYN = 3;
319
320/// A core file.
321pub const ET_CORE = 4;
322
308323pub const FileType = enum {
309324 Relocatable,
310325 Executable,
std/fmt/errol/index.zig+41-41
......@@ -29,11 +29,11 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro
2929 switch (mode) {
3030 RoundMode.Decimal => {
3131 if (float_decimal.exp >= 0) {
32 round_digit = precision + usize(float_decimal.exp);
32 round_digit = precision + @intCast(usize, float_decimal.exp);
3333 } else {
3434 // if a small negative exp, then adjust we need to offset by the number
3535 // of leading zeros that will occur.
36 const min_exp_required = usize(-float_decimal.exp);
36 const min_exp_required = @intCast(usize, -float_decimal.exp);
3737 if (precision > min_exp_required) {
3838 round_digit = precision - min_exp_required;
3939 }
......@@ -107,16 +107,16 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
107107 // normalize the midpoint
108108
109109 const e = math.frexp(val).exponent;
110 var exp = i16(math.floor(307 + f64(e) * 0.30103));
110 var exp = @floatToInt(i16, math.floor(307 + @intToFloat(f64, e) * 0.30103));
111111 if (exp < 20) {
112112 exp = 20;
113 } else if (usize(exp) >= lookup_table.len) {
114 exp = i16(lookup_table.len - 1);
113 } else if (@intCast(usize, exp) >= lookup_table.len) {
114 exp = @intCast(i16, lookup_table.len - 1);
115115 }
116116
117 var mid = lookup_table[usize(exp)];
117 var mid = lookup_table[@intCast(usize, exp)];
118118 mid = hpProd(mid, val);
119 const lten = lookup_table[usize(exp)].val;
119 const lten = lookup_table[@intCast(usize, exp)].val;
120120
121121 exp -= 307;
122122
......@@ -168,25 +168,25 @@ fn errol3u(val: f64, buffer: []u8) FloatDecimal {
168168 // the 0-index for this extra digit.
169169 var buf_index: usize = 1;
170170 while (true) {
171 var hdig = u8(math.floor(high.val));
172 if ((high.val == f64(hdig)) and (high.off < 0)) hdig -= 1;
171 var hdig = @floatToInt(u8, math.floor(high.val));
172 if ((high.val == @intToFloat(f64, hdig)) and (high.off < 0)) hdig -= 1;
173173
174 var ldig = u8(math.floor(low.val));
175 if ((low.val == f64(ldig)) and (low.off < 0)) ldig -= 1;
174 var ldig = @floatToInt(u8, math.floor(low.val));
175 if ((low.val == @intToFloat(f64, ldig)) and (low.off < 0)) ldig -= 1;
176176
177177 if (ldig != hdig) break;
178178
179179 buffer[buf_index] = hdig + '0';
180180 buf_index += 1;
181 high.val -= f64(hdig);
182 low.val -= f64(ldig);
181 high.val -= @intToFloat(f64, hdig);
182 low.val -= @intToFloat(f64, ldig);
183183 hpMul10(&high);
184184 hpMul10(&low);
185185 }
186186
187187 const tmp = (high.val + low.val) / 2.0;
188 var mdig = u8(math.floor(tmp + 0.5));
189 if ((f64(mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1;
188 var mdig = @floatToInt(u8, math.floor(tmp + 0.5));
189 if ((@intToFloat(f64, mdig) - tmp) == 0.5 and (mdig & 0x1) != 0) mdig -= 1;
190190
191191 buffer[buf_index] = mdig + '0';
192192 buf_index += 1;
......@@ -304,7 +304,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
304304
305305 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
306306
307 var mid = u128(val);
307 var mid = @floatToInt(u128, val);
308308 var low: u128 = mid - fpeint((fpnext(val) - val) / 2.0);
309309 var high: u128 = mid + fpeint((val - fpprev(val)) / 2.0);
310310
......@@ -314,11 +314,11 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
314314 low -= 1;
315315 }
316316
317 var l64 = u64(low % pow19);
318 const lf = u64((low / pow19) % pow19);
317 var l64 = @intCast(u64, low % pow19);
318 const lf = @intCast(u64, (low / pow19) % pow19);
319319
320 var h64 = u64(high % pow19);
321 const hf = u64((high / pow19) % pow19);
320 var h64 = @intCast(u64, high % pow19);
321 const hf = @intCast(u64, (high / pow19) % pow19);
322322
323323 if (lf != hf) {
324324 l64 = lf;
......@@ -329,7 +329,7 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
329329 var mi: i32 = mismatch10(l64, h64);
330330 var x: u64 = 1;
331331 {
332 var i = i32(lf == hf);
332 var i: i32 = @boolToInt(lf == hf);
333333 while (i < mi) : (i += 1) {
334334 x *= 10;
335335 }
......@@ -341,14 +341,14 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
341341 var buf_index = u64toa(m64, buffer) - 1;
342342
343343 if (mi != 0) {
344 buffer[buf_index - 1] += u8(buffer[buf_index] >= '5');
344 buffer[buf_index - 1] += @boolToInt(buffer[buf_index] >= '5');
345345 } else {
346346 buf_index += 1;
347347 }
348348
349349 return FloatDecimal{
350350 .digits = buffer[0..buf_index],
351 .exp = i32(buf_index) + mi,
351 .exp = @intCast(i32, buf_index) + mi,
352352 };
353353}
354354
......@@ -359,33 +359,33 @@ fn errolInt(val: f64, buffer: []u8) FloatDecimal {
359359fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
360360 assert((val >= 16.0) and (val < 9.007199254740992e15));
361361
362 const u = u64(val);
363 const n = f64(u);
362 const u = @floatToInt(u64, val);
363 const n = @intToFloat(f64, u);
364364
365365 var mid = val - n;
366366 var lo = ((fpprev(val) - n) + mid) / 2.0;
367367 var hi = ((fpnext(val) - n) + mid) / 2.0;
368368
369369 var buf_index = u64toa(u, buffer);
370 var exp = i32(buf_index);
370 var exp = @intCast(i32, buf_index);
371371 var j = buf_index;
372372 buffer[j] = 0;
373373
374374 if (mid != 0.0) {
375375 while (mid != 0.0) {
376376 lo *= 10.0;
377 const ldig = i32(lo);
378 lo -= f64(ldig);
377 const ldig = @floatToInt(i32, lo);
378 lo -= @intToFloat(f64, ldig);
379379
380380 mid *= 10.0;
381 const mdig = i32(mid);
382 mid -= f64(mdig);
381 const mdig = @floatToInt(i32, mid);
382 mid -= @intToFloat(f64, mdig);
383383
384384 hi *= 10.0;
385 const hdig = i32(hi);
386 hi -= f64(hdig);
385 const hdig = @floatToInt(i32, hi);
386 hi -= @intToFloat(f64, hdig);
387387
388 buffer[j] = u8(mdig + '0');
388 buffer[j] = @intCast(u8, mdig + '0');
389389 j += 1;
390390
391391 if (hdig != ldig or j > 50) break;
......@@ -452,7 +452,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
452452 var buf_index: usize = 0;
453453
454454 if (value < kTen8) {
455 const v = u32(value);
455 const v = @intCast(u32, value);
456456 if (v < 10000) {
457457 const d1: u32 = (v / 100) << 1;
458458 const d2: u32 = (v % 100) << 1;
......@@ -507,8 +507,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
507507 buf_index += 1;
508508 }
509509 } else if (value < kTen16) {
510 const v0: u32 = u32(value / kTen8);
511 const v1: u32 = u32(value % kTen8);
510 const v0: u32 = @intCast(u32, value / kTen8);
511 const v1: u32 = @intCast(u32, value % kTen8);
512512
513513 const b0: u32 = v0 / 10000;
514514 const c0: u32 = v0 % 10000;
......@@ -578,11 +578,11 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
578578 buffer[buf_index] = c_digits_lut[d8 + 1];
579579 buf_index += 1;
580580 } else {
581 const a = u32(value / kTen16); // 1 to 1844
581 const a = @intCast(u32, value / kTen16); // 1 to 1844
582582 value %= kTen16;
583583
584584 if (a < 10) {
585 buffer[buf_index] = '0' + u8(a);
585 buffer[buf_index] = '0' + @intCast(u8, a);
586586 buf_index += 1;
587587 } else if (a < 100) {
588588 const i: u32 = a << 1;
......@@ -591,7 +591,7 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
591591 buffer[buf_index] = c_digits_lut[i + 1];
592592 buf_index += 1;
593593 } else if (a < 1000) {
594 buffer[buf_index] = '0' + u8(a / 100);
594 buffer[buf_index] = '0' + @intCast(u8, a / 100);
595595 buf_index += 1;
596596
597597 const i: u32 = (a % 100) << 1;
......@@ -612,8 +612,8 @@ fn u64toa(value_param: u64, buffer: []u8) usize {
612612 buf_index += 1;
613613 }
614614
615 const v0 = u32(value / kTen8);
616 const v1 = u32(value % kTen8);
615 const v0 = @intCast(u32, value / kTen8);
616 const v1 = @intCast(u32, value % kTen8);
617617
618618 const b0: u32 = v0 / 10000;
619619 const c0: u32 = v0 % 10000;
std/fmt/index.zig+16-11
......@@ -5,6 +5,7 @@ const assert = debug.assert;
55const mem = std.mem;
66const builtin = @import("builtin");
77const errol = @import("errol/index.zig");
8const lossyCast = std.math.lossyCast;
89
910const max_int_digits = 65;
1011
......@@ -162,8 +163,6 @@ pub fn formatType(
162163 },
163164 builtin.TypeInfo.Pointer.Size.Many => {
164165 if (ptr_info.child == u8) {
165 //This is a bit of a hack, but it made more sense to
166 // do this check here than have formatText do it
167166 if (fmt[0] == 's') {
168167 const len = std.cstr.len(value);
169168 return formatText(value[0..len], fmt, context, Errors, output);
......@@ -176,6 +175,12 @@ pub fn formatType(
176175 return output(context, casted_value);
177176 },
178177 },
178 builtin.TypeId.Array => |info| {
179 if (info.child == u8) {
180 return formatText(value, fmt, context, Errors, output);
181 }
182 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(&value));
183 },
179184 else => @compileError("Unable to format type '" ++ @typeName(T) ++ "'"),
180185 }
181186}
......@@ -459,7 +464,7 @@ pub fn formatFloatDecimal(
459464 errol.roundToPrecision(&float_decimal, precision, errol.RoundMode.Decimal);
460465
461466 // exp < 0 means the leading is always 0 as errol result is normalized.
462 var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0;
467 var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0;
463468
464469 // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this.
465470 var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len);
......@@ -488,7 +493,7 @@ pub fn formatFloatDecimal(
488493
489494 // Zero-fill until we reach significant digits or run out of precision.
490495 if (float_decimal.exp <= 0) {
491 const zero_digit_count = usize(-float_decimal.exp);
496 const zero_digit_count = @intCast(usize, -float_decimal.exp);
492497 const zeros_to_print = math.min(zero_digit_count, precision);
493498
494499 var i: usize = 0;
......@@ -517,7 +522,7 @@ pub fn formatFloatDecimal(
517522 }
518523 } else {
519524 // exp < 0 means the leading is always 0 as errol result is normalized.
520 var num_digits_whole = if (float_decimal.exp > 0) usize(float_decimal.exp) else 0;
525 var num_digits_whole = if (float_decimal.exp > 0) @intCast(usize, float_decimal.exp) else 0;
521526
522527 // the actual slice into the buffer, we may need to zero-pad between num_digits_whole and this.
523528 var num_digits_whole_no_pad = math.min(num_digits_whole, float_decimal.digits.len);
......@@ -543,7 +548,7 @@ pub fn formatFloatDecimal(
543548
544549 // Zero-fill until we reach significant digits or run out of precision.
545550 if (float_decimal.exp < 0) {
546 const zero_digit_count = usize(-float_decimal.exp);
551 const zero_digit_count = @intCast(usize, -float_decimal.exp);
547552
548553 var i: usize = 0;
549554 while (i < zero_digit_count) : (i += 1) {
......@@ -574,7 +579,7 @@ pub fn formatBytes(
574579 1024 => math.min(math.log2(value) / 10, mags_iec.len - 1),
575580 else => unreachable,
576581 };
577 const new_value = f64(value) / math.pow(f64, f64(radix), f64(magnitude));
582 const new_value = lossyCast(f64, value) / math.pow(f64, lossyCast(f64, radix), lossyCast(f64, magnitude));
578583 const suffix = switch (radix) {
579584 1000 => mags_si[magnitude],
580585 1024 => mags_iec[magnitude],
......@@ -624,15 +629,15 @@ fn formatIntSigned(
624629 if (value < 0) {
625630 const minus_sign: u8 = '-';
626631 try output(context, (*[1]u8)(&minus_sign)[0..]);
627 const new_value = uint(-(value + 1)) + 1;
632 const new_value = @intCast(uint, -(value + 1)) + 1;
628633 const new_width = if (width == 0) 0 else (width - 1);
629634 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
630635 } else if (width == 0) {
631 return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output);
636 return formatIntUnsigned(@intCast(uint, value), base, uppercase, width, context, Errors, output);
632637 } else {
633638 const plus_sign: u8 = '+';
634639 try output(context, (*[1]u8)(&plus_sign)[0..]);
635 const new_value = uint(value);
640 const new_value = @intCast(uint, value);
636641 const new_width = if (width == 0) 0 else (width - 1);
637642 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
638643 }
......@@ -656,7 +661,7 @@ fn formatIntUnsigned(
656661 while (true) {
657662 const digit = a % base;
658663 index -= 1;
659 buf[index] = digitToChar(u8(digit), uppercase);
664 buf[index] = digitToChar(@intCast(u8, digit), uppercase);
660665 a /= base;
661666 if (a == 0) break;
662667 }
std/hash/crc.zig+2-2
......@@ -26,7 +26,7 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
2626 var tables: [8][256]u32 = undefined;
2727
2828 for (tables[0]) |*e, i| {
29 var crc = u32(i);
29 var crc = @intCast(u32, i);
3030 var j: usize = 0;
3131 while (j < 8) : (j += 1) {
3232 if (crc & 1 == 1) {
......@@ -122,7 +122,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
122122 var table: [16]u32 = undefined;
123123
124124 for (table) |*e, i| {
125 var crc = u32(i * 16);
125 var crc = @intCast(u32, i * 16);
126126 var j: usize = 0;
127127 while (j < 8) : (j += 1) {
128128 if (crc & 1 == 1) {
std/hash/siphash.zig+3-3
......@@ -81,7 +81,7 @@ fn SipHash(comptime T: type, comptime c_rounds: usize, comptime d_rounds: usize)
8181
8282 // Remainder for next pass.
8383 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
84 d.buf_len += u8(b[off..].len);
84 d.buf_len += @intCast(u8, b[off..].len);
8585 d.msg_len +%= @truncate(u8, b.len);
8686 }
8787
......@@ -233,7 +233,7 @@ test "siphash64-2-4 sanity" {
233233
234234 var buffer: [64]u8 = undefined;
235235 for (vectors) |vector, i| {
236 buffer[i] = u8(i);
236 buffer[i] = @intCast(u8, i);
237237
238238 const expected = mem.readInt(vector, u64, Endian.Little);
239239 debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
......@@ -312,7 +312,7 @@ test "siphash128-2-4 sanity" {
312312
313313 var buffer: [64]u8 = undefined;
314314 for (vectors) |vector, i| {
315 buffer[i] = u8(i);
315 buffer[i] = @intCast(u8, i);
316316
317317 const expected = mem.readInt(vector, u128, Endian.Little);
318318 debug.assert(siphash.hash(test_key, buffer[0..i]) == expected);
std/heap.zig+1-1
......@@ -408,7 +408,7 @@ fn testAllocator(allocator: *mem.Allocator) !void {
408408
409409 for (slice) |*item, i| {
410410 item.* = try allocator.create(i32);
411 item.*.* = i32(i);
411 item.*.* = @intCast(i32, i);
412412 }
413413
414414 for (slice) |item, i| {
std/index.zig+1
......@@ -8,6 +8,7 @@ pub const HashMap = @import("hash_map.zig").HashMap;
88pub const LinkedList = @import("linked_list.zig").LinkedList;
99pub const IntrusiveLinkedList = @import("linked_list.zig").IntrusiveLinkedList;
1010pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
11pub const DynLib = @import("dynamic_library.zig").DynLib;
1112
1213pub const atomic = @import("atomic/index.zig");
1314pub const base64 = @import("base64.zig");
std/io.zig+6-1
......@@ -242,11 +242,16 @@ pub fn writeFile(allocator: *mem.Allocator, path: []const u8, data: []const u8)
242242
243243/// On success, caller owns returned buffer.
244244pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 {
245 return readFileAllocAligned(allocator, path, @alignOf(u8));
246}
247
248/// On success, caller owns returned buffer.
249pub fn readFileAllocAligned(allocator: *mem.Allocator, path: []const u8, comptime A: u29) ![]align(A) u8 {
245250 var file = try File.openRead(allocator, path);
246251 defer file.close();
247252
248253 const size = try file.getEndPos();
249 const buf = try allocator.alloc(u8, size);
254 const buf = try allocator.alignedAlloc(u8, A, size);
250255 errdefer allocator.free(buf);
251256
252257 var adapter = FileInStream.init(&file);
std/json.zig+2-2
......@@ -180,7 +180,7 @@ pub const StreamingParser = struct {
180180 pub fn fromInt(x: var) State {
181181 debug.assert(x == 0 or x == 1);
182182 const T = @TagType(State);
183 return State(T(x));
183 return State(@intCast(T, x));
184184 }
185185 };
186186
......@@ -1326,7 +1326,7 @@ pub const Parser = struct {
13261326 },
13271327 // Array Parent -> [ ..., <array>, value ]
13281328 Value.Array => |*array| {
1329 try array.append(value);
1329 try array.append(value.*);
13301330 p.state = State.ArrayValue;
13311331 },
13321332 else => {
std/math/acos.zig+2-2
......@@ -95,12 +95,12 @@ fn acos64(x: f64) f64 {
9595 const pio2_lo: f64 = 6.12323399573676603587e-17;
9696
9797 const ux = @bitCast(u64, x);
98 const hx = u32(ux >> 32);
98 const hx = @intCast(u32, ux >> 32);
9999 const ix = hx & 0x7FFFFFFF;
100100
101101 // |x| >= 1 or nan
102102 if (ix >= 0x3FF00000) {
103 const lx = u32(ux & 0xFFFFFFFF);
103 const lx = @intCast(u32, ux & 0xFFFFFFFF);
104104
105105 // acos(1) = 0, acos(-1) = pi
106106 if ((ix - 0x3FF00000) | lx == 0) {
std/math/asin.zig+2-2
......@@ -87,12 +87,12 @@ fn asin64(x: f64) f64 {
8787 const pio2_lo: f64 = 6.12323399573676603587e-17;
8888
8989 const ux = @bitCast(u64, x);
90 const hx = u32(ux >> 32);
90 const hx = @intCast(u32, ux >> 32);
9191 const ix = hx & 0x7FFFFFFF;
9292
9393 // |x| >= 1 or nan
9494 if (ix >= 0x3FF00000) {
95 const lx = u32(ux & 0xFFFFFFFF);
95 const lx = @intCast(u32, ux & 0xFFFFFFFF);
9696
9797 // asin(1) = +-pi/2 with inexact
9898 if ((ix - 0x3FF00000) | lx == 0) {
std/math/atan.zig+2-2
......@@ -138,7 +138,7 @@ fn atan64(x_: f64) f64 {
138138
139139 var x = x_;
140140 var ux = @bitCast(u64, x);
141 var ix = u32(ux >> 32);
141 var ix = @intCast(u32, ux >> 32);
142142 const sign = ix >> 31;
143143 ix &= 0x7FFFFFFF;
144144
......@@ -159,7 +159,7 @@ fn atan64(x_: f64) f64 {
159159 // |x| < 2^(-27)
160160 if (ix < 0x3E400000) {
161161 if (ix < 0x00100000) {
162 math.forceEval(f32(x));
162 math.forceEval(@floatCast(f32, x));
163163 }
164164 return x;
165165 }
std/math/atan2.zig+4-4
......@@ -124,12 +124,12 @@ fn atan2_64(y: f64, x: f64) f64 {
124124 }
125125
126126 var ux = @bitCast(u64, x);
127 var ix = u32(ux >> 32);
128 var lx = u32(ux & 0xFFFFFFFF);
127 var ix = @intCast(u32, ux >> 32);
128 var lx = @intCast(u32, ux & 0xFFFFFFFF);
129129
130130 var uy = @bitCast(u64, y);
131 var iy = u32(uy >> 32);
132 var ly = u32(uy & 0xFFFFFFFF);
131 var iy = @intCast(u32, uy >> 32);
132 var ly = @intCast(u32, uy & 0xFFFFFFFF);
133133
134134 // x = 1.0
135135 if ((ix -% 0x3FF00000) | lx == 0) {
std/math/atanh.zig+1-1
......@@ -62,7 +62,7 @@ fn atanh_64(x: f64) f64 {
6262 if (e < 0x3FF - 32) {
6363 // underflow
6464 if (e == 0) {
65 math.forceEval(f32(y));
65 math.forceEval(@floatCast(f32, y));
6666 }
6767 }
6868 // |x| < 0.5
std/math/big/int.zig+164-222
......@@ -18,39 +18,6 @@ comptime {
1818 debug.assert(Limb.is_signed == false);
1919}
2020
21const wrapped_buffer_size = 512;
22
23// Converts primitive integer values onto a stack-based big integer, or passes through existing
24// Int types with no modifications. This can fail at runtime if using a very large dynamic
25// integer but it is very unlikely and is considered a user error.
26fn wrapInt(allocator: *Allocator, bn: var) *const Int {
27 const T = @typeOf(bn);
28 switch (@typeInfo(T)) {
29 TypeId.Pointer => |info| {
30 if (info.child == Int) {
31 return bn;
32 } else {
33 @compileError("cannot set Int using type " ++ @typeName(T));
34 }
35 },
36 else => {
37 var s = allocator.create(Int) catch unreachable;
38 s.* = Int{
39 .allocator = allocator,
40 .positive = false,
41 .limbs = block: {
42 var limbs = allocator.alloc(Limb, Int.default_capacity) catch unreachable;
43 limbs[0] = 0;
44 break :block limbs;
45 },
46 .len = 1,
47 };
48 s.set(bn) catch unreachable;
49 return s;
50 },
51 }
52}
53
5421pub const Int = struct {
5522 allocator: *Allocator,
5623 positive: bool,
......@@ -93,11 +60,11 @@ pub const Int = struct {
9360 self.limbs = try self.allocator.realloc(Limb, self.limbs, capacity);
9461 }
9562
96 pub fn deinit(self: *const Int) void {
63 pub fn deinit(self: Int) void {
9764 self.allocator.free(self.limbs);
9865 }
9966
100 pub fn clone(other: *const Int) !Int {
67 pub fn clone(other: Int) !Int {
10168 return Int{
10269 .allocator = other.allocator,
10370 .positive = other.positive,
......@@ -110,8 +77,8 @@ pub const Int = struct {
11077 };
11178 }
11279
113 pub fn copy(self: *Int, other: *const Int) !void {
114 if (self == other) {
80 pub fn copy(self: *Int, other: Int) !void {
81 if (self == &other) {
11582 return;
11683 }
11784
......@@ -125,7 +92,7 @@ pub const Int = struct {
12592 mem.swap(Int, self, other);
12693 }
12794
128 pub fn dump(self: *const Int) void {
95 pub fn dump(self: Int) void {
12996 for (self.limbs) |limb| {
13097 debug.warn("{x} ", limb);
13198 }
......@@ -140,20 +107,20 @@ pub const Int = struct {
140107 r.positive = true;
141108 }
142109
143 pub fn isOdd(r: *const Int) bool {
110 pub fn isOdd(r: Int) bool {
144111 return r.limbs[0] & 1 != 0;
145112 }
146113
147 pub fn isEven(r: *const Int) bool {
114 pub fn isEven(r: Int) bool {
148115 return !r.isOdd();
149116 }
150117
151 fn bitcount(self: *const Int) usize {
118 fn bitcount(self: Int) usize {
152119 const u_bit_count = (self.len - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len - 1]));
153 return usize(!self.positive) + u_bit_count;
120 return usize(@boolToInt(!self.positive)) + u_bit_count;
154121 }
155122
156 pub fn sizeInBase(self: *const Int, base: usize) usize {
123 pub fn sizeInBase(self: Int, base: usize) usize {
157124 return (self.bitcount() / math.log2(base)) + 1;
158125 }
159126
......@@ -168,7 +135,7 @@ pub const Int = struct {
168135 self.positive = value >= 0;
169136 self.len = 0;
170137
171 var w_value: UT = if (value < 0) UT(-value) else UT(value);
138 var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);
172139
173140 if (info.bits <= Limb.bit_count) {
174141 self.limbs[0] = Limb(w_value);
......@@ -219,7 +186,7 @@ pub const Int = struct {
219186 TargetTooSmall,
220187 };
221188
222 pub fn to(self: *const Int, comptime T: type) ConvertError!T {
189 pub fn to(self: Int, comptime T: type) ConvertError!T {
223190 switch (@typeId(T)) {
224191 TypeId.Int => {
225192 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;
......@@ -231,7 +198,7 @@ pub const Int = struct {
231198 var r: UT = 0;
232199
233200 if (@sizeOf(UT) <= @sizeOf(Limb)) {
234 r = UT(self.limbs[0]);
201 r = @intCast(UT, self.limbs[0]);
235202 } else {
236203 for (self.limbs[0..self.len]) |_, ri| {
237204 const limb = self.limbs[self.len - ri - 1];
......@@ -243,7 +210,7 @@ pub const Int = struct {
243210 if (!T.is_signed) {
244211 return if (self.positive) r else error.NegativeIntoUnsigned;
245212 } else {
246 return if (self.positive) T(r) else -T(r);
213 return if (self.positive) @intCast(T, r) else -@intCast(T, r);
247214 }
248215 },
249216 else => {
......@@ -286,16 +253,28 @@ pub const Int = struct {
286253 i += 1;
287254 }
288255
256 // TODO values less than limb size should guarantee non allocating
257 var base_buffer: [512]u8 = undefined;
258 const base_al = &std.heap.FixedBufferAllocator.init(base_buffer[0..]).allocator;
259 const base_ap = try Int.initSet(base_al, base);
260
261 var d_buffer: [512]u8 = undefined;
262 var d_fba = std.heap.FixedBufferAllocator.init(d_buffer[0..]);
263 const d_al = &d_fba.allocator;
264
289265 try self.set(0);
290266 for (value[i..]) |ch| {
291267 const d = try charToDigit(ch, base);
292 try self.mul(self, base);
293 try self.add(self, d);
268 d_fba.end_index = 0;
269 const d_ap = try Int.initSet(d_al, d);
270
271 try self.mul(self.*, base_ap);
272 try self.add(self.*, d_ap);
294273 }
295274 self.positive = positive;
296275 }
297276
298 pub fn toString(self: *const Int, allocator: *Allocator, base: u8) ![]const u8 {
277 pub fn toString(self: Int, allocator: *Allocator, base: u8) ![]const u8 {
299278 if (base < 2 or base > 16) {
300279 return error.InvalidBase;
301280 }
......@@ -316,7 +295,7 @@ pub const Int = struct {
316295 for (self.limbs[0..self.len]) |limb| {
317296 var shift: usize = 0;
318297 while (shift < Limb.bit_count) : (shift += base_shift) {
319 const r = u8((limb >> Log2Limb(shift)) & Limb(base - 1));
298 const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1));
320299 const ch = try digitToChar(r, base);
321300 try digits.append(ch);
322301 }
......@@ -345,12 +324,12 @@ pub const Int = struct {
345324 var b = try Int.initSet(allocator, limb_base);
346325
347326 while (q.len >= 2) {
348 try Int.divTrunc(&q, &r, &q, &b);
327 try Int.divTrunc(&q, &r, q, b);
349328
350329 var r_word = r.limbs[0];
351330 var i: usize = 0;
352331 while (i < digits_per_limb) : (i += 1) {
353 const ch = try digitToChar(u8(r_word % base), base);
332 const ch = try digitToChar(@intCast(u8, r_word % base), base);
354333 r_word /= base;
355334 try digits.append(ch);
356335 }
......@@ -361,7 +340,7 @@ pub const Int = struct {
361340
362341 var r_word = q.limbs[0];
363342 while (r_word != 0) {
364 const ch = try digitToChar(u8(r_word % base), base);
343 const ch = try digitToChar(@intCast(u8, r_word % base), base);
365344 r_word /= base;
366345 try digits.append(ch);
367346 }
......@@ -378,12 +357,7 @@ pub const Int = struct {
378357 }
379358
380359 // returns -1, 0, 1 if |a| < |b|, |a| == |b| or |a| > |b| respectively.
381 pub fn cmpAbs(a: *const Int, bv: var) i8 {
382 // TODO: Thread-local buffer.
383 var buffer: [wrapped_buffer_size]u8 = undefined;
384 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
385 var b = wrapInt(&stack.allocator, bv);
386
360 pub fn cmpAbs(a: Int, b: Int) i8 {
387361 if (a.len < b.len) {
388362 return -1;
389363 }
......@@ -408,11 +382,7 @@ pub const Int = struct {
408382 }
409383
410384 // returns -1, 0, 1 if a < b, a == b or a > b respectively.
411 pub fn cmp(a: *const Int, bv: var) i8 {
412 var buffer: [wrapped_buffer_size]u8 = undefined;
413 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
414 var b = wrapInt(&stack.allocator, bv);
415
385 pub fn cmp(a: Int, b: Int) i8 {
416386 if (a.positive != b.positive) {
417387 return if (a.positive) i8(1) else -1;
418388 } else {
......@@ -422,17 +392,17 @@ pub const Int = struct {
422392 }
423393
424394 // if a == 0
425 pub fn eqZero(a: *const Int) bool {
395 pub fn eqZero(a: Int) bool {
426396 return a.len == 1 and a.limbs[0] == 0;
427397 }
428398
429399 // if |a| == |b|
430 pub fn eqAbs(a: *const Int, b: var) bool {
400 pub fn eqAbs(a: Int, b: Int) bool {
431401 return cmpAbs(a, b) == 0;
432402 }
433403
434404 // if a == b
435 pub fn eq(a: *const Int, b: var) bool {
405 pub fn eq(a: Int, b: Int) bool {
436406 return cmp(a, b) == 0;
437407 }
438408
......@@ -473,12 +443,7 @@ pub const Int = struct {
473443 }
474444
475445 // r = a + b
476 pub fn add(r: *Int, av: var, bv: var) Allocator.Error!void {
477 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
478 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
479 var a = wrapInt(&stack.allocator, av);
480 var b = wrapInt(&stack.allocator, bv);
481
446 pub fn add(r: *Int, a: Int, b: Int) Allocator.Error!void {
482447 if (a.eqZero()) {
483448 try r.copy(b);
484449 return;
......@@ -534,25 +499,20 @@ pub const Int = struct {
534499
535500 while (i < b.len) : (i += 1) {
536501 var c: Limb = 0;
537 c += Limb(@addWithOverflow(Limb, a[i], b[i], &r[i]));
538 c += Limb(@addWithOverflow(Limb, r[i], carry, &r[i]));
502 c += @boolToInt(@addWithOverflow(Limb, a[i], b[i], &r[i]));
503 c += @boolToInt(@addWithOverflow(Limb, r[i], carry, &r[i]));
539504 carry = c;
540505 }
541506
542507 while (i < a.len) : (i += 1) {
543 carry = Limb(@addWithOverflow(Limb, a[i], carry, &r[i]));
508 carry = @boolToInt(@addWithOverflow(Limb, a[i], carry, &r[i]));
544509 }
545510
546511 r[i] = carry;
547512 }
548513
549514 // r = a - b
550 pub fn sub(r: *Int, av: var, bv: var) !void {
551 var buffer: [wrapped_buffer_size]u8 = undefined;
552 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
553 var a = wrapInt(&stack.allocator, av);
554 var b = wrapInt(&stack.allocator, bv);
555
515 pub fn sub(r: *Int, a: Int, b: Int) !void {
556516 if (a.positive != b.positive) {
557517 if (a.positive) {
558518 // (a) - (-b) => a + b
......@@ -617,13 +577,13 @@ pub const Int = struct {
617577
618578 while (i < b.len) : (i += 1) {
619579 var c: Limb = 0;
620 c += Limb(@subWithOverflow(Limb, a[i], b[i], &r[i]));
621 c += Limb(@subWithOverflow(Limb, r[i], borrow, &r[i]));
580 c += @boolToInt(@subWithOverflow(Limb, a[i], b[i], &r[i]));
581 c += @boolToInt(@subWithOverflow(Limb, r[i], borrow, &r[i]));
622582 borrow = c;
623583 }
624584
625585 while (i < a.len) : (i += 1) {
626 borrow = Limb(@subWithOverflow(Limb, a[i], borrow, &r[i]));
586 borrow = @boolToInt(@subWithOverflow(Limb, a[i], borrow, &r[i]));
627587 }
628588
629589 debug.assert(borrow == 0);
......@@ -632,14 +592,9 @@ pub const Int = struct {
632592 // rma = a * b
633593 //
634594 // For greatest efficiency, ensure rma does not alias a or b.
635 pub fn mul(rma: *Int, av: var, bv: var) !void {
636 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
637 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
638 var a = wrapInt(&stack.allocator, av);
639 var b = wrapInt(&stack.allocator, bv);
640
595 pub fn mul(rma: *Int, a: Int, b: Int) !void {
641596 var r = rma;
642 var aliased = rma == a or rma == b;
597 var aliased = rma.limbs.ptr == a.limbs.ptr or rma.limbs.ptr == b.limbs.ptr;
643598
644599 var sr: Int = undefined;
645600 if (aliased) {
......@@ -669,7 +624,7 @@ pub const Int = struct {
669624 var r1: Limb = undefined;
670625
671626 // r1 = a + *carry
672 const c1 = Limb(@addWithOverflow(Limb, a, carry.*, &r1));
627 const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));
673628
674629 // r2 = b * c
675630 //
......@@ -684,7 +639,7 @@ pub const Int = struct {
684639 const c2 = @truncate(Limb, bc >> Limb.bit_count);
685640
686641 // r1 = r1 + r2
687 const c3 = Limb(@addWithOverflow(Limb, r1, r2, &r1));
642 const c3: Limb = @boolToInt(@addWithOverflow(Limb, r1, r2, &r1));
688643
689644 // This never overflows, c1, c3 are either 0 or 1 and if both are 1 then
690645 // c2 is at least <= @maxValue(Limb) - 2.
......@@ -714,29 +669,29 @@ pub const Int = struct {
714669 }
715670 }
716671
717 pub fn divFloor(q: *Int, r: *Int, a: var, b: var) !void {
672 pub fn divFloor(q: *Int, r: *Int, a: Int, b: Int) !void {
718673 try div(q, r, a, b);
719674
720675 // Trunc -> Floor.
721676 if (!q.positive) {
722 try q.sub(q, 1);
723 try r.add(q, 1);
677 // TODO values less than limb size should guarantee non allocating
678 var one_buffer: [512]u8 = undefined;
679 const one_al = &std.heap.FixedBufferAllocator.init(one_buffer[0..]).allocator;
680 const one_ap = try Int.initSet(one_al, 1);
681
682 try q.sub(q.*, one_ap);
683 try r.add(q.*, one_ap);
724684 }
725685 r.positive = b.positive;
726686 }
727687
728 pub fn divTrunc(q: *Int, r: *Int, a: var, b: var) !void {
688 pub fn divTrunc(q: *Int, r: *Int, a: Int, b: Int) !void {
729689 try div(q, r, a, b);
730690 r.positive = a.positive;
731691 }
732692
733693 // Truncates by default.
734 fn div(quo: *Int, rem: *Int, av: var, bv: var) !void {
735 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
736 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
737 var a = wrapInt(&stack.allocator, av);
738 var b = wrapInt(&stack.allocator, bv);
739
694 fn div(quo: *Int, rem: *Int, a: Int, b: Int) !void {
740695 if (b.eqZero()) {
741696 @panic("division by zero");
742697 }
......@@ -821,8 +776,8 @@ pub const Int = struct {
821776
822777 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set)
823778 const norm_shift = @clz(y.limbs[y.len - 1]);
824 try x.shiftLeft(x, norm_shift);
825 try y.shiftLeft(y, norm_shift);
779 try x.shiftLeft(x.*, norm_shift);
780 try y.shiftLeft(y.*, norm_shift);
826781
827782 const n = x.len - 1;
828783 const t = y.len - 1;
......@@ -832,10 +787,10 @@ pub const Int = struct {
832787 mem.set(Limb, q.limbs[0..q.len], 0);
833788
834789 // 2.
835 try tmp.shiftLeft(y, Limb.bit_count * (n - t));
836 while (x.cmp(&tmp) >= 0) {
790 try tmp.shiftLeft(y.*, Limb.bit_count * (n - t));
791 while (x.cmp(tmp) >= 0) {
837792 q.limbs[n - t] += 1;
838 try x.sub(x, tmp);
793 try x.sub(x.*, tmp);
839794 }
840795
841796 // 3.
......@@ -846,7 +801,7 @@ pub const Int = struct {
846801 q.limbs[i - t - 1] = @maxValue(Limb);
847802 } else {
848803 const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]);
849 const z = Limb(num / DoubleLimb(y.limbs[t]));
804 const z = @intCast(Limb, num / DoubleLimb(y.limbs[t]));
850805 q.limbs[i - t - 1] = if (z > @maxValue(Limb)) @maxValue(Limb) else Limb(z);
851806 }
852807
......@@ -864,7 +819,7 @@ pub const Int = struct {
864819 r.limbs[2] = carry;
865820 r.normN(3);
866821
867 if (r.cmpAbs(&tmp) <= 0) {
822 if (r.cmpAbs(tmp) <= 0) {
868823 break;
869824 }
870825
......@@ -873,13 +828,13 @@ pub const Int = struct {
873828
874829 // 3.3
875830 try tmp.set(q.limbs[i - t - 1]);
876 try tmp.mul(&tmp, y);
877 try tmp.shiftLeft(&tmp, Limb.bit_count * (i - t - 1));
878 try x.sub(x, &tmp);
831 try tmp.mul(tmp, y.*);
832 try tmp.shiftLeft(tmp, Limb.bit_count * (i - t - 1));
833 try x.sub(x.*, tmp);
879834
880835 if (!x.positive) {
881 try tmp.shiftLeft(y, Limb.bit_count * (i - t - 1));
882 try x.add(x, &tmp);
836 try tmp.shiftLeft(y.*, Limb.bit_count * (i - t - 1));
837 try x.add(x.*, tmp);
883838 q.limbs[i - t - 1] -= 1;
884839 }
885840 }
......@@ -887,16 +842,12 @@ pub const Int = struct {
887842 // Denormalize
888843 q.normN(q.len);
889844
890 try r.shiftRight(x, norm_shift);
845 try r.shiftRight(x.*, norm_shift);
891846 r.normN(r.len);
892847 }
893848
894849 // r = a << shift, in other words, r = a * 2^shift
895 pub fn shiftLeft(r: *Int, av: var, shift: usize) !void {
896 var buffer: [wrapped_buffer_size]u8 = undefined;
897 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
898 var a = wrapInt(&stack.allocator, av);
899
850 pub fn shiftLeft(r: *Int, a: Int, shift: usize) !void {
900851 try r.ensureCapacity(a.len + (shift / Limb.bit_count) + 1);
901852 llshl(r.limbs[0..], a.limbs[0..a.len], shift);
902853 r.norm1(a.len + (shift / Limb.bit_count) + 1);
......@@ -909,7 +860,7 @@ pub const Int = struct {
909860 debug.assert(r.len >= a.len + (shift / Limb.bit_count) + 1);
910861
911862 const limb_shift = shift / Limb.bit_count + 1;
912 const interior_limb_shift = Log2Limb(shift % Limb.bit_count);
863 const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count);
913864
914865 var carry: Limb = 0;
915866 var i: usize = 0;
......@@ -918,7 +869,7 @@ pub const Int = struct {
918869 const dst_i = src_i + limb_shift;
919870
920871 const src_digit = a[src_i];
921 r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift));
872 r[dst_i] = carry | @inlineCall(math.shr, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift));
922873 carry = (src_digit << interior_limb_shift);
923874 }
924875
......@@ -927,11 +878,7 @@ pub const Int = struct {
927878 }
928879
929880 // r = a >> shift
930 pub fn shiftRight(r: *Int, av: var, shift: usize) !void {
931 var buffer: [wrapped_buffer_size]u8 = undefined;
932 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
933 var a = wrapInt(&stack.allocator, av);
934
881 pub fn shiftRight(r: *Int, a: Int, shift: usize) !void {
935882 if (a.len <= shift / Limb.bit_count) {
936883 r.len = 1;
937884 r.limbs[0] = 0;
......@@ -951,7 +898,7 @@ pub const Int = struct {
951898 debug.assert(r.len >= a.len - (shift / Limb.bit_count));
952899
953900 const limb_shift = shift / Limb.bit_count;
954 const interior_limb_shift = Log2Limb(shift % Limb.bit_count);
901 const interior_limb_shift = @intCast(Log2Limb, shift % Limb.bit_count);
955902
956903 var carry: Limb = 0;
957904 var i: usize = 0;
......@@ -961,17 +908,12 @@ pub const Int = struct {
961908
962909 const src_digit = a[src_i];
963910 r[dst_i] = carry | (src_digit >> interior_limb_shift);
964 carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - Limb(interior_limb_shift));
911 carry = @inlineCall(math.shl, Limb, src_digit, Limb.bit_count - @intCast(Limb, interior_limb_shift));
965912 }
966913 }
967914
968915 // r = a | b
969 pub fn bitOr(r: *Int, av: var, bv: var) !void {
970 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
971 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
972 var a = wrapInt(&stack.allocator, av);
973 var b = wrapInt(&stack.allocator, bv);
974
916 pub fn bitOr(r: *Int, a: Int, b: Int) !void {
975917 if (a.len > b.len) {
976918 try r.ensureCapacity(a.len);
977919 llor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -998,12 +940,7 @@ pub const Int = struct {
998940 }
999941
1000942 // r = a & b
1001 pub fn bitAnd(r: *Int, av: var, bv: var) !void {
1002 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1003 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1004 var a = wrapInt(&stack.allocator, av);
1005 var b = wrapInt(&stack.allocator, bv);
1006
943 pub fn bitAnd(r: *Int, a: Int, b: Int) !void {
1007944 if (a.len > b.len) {
1008945 try r.ensureCapacity(b.len);
1009946 lland(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -1027,12 +964,7 @@ pub const Int = struct {
1027964 }
1028965
1029966 // r = a ^ b
1030 pub fn bitXor(r: *Int, av: var, bv: var) !void {
1031 var buffer: [2 * wrapped_buffer_size]u8 = undefined;
1032 var stack = std.heap.FixedBufferAllocator.init(buffer[0..]);
1033 var a = wrapInt(&stack.allocator, av);
1034 var b = wrapInt(&stack.allocator, bv);
1035
967 pub fn bitXor(r: *Int, a: Int, b: Int) !void {
1036968 if (a.len > b.len) {
1037969 try r.ensureCapacity(a.len);
1038970 llxor(r.limbs[0..], a.limbs[0..a.len], b.limbs[0..b.len]);
......@@ -1065,7 +997,7 @@ pub const Int = struct {
1065997// may be untested in some cases.
1066998
1067999const u256 = @IntType(false, 256);
1068var al = debug.global_allocator;
1000const al = debug.global_allocator;
10691001
10701002test "big.int comptime_int set" {
10711003 comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
......@@ -1198,7 +1130,7 @@ test "big.int bitcount + sizeInBase" {
11981130 debug.assert(a.sizeInBase(2) >= 32);
11991131 debug.assert(a.sizeInBase(10) >= 10);
12001132
1201 try a.shiftLeft(&a, 5000);
1133 try a.shiftLeft(a, 5000);
12021134 debug.assert(a.bitcount() == 5032);
12031135 debug.assert(a.sizeInBase(2) >= 5032);
12041136 a.positive = false;
......@@ -1320,40 +1252,40 @@ test "big.int compare" {
13201252 var a = try Int.initSet(al, -11);
13211253 var b = try Int.initSet(al, 10);
13221254
1323 debug.assert(a.cmpAbs(&b) == 1);
1324 debug.assert(a.cmp(&b) == -1);
1255 debug.assert(a.cmpAbs(b) == 1);
1256 debug.assert(a.cmp(b) == -1);
13251257}
13261258
13271259test "big.int compare similar" {
13281260 var a = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeee);
13291261 var b = try Int.initSet(al, 0xffffffffeeeeeeeeffffffffeeeeeeef);
13301262
1331 debug.assert(a.cmpAbs(&b) == -1);
1332 debug.assert(b.cmpAbs(&a) == 1);
1263 debug.assert(a.cmpAbs(b) == -1);
1264 debug.assert(b.cmpAbs(a) == 1);
13331265}
13341266
13351267test "big.int compare different limb size" {
13361268 var a = try Int.initSet(al, @maxValue(Limb) + 1);
13371269 var b = try Int.initSet(al, 1);
13381270
1339 debug.assert(a.cmpAbs(&b) == 1);
1340 debug.assert(b.cmpAbs(&a) == -1);
1271 debug.assert(a.cmpAbs(b) == 1);
1272 debug.assert(b.cmpAbs(a) == -1);
13411273}
13421274
13431275test "big.int compare multi-limb" {
13441276 var a = try Int.initSet(al, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
13451277 var b = try Int.initSet(al, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
13461278
1347 debug.assert(a.cmpAbs(&b) == 1);
1348 debug.assert(a.cmp(&b) == -1);
1279 debug.assert(a.cmpAbs(b) == 1);
1280 debug.assert(a.cmp(b) == -1);
13491281}
13501282
13511283test "big.int equality" {
13521284 var a = try Int.initSet(al, 0xffffffff1);
13531285 var b = try Int.initSet(al, -0xffffffff1);
13541286
1355 debug.assert(a.eqAbs(&b));
1356 debug.assert(!a.eq(&b));
1287 debug.assert(a.eqAbs(b));
1288 debug.assert(!a.eq(b));
13571289}
13581290
13591291test "big.int abs" {
......@@ -1381,7 +1313,7 @@ test "big.int add single-single" {
13811313 var b = try Int.initSet(al, 5);
13821314
13831315 var c = try Int.init(al);
1384 try c.add(&a, &b);
1316 try c.add(a, b);
13851317
13861318 debug.assert((try c.to(u32)) == 55);
13871319}
......@@ -1392,10 +1324,10 @@ test "big.int add multi-single" {
13921324
13931325 var c = try Int.init(al);
13941326
1395 try c.add(&a, &b);
1327 try c.add(a, b);
13961328 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
13971329
1398 try c.add(&b, &a);
1330 try c.add(b, a);
13991331 debug.assert((try c.to(DoubleLimb)) == @maxValue(Limb) + 2);
14001332}
14011333
......@@ -1406,7 +1338,7 @@ test "big.int add multi-multi" {
14061338 var b = try Int.initSet(al, op2);
14071339
14081340 var c = try Int.init(al);
1409 try c.add(&a, &b);
1341 try c.add(a, b);
14101342
14111343 debug.assert((try c.to(u128)) == op1 + op2);
14121344}
......@@ -1416,7 +1348,7 @@ test "big.int add zero-zero" {
14161348 var b = try Int.initSet(al, 0);
14171349
14181350 var c = try Int.init(al);
1419 try c.add(&a, &b);
1351 try c.add(a, b);
14201352
14211353 debug.assert((try c.to(u32)) == 0);
14221354}
......@@ -1426,7 +1358,7 @@ test "big.int add alias multi-limb nonzero-zero" {
14261358 var a = try Int.initSet(al, op1);
14271359 var b = try Int.initSet(al, 0);
14281360
1429 try a.add(&a, &b);
1361 try a.add(a, b);
14301362
14311363 debug.assert((try a.to(u128)) == op1);
14321364}
......@@ -1434,16 +1366,21 @@ test "big.int add alias multi-limb nonzero-zero" {
14341366test "big.int add sign" {
14351367 var a = try Int.init(al);
14361368
1437 try a.add(1, 2);
1369 const one = try Int.initSet(al, 1);
1370 const two = try Int.initSet(al, 2);
1371 const neg_one = try Int.initSet(al, -1);
1372 const neg_two = try Int.initSet(al, -2);
1373
1374 try a.add(one, two);
14381375 debug.assert((try a.to(i32)) == 3);
14391376
1440 try a.add(-1, 2);
1377 try a.add(neg_one, two);
14411378 debug.assert((try a.to(i32)) == 1);
14421379
1443 try a.add(1, -2);
1380 try a.add(one, neg_two);
14441381 debug.assert((try a.to(i32)) == -1);
14451382
1446 try a.add(-1, -2);
1383 try a.add(neg_one, neg_two);
14471384 debug.assert((try a.to(i32)) == -3);
14481385}
14491386
......@@ -1452,7 +1389,7 @@ test "big.int sub single-single" {
14521389 var b = try Int.initSet(al, 5);
14531390
14541391 var c = try Int.init(al);
1455 try c.sub(&a, &b);
1392 try c.sub(a, b);
14561393
14571394 debug.assert((try c.to(u32)) == 45);
14581395}
......@@ -1462,7 +1399,7 @@ test "big.int sub multi-single" {
14621399 var b = try Int.initSet(al, 1);
14631400
14641401 var c = try Int.init(al);
1465 try c.sub(&a, &b);
1402 try c.sub(a, b);
14661403
14671404 debug.assert((try c.to(Limb)) == @maxValue(Limb));
14681405}
......@@ -1475,7 +1412,7 @@ test "big.int sub multi-multi" {
14751412 var b = try Int.initSet(al, op2);
14761413
14771414 var c = try Int.init(al);
1478 try c.sub(&a, &b);
1415 try c.sub(a, b);
14791416
14801417 debug.assert((try c.to(u128)) == op1 - op2);
14811418}
......@@ -1485,7 +1422,7 @@ test "big.int sub equal" {
14851422 var b = try Int.initSet(al, 0x11efefefefefefefefefefefef);
14861423
14871424 var c = try Int.init(al);
1488 try c.sub(&a, &b);
1425 try c.sub(a, b);
14891426
14901427 debug.assert((try c.to(u32)) == 0);
14911428}
......@@ -1493,19 +1430,24 @@ test "big.int sub equal" {
14931430test "big.int sub sign" {
14941431 var a = try Int.init(al);
14951432
1496 try a.sub(1, 2);
1433 const one = try Int.initSet(al, 1);
1434 const two = try Int.initSet(al, 2);
1435 const neg_one = try Int.initSet(al, -1);
1436 const neg_two = try Int.initSet(al, -2);
1437
1438 try a.sub(one, two);
14971439 debug.assert((try a.to(i32)) == -1);
14981440
1499 try a.sub(-1, 2);
1441 try a.sub(neg_one, two);
15001442 debug.assert((try a.to(i32)) == -3);
15011443
1502 try a.sub(1, -2);
1444 try a.sub(one, neg_two);
15031445 debug.assert((try a.to(i32)) == 3);
15041446
1505 try a.sub(-1, -2);
1447 try a.sub(neg_one, neg_two);
15061448 debug.assert((try a.to(i32)) == 1);
15071449
1508 try a.sub(-2, -1);
1450 try a.sub(neg_two, neg_one);
15091451 debug.assert((try a.to(i32)) == -1);
15101452}
15111453
......@@ -1514,7 +1456,7 @@ test "big.int mul single-single" {
15141456 var b = try Int.initSet(al, 5);
15151457
15161458 var c = try Int.init(al);
1517 try c.mul(&a, &b);
1459 try c.mul(a, b);
15181460
15191461 debug.assert((try c.to(u64)) == 250);
15201462}
......@@ -1524,7 +1466,7 @@ test "big.int mul multi-single" {
15241466 var b = try Int.initSet(al, 2);
15251467
15261468 var c = try Int.init(al);
1527 try c.mul(&a, &b);
1469 try c.mul(a, b);
15281470
15291471 debug.assert((try c.to(DoubleLimb)) == 2 * @maxValue(Limb));
15301472}
......@@ -1536,7 +1478,7 @@ test "big.int mul multi-multi" {
15361478 var b = try Int.initSet(al, op2);
15371479
15381480 var c = try Int.init(al);
1539 try c.mul(&a, &b);
1481 try c.mul(a, b);
15401482
15411483 debug.assert((try c.to(u256)) == op1 * op2);
15421484}
......@@ -1545,7 +1487,7 @@ test "big.int mul alias r with a" {
15451487 var a = try Int.initSet(al, @maxValue(Limb));
15461488 var b = try Int.initSet(al, 2);
15471489
1548 try a.mul(&a, &b);
1490 try a.mul(a, b);
15491491
15501492 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
15511493}
......@@ -1554,7 +1496,7 @@ test "big.int mul alias r with b" {
15541496 var a = try Int.initSet(al, @maxValue(Limb));
15551497 var b = try Int.initSet(al, 2);
15561498
1557 try a.mul(&b, &a);
1499 try a.mul(b, a);
15581500
15591501 debug.assert((try a.to(DoubleLimb)) == 2 * @maxValue(Limb));
15601502}
......@@ -1562,7 +1504,7 @@ test "big.int mul alias r with b" {
15621504test "big.int mul alias r with a and b" {
15631505 var a = try Int.initSet(al, @maxValue(Limb));
15641506
1565 try a.mul(&a, &a);
1507 try a.mul(a, a);
15661508
15671509 debug.assert((try a.to(DoubleLimb)) == @maxValue(Limb) * @maxValue(Limb));
15681510}
......@@ -1572,7 +1514,7 @@ test "big.int mul a*0" {
15721514 var b = try Int.initSet(al, 0);
15731515
15741516 var c = try Int.init(al);
1575 try c.mul(&a, &b);
1517 try c.mul(a, b);
15761518
15771519 debug.assert((try c.to(u32)) == 0);
15781520}
......@@ -1582,7 +1524,7 @@ test "big.int mul 0*0" {
15821524 var b = try Int.initSet(al, 0);
15831525
15841526 var c = try Int.init(al);
1585 try c.mul(&a, &b);
1527 try c.mul(a, b);
15861528
15871529 debug.assert((try c.to(u32)) == 0);
15881530}
......@@ -1593,7 +1535,7 @@ test "big.int div single-single no rem" {
15931535
15941536 var q = try Int.init(al);
15951537 var r = try Int.init(al);
1596 try Int.divTrunc(&q, &r, &a, &b);
1538 try Int.divTrunc(&q, &r, a, b);
15971539
15981540 debug.assert((try q.to(u32)) == 10);
15991541 debug.assert((try r.to(u32)) == 0);
......@@ -1605,7 +1547,7 @@ test "big.int div single-single with rem" {
16051547
16061548 var q = try Int.init(al);
16071549 var r = try Int.init(al);
1608 try Int.divTrunc(&q, &r, &a, &b);
1550 try Int.divTrunc(&q, &r, a, b);
16091551
16101552 debug.assert((try q.to(u32)) == 9);
16111553 debug.assert((try r.to(u32)) == 4);
......@@ -1620,7 +1562,7 @@ test "big.int div multi-single no rem" {
16201562
16211563 var q = try Int.init(al);
16221564 var r = try Int.init(al);
1623 try Int.divTrunc(&q, &r, &a, &b);
1565 try Int.divTrunc(&q, &r, a, b);
16241566
16251567 debug.assert((try q.to(u64)) == op1 / op2);
16261568 debug.assert((try r.to(u64)) == 0);
......@@ -1635,7 +1577,7 @@ test "big.int div multi-single with rem" {
16351577
16361578 var q = try Int.init(al);
16371579 var r = try Int.init(al);
1638 try Int.divTrunc(&q, &r, &a, &b);
1580 try Int.divTrunc(&q, &r, a, b);
16391581
16401582 debug.assert((try q.to(u64)) == op1 / op2);
16411583 debug.assert((try r.to(u64)) == 3);
......@@ -1650,7 +1592,7 @@ test "big.int div multi>2-single" {
16501592
16511593 var q = try Int.init(al);
16521594 var r = try Int.init(al);
1653 try Int.divTrunc(&q, &r, &a, &b);
1595 try Int.divTrunc(&q, &r, a, b);
16541596
16551597 debug.assert((try q.to(u128)) == op1 / op2);
16561598 debug.assert((try r.to(u32)) == 0x3e4e);
......@@ -1662,7 +1604,7 @@ test "big.int div single-single q < r" {
16621604
16631605 var q = try Int.init(al);
16641606 var r = try Int.init(al);
1665 try Int.divTrunc(&q, &r, &a, &b);
1607 try Int.divTrunc(&q, &r, a, b);
16661608
16671609 debug.assert((try q.to(u64)) == 0);
16681610 debug.assert((try r.to(u64)) == 0x0078f432);
......@@ -1674,7 +1616,7 @@ test "big.int div single-single q == r" {
16741616
16751617 var q = try Int.init(al);
16761618 var r = try Int.init(al);
1677 try Int.divTrunc(&q, &r, &a, &b);
1619 try Int.divTrunc(&q, &r, a, b);
16781620
16791621 debug.assert((try q.to(u64)) == 1);
16801622 debug.assert((try r.to(u64)) == 0);
......@@ -1684,7 +1626,7 @@ test "big.int div q=0 alias" {
16841626 var a = try Int.initSet(al, 3);
16851627 var b = try Int.initSet(al, 10);
16861628
1687 try Int.divTrunc(&a, &b, &a, &b);
1629 try Int.divTrunc(&a, &b, a, b);
16881630
16891631 debug.assert((try a.to(u64)) == 0);
16901632 debug.assert((try b.to(u64)) == 3);
......@@ -1698,7 +1640,7 @@ test "big.int div multi-multi q < r" {
16981640
16991641 var q = try Int.init(al);
17001642 var r = try Int.init(al);
1701 try Int.divTrunc(&q, &r, &a, &b);
1643 try Int.divTrunc(&q, &r, a, b);
17021644
17031645 debug.assert((try q.to(u128)) == 0);
17041646 debug.assert((try r.to(u128)) == op1);
......@@ -1713,7 +1655,7 @@ test "big.int div trunc single-single +/+" {
17131655
17141656 var q = try Int.init(al);
17151657 var r = try Int.init(al);
1716 try Int.divTrunc(&q, &r, &a, &b);
1658 try Int.divTrunc(&q, &r, a, b);
17171659
17181660 // n = q * d + r
17191661 // 5 = 1 * 3 + 2
......@@ -1733,7 +1675,7 @@ test "big.int div trunc single-single -/+" {
17331675
17341676 var q = try Int.init(al);
17351677 var r = try Int.init(al);
1736 try Int.divTrunc(&q, &r, &a, &b);
1678 try Int.divTrunc(&q, &r, a, b);
17371679
17381680 // n = q * d + r
17391681 // -5 = 1 * -3 - 2
......@@ -1753,7 +1695,7 @@ test "big.int div trunc single-single +/-" {
17531695
17541696 var q = try Int.init(al);
17551697 var r = try Int.init(al);
1756 try Int.divTrunc(&q, &r, &a, &b);
1698 try Int.divTrunc(&q, &r, a, b);
17571699
17581700 // n = q * d + r
17591701 // 5 = -1 * -3 + 2
......@@ -1773,7 +1715,7 @@ test "big.int div trunc single-single -/-" {
17731715
17741716 var q = try Int.init(al);
17751717 var r = try Int.init(al);
1776 try Int.divTrunc(&q, &r, &a, &b);
1718 try Int.divTrunc(&q, &r, a, b);
17771719
17781720 // n = q * d + r
17791721 // -5 = 1 * -3 - 2
......@@ -1793,7 +1735,7 @@ test "big.int div floor single-single +/+" {
17931735
17941736 var q = try Int.init(al);
17951737 var r = try Int.init(al);
1796 try Int.divFloor(&q, &r, &a, &b);
1738 try Int.divFloor(&q, &r, a, b);
17971739
17981740 // n = q * d + r
17991741 // 5 = 1 * 3 + 2
......@@ -1813,7 +1755,7 @@ test "big.int div floor single-single -/+" {
18131755
18141756 var q = try Int.init(al);
18151757 var r = try Int.init(al);
1816 try Int.divFloor(&q, &r, &a, &b);
1758 try Int.divFloor(&q, &r, a, b);
18171759
18181760 // n = q * d + r
18191761 // -5 = -2 * 3 + 1
......@@ -1833,7 +1775,7 @@ test "big.int div floor single-single +/-" {
18331775
18341776 var q = try Int.init(al);
18351777 var r = try Int.init(al);
1836 try Int.divFloor(&q, &r, &a, &b);
1778 try Int.divFloor(&q, &r, a, b);
18371779
18381780 // n = q * d + r
18391781 // 5 = -2 * -3 - 1
......@@ -1853,7 +1795,7 @@ test "big.int div floor single-single -/-" {
18531795
18541796 var q = try Int.init(al);
18551797 var r = try Int.init(al);
1856 try Int.divFloor(&q, &r, &a, &b);
1798 try Int.divFloor(&q, &r, a, b);
18571799
18581800 // n = q * d + r
18591801 // -5 = 2 * -3 + 1
......@@ -1870,7 +1812,7 @@ test "big.int div multi-multi with rem" {
18701812
18711813 var q = try Int.init(al);
18721814 var r = try Int.init(al);
1873 try Int.divTrunc(&q, &r, &a, &b);
1815 try Int.divTrunc(&q, &r, a, b);
18741816
18751817 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
18761818 debug.assert((try r.to(u128)) == 0x28de0acacd806823638);
......@@ -1882,7 +1824,7 @@ test "big.int div multi-multi no rem" {
18821824
18831825 var q = try Int.init(al);
18841826 var r = try Int.init(al);
1885 try Int.divTrunc(&q, &r, &a, &b);
1827 try Int.divTrunc(&q, &r, a, b);
18861828
18871829 debug.assert((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
18881830 debug.assert((try r.to(u128)) == 0);
......@@ -1894,7 +1836,7 @@ test "big.int div multi-multi (2 branch)" {
18941836
18951837 var q = try Int.init(al);
18961838 var r = try Int.init(al);
1897 try Int.divTrunc(&q, &r, &a, &b);
1839 try Int.divTrunc(&q, &r, a, b);
18981840
18991841 debug.assert((try q.to(u128)) == 0x10000000000000000);
19001842 debug.assert((try r.to(u128)) == 0x44444443444444431111111111111111);
......@@ -1906,7 +1848,7 @@ test "big.int div multi-multi (3.1/3.3 branch)" {
19061848
19071849 var q = try Int.init(al);
19081850 var r = try Int.init(al);
1909 try Int.divTrunc(&q, &r, &a, &b);
1851 try Int.divTrunc(&q, &r, a, b);
19101852
19111853 debug.assert((try q.to(u128)) == 0xfffffffffffffffffff);
19121854 debug.assert((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
......@@ -1943,17 +1885,17 @@ test "big.int shift-left multi" {
19431885test "big.int shift-right negative" {
19441886 var a = try Int.init(al);
19451887
1946 try a.shiftRight(-20, 2);
1888 try a.shiftRight(try Int.initSet(al, -20), 2);
19471889 debug.assert((try a.to(i32)) == -20 >> 2);
19481890
1949 try a.shiftRight(-5, 10);
1891 try a.shiftRight(try Int.initSet(al, -5), 10);
19501892 debug.assert((try a.to(i32)) == -5 >> 10);
19511893}
19521894
19531895test "big.int shift-left negative" {
19541896 var a = try Int.init(al);
19551897
1956 try a.shiftRight(-10, 1232);
1898 try a.shiftRight(try Int.initSet(al, -10), 1232);
19571899 debug.assert((try a.to(i32)) == -10 >> 1232);
19581900}
19591901
......@@ -1961,7 +1903,7 @@ test "big.int bitwise and simple" {
19611903 var a = try Int.initSet(al, 0xffffffff11111111);
19621904 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19631905
1964 try a.bitAnd(&a, &b);
1906 try a.bitAnd(a, b);
19651907
19661908 debug.assert((try a.to(u64)) == 0xeeeeeeee00000000);
19671909}
......@@ -1970,7 +1912,7 @@ test "big.int bitwise and multi-limb" {
19701912 var a = try Int.initSet(al, @maxValue(Limb) + 1);
19711913 var b = try Int.initSet(al, @maxValue(Limb));
19721914
1973 try a.bitAnd(&a, &b);
1915 try a.bitAnd(a, b);
19741916
19751917 debug.assert((try a.to(u128)) == 0);
19761918}
......@@ -1979,7 +1921,7 @@ test "big.int bitwise xor simple" {
19791921 var a = try Int.initSet(al, 0xffffffff11111111);
19801922 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19811923
1982 try a.bitXor(&a, &b);
1924 try a.bitXor(a, b);
19831925
19841926 debug.assert((try a.to(u64)) == 0x1111111133333333);
19851927}
......@@ -1988,7 +1930,7 @@ test "big.int bitwise xor multi-limb" {
19881930 var a = try Int.initSet(al, @maxValue(Limb) + 1);
19891931 var b = try Int.initSet(al, @maxValue(Limb));
19901932
1991 try a.bitXor(&a, &b);
1933 try a.bitXor(a, b);
19921934
19931935 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) ^ @maxValue(Limb));
19941936}
......@@ -1997,7 +1939,7 @@ test "big.int bitwise or simple" {
19971939 var a = try Int.initSet(al, 0xffffffff11111111);
19981940 var b = try Int.initSet(al, 0xeeeeeeee22222222);
19991941
2000 try a.bitOr(&a, &b);
1942 try a.bitOr(a, b);
20011943
20021944 debug.assert((try a.to(u64)) == 0xffffffff33333333);
20031945}
......@@ -2006,7 +1948,7 @@ test "big.int bitwise or multi-limb" {
20061948 var a = try Int.initSet(al, @maxValue(Limb) + 1);
20071949 var b = try Int.initSet(al, @maxValue(Limb));
20081950
2009 try a.bitOr(&a, &b);
1951 try a.bitOr(a, b);
20101952
20111953 // TODO: big.int.cpp or is wrong on multi-limb.
20121954 debug.assert((try a.to(DoubleLimb)) == (@maxValue(Limb) + 1) + @maxValue(Limb));
......@@ -2015,9 +1957,9 @@ test "big.int bitwise or multi-limb" {
20151957test "big.int var args" {
20161958 var a = try Int.initSet(al, 5);
20171959
2018 try a.add(&a, 6);
1960 try a.add(a, try Int.initSet(al, 6));
20191961 debug.assert((try a.to(u64)) == 11);
20201962
2021 debug.assert(a.cmp(11) == 0);
2022 debug.assert(a.cmp(14) <= 0);
1963 debug.assert(a.cmp(try Int.initSet(al, 11)) == 0);
1964 debug.assert(a.cmp(try Int.initSet(al, 14)) <= 0);
20231965}
std/math/cbrt.zig+3-3
......@@ -54,7 +54,7 @@ fn cbrt32(x: f32) f32 {
5454 r = t * t * t;
5555 t = t * (f64(x) + x + r) / (x + r + r);
5656
57 return f32(t);
57 return @floatCast(f32, t);
5858}
5959
6060fn cbrt64(x: f64) f64 {
......@@ -69,7 +69,7 @@ fn cbrt64(x: f64) f64 {
6969 const P4: f64 = 0.145996192886612446982;
7070
7171 var u = @bitCast(u64, x);
72 var hx = u32(u >> 32) & 0x7FFFFFFF;
72 var hx = @intCast(u32, u >> 32) & 0x7FFFFFFF;
7373
7474 // cbrt(nan, inf) = itself
7575 if (hx >= 0x7FF00000) {
......@@ -79,7 +79,7 @@ fn cbrt64(x: f64) f64 {
7979 // cbrt to ~5bits
8080 if (hx < 0x00100000) {
8181 u = @bitCast(u64, x * 0x1.0p54);
82 hx = u32(u >> 32) & 0x7FFFFFFF;
82 hx = @intCast(u32, u >> 32) & 0x7FFFFFFF;
8383
8484 // cbrt(0) is itself
8585 if (hx == 0) {
std/math/ceil.zig+2-2
......@@ -20,7 +20,7 @@ pub fn ceil(x: var) @typeOf(x) {
2020
2121fn ceil32(x: f32) f32 {
2222 var u = @bitCast(u32, x);
23 var e = i32((u >> 23) & 0xFF) - 0x7F;
23 var e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
2424 var m: u32 = undefined;
2525
2626 // TODO: Shouldn't need this explicit check.
......@@ -31,7 +31,7 @@ fn ceil32(x: f32) f32 {
3131 if (e >= 23) {
3232 return x;
3333 } else if (e >= 0) {
34 m = u32(0x007FFFFF) >> u5(e);
34 m = u32(0x007FFFFF) >> @intCast(u5, e);
3535 if (u & m == 0) {
3636 return x;
3737 }
std/math/complex/atan.zig+5-5
......@@ -4,7 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7pub fn atan(z: var) Complex(@typeOf(z.re)) {
7pub fn atan(z: var) @typeOf(z) {
88 const T = @typeOf(z.re);
99 return switch (T) {
1010 f32 => atan32(z),
......@@ -25,11 +25,11 @@ fn redupif32(x: f32) f32 {
2525 t -= 0.5;
2626 }
2727
28 const u = f32(i32(t));
28 const u = @intToFloat(f32, @floatToInt(i32, t));
2929 return ((x - u * DP1) - u * DP2) - t * DP3;
3030}
3131
32fn atan32(z: *const Complex(f32)) Complex(f32) {
32fn atan32(z: Complex(f32)) Complex(f32) {
3333 const maxnum = 1.0e38;
3434
3535 const x = z.re;
......@@ -74,11 +74,11 @@ fn redupif64(x: f64) f64 {
7474 t -= 0.5;
7575 }
7676
77 const u = f64(i64(t));
77 const u = @intToFloat(f64, @floatToInt(i64, t));
7878 return ((x - u * DP1) - u * DP2) - t * DP3;
7979}
8080
81fn atan64(z: *const Complex(f64)) Complex(f64) {
81fn atan64(z: Complex(f64)) Complex(f64) {
8282 const maxnum = 1.0e308;
8383
8484 const x = z.re;
std/math/complex/cosh.zig+2-2
......@@ -83,12 +83,12 @@ fn cosh64(z: *const Complex(f64)) Complex(f64) {
8383 const y = z.im;
8484
8585 const fx = @bitCast(u64, x);
86 const hx = u32(fx >> 32);
86 const hx = @intCast(u32, fx >> 32);
8787 const lx = @truncate(u32, fx);
8888 const ix = hx & 0x7fffffff;
8989
9090 const fy = @bitCast(u64, y);
91 const hy = u32(fy >> 32);
91 const hy = @intCast(u32, fy >> 32);
9292 const ly = @truncate(u32, fy);
9393 const iy = hy & 0x7fffffff;
9494
std/math/complex/exp.zig+3-3
......@@ -6,7 +6,7 @@ const Complex = cmath.Complex;
66
77const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
88
9pub fn exp(z: var) Complex(@typeOf(z.re)) {
9pub fn exp(z: var) @typeOf(z) {
1010 const T = @typeOf(z.re);
1111
1212 return switch (T) {
......@@ -16,7 +16,7 @@ pub fn exp(z: var) Complex(@typeOf(z.re)) {
1616 };
1717}
1818
19fn exp32(z: *const Complex(f32)) Complex(f32) {
19fn exp32(z: Complex(f32)) Complex(f32) {
2020 @setFloatMode(this, @import("builtin").FloatMode.Strict);
2121
2222 const exp_overflow = 0x42b17218; // max_exp * ln2 ~= 88.72283955
......@@ -63,7 +63,7 @@ fn exp32(z: *const Complex(f32)) Complex(f32) {
6363 }
6464}
6565
66fn exp64(z: *const Complex(f64)) Complex(f64) {
66fn exp64(z: Complex(f64)) Complex(f64) {
6767 const exp_overflow = 0x40862e42; // high bits of max_exp * ln2 ~= 710
6868 const cexp_overflow = 0x4096b8e4; // (max_exp - min_denorm_exp) * ln2
6969
std/math/complex/index.zig+7-7
......@@ -37,28 +37,28 @@ pub fn Complex(comptime T: type) type {
3737 };
3838 }
3939
40 pub fn add(self: *const Self, other: *const Self) Self {
40 pub fn add(self: Self, other: Self) Self {
4141 return Self{
4242 .re = self.re + other.re,
4343 .im = self.im + other.im,
4444 };
4545 }
4646
47 pub fn sub(self: *const Self, other: *const Self) Self {
47 pub fn sub(self: Self, other: Self) Self {
4848 return Self{
4949 .re = self.re - other.re,
5050 .im = self.im - other.im,
5151 };
5252 }
5353
54 pub fn mul(self: *const Self, other: *const Self) Self {
54 pub fn mul(self: Self, other: Self) Self {
5555 return Self{
5656 .re = self.re * other.re - self.im * other.im,
5757 .im = self.im * other.re + self.re * other.im,
5858 };
5959 }
6060
61 pub fn div(self: *const Self, other: *const Self) Self {
61 pub fn div(self: Self, other: Self) Self {
6262 const re_num = self.re * other.re + self.im * other.im;
6363 const im_num = self.im * other.re - self.re * other.im;
6464 const den = other.re * other.re + other.im * other.im;
......@@ -69,14 +69,14 @@ pub fn Complex(comptime T: type) type {
6969 };
7070 }
7171
72 pub fn conjugate(self: *const Self) Self {
72 pub fn conjugate(self: Self) Self {
7373 return Self{
7474 .re = self.re,
7575 .im = -self.im,
7676 };
7777 }
7878
79 pub fn reciprocal(self: *const Self) Self {
79 pub fn reciprocal(self: Self) Self {
8080 const m = self.re * self.re + self.im * self.im;
8181 return Self{
8282 .re = self.re / m,
......@@ -84,7 +84,7 @@ pub fn Complex(comptime T: type) type {
8484 };
8585 }
8686
87 pub fn magnitude(self: *const Self) T {
87 pub fn magnitude(self: Self) T {
8888 return math.sqrt(self.re * self.re + self.im * self.im);
8989 }
9090 };
std/math/complex/ldexp.zig+7-6
......@@ -4,7 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7pub fn ldexp_cexp(z: var, expt: i32) Complex(@typeOf(z.re)) {
7pub fn ldexp_cexp(z: var, expt: i32) @typeOf(z) {
88 const T = @typeOf(z.re);
99
1010 return switch (T) {
......@@ -20,11 +20,12 @@ fn frexp_exp32(x: f32, expt: *i32) f32 {
2020
2121 const exp_x = math.exp(x - kln2);
2222 const hx = @bitCast(u32, exp_x);
23 expt.* = i32(hx >> 23) - (0x7f + 127) + k;
23 // TODO zig should allow this cast implicitly because it should know the value is in range
24 expt.* = @intCast(i32, hx >> 23) - (0x7f + 127) + k;
2425 return @bitCast(f32, (hx & 0x7fffff) | ((0x7f + 127) << 23));
2526}
2627
27fn ldexp_cexp32(z: *const Complex(f32), expt: i32) Complex(f32) {
28fn ldexp_cexp32(z: Complex(f32), expt: i32) Complex(f32) {
2829 var ex_expt: i32 = undefined;
2930 const exp_x = frexp_exp32(z.re, &ex_expt);
3031 const exptf = expt + ex_expt;
......@@ -45,16 +46,16 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {
4546 const exp_x = math.exp(x - kln2);
4647
4748 const fx = @bitCast(u64, x);
48 const hx = u32(fx >> 32);
49 const hx = @intCast(u32, fx >> 32);
4950 const lx = @truncate(u32, fx);
5051
51 expt.* = i32(hx >> 20) - (0x3ff + 1023) + k;
52 expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k;
5253
5354 const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);
5455 return @bitCast(f64, (u64(high_word) << 32) | lx);
5556}
5657
57fn ldexp_cexp64(z: *const Complex(f64), expt: i32) Complex(f64) {
58fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {
5859 var ex_expt: i32 = undefined;
5960 const exp_x = frexp_exp64(z.re, &ex_expt);
6061 const exptf = i64(expt + ex_expt);
std/math/complex/sinh.zig+5-5
......@@ -6,7 +6,7 @@ const Complex = cmath.Complex;
66
77const ldexp_cexp = @import("ldexp.zig").ldexp_cexp;
88
9pub fn sinh(z: var) Complex(@typeOf(z.re)) {
9pub fn sinh(z: var) @typeOf(z) {
1010 const T = @typeOf(z.re);
1111 return switch (T) {
1212 f32 => sinh32(z),
......@@ -15,7 +15,7 @@ pub fn sinh(z: var) Complex(@typeOf(z.re)) {
1515 };
1616}
1717
18fn sinh32(z: *const Complex(f32)) Complex(f32) {
18fn sinh32(z: Complex(f32)) Complex(f32) {
1919 const x = z.re;
2020 const y = z.im;
2121
......@@ -78,17 +78,17 @@ fn sinh32(z: *const Complex(f32)) Complex(f32) {
7878 return Complex(f32).new((x * x) * (y - y), (x + x) * (y - y));
7979}
8080
81fn sinh64(z: *const Complex(f64)) Complex(f64) {
81fn sinh64(z: Complex(f64)) Complex(f64) {
8282 const x = z.re;
8383 const y = z.im;
8484
8585 const fx = @bitCast(u64, x);
86 const hx = u32(fx >> 32);
86 const hx = @intCast(u32, fx >> 32);
8787 const lx = @truncate(u32, fx);
8888 const ix = hx & 0x7fffffff;
8989
9090 const fy = @bitCast(u64, y);
91 const hy = u32(fy >> 32);
91 const hy = @intCast(u32, fy >> 32);
9292 const ly = @truncate(u32, fy);
9393 const iy = hy & 0x7fffffff;
9494
std/math/complex/sqrt.zig+12-7
......@@ -4,18 +4,17 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7// TODO when #733 is solved this can be @typeOf(z) instead of Complex(@typeOf(z.re))
8pub fn sqrt(z: var) Complex(@typeOf(z.re)) {
7pub fn sqrt(z: var) @typeOf(z) {
98 const T = @typeOf(z.re);
109
1110 return switch (T) {
1211 f32 => sqrt32(z),
1312 f64 => sqrt64(z),
14 else => @compileError("sqrt not implemented for " ++ @typeName(z)),
13 else => @compileError("sqrt not implemented for " ++ @typeName(T)),
1514 };
1615}
1716
18fn sqrt32(z: *const Complex(f32)) Complex(f32) {
17fn sqrt32(z: Complex(f32)) Complex(f32) {
1918 const x = z.re;
2019 const y = z.im;
2120
......@@ -50,14 +49,20 @@ fn sqrt32(z: *const Complex(f32)) Complex(f32) {
5049
5150 if (dx >= 0) {
5251 const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5);
53 return Complex(f32).new(f32(t), f32(dy / (2.0 * t)));
52 return Complex(f32).new(
53 @floatCast(f32, t),
54 @floatCast(f32, dy / (2.0 * t)),
55 );
5456 } else {
5557 const t = math.sqrt((-dx + math.hypot(f64, dx, dy)) * 0.5);
56 return Complex(f32).new(f32(math.fabs(y) / (2.0 * t)), f32(math.copysign(f64, t, y)));
58 return Complex(f32).new(
59 @floatCast(f32, math.fabs(y) / (2.0 * t)),
60 @floatCast(f32, math.copysign(f64, t, y)),
61 );
5762 }
5863}
5964
60fn sqrt64(z: *const Complex(f64)) Complex(f64) {
65fn sqrt64(z: Complex(f64)) Complex(f64) {
6166 // may encounter overflow for im,re >= DBL_MAX / (1 + sqrt(2))
6267 const threshold = 0x1.a827999fcef32p+1022;
6368
std/math/complex/tanh.zig+6-4
......@@ -4,7 +4,7 @@ const math = std.math;
44const cmath = math.complex;
55const Complex = cmath.Complex;
66
7pub fn tanh(z: var) Complex(@typeOf(z.re)) {
7pub fn tanh(z: var) @typeOf(z) {
88 const T = @typeOf(z.re);
99 return switch (T) {
1010 f32 => tanh32(z),
......@@ -13,7 +13,7 @@ pub fn tanh(z: var) Complex(@typeOf(z.re)) {
1313 };
1414}
1515
16fn tanh32(z: *const Complex(f32)) Complex(f32) {
16fn tanh32(z: Complex(f32)) Complex(f32) {
1717 const x = z.re;
1818 const y = z.im;
1919
......@@ -51,12 +51,14 @@ fn tanh32(z: *const Complex(f32)) Complex(f32) {
5151 return Complex(f32).new((beta * rho * s) / den, t / den);
5252}
5353
54fn tanh64(z: *const Complex(f64)) Complex(f64) {
54fn tanh64(z: Complex(f64)) Complex(f64) {
5555 const x = z.re;
5656 const y = z.im;
5757
5858 const fx = @bitCast(u64, x);
59 const hx = u32(fx >> 32);
59 // TODO: zig should allow this conversion implicitly because it can notice that the value necessarily
60 // fits in range.
61 const hx = @intCast(u32, fx >> 32);
6062 const lx = @truncate(u32, fx);
6163 const ix = hx & 0x7fffffff;
6264
std/math/cos.zig+2-2
......@@ -55,7 +55,7 @@ fn cos32(x_: f32) f32 {
5555 }
5656
5757 var y = math.floor(x * m4pi);
58 var j = i64(y);
58 var j = @floatToInt(i64, y);
5959
6060 if (j & 1 == 1) {
6161 j += 1;
......@@ -106,7 +106,7 @@ fn cos64(x_: f64) f64 {
106106 }
107107
108108 var y = math.floor(x * m4pi);
109 var j = i64(y);
109 var j = @floatToInt(i64, y);
110110
111111 if (j & 1 == 1) {
112112 j += 1;
std/math/cosh.zig+1-1
......@@ -49,7 +49,7 @@ fn cosh32(x: f32) f32 {
4949
5050fn cosh64(x: f64) f64 {
5151 const u = @bitCast(u64, x);
52 const w = u32(u >> 32);
52 const w = @intCast(u32, u >> 32);
5353 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
5454
5555 // TODO: Shouldn't need this explicit check.
std/math/exp.zig+6-6
......@@ -29,7 +29,7 @@ fn exp32(x_: f32) f32 {
2929
3030 var x = x_;
3131 var hx = @bitCast(u32, x);
32 const sign = i32(hx >> 31);
32 const sign = @intCast(i32, hx >> 31);
3333 hx &= 0x7FFFFFFF;
3434
3535 if (math.isNan(x)) {
......@@ -63,12 +63,12 @@ fn exp32(x_: f32) f32 {
6363 if (hx > 0x3EB17218) {
6464 // |x| > 1.5 * ln2
6565 if (hx > 0x3F851592) {
66 k = i32(invln2 * x + half[usize(sign)]);
66 k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]);
6767 } else {
6868 k = 1 - sign - sign;
6969 }
7070
71 const fk = f32(k);
71 const fk = @intToFloat(f32, k);
7272 hi = x - fk * ln2hi;
7373 lo = fk * ln2lo;
7474 x = hi - lo;
......@@ -110,7 +110,7 @@ fn exp64(x_: f64) f64 {
110110 var x = x_;
111111 var ux = @bitCast(u64, x);
112112 var hx = ux >> 32;
113 const sign = i32(hx >> 31);
113 const sign = @intCast(i32, hx >> 31);
114114 hx &= 0x7FFFFFFF;
115115
116116 if (math.isNan(x)) {
......@@ -148,12 +148,12 @@ fn exp64(x_: f64) f64 {
148148 if (hx > 0x3EB17218) {
149149 // |x| >= 1.5 * ln2
150150 if (hx > 0x3FF0A2B2) {
151 k = i32(invln2 * x + half[usize(sign)]);
151 k = @floatToInt(i32, invln2 * x + half[@intCast(usize, sign)]);
152152 } else {
153153 k = 1 - sign - sign;
154154 }
155155
156 const dk = f64(k);
156 const dk = @intToFloat(f64, k);
157157 hi = x - dk * ln2hi;
158158 lo = dk * ln2lo;
159159 x = hi - lo;
std/math/exp2.zig+7-7
......@@ -38,8 +38,8 @@ const exp2ft = []const f64{
3838fn exp2_32(x: f32) f32 {
3939 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4040
41 const tblsiz = u32(exp2ft.len);
42 const redux: f32 = 0x1.8p23 / f32(tblsiz);
41 const tblsiz = @intCast(u32, exp2ft.len);
42 const redux: f32 = 0x1.8p23 / @intToFloat(f32, tblsiz);
4343 const P1: f32 = 0x1.62e430p-1;
4444 const P2: f32 = 0x1.ebfbe0p-3;
4545 const P3: f32 = 0x1.c6b348p-5;
......@@ -89,7 +89,7 @@ fn exp2_32(x: f32) f32 {
8989 var r: f64 = exp2ft[i0];
9090 const t: f64 = r * z;
9191 r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
92 return f32(r * uk);
92 return @floatCast(f32, r * uk);
9393}
9494
9595const exp2dt = []f64{
......@@ -355,8 +355,8 @@ const exp2dt = []f64{
355355fn exp2_64(x: f64) f64 {
356356 @setFloatMode(this, @import("builtin").FloatMode.Strict);
357357
358 const tblsiz = u32(exp2dt.len / 2);
359 const redux: f64 = 0x1.8p52 / f64(tblsiz);
358 const tblsiz = @intCast(u32, exp2dt.len / 2);
359 const redux: f64 = 0x1.8p52 / @intToFloat(f64, tblsiz);
360360 const P1: f64 = 0x1.62e42fefa39efp-1;
361361 const P2: f64 = 0x1.ebfbdff82c575p-3;
362362 const P3: f64 = 0x1.c6b08d704a0a6p-5;
......@@ -364,7 +364,7 @@ fn exp2_64(x: f64) f64 {
364364 const P5: f64 = 0x1.5d88003875c74p-10;
365365
366366 const ux = @bitCast(u64, x);
367 const ix = u32(ux >> 32) & 0x7FFFFFFF;
367 const ix = @intCast(u32, ux >> 32) & 0x7FFFFFFF;
368368
369369 // TODO: This should be handled beneath.
370370 if (math.isNan(x)) {
......@@ -386,7 +386,7 @@ fn exp2_64(x: f64) f64 {
386386 if (ux >> 63 != 0) {
387387 // underflow
388388 if (x <= -1075 or x - 0x1.0p52 + 0x1.0p52 != x) {
389 math.forceEval(f32(-0x1.0p-149 / x));
389 math.forceEval(@floatCast(f32, -0x1.0p-149 / x));
390390 }
391391 if (x <= -1075) {
392392 return 0;
std/math/expm1.zig+10-10
......@@ -78,8 +78,8 @@ fn expm1_32(x_: f32) f32 {
7878 kf += 0.5;
7979 }
8080
81 k = i32(kf);
82 const t = f32(k);
81 k = @floatToInt(i32, kf);
82 const t = @intToFloat(f32, k);
8383 hi = x - t * ln2_hi;
8484 lo = t * ln2_lo;
8585 }
......@@ -123,7 +123,7 @@ fn expm1_32(x_: f32) f32 {
123123 }
124124 }
125125
126 const twopk = @bitCast(f32, u32((0x7F +% k) << 23));
126 const twopk = @bitCast(f32, @intCast(u32, (0x7F +% k) << 23));
127127
128128 if (k < 0 or k > 56) {
129129 var y = x - e + 1.0;
......@@ -136,7 +136,7 @@ fn expm1_32(x_: f32) f32 {
136136 return y - 1.0;
137137 }
138138
139 const uf = @bitCast(f32, u32(0x7F -% k) << 23);
139 const uf = @bitCast(f32, @intCast(u32, 0x7F -% k) << 23);
140140 if (k < 23) {
141141 return (x - e + (1 - uf)) * twopk;
142142 } else {
......@@ -158,7 +158,7 @@ fn expm1_64(x_: f64) f64 {
158158
159159 var x = x_;
160160 const ux = @bitCast(u64, x);
161 const hx = u32(ux >> 32) & 0x7FFFFFFF;
161 const hx = @intCast(u32, ux >> 32) & 0x7FFFFFFF;
162162 const sign = ux >> 63;
163163
164164 if (math.isNegativeInf(x)) {
......@@ -207,8 +207,8 @@ fn expm1_64(x_: f64) f64 {
207207 kf += 0.5;
208208 }
209209
210 k = i32(kf);
211 const t = f64(k);
210 k = @floatToInt(i32, kf);
211 const t = @intToFloat(f64, k);
212212 hi = x - t * ln2_hi;
213213 lo = t * ln2_lo;
214214 }
......@@ -219,7 +219,7 @@ fn expm1_64(x_: f64) f64 {
219219 // |x| < 2^(-54)
220220 else if (hx < 0x3C900000) {
221221 if (hx < 0x00100000) {
222 math.forceEval(f32(x));
222 math.forceEval(@floatCast(f32, x));
223223 }
224224 return x;
225225 } else {
......@@ -252,7 +252,7 @@ fn expm1_64(x_: f64) f64 {
252252 }
253253 }
254254
255 const twopk = @bitCast(f64, u64(0x3FF +% k) << 52);
255 const twopk = @bitCast(f64, @intCast(u64, 0x3FF +% k) << 52);
256256
257257 if (k < 0 or k > 56) {
258258 var y = x - e + 1.0;
......@@ -265,7 +265,7 @@ fn expm1_64(x_: f64) f64 {
265265 return y - 1.0;
266266 }
267267
268 const uf = @bitCast(f64, u64(0x3FF -% k) << 52);
268 const uf = @bitCast(f64, @intCast(u64, 0x3FF -% k) << 52);
269269 if (k < 20) {
270270 return (x - e + (1 - uf)) * twopk;
271271 } else {
std/math/floor.zig+2-2
......@@ -20,7 +20,7 @@ pub fn floor(x: var) @typeOf(x) {
2020
2121fn floor32(x: f32) f32 {
2222 var u = @bitCast(u32, x);
23 const e = i32((u >> 23) & 0xFF) - 0x7F;
23 const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
2424 var m: u32 = undefined;
2525
2626 // TODO: Shouldn't need this explicit check.
......@@ -33,7 +33,7 @@ fn floor32(x: f32) f32 {
3333 }
3434
3535 if (e >= 0) {
36 m = u32(0x007FFFFF) >> u5(e);
36 m = u32(0x007FFFFF) >> @intCast(u5, e);
3737 if (u & m == 0) {
3838 return x;
3939 }
std/math/fma.zig+3-3
......@@ -17,10 +17,10 @@ fn fma32(x: f32, y: f32, z: f32) f32 {
1717 const e = (u >> 52) & 0x7FF;
1818
1919 if ((u & 0x1FFFFFFF) != 0x10000000 or e == 0x7FF or xy_z - xy == z) {
20 return f32(xy_z);
20 return @floatCast(f32, xy_z);
2121 } else {
2222 // TODO: Handle inexact case with double-rounding
23 return f32(xy_z);
23 return @floatCast(f32, xy_z);
2424 }
2525}
2626
......@@ -124,7 +124,7 @@ fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
124124 var sum = dd_add(a, b);
125125 if (sum.lo != 0) {
126126 var uhii = @bitCast(u64, sum.hi);
127 const bits_lost = -i32((uhii >> 52) & 0x7FF) - scale + 1;
127 const bits_lost = -@intCast(i32, (uhii >> 52) & 0x7FF) - scale + 1;
128128 if ((bits_lost != 1) == (uhii & 1 != 0)) {
129129 const uloi = @bitCast(u64, sum.lo);
130130 uhii += 1 - (((uhii ^ uloi) >> 62) & 2);
std/math/frexp.zig+2-2
......@@ -30,7 +30,7 @@ fn frexp32(x: f32) frexp32_result {
3030 var result: frexp32_result = undefined;
3131
3232 var y = @bitCast(u32, x);
33 const e = i32(y >> 23) & 0xFF;
33 const e = @intCast(i32, y >> 23) & 0xFF;
3434
3535 if (e == 0) {
3636 if (x != 0) {
......@@ -67,7 +67,7 @@ fn frexp64(x: f64) frexp64_result {
6767 var result: frexp64_result = undefined;
6868
6969 var y = @bitCast(u64, x);
70 const e = i32(y >> 52) & 0x7FF;
70 const e = @intCast(i32, y >> 52) & 0x7FF;
7171
7272 if (e == 0) {
7373 if (x != 0) {
std/math/hypot.zig+1-1
......@@ -49,7 +49,7 @@ fn hypot32(x: f32, y: f32) f32 {
4949 yy *= 0x1.0p-90;
5050 }
5151
52 return z * math.sqrt(f32(f64(x) * x + f64(y) * y));
52 return z * math.sqrt(@floatCast(f32, f64(x) * x + f64(y) * y));
5353}
5454
5555fn sq(hi: *f64, lo: *f64, x: f64) void {
std/math/ilogb.zig+2-2
......@@ -23,7 +23,7 @@ const fp_ilogb0 = fp_ilogbnan;
2323
2424fn ilogb32(x: f32) i32 {
2525 var u = @bitCast(u32, x);
26 var e = i32((u >> 23) & 0xFF);
26 var e = @intCast(i32, (u >> 23) & 0xFF);
2727
2828 // TODO: We should be able to merge this with the lower check.
2929 if (math.isNan(x)) {
......@@ -59,7 +59,7 @@ fn ilogb32(x: f32) i32 {
5959
6060fn ilogb64(x: f64) i32 {
6161 var u = @bitCast(u64, x);
62 var e = i32((u >> 52) & 0x7FF);
62 var e = @intCast(i32, (u >> 52) & 0x7FF);
6363
6464 if (math.isNan(x)) {
6565 return @maxValue(i32);
std/math/index.zig+29-7
......@@ -227,7 +227,7 @@ pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T {
227227/// A negative shift amount results in a right shift.
228228pub fn shl(comptime T: type, a: T, shift_amt: var) T {
229229 const abs_shift_amt = absCast(shift_amt);
230 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
230 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt);
231231
232232 if (@typeOf(shift_amt).is_signed) {
233233 if (shift_amt >= 0) {
......@@ -251,7 +251,7 @@ test "math.shl" {
251251/// A negative shift amount results in a lefft shift.
252252pub fn shr(comptime T: type, a: T, shift_amt: var) T {
253253 const abs_shift_amt = absCast(shift_amt);
254 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
254 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else @intCast(Log2Int(T), abs_shift_amt);
255255
256256 if (@typeOf(shift_amt).is_signed) {
257257 if (shift_amt >= 0) {
......@@ -473,9 +473,9 @@ fn testRem() void {
473473/// Result is an unsigned integer.
474474pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
475475 const uint = @IntType(false, @typeOf(x).bit_count);
476 if (x >= 0) return uint(x);
476 if (x >= 0) return @intCast(uint, x);
477477
478 return uint(-(x + 1)) + 1;
478 return @intCast(uint, -(x + 1)) + 1;
479479}
480480
481481test "math.absCast" {
......@@ -499,7 +499,7 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
499499
500500 if (x == -@minValue(int)) return @minValue(int);
501501
502 return -int(x);
502 return -@intCast(int, x);
503503}
504504
505505test "math.negateCast" {
......@@ -522,7 +522,7 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
522522 } else if (@minValue(@typeOf(x)) < @minValue(T) and x < @minValue(T)) {
523523 return error.Overflow;
524524 } else {
525 return T(x);
525 return @intCast(T, x);
526526 }
527527}
528528
......@@ -536,6 +536,17 @@ test "math.cast" {
536536 assert(@typeOf(try cast(u8, u32(255))) == u8);
537537}
538538
539pub const AlignCastError = error{UnalignedMemory};
540
541/// Align cast a pointer but return an error if it's the wrong alignment
542pub fn alignCast(comptime alignment: u29, ptr: var) AlignCastError!@typeOf(@alignCast(alignment, ptr)) {
543 const addr = @ptrToInt(ptr);
544 if (addr % alignment != 0) {
545 return error.UnalignedMemory;
546 }
547 return @alignCast(alignment, ptr);
548}
549
539550pub fn floorPowerOfTwo(comptime T: type, value: T) T {
540551 var x = value;
541552
......@@ -554,7 +565,7 @@ test "math.floorPowerOfTwo" {
554565
555566pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
556567 assert(x != 0);
557 return Log2Int(T)(T.bit_count - 1 - @clz(x));
568 return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x));
558569}
559570
560571pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {
......@@ -586,3 +597,14 @@ fn testFloorPowerOfTwo() void {
586597 assert(floorPowerOfTwo(u4, 8) == 8);
587598 assert(floorPowerOfTwo(u4, 9) == 8);
588599}
600
601pub fn lossyCast(comptime T: type, value: var) T {
602 switch (@typeInfo(@typeOf(value))) {
603 builtin.TypeId.Int => return @intToFloat(T, value),
604 builtin.TypeId.Float => return @floatCast(T, value),
605 builtin.TypeId.ComptimeInt => return T(value),
606 builtin.TypeId.ComptimeFloat => return T(value),
607 else => @compileError("bad type"),
608 }
609}
610
std/math/ln.zig+6-6
......@@ -71,7 +71,7 @@ pub fn ln_32(x_: f32) f32 {
7171
7272 // x into [sqrt(2) / 2, sqrt(2)]
7373 ix += 0x3F800000 - 0x3F3504F3;
74 k += i32(ix >> 23) - 0x7F;
74 k += @intCast(i32, ix >> 23) - 0x7F;
7575 ix = (ix & 0x007FFFFF) + 0x3F3504F3;
7676 x = @bitCast(f32, ix);
7777
......@@ -83,7 +83,7 @@ pub fn ln_32(x_: f32) f32 {
8383 const t2 = z * (Lg1 + w * Lg3);
8484 const R = t2 + t1;
8585 const hfsq = 0.5 * f * f;
86 const dk = f32(k);
86 const dk = @intToFloat(f32, k);
8787
8888 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
8989}
......@@ -103,7 +103,7 @@ pub fn ln_64(x_: f64) f64 {
103103
104104 var x = x_;
105105 var ix = @bitCast(u64, x);
106 var hx = u32(ix >> 32);
106 var hx = @intCast(u32, ix >> 32);
107107 var k: i32 = 0;
108108
109109 if (hx < 0x00100000 or hx >> 31 != 0) {
......@@ -119,7 +119,7 @@ pub fn ln_64(x_: f64) f64 {
119119 // subnormal, scale x
120120 k -= 54;
121121 x *= 0x1.0p54;
122 hx = u32(@bitCast(u64, ix) >> 32);
122 hx = @intCast(u32, @bitCast(u64, ix) >> 32);
123123 } else if (hx >= 0x7FF00000) {
124124 return x;
125125 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
......@@ -128,7 +128,7 @@ pub fn ln_64(x_: f64) f64 {
128128
129129 // x into [sqrt(2) / 2, sqrt(2)]
130130 hx += 0x3FF00000 - 0x3FE6A09E;
131 k += i32(hx >> 20) - 0x3FF;
131 k += @intCast(i32, hx >> 20) - 0x3FF;
132132 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
133133 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
134134 x = @bitCast(f64, ix);
......@@ -141,7 +141,7 @@ pub fn ln_64(x_: f64) f64 {
141141 const t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
142142 const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
143143 const R = t2 + t1;
144 const dk = f64(k);
144 const dk = @intToFloat(f64, k);
145145
146146 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
147147}
std/math/log.zig+6-5
......@@ -13,22 +13,23 @@ pub fn log(comptime T: type, base: T, x: T) T {
1313 return math.ln(x);
1414 }
1515
16 const float_base = math.lossyCast(f64, base);
1617 switch (@typeId(T)) {
1718 TypeId.ComptimeFloat => {
18 return @typeOf(1.0)(math.ln(f64(x)) / math.ln(f64(base)));
19 return @typeOf(1.0)(math.ln(f64(x)) / math.ln(float_base));
1920 },
2021 TypeId.ComptimeInt => {
21 return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(f64(base))));
22 return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(float_base)));
2223 },
2324 builtin.TypeId.Int => {
2425 // TODO implement integer log without using float math
25 return T(math.floor(math.ln(f64(x)) / math.ln(f64(base))));
26 return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base)));
2627 },
2728
2829 builtin.TypeId.Float => {
2930 switch (T) {
30 f32 => return f32(math.ln(f64(x)) / math.ln(f64(base))),
31 f64 => return math.ln(x) / math.ln(f64(base)),
31 f32 => return @floatCast(f32, math.ln(f64(x)) / math.ln(float_base)),
32 f64 => return math.ln(x) / math.ln(float_base),
3233 else => @compileError("log not implemented for " ++ @typeName(T)),
3334 }
3435 },
std/math/log10.zig+7-7
......@@ -28,7 +28,7 @@ pub fn log10(x: var) @typeOf(x) {
2828 return @typeOf(1)(math.floor(log10_64(f64(x))));
2929 },
3030 TypeId.Int => {
31 return T(math.floor(log10_64(f64(x))));
31 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));
3232 },
3333 else => @compileError("log10 not implemented for " ++ @typeName(T)),
3434 }
......@@ -71,7 +71,7 @@ pub fn log10_32(x_: f32) f32 {
7171
7272 // x into [sqrt(2) / 2, sqrt(2)]
7373 ix += 0x3F800000 - 0x3F3504F3;
74 k += i32(ix >> 23) - 0x7F;
74 k += @intCast(i32, ix >> 23) - 0x7F;
7575 ix = (ix & 0x007FFFFF) + 0x3F3504F3;
7676 x = @bitCast(f32, ix);
7777
......@@ -89,7 +89,7 @@ pub fn log10_32(x_: f32) f32 {
8989 u &= 0xFFFFF000;
9090 hi = @bitCast(f32, u);
9191 const lo = f - hi - hfsq + s * (hfsq + R);
92 const dk = f32(k);
92 const dk = @intToFloat(f32, k);
9393
9494 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
9595}
......@@ -109,7 +109,7 @@ pub fn log10_64(x_: f64) f64 {
109109
110110 var x = x_;
111111 var ix = @bitCast(u64, x);
112 var hx = u32(ix >> 32);
112 var hx = @intCast(u32, ix >> 32);
113113 var k: i32 = 0;
114114
115115 if (hx < 0x00100000 or hx >> 31 != 0) {
......@@ -125,7 +125,7 @@ pub fn log10_64(x_: f64) f64 {
125125 // subnormal, scale x
126126 k -= 54;
127127 x *= 0x1.0p54;
128 hx = u32(@bitCast(u64, x) >> 32);
128 hx = @intCast(u32, @bitCast(u64, x) >> 32);
129129 } else if (hx >= 0x7FF00000) {
130130 return x;
131131 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
......@@ -134,7 +134,7 @@ pub fn log10_64(x_: f64) f64 {
134134
135135 // x into [sqrt(2) / 2, sqrt(2)]
136136 hx += 0x3FF00000 - 0x3FE6A09E;
137 k += i32(hx >> 20) - 0x3FF;
137 k += @intCast(i32, hx >> 20) - 0x3FF;
138138 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
139139 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
140140 x = @bitCast(f64, ix);
......@@ -157,7 +157,7 @@ pub fn log10_64(x_: f64) f64 {
157157
158158 // val_hi + val_lo ~ log10(1 + f) + k * log10(2)
159159 var val_hi = hi * ivln10hi;
160 const dk = f64(k);
160 const dk = @intToFloat(f64, k);
161161 const y = dk * log10_2hi;
162162 var val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi;
163163
std/math/log1p.zig+6-6
......@@ -71,7 +71,7 @@ fn log1p_32(x: f32) f32 {
7171 const uf = 1 + x;
7272 var iu = @bitCast(u32, uf);
7373 iu += 0x3F800000 - 0x3F3504F3;
74 k = i32(iu >> 23) - 0x7F;
74 k = @intCast(i32, iu >> 23) - 0x7F;
7575
7676 // correction to avoid underflow in c / u
7777 if (k < 25) {
......@@ -93,7 +93,7 @@ fn log1p_32(x: f32) f32 {
9393 const t2 = z * (Lg1 + w * Lg3);
9494 const R = t2 + t1;
9595 const hfsq = 0.5 * f * f;
96 const dk = f32(k);
96 const dk = @intToFloat(f32, k);
9797
9898 return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
9999}
......@@ -112,7 +112,7 @@ fn log1p_64(x: f64) f64 {
112112 const Lg7: f64 = 1.479819860511658591e-01;
113113
114114 var ix = @bitCast(u64, x);
115 var hx = u32(ix >> 32);
115 var hx = @intCast(u32, ix >> 32);
116116 var k: i32 = 1;
117117 var c: f64 = undefined;
118118 var f: f64 = undefined;
......@@ -150,9 +150,9 @@ fn log1p_64(x: f64) f64 {
150150 if (k != 0) {
151151 const uf = 1 + x;
152152 const hu = @bitCast(u64, uf);
153 var iu = u32(hu >> 32);
153 var iu = @intCast(u32, hu >> 32);
154154 iu += 0x3FF00000 - 0x3FE6A09E;
155 k = i32(iu >> 20) - 0x3FF;
155 k = @intCast(i32, iu >> 20) - 0x3FF;
156156
157157 // correction to avoid underflow in c / u
158158 if (k < 54) {
......@@ -175,7 +175,7 @@ fn log1p_64(x: f64) f64 {
175175 const t1 = w * (Lg2 + w * (Lg4 + w * Lg6));
176176 const t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));
177177 const R = t2 + t1;
178 const dk = f64(k);
178 const dk = @intToFloat(f64, k);
179179
180180 return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
181181}
std/math/log2.zig+6-6
......@@ -75,7 +75,7 @@ pub fn log2_32(x_: f32) f32 {
7575
7676 // x into [sqrt(2) / 2, sqrt(2)]
7777 ix += 0x3F800000 - 0x3F3504F3;
78 k += i32(ix >> 23) - 0x7F;
78 k += @intCast(i32, ix >> 23) - 0x7F;
7979 ix = (ix & 0x007FFFFF) + 0x3F3504F3;
8080 x = @bitCast(f32, ix);
8181
......@@ -93,7 +93,7 @@ pub fn log2_32(x_: f32) f32 {
9393 u &= 0xFFFFF000;
9494 hi = @bitCast(f32, u);
9595 const lo = f - hi - hfsq + s * (hfsq + R);
96 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);
96 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + @intToFloat(f32, k);
9797}
9898
9999pub fn log2_64(x_: f64) f64 {
......@@ -109,7 +109,7 @@ pub fn log2_64(x_: f64) f64 {
109109
110110 var x = x_;
111111 var ix = @bitCast(u64, x);
112 var hx = u32(ix >> 32);
112 var hx = @intCast(u32, ix >> 32);
113113 var k: i32 = 0;
114114
115115 if (hx < 0x00100000 or hx >> 31 != 0) {
......@@ -125,7 +125,7 @@ pub fn log2_64(x_: f64) f64 {
125125 // subnormal, scale x
126126 k -= 54;
127127 x *= 0x1.0p54;
128 hx = u32(@bitCast(u64, x) >> 32);
128 hx = @intCast(u32, @bitCast(u64, x) >> 32);
129129 } else if (hx >= 0x7FF00000) {
130130 return x;
131131 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
......@@ -134,7 +134,7 @@ pub fn log2_64(x_: f64) f64 {
134134
135135 // x into [sqrt(2) / 2, sqrt(2)]
136136 hx += 0x3FF00000 - 0x3FE6A09E;
137 k += i32(hx >> 20) - 0x3FF;
137 k += @intCast(i32, hx >> 20) - 0x3FF;
138138 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
139139 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);
140140 x = @bitCast(f64, ix);
......@@ -159,7 +159,7 @@ pub fn log2_64(x_: f64) f64 {
159159 var val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;
160160
161161 // spadd(val_hi, val_lo, y)
162 const y = f64(k);
162 const y = @intToFloat(f64, k);
163163 const ww = y + val_hi;
164164 val_lo += (y - ww) + val_hi;
165165 val_hi = ww;
std/math/modf.zig+4-4
......@@ -29,7 +29,7 @@ fn modf32(x: f32) modf32_result {
2929 var result: modf32_result = undefined;
3030
3131 const u = @bitCast(u32, x);
32 const e = i32((u >> 23) & 0xFF) - 0x7F;
32 const e = @intCast(i32, (u >> 23) & 0xFF) - 0x7F;
3333 const us = u & 0x80000000;
3434
3535 // TODO: Shouldn't need this.
......@@ -57,7 +57,7 @@ fn modf32(x: f32) modf32_result {
5757 return result;
5858 }
5959
60 const mask = u32(0x007FFFFF) >> u5(e);
60 const mask = u32(0x007FFFFF) >> @intCast(u5, e);
6161 if (u & mask == 0) {
6262 result.ipart = x;
6363 result.fpart = @bitCast(f32, us);
......@@ -74,7 +74,7 @@ fn modf64(x: f64) modf64_result {
7474 var result: modf64_result = undefined;
7575
7676 const u = @bitCast(u64, x);
77 const e = i32((u >> 52) & 0x7FF) - 0x3FF;
77 const e = @intCast(i32, (u >> 52) & 0x7FF) - 0x3FF;
7878 const us = u & (1 << 63);
7979
8080 if (math.isInf(x)) {
......@@ -101,7 +101,7 @@ fn modf64(x: f64) modf64_result {
101101 return result;
102102 }
103103
104 const mask = u64(@maxValue(u64) >> 12) >> u6(e);
104 const mask = u64(@maxValue(u64) >> 12) >> @intCast(u6, e);
105105 if (u & mask == 0) {
106106 result.ipart = x;
107107 result.fpart = @bitCast(f64, us);
std/math/pow.zig+2-2
......@@ -146,7 +146,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
146146 var xe = r2.exponent;
147147 var x1 = r2.significand;
148148
149 var i = i32(yi);
149 var i = @floatToInt(i32, yi);
150150 while (i != 0) : (i >>= 1) {
151151 if (i & 1 == 1) {
152152 a1 *= x1;
......@@ -171,7 +171,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
171171
172172fn isOddInteger(x: f64) bool {
173173 const r = math.modf(x);
174 return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;
174 return r.fpart == 0.0 and @floatToInt(i64, r.ipart) & 1 == 1;
175175}
176176
177177test "math.pow" {
std/math/scalbn.zig+2-2
......@@ -37,7 +37,7 @@ fn scalbn32(x: f32, n_: i32) f32 {
3737 }
3838 }
3939
40 const u = u32(n +% 0x7F) << 23;
40 const u = @intCast(u32, n +% 0x7F) << 23;
4141 return y * @bitCast(f32, u);
4242}
4343
......@@ -67,7 +67,7 @@ fn scalbn64(x: f64, n_: i32) f64 {
6767 }
6868 }
6969
70 const u = u64(n +% 0x3FF) << 52;
70 const u = @intCast(u64, n +% 0x3FF) << 52;
7171 return y * @bitCast(f64, u);
7272}
7373
std/math/sin.zig+2-2
......@@ -60,7 +60,7 @@ fn sin32(x_: f32) f32 {
6060 }
6161
6262 var y = math.floor(x * m4pi);
63 var j = i64(y);
63 var j = @floatToInt(i64, y);
6464
6565 if (j & 1 == 1) {
6666 j += 1;
......@@ -112,7 +112,7 @@ fn sin64(x_: f64) f64 {
112112 }
113113
114114 var y = math.floor(x * m4pi);
115 var j = i64(y);
115 var j = @floatToInt(i64, y);
116116
117117 if (j & 1 == 1) {
118118 j += 1;
std/math/sinh.zig+1-1
......@@ -57,7 +57,7 @@ fn sinh64(x: f64) f64 {
5757 @setFloatMode(this, @import("builtin").FloatMode.Strict);
5858
5959 const u = @bitCast(u64, x);
60 const w = u32(u >> 32);
60 const w = @intCast(u32, u >> 32);
6161 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
6262
6363 if (x == 0.0 or math.isNan(x)) {
std/math/sqrt.zig+1-1
......@@ -99,7 +99,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
9999 }
100100
101101 const ResultType = @IntType(false, T.bit_count / 2);
102 return ResultType(res);
102 return @intCast(ResultType, res);
103103}
104104
105105test "math.sqrt_int" {
std/math/tan.zig+2-2
......@@ -53,7 +53,7 @@ fn tan32(x_: f32) f32 {
5353 }
5454
5555 var y = math.floor(x * m4pi);
56 var j = i64(y);
56 var j = @floatToInt(i64, y);
5757
5858 if (j & 1 == 1) {
5959 j += 1;
......@@ -102,7 +102,7 @@ fn tan64(x_: f64) f64 {
102102 }
103103
104104 var y = math.floor(x * m4pi);
105 var j = i64(y);
105 var j = @floatToInt(i64, y);
106106
107107 if (j & 1 == 1) {
108108 j += 1;
std/math/tanh.zig+2-2
......@@ -68,7 +68,7 @@ fn tanh32(x: f32) f32 {
6868
6969fn tanh64(x: f64) f64 {
7070 const u = @bitCast(u64, x);
71 const w = u32(u >> 32);
71 const w = @intCast(u32, u >> 32);
7272 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
7373
7474 var t: f64 = undefined;
......@@ -100,7 +100,7 @@ fn tanh64(x: f64) f64 {
100100 }
101101 // |x| is subnormal
102102 else {
103 math.forceEval(f32(x));
103 math.forceEval(@floatCast(f32, x));
104104 t = x;
105105 }
106106
std/math/trunc.zig+4-4
......@@ -19,7 +19,7 @@ pub fn trunc(x: var) @typeOf(x) {
1919
2020fn trunc32(x: f32) f32 {
2121 const u = @bitCast(u32, x);
22 var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9;
22 var e = @intCast(i32, ((u >> 23) & 0xFF)) - 0x7F + 9;
2323 var m: u32 = undefined;
2424
2525 if (e >= 23 + 9) {
......@@ -29,7 +29,7 @@ fn trunc32(x: f32) f32 {
2929 e = 1;
3030 }
3131
32 m = u32(@maxValue(u32)) >> u5(e);
32 m = u32(@maxValue(u32)) >> @intCast(u5, e);
3333 if (u & m == 0) {
3434 return x;
3535 } else {
......@@ -40,7 +40,7 @@ fn trunc32(x: f32) f32 {
4040
4141fn trunc64(x: f64) f64 {
4242 const u = @bitCast(u64, x);
43 var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12;
43 var e = @intCast(i32, ((u >> 52) & 0x7FF)) - 0x3FF + 12;
4444 var m: u64 = undefined;
4545
4646 if (e >= 52 + 12) {
......@@ -50,7 +50,7 @@ fn trunc64(x: f64) f64 {
5050 e = 1;
5151 }
5252
53 m = u64(@maxValue(u64)) >> u6(e);
53 m = u64(@maxValue(u64)) >> @intCast(u6, e);
5454 if (u & m == 0) {
5555 return x;
5656 } else {
std/mem.zig+4-8
......@@ -40,16 +40,12 @@ pub const Allocator = struct {
4040
4141 /// Call destroy with the result
4242 /// TODO once #733 is solved, this will replace create
43 pub fn construct(self: *Allocator, init: var) t: {
44 // TODO this is a workaround for type getting parsed as Error!&const T
45 const T = @typeOf(init).Child;
46 break :t Error!*T;
47 } {
48 const T = @typeOf(init).Child;
43 pub fn construct(self: *Allocator, init: var) Error!*@typeOf(init) {
44 const T = @typeOf(init);
4945 if (@sizeOf(T) == 0) return &{};
5046 const slice = try self.alloc(T, 1);
5147 const ptr = &slice[0];
52 ptr.* = init.*;
48 ptr.* = init;
5349 return ptr;
5450 }
5551
......@@ -338,7 +334,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T {
338334 builtin.Endian.Little => {
339335 const ShiftType = math.Log2Int(T);
340336 for (bytes) |b, index| {
341 result = result | (T(b) << ShiftType(index * 8));
337 result = result | (T(b) << @intCast(ShiftType, index * 8));
342338 }
343339 },
344340 }
std/os/child_process.zig+1-1
......@@ -413,7 +413,7 @@ pub const ChildProcess = struct {
413413 }
414414
415415 // we are the parent
416 const pid = i32(pid_result);
416 const pid = @intCast(i32, pid_result);
417417 if (self.stdin_behavior == StdIo.Pipe) {
418418 self.stdin = os.File.openHandle(stdin_pipe[1]);
419419 } else {
std/os/darwin.zig+9-2
......@@ -290,7 +290,7 @@ pub fn WIFSIGNALED(x: i32) bool {
290290/// Get the errno from a syscall return value, or 0 for no error.
291291pub fn getErrno(r: usize) usize {
292292 const signed_r = @bitCast(isize, r);
293 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
293 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
294294}
295295
296296pub fn close(fd: i32) usize {
......@@ -339,7 +339,14 @@ pub fn write(fd: i32, buf: [*]const u8, nbyte: usize) usize {
339339}
340340
341341pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
342 const ptr_result = c.mmap(@ptrCast(*c_void, address), length, @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
342 const ptr_result = c.mmap(
343 @ptrCast(*c_void, address),
344 length,
345 @bitCast(c_int, @intCast(c_uint, prot)),
346 @bitCast(c_int, c_uint(flags)),
347 fd,
348 offset,
349 );
343350 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
344351 return errnoWrap(isize_result);
345352}
std/os/file.zig+13-15
......@@ -265,17 +265,8 @@ pub const File = struct {
265265
266266 pub fn getEndPos(self: *File) !usize {
267267 if (is_posix) {
268 var stat: posix.Stat = undefined;
269 const err = posix.getErrno(posix.fstat(self.handle, &stat));
270 if (err > 0) {
271 return switch (err) {
272 posix.EBADF => error.BadFd,
273 posix.ENOMEM => error.SystemResources,
274 else => os.unexpectedErrorPosix(err),
275 };
276 }
277
278 return usize(stat.size);
268 const stat = try os.posixFStat(self.handle);
269 return @intCast(usize, stat.size);
279270 } else if (is_windows) {
280271 var file_size: windows.LARGE_INTEGER = undefined;
281272 if (windows.GetFileSizeEx(self.handle, &file_size) == 0) {
......@@ -286,7 +277,7 @@ pub const File = struct {
286277 }
287278 if (file_size < 0)
288279 return error.Overflow;
289 return math.cast(usize, u64(file_size));
280 return math.cast(usize, @intCast(u64, file_size));
290281 } else {
291282 @compileError("TODO support getEndPos on this OS");
292283 }
......@@ -320,9 +311,15 @@ pub const File = struct {
320311 }
321312 }
322313
323 pub const ReadError = error{};
314 pub const ReadError = error{
315 BadFd,
316 Io,
317 IsDir,
318
319 Unexpected,
320 };
324321
325 pub fn read(self: *File, buffer: []u8) !usize {
322 pub fn read(self: *File, buffer: []u8) ReadError!usize {
326323 if (is_posix) {
327324 var index: usize = 0;
328325 while (index < buffer.len) {
......@@ -335,6 +332,7 @@ pub const File = struct {
335332 posix.EFAULT => unreachable,
336333 posix.EBADF => return error.BadFd,
337334 posix.EIO => return error.Io,
335 posix.EISDIR => return error.IsDir,
338336 else => return os.unexpectedErrorPosix(read_err),
339337 }
340338 }
......@@ -345,7 +343,7 @@ pub const File = struct {
345343 } else if (is_windows) {
346344 var index: usize = 0;
347345 while (index < buffer.len) {
348 const want_read_count = windows.DWORD(math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index));
346 const want_read_count = @intCast(windows.DWORD, math.min(windows.DWORD(@maxValue(windows.DWORD)), buffer.len - index));
349347 var amt_read: windows.DWORD = undefined;
350348 if (windows.ReadFile(self.handle, @ptrCast(*c_void, buffer.ptr + index), want_read_count, &amt_read, null) == 0) {
351349 const err = windows.GetLastError();
std/os/index.zig+22-8
......@@ -126,7 +126,7 @@ pub fn getRandomBytes(buf: []u8) !void {
126126 }
127127 defer _ = windows.CryptReleaseContext(hCryptProv, 0);
128128
129 if (windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr) == 0) {
129 if (windows.CryptGenRandom(hCryptProv, @intCast(windows.DWORD, buf.len), buf.ptr) == 0) {
130130 const err = windows.GetLastError();
131131 return switch (err) {
132132 else => unexpectedErrorWindows(err),
......@@ -343,7 +343,7 @@ pub fn posixOpenC(file_path: [*]const u8, flags: u32, perm: usize) !i32 {
343343 else => return unexpectedErrorPosix(err),
344344 }
345345 }
346 return i32(result);
346 return @intCast(i32, result);
347347 }
348348}
349349
......@@ -586,7 +586,7 @@ pub fn getCwd(allocator: *Allocator) ![]u8 {
586586 errdefer allocator.free(buf);
587587
588588 while (true) {
589 const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr);
589 const result = windows.GetCurrentDirectoryA(@intCast(windows.WORD, buf.len), buf.ptr);
590590
591591 if (result == 0) {
592592 const err = windows.GetLastError();
......@@ -2019,7 +2019,7 @@ pub fn posixSocket(domain: u32, socket_type: u32, protocol: u32) !i32 {
20192019 const rc = posix.socket(domain, socket_type, protocol);
20202020 const err = posix.getErrno(rc);
20212021 switch (err) {
2022 0 => return i32(rc),
2022 0 => return @intCast(i32, rc),
20232023 posix.EACCES => return PosixSocketError.PermissionDenied,
20242024 posix.EAFNOSUPPORT => return PosixSocketError.AddressFamilyNotSupported,
20252025 posix.EINVAL => return PosixSocketError.ProtocolFamilyNotAvailable,
......@@ -2183,7 +2183,7 @@ pub fn posixAccept(fd: i32, addr: *posix.sockaddr, flags: u32) PosixAcceptError!
21832183 const rc = posix.accept4(fd, addr, &sockaddr_size, flags);
21842184 const err = posix.getErrno(rc);
21852185 switch (err) {
2186 0 => return i32(rc),
2186 0 => return @intCast(i32, rc),
21872187 posix.EINTR => continue,
21882188 else => return unexpectedErrorPosix(err),
21892189
......@@ -2226,7 +2226,7 @@ pub fn linuxEpollCreate(flags: u32) LinuxEpollCreateError!i32 {
22262226 const rc = posix.epoll_create1(flags);
22272227 const err = posix.getErrno(rc);
22282228 switch (err) {
2229 0 => return i32(rc),
2229 0 => return @intCast(i32, rc),
22302230 else => return unexpectedErrorPosix(err),
22312231
22322232 posix.EINVAL => return LinuxEpollCreateError.InvalidSyscall,
......@@ -2296,7 +2296,7 @@ pub fn linuxEpollCtl(epfd: i32, op: u32, fd: i32, event: *linux.epoll_event) Lin
22962296
22972297pub fn linuxEpollWait(epfd: i32, events: []linux.epoll_event, timeout: i32) usize {
22982298 while (true) {
2299 const rc = posix.epoll_wait(epfd, events.ptr, u32(events.len), timeout);
2299 const rc = posix.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);
23002300 const err = posix.getErrno(rc);
23012301 switch (err) {
23022302 0 => return rc,
......@@ -2661,7 +2661,7 @@ pub fn spawnThread(context: var, comptime startFn: var) SpawnThreadError!*Thread
26612661 posix.EAGAIN => return SpawnThreadError.SystemResources,
26622662 posix.EPERM => unreachable,
26632663 posix.EINVAL => unreachable,
2664 else => return unexpectedErrorPosix(usize(err)),
2664 else => return unexpectedErrorPosix(@intCast(usize, err)),
26652665 }
26662666 } else if (builtin.os == builtin.Os.linux) {
26672667 // use linux API directly. TODO use posix.CLONE_SETTLS and initialize thread local storage correctly
......@@ -2697,3 +2697,17 @@ pub fn posixWait(pid: i32) i32 {
26972697 }
26982698 }
26992699}
2700
2701pub fn posixFStat(fd: i32) !posix.Stat {
2702 var stat: posix.Stat = undefined;
2703 const err = posix.getErrno(posix.fstat(fd, &stat));
2704 if (err > 0) {
2705 return switch (err) {
2706 posix.EBADF => error.BadFd,
2707 posix.ENOMEM => error.SystemResources,
2708 else => os.unexpectedErrorPosix(err),
2709 };
2710 }
2711
2712 return stat;
2713}
std/os/linux/index.zig+40-40
......@@ -642,7 +642,7 @@ pub fn WIFEXITED(s: i32) bool {
642642 return WTERMSIG(s) == 0;
643643}
644644pub fn WIFSTOPPED(s: i32) bool {
645 return (u16)(((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00;
645 return @intCast(u16, ((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00;
646646}
647647pub fn WIFSIGNALED(s: i32) bool {
648648 return (unsigned(s) & 0xffff) -% 1 < 0xff;
......@@ -658,11 +658,11 @@ pub const winsize = extern struct {
658658/// Get the errno from a syscall return value, or 0 for no error.
659659pub fn getErrno(r: usize) usize {
660660 const signed_r = @bitCast(isize, r);
661 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
661 return if (signed_r > -4096 and signed_r < 0) @intCast(usize, -signed_r) else 0;
662662}
663663
664664pub fn dup2(old: i32, new: i32) usize {
665 return syscall2(SYS_dup2, usize(old), usize(new));
665 return syscall2(SYS_dup2, @intCast(usize, old), @intCast(usize, new));
666666}
667667
668668// TODO https://github.com/ziglang/zig/issues/265
......@@ -693,12 +693,12 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {
693693}
694694
695695pub fn getdents(fd: i32, dirp: [*]u8, count: usize) usize {
696 return syscall3(SYS_getdents, usize(fd), @ptrToInt(dirp), count);
696 return syscall3(SYS_getdents, @intCast(usize, fd), @ptrToInt(dirp), count);
697697}
698698
699699pub fn isatty(fd: i32) bool {
700700 var wsz: winsize = undefined;
701 return syscall3(SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
701 return syscall3(SYS_ioctl, @intCast(usize, fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
702702}
703703
704704// TODO https://github.com/ziglang/zig/issues/265
......@@ -727,7 +727,7 @@ pub fn umount2(special: [*]const u8, flags: u32) usize {
727727}
728728
729729pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, offset: isize) usize {
730 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), @bitCast(usize, offset));
730 return syscall6(SYS_mmap, @ptrToInt(address), length, prot, flags, @intCast(usize, fd), @bitCast(usize, offset));
731731}
732732
733733pub fn munmap(address: usize, length: usize) usize {
......@@ -735,7 +735,7 @@ pub fn munmap(address: usize, length: usize) usize {
735735}
736736
737737pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
738 return syscall3(SYS_read, usize(fd), @ptrToInt(buf), count);
738 return syscall3(SYS_read, @intCast(usize, fd), @ptrToInt(buf), count);
739739}
740740
741741// TODO https://github.com/ziglang/zig/issues/265
......@@ -749,7 +749,7 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
749749}
750750
751751pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
752 return syscall4(SYS_pread, usize(fd), @ptrToInt(buf), count, offset);
752 return syscall4(SYS_pread, @intCast(usize, fd), @ptrToInt(buf), count, offset);
753753}
754754
755755// TODO https://github.com/ziglang/zig/issues/265
......@@ -766,11 +766,11 @@ pub fn pipe2(fd: *[2]i32, flags: usize) usize {
766766}
767767
768768pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
769 return syscall3(SYS_write, usize(fd), @ptrToInt(buf), count);
769 return syscall3(SYS_write, @intCast(usize, fd), @ptrToInt(buf), count);
770770}
771771
772772pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
773 return syscall4(SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);
773 return syscall4(SYS_pwrite, @intCast(usize, fd), @ptrToInt(buf), count, offset);
774774}
775775
776776// TODO https://github.com/ziglang/zig/issues/265
......@@ -790,7 +790,7 @@ pub fn create(path: [*]const u8, perm: usize) usize {
790790
791791// TODO https://github.com/ziglang/zig/issues/265
792792pub fn openat(dirfd: i32, path: [*]const u8, flags: usize, mode: usize) usize {
793 return syscall4(SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);
793 return syscall4(SYS_openat, @intCast(usize, dirfd), @ptrToInt(path), flags, mode);
794794}
795795
796796/// See also `clone` (from the arch-specific include)
......@@ -804,11 +804,11 @@ pub fn clone2(flags: usize, child_stack_ptr: usize) usize {
804804}
805805
806806pub fn close(fd: i32) usize {
807 return syscall1(SYS_close, usize(fd));
807 return syscall1(SYS_close, @intCast(usize, fd));
808808}
809809
810810pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {
811 return syscall3(SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos);
811 return syscall3(SYS_lseek, @intCast(usize, fd), @bitCast(usize, offset), ref_pos);
812812}
813813
814814pub fn exit(status: i32) noreturn {
......@@ -817,11 +817,11 @@ pub fn exit(status: i32) noreturn {
817817}
818818
819819pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
820 return syscall3(SYS_getrandom, @ptrToInt(buf), count, usize(flags));
820 return syscall3(SYS_getrandom, @ptrToInt(buf), count, @intCast(usize, flags));
821821}
822822
823823pub fn kill(pid: i32, sig: i32) usize {
824 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), usize(sig));
824 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @intCast(usize, sig));
825825}
826826
827827// TODO https://github.com/ziglang/zig/issues/265
......@@ -999,8 +999,8 @@ pub const empty_sigset = []usize{0} ** sigset_t.len;
999999pub fn raise(sig: i32) usize {
10001000 var set: sigset_t = undefined;
10011001 blockAppSignals(&set);
1002 const tid = i32(syscall0(SYS_gettid));
1003 const ret = syscall2(SYS_tkill, usize(tid), usize(sig));
1002 const tid = @intCast(i32, syscall0(SYS_gettid));
1003 const ret = syscall2(SYS_tkill, @intCast(usize, tid), @intCast(usize, sig));
10041004 restoreSignals(&set);
10051005 return ret;
10061006}
......@@ -1019,12 +1019,12 @@ fn restoreSignals(set: *sigset_t) void {
10191019
10201020pub fn sigaddset(set: *sigset_t, sig: u6) void {
10211021 const s = sig - 1;
1022 (set.*)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));
1022 (set.*)[@intCast(usize, s) / usize.bit_count] |= @intCast(usize, 1) << (s & (usize.bit_count - 1));
10231023}
10241024
10251025pub fn sigismember(set: *const sigset_t, sig: u6) bool {
10261026 const s = sig - 1;
1027 return ((set.*)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;
1027 return ((set.*)[@intCast(usize, s) / usize.bit_count] & (@intCast(usize, 1) << (s & (usize.bit_count - 1)))) != 0;
10281028}
10291029
10301030pub const in_port_t = u16;
......@@ -1057,11 +1057,11 @@ pub const iovec = extern struct {
10571057};
10581058
10591059pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
1060 return syscall3(SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len));
1060 return syscall3(SYS_getsockname, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len));
10611061}
10621062
10631063pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
1064 return syscall3(SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len));
1064 return syscall3(SYS_getpeername, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len));
10651065}
10661066
10671067pub 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 {
10691069}
10701070
10711071pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
1072 return syscall5(SYS_setsockopt, usize(fd), level, optname, usize(optval), @ptrToInt(optlen));
1072 return syscall5(SYS_setsockopt, @intCast(usize, fd), level, optname, @intCast(usize, optval), @ptrToInt(optlen));
10731073}
10741074
10751075pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
1076 return syscall5(SYS_getsockopt, usize(fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
1076 return syscall5(SYS_getsockopt, @intCast(usize, fd), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
10771077}
10781078
10791079pub fn sendmsg(fd: i32, msg: *const msghdr, flags: u32) usize {
1080 return syscall3(SYS_sendmsg, usize(fd), @ptrToInt(msg), flags);
1080 return syscall3(SYS_sendmsg, @intCast(usize, fd), @ptrToInt(msg), flags);
10811081}
10821082
10831083pub fn connect(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
1084 return syscall3(SYS_connect, usize(fd), @ptrToInt(addr), usize(len));
1084 return syscall3(SYS_connect, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len));
10851085}
10861086
10871087pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
1088 return syscall3(SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
1088 return syscall3(SYS_recvmsg, @intCast(usize, fd), @ptrToInt(msg), flags);
10891089}
10901090
10911091pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
1092 return syscall6(SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
1092 return syscall6(SYS_recvfrom, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
10931093}
10941094
10951095pub fn shutdown(fd: i32, how: i32) usize {
1096 return syscall2(SYS_shutdown, usize(fd), usize(how));
1096 return syscall2(SYS_shutdown, @intCast(usize, fd), @intCast(usize, how));
10971097}
10981098
10991099pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
1100 return syscall3(SYS_bind, usize(fd), @ptrToInt(addr), usize(len));
1100 return syscall3(SYS_bind, @intCast(usize, fd), @ptrToInt(addr), @intCast(usize, len));
11011101}
11021102
11031103pub fn listen(fd: i32, backlog: u32) usize {
1104 return syscall2(SYS_listen, usize(fd), backlog);
1104 return syscall2(SYS_listen, @intCast(usize, fd), backlog);
11051105}
11061106
11071107pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
1108 return syscall6(SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));
1108 return syscall6(SYS_sendto, @intCast(usize, fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
11091109}
11101110
11111111pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
1112 return syscall4(SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(*fd[0]));
1112 return syscall4(SYS_socketpair, @intCast(usize, domain), @intCast(usize, socket_type), @intCast(usize, protocol), @ptrToInt(*fd[0]));
11131113}
11141114
11151115pub 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 {
11171117}
11181118
11191119pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {
1120 return syscall4(SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags);
1120 return syscall4(SYS_accept4, @intCast(usize, fd), @ptrToInt(addr), @ptrToInt(len), flags);
11211121}
11221122
11231123pub fn fstat(fd: i32, stat_buf: *Stat) usize {
1124 return syscall2(SYS_fstat, usize(fd), @ptrToInt(stat_buf));
1124 return syscall2(SYS_fstat, @intCast(usize, fd), @ptrToInt(stat_buf));
11251125}
11261126
11271127// TODO https://github.com/ziglang/zig/issues/265
......@@ -1214,15 +1214,15 @@ pub fn epoll_create1(flags: usize) usize {
12141214}
12151215
12161216pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: *epoll_event) usize {
1217 return syscall4(SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));
1217 return syscall4(SYS_epoll_ctl, @intCast(usize, epoll_fd), @intCast(usize, op), @intCast(usize, fd), @ptrToInt(ev));
12181218}
12191219
12201220pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
1221 return syscall4(SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));
1221 return syscall4(SYS_epoll_wait, @intCast(usize, epoll_fd), @ptrToInt(events), @intCast(usize, maxevents), @intCast(usize, timeout));
12221222}
12231223
12241224pub fn timerfd_create(clockid: i32, flags: u32) usize {
1225 return syscall2(SYS_timerfd_create, usize(clockid), usize(flags));
1225 return syscall2(SYS_timerfd_create, @intCast(usize, clockid), @intCast(usize, flags));
12261226}
12271227
12281228pub const itimerspec = extern struct {
......@@ -1231,11 +1231,11 @@ pub const itimerspec = extern struct {
12311231};
12321232
12331233pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
1234 return syscall2(SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value));
1234 return syscall2(SYS_timerfd_gettime, @intCast(usize, fd), @ptrToInt(curr_value));
12351235}
12361236
12371237pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
1238 return syscall4(SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value));
1238 return syscall4(SYS_timerfd_settime, @intCast(usize, fd), @intCast(usize, flags), @ptrToInt(new_value), @ptrToInt(old_value));
12391239}
12401240
12411241pub const _LINUX_CAPABILITY_VERSION_1 = 0x19980330;
......@@ -1345,7 +1345,7 @@ pub const cap_user_data_t = extern struct {
13451345};
13461346
13471347pub fn unshare(flags: usize) usize {
1348 return syscall1(SYS_unshare, usize(flags));
1348 return syscall1(SYS_unshare, @intCast(usize, flags));
13491349}
13501350
13511351pub fn capget(hdrp: *cap_user_header_t, datap: *cap_user_data_t) usize {
std/os/linux/test.zig+3-3
......@@ -21,7 +21,7 @@ test "timer" {
2121 .it_value = time_interval,
2222 };
2323
24 err = linux.timerfd_settime(i32(timer_fd), 0, &new_time, null);
24 err = linux.timerfd_settime(@intCast(i32, timer_fd), 0, &new_time, null);
2525 assert(err == 0);
2626
2727 var event = linux.epoll_event{
......@@ -29,12 +29,12 @@ test "timer" {
2929 .data = linux.epoll_data{ .ptr = 0 },
3030 };
3131
32 err = linux.epoll_ctl(i32(epoll_fd), linux.EPOLL_CTL_ADD, i32(timer_fd), &event);
32 err = linux.epoll_ctl(@intCast(i32, epoll_fd), linux.EPOLL_CTL_ADD, @intCast(i32, timer_fd), &event);
3333 assert(err == 0);
3434
3535 const events_one: linux.epoll_event = undefined;
3636 var events = []linux.epoll_event{events_one} ** 8;
3737
3838 // TODO implicit cast from *[N]T to [*]T
39 err = linux.epoll_wait(i32(epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
39 err = linux.epoll_wait(@intCast(i32, epoll_fd), @ptrCast([*]linux.epoll_event, &events), 8, -1);
4040}
std/os/linux/vdso.zig+2-2
......@@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
6262
6363 var i: usize = 0;
6464 while (i < hashtab[1]) : (i += 1) {
65 if (0 == (u32(1) << u5(syms[i].st_info & 0xf) & OK_TYPES)) continue;
66 if (0 == (u32(1) << u5(syms[i].st_info >> 4) & OK_BINDS)) continue;
65 if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue;
66 if (0 == (u32(1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
6767 if (0 == syms[i].st_shndx) continue;
6868 if (!mem.eql(u8, name, cstr.toSliceConst(strings + syms[i].st_name))) continue;
6969 if (maybe_versym) |versym| {
std/os/time.zig+12-12
......@@ -14,12 +14,12 @@ pub const epoch = @import("epoch.zig");
1414pub fn sleep(seconds: usize, nanoseconds: usize) void {
1515 switch (builtin.os) {
1616 Os.linux, Os.macosx, Os.ios => {
17 posixSleep(u63(seconds), u63(nanoseconds));
17 posixSleep(@intCast(u63, seconds), @intCast(u63, nanoseconds));
1818 },
1919 Os.windows => {
2020 const ns_per_ms = ns_per_s / ms_per_s;
2121 const milliseconds = seconds * ms_per_s + nanoseconds / ns_per_ms;
22 windows.Sleep(windows.DWORD(milliseconds));
22 windows.Sleep(@intCast(windows.DWORD, milliseconds));
2323 },
2424 else => @compileError("Unsupported OS"),
2525 }
......@@ -83,8 +83,8 @@ fn milliTimestampDarwin() u64 {
8383 var tv: darwin.timeval = undefined;
8484 var err = darwin.gettimeofday(&tv, null);
8585 debug.assert(err == 0);
86 const sec_ms = u64(tv.tv_sec) * ms_per_s;
87 const usec_ms = @divFloor(u64(tv.tv_usec), us_per_s / ms_per_s);
86 const sec_ms = @intCast(u64, tv.tv_sec) * ms_per_s;
87 const usec_ms = @divFloor(@intCast(u64, tv.tv_usec), us_per_s / ms_per_s);
8888 return u64(sec_ms) + u64(usec_ms);
8989}
9090
......@@ -95,8 +95,8 @@ fn milliTimestampPosix() u64 {
9595 var ts: posix.timespec = undefined;
9696 const err = posix.clock_gettime(posix.CLOCK_REALTIME, &ts);
9797 debug.assert(err == 0);
98 const sec_ms = u64(ts.tv_sec) * ms_per_s;
99 const nsec_ms = @divFloor(u64(ts.tv_nsec), ns_per_s / ms_per_s);
98 const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s;
99 const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s);
100100 return sec_ms + nsec_ms;
101101}
102102
......@@ -162,13 +162,13 @@ pub const Timer = struct {
162162 var freq: i64 = undefined;
163163 var err = windows.QueryPerformanceFrequency(&freq);
164164 if (err == windows.FALSE) return error.TimerUnsupported;
165 self.frequency = u64(freq);
165 self.frequency = @intCast(u64, freq);
166166 self.resolution = @divFloor(ns_per_s, self.frequency);
167167
168168 var start_time: i64 = undefined;
169169 err = windows.QueryPerformanceCounter(&start_time);
170170 debug.assert(err != windows.FALSE);
171 self.start_time = u64(start_time);
171 self.start_time = @intCast(u64, start_time);
172172 },
173173 Os.linux => {
174174 //On Linux, seccomp can do arbitrary things to our ability to call
......@@ -184,12 +184,12 @@ pub const Timer = struct {
184184 posix.EINVAL => return error.TimerUnsupported,
185185 else => return std.os.unexpectedErrorPosix(errno),
186186 }
187 self.resolution = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec);
187 self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
188188
189189 result = posix.clock_gettime(monotonic_clock_id, &ts);
190190 errno = posix.getErrno(result);
191191 if (errno != 0) return std.os.unexpectedErrorPosix(errno);
192 self.start_time = u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec);
192 self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
193193 },
194194 Os.macosx, Os.ios => {
195195 darwin.mach_timebase_info(&self.frequency);
......@@ -236,7 +236,7 @@ pub const Timer = struct {
236236 var result: i64 = undefined;
237237 var err = windows.QueryPerformanceCounter(&result);
238238 debug.assert(err != windows.FALSE);
239 return u64(result);
239 return @intCast(u64, result);
240240 }
241241
242242 fn clockDarwin() u64 {
......@@ -247,7 +247,7 @@ pub const Timer = struct {
247247 var ts: posix.timespec = undefined;
248248 var result = posix.clock_gettime(monotonic_clock_id, &ts);
249249 debug.assert(posix.getErrno(result) == 0);
250 return u64(ts.tv_sec) * u64(ns_per_s) + u64(ts.tv_nsec);
250 return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);
251251 }
252252};
253253
std/os/windows/util.zig+7-2
......@@ -42,7 +42,7 @@ pub const WriteError = error{
4242};
4343
4444pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void {
45 if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
45 if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), @intCast(u32, bytes.len), null, null) == 0) {
4646 const err = windows.GetLastError();
4747 return switch (err) {
4848 windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources,
......@@ -68,7 +68,12 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
6868 const size = @sizeOf(windows.FILE_NAME_INFO);
6969 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
7070
71 if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo, @ptrCast(*c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0) {
71 if (windows.GetFileInformationByHandleEx(
72 handle,
73 windows.FileNameInfo,
74 @ptrCast(*c_void, &name_info_bytes[0]),
75 @intCast(u32, name_info_bytes.len),
76 ) == 0) {
7277 return true;
7378 }
7479
std/rand/index.zig+8-8
......@@ -55,16 +55,16 @@ pub const Random = struct {
5555 if (T.is_signed) {
5656 const uint = @IntType(false, T.bit_count);
5757 if (start >= 0 and end >= 0) {
58 return T(r.range(uint, uint(start), uint(end)));
58 return @intCast(T, r.range(uint, @intCast(uint, start), @intCast(uint, end)));
5959 } else if (start < 0 and end < 0) {
6060 // Can't overflow because the range is over signed ints
6161 return math.negateCast(r.range(uint, math.absCast(end), math.absCast(start)) + 1) catch unreachable;
6262 } else if (start < 0 and end >= 0) {
63 const end_uint = uint(end);
63 const end_uint = @intCast(uint, end);
6464 const total_range = math.absCast(start) + end_uint;
6565 const value = r.range(uint, 0, total_range);
6666 const result = if (value < end_uint) x: {
67 break :x T(value);
67 break :x @intCast(T, value);
6868 } else if (value == end_uint) x: {
6969 break :x start;
7070 } else x: {
......@@ -213,9 +213,9 @@ pub const Pcg = struct {
213213 self.s = l *% default_multiplier +% (self.i | 1);
214214
215215 const xor_s = @truncate(u32, ((l >> 18) ^ l) >> 27);
216 const rot = u32(l >> 59);
216 const rot = @intCast(u32, l >> 59);
217217
218 return (xor_s >> u5(rot)) | (xor_s << u5((0 -% rot) & 31));
218 return (xor_s >> @intCast(u5, rot)) | (xor_s << @intCast(u5, (0 -% rot) & 31));
219219 }
220220
221221 fn seed(self: *Pcg, init_s: u64) void {
......@@ -322,7 +322,7 @@ pub const Xoroshiro128 = struct {
322322 inline for (table) |entry| {
323323 var b: usize = 0;
324324 while (b < 64) : (b += 1) {
325 if ((entry & (u64(1) << u6(b))) != 0) {
325 if ((entry & (u64(1) << @intCast(u6, b))) != 0) {
326326 s0 ^= self.s[0];
327327 s1 ^= self.s[1];
328328 }
......@@ -667,13 +667,13 @@ test "Random range" {
667667}
668668
669669fn testRange(r: *Random, start: i32, end: i32) void {
670 const count = usize(end - start);
670 const count = @intCast(usize, end - start);
671671 var values_buffer = []bool{false} ** 20;
672672 const values = values_buffer[0..count];
673673 var i: usize = 0;
674674 while (i < count) {
675675 const value = r.range(i32, start, end);
676 const index = usize(value - start);
676 const index = @intCast(usize, value - start);
677677 if (!values[index]) {
678678 i += 1;
679679 values[index] = true;
std/segmented_list.zig+6-6
......@@ -104,7 +104,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
104104 }
105105
106106 pub fn deinit(self: *Self) void {
107 self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0);
107 self.freeShelves(@intCast(ShelfIndex, self.dynamic_segments.len), 0);
108108 self.allocator.free(self.dynamic_segments);
109109 self.* = undefined;
110110 }
......@@ -158,7 +158,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
158158 /// Only grows capacity, or retains current capacity
159159 pub fn growCapacity(self: *Self, new_capacity: usize) !void {
160160 const new_cap_shelf_count = shelfCount(new_capacity);
161 const old_shelf_count = ShelfIndex(self.dynamic_segments.len);
161 const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len);
162162 if (new_cap_shelf_count > old_shelf_count) {
163163 self.dynamic_segments = try self.allocator.realloc([*]T, self.dynamic_segments, new_cap_shelf_count);
164164 var i = old_shelf_count;
......@@ -175,7 +175,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
175175 /// Only shrinks capacity or retains current capacity
176176 pub fn shrinkCapacity(self: *Self, new_capacity: usize) void {
177177 if (new_capacity <= prealloc_item_count) {
178 const len = ShelfIndex(self.dynamic_segments.len);
178 const len = @intCast(ShelfIndex, self.dynamic_segments.len);
179179 self.freeShelves(len, 0);
180180 self.allocator.free(self.dynamic_segments);
181181 self.dynamic_segments = [][*]T{};
......@@ -183,7 +183,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
183183 }
184184
185185 const new_cap_shelf_count = shelfCount(new_capacity);
186 const old_shelf_count = ShelfIndex(self.dynamic_segments.len);
186 const old_shelf_count = @intCast(ShelfIndex, self.dynamic_segments.len);
187187 assert(new_cap_shelf_count <= old_shelf_count);
188188 if (new_cap_shelf_count == old_shelf_count) {
189189 return;
......@@ -338,7 +338,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
338338 {
339339 var i: usize = 0;
340340 while (i < 100) : (i += 1) {
341 try list.push(i32(i + 1));
341 try list.push(@intCast(i32, i + 1));
342342 assert(list.len == i + 1);
343343 }
344344 }
......@@ -346,7 +346,7 @@ fn testSegmentedList(comptime prealloc: usize, allocator: *Allocator) !void {
346346 {
347347 var i: usize = 0;
348348 while (i < 100) : (i += 1) {
349 assert(list.at(i).* == i32(i + 1));
349 assert(list.at(i).* == @intCast(i32, i + 1));
350350 }
351351 }
352352
std/special/bootstrap.zig+1-1
......@@ -80,7 +80,7 @@ extern fn main(c_argc: i32, c_argv: [*][*]u8, c_envp: [*]?[*]u8) i32 {
8080 var env_count: usize = 0;
8181 while (c_envp[env_count] != null) : (env_count += 1) {}
8282 const envp = @ptrCast([*][*]u8, c_envp)[0..env_count];
83 return callMainWithArgs(usize(c_argc), c_argv, envp);
83 return callMainWithArgs(@intCast(usize, c_argc), c_argv, envp);
8484}
8585
8686fn callMain() u8 {
std/special/builtin.zig+15-15
......@@ -135,9 +135,9 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
135135 const mask = if (T == f32) 0xff else 0x7ff;
136136 var ux = @bitCast(uint, x);
137137 var uy = @bitCast(uint, y);
138 var ex = i32((ux >> digits) & mask);
139 var ey = i32((uy >> digits) & mask);
140 const sx = if (T == f32) u32(ux & 0x80000000) else i32(ux >> bits_minus_1);
138 var ex = @intCast(i32, (ux >> digits) & mask);
139 var ey = @intCast(i32, (uy >> digits) & mask);
140 const sx = if (T == f32) @intCast(u32, ux & 0x80000000) else @intCast(i32, ux >> bits_minus_1);
141141 var i: uint = undefined;
142142
143143 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 {
156156 ex -= 1;
157157 i <<= 1;
158158 }) {}
159 ux <<= log2uint(@bitCast(u32, -ex + 1));
159 ux <<= @intCast(log2uint, @bitCast(u32, -ex + 1));
160160 } else {
161161 ux &= @maxValue(uint) >> exp_bits;
162162 ux |= 1 << digits;
......@@ -167,7 +167,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
167167 ey -= 1;
168168 i <<= 1;
169169 }) {}
170 uy <<= log2uint(@bitCast(u32, -ey + 1));
170 uy <<= @intCast(log2uint, @bitCast(u32, -ey + 1));
171171 } else {
172172 uy &= @maxValue(uint) >> exp_bits;
173173 uy |= 1 << digits;
......@@ -199,12 +199,12 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
199199 ux -%= 1 << digits;
200200 ux |= uint(@bitCast(u32, ex)) << digits;
201201 } else {
202 ux >>= log2uint(@bitCast(u32, -ex + 1));
202 ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));
203203 }
204204 if (T == f32) {
205205 ux |= sx;
206206 } else {
207 ux |= uint(sx) << bits_minus_1;
207 ux |= @intCast(uint, sx) << bits_minus_1;
208208 }
209209 return @bitCast(T, ux);
210210}
......@@ -229,8 +229,8 @@ export fn sqrt(x: f64) f64 {
229229 const sign: u32 = 0x80000000;
230230 const u = @bitCast(u64, x);
231231
232 var ix0 = u32(u >> 32);
233 var ix1 = u32(u & 0xFFFFFFFF);
232 var ix0 = @intCast(u32, u >> 32);
233 var ix1 = @intCast(u32, u & 0xFFFFFFFF);
234234
235235 // sqrt(nan) = nan, sqrt(+inf) = +inf, sqrt(-inf) = nan
236236 if (ix0 & 0x7FF00000 == 0x7FF00000) {
......@@ -247,7 +247,7 @@ export fn sqrt(x: f64) f64 {
247247 }
248248
249249 // normalize x
250 var m = i32(ix0 >> 20);
250 var m = @intCast(i32, ix0 >> 20);
251251 if (m == 0) {
252252 // subnormal
253253 while (ix0 == 0) {
......@@ -261,9 +261,9 @@ export fn sqrt(x: f64) f64 {
261261 while (ix0 & 0x00100000 == 0) : (i += 1) {
262262 ix0 <<= 1;
263263 }
264 m -= i32(i) - 1;
265 ix0 |= ix1 >> u5(32 - i);
266 ix1 <<= u5(i);
264 m -= @intCast(i32, i) - 1;
265 ix0 |= ix1 >> @intCast(u5, 32 - i);
266 ix1 <<= @intCast(u5, i);
267267 }
268268
269269 // unbias exponent
......@@ -347,10 +347,10 @@ export fn sqrt(x: f64) f64 {
347347
348348 // NOTE: musl here appears to rely on signed twos-complement wraparound. +% has the same
349349 // behaviour at least.
350 var iix0 = i32(ix0);
350 var iix0 = @intCast(i32, ix0);
351351 iix0 = iix0 +% (m << 20);
352352
353 const uz = (u64(iix0) << 32) | ix1;
353 const uz = (@intCast(u64, iix0) << 32) | ix1;
354354 return @bitCast(f64, uz);
355355}
356356
std/special/compiler_rt/comparetf2.zig+1-1
......@@ -91,5 +91,5 @@ pub extern fn __unordtf2(a: f128, b: f128) c_int {
9191
9292 const aAbs = @bitCast(rep_t, a) & absMask;
9393 const bAbs = @bitCast(rep_t, b) & absMask;
94 return c_int(aAbs > infRep or bAbs > infRep);
94 return @boolToInt(aAbs > infRep or bAbs > infRep);
9595}
std/special/compiler_rt/divti3.zig+1-1
......@@ -13,7 +13,7 @@ pub extern fn __divti3(a: i128, b: i128) i128 {
1313
1414 const r = udivmod(u128, @bitCast(u128, an), @bitCast(u128, bn), null);
1515 const s = s_a ^ s_b;
16 return (i128(r) ^ s) -% s;
16 return (@bitCast(i128, r) ^ s) -% s;
1717}
1818
1919pub extern fn __divti3_windows_x86_64(a: *const i128, b: *const i128) void {
std/special/compiler_rt/fixuint.zig+4-4
......@@ -32,14 +32,14 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
3232 const aAbs: rep_t = aRep & absMask;
3333
3434 const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1);
35 const exponent = i32(aAbs >> significandBits) - exponentBias;
35 const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
3636 const significand: rep_t = (aAbs & significandMask) | implicitBit;
3737
3838 // If either the value or the exponent is negative, the result is zero.
3939 if (sign == -1 or exponent < 0) return 0;
4040
4141 // If the value is too large for the integer type, saturate.
42 if (c_uint(exponent) >= fixuint_t.bit_count) return ~fixuint_t(0);
42 if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~fixuint_t(0);
4343
4444 // If 0 <= exponent < significandBits, right shift to get the result.
4545 // Otherwise, shift left.
......@@ -47,11 +47,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
4747 // TODO this is a workaround for the mysterious "integer cast truncated bits"
4848 // happening on the next line
4949 @setRuntimeSafety(false);
50 return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent));
50 return @intCast(fixuint_t, significand >> @intCast(Log2Int(rep_t), significandBits - exponent));
5151 } else {
5252 // TODO this is a workaround for the mysterious "integer cast truncated bits"
5353 // happening on the next line
5454 @setRuntimeSafety(false);
55 return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits);
55 return @intCast(fixuint_t, significand) << @intCast(Log2Int(fixuint_t), exponent - significandBits);
5656 }
5757}
std/special/compiler_rt/index.zig+6-6
......@@ -292,7 +292,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: *u32) u32 {
292292 @setRuntimeSafety(is_test);
293293
294294 const d = __udivsi3(a, b);
295 rem.* = u32(i32(a) -% (i32(d) * i32(b)));
295 rem.* = @bitCast(u32, @bitCast(i32, a) -% (@bitCast(i32, d) * @bitCast(i32, b)));
296296 return d;
297297}
298298
......@@ -316,12 +316,12 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
316316 sr += 1;
317317 // 1 <= sr <= n_uword_bits - 1
318318 // Not a special case
319 var q: u32 = n << u5(n_uword_bits - sr);
320 var r: u32 = n >> u5(sr);
319 var q: u32 = n << @intCast(u5, n_uword_bits - sr);
320 var r: u32 = n >> @intCast(u5, sr);
321321 var carry: u32 = 0;
322322 while (sr > 0) : (sr -= 1) {
323323 // r:q = ((r:q) << 1) | carry
324 r = (r << 1) | (q >> u5(n_uword_bits - 1));
324 r = (r << 1) | (q >> @intCast(u5, n_uword_bits - 1));
325325 q = (q << 1) | carry;
326326 // carry = 0;
327327 // if (r.all >= d.all)
......@@ -329,8 +329,8 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
329329 // r.all -= d.all;
330330 // carry = 1;
331331 // }
332 const s = i32(d -% r -% 1) >> u5(n_uword_bits - 1);
333 carry = u32(s & 1);
332 const s = @intCast(i32, d -% r -% 1) >> @intCast(u5, n_uword_bits - 1);
333 carry = @intCast(u32, s & 1);
334334 r -= d & @bitCast(u32, s);
335335 }
336336 q = (q << 1) | carry;
std/special/compiler_rt/udivmod.zig+17-17
......@@ -71,7 +71,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
7171 r[high] = n[high] & (d[high] - 1);
7272 rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
7373 }
74 return n[high] >> Log2SingleInt(@ctz(d[high]));
74 return n[high] >> @intCast(Log2SingleInt, @ctz(d[high]));
7575 }
7676 // K K
7777 // ---
......@@ -88,10 +88,10 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
8888 // 1 <= sr <= SingleInt.bit_count - 1
8989 // q.all = a << (DoubleInt.bit_count - sr);
9090 q[low] = 0;
91 q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr);
91 q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr);
9292 // r.all = a >> sr;
93 r[high] = n[high] >> Log2SingleInt(sr);
94 r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
93 r[high] = n[high] >> @intCast(Log2SingleInt, sr);
94 r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
9595 } else {
9696 // d[low] != 0
9797 if (d[high] == 0) {
......@@ -107,8 +107,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
107107 return a;
108108 }
109109 sr = @ctz(d[low]);
110 q[high] = n[high] >> Log2SingleInt(sr);
111 q[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
110 q[high] = n[high] >> @intCast(Log2SingleInt, sr);
111 q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
112112 return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421
113113 }
114114 // K X
......@@ -126,15 +126,15 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
126126 } else if (sr < SingleInt.bit_count) {
127127 // 2 <= sr <= SingleInt.bit_count - 1
128128 q[low] = 0;
129 q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr);
130 r[high] = n[high] >> Log2SingleInt(sr);
131 r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
129 q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr);
130 r[high] = n[high] >> @intCast(Log2SingleInt, sr);
131 r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
132132 } else {
133133 // SingleInt.bit_count + 1 <= sr <= DoubleInt.bit_count - 1
134 q[low] = n[low] << Log2SingleInt(DoubleInt.bit_count - sr);
135 q[high] = (n[high] << Log2SingleInt(DoubleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr - SingleInt.bit_count));
134 q[low] = n[low] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr);
135 q[high] = (n[high] << @intCast(Log2SingleInt, DoubleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count));
136136 r[high] = 0;
137 r[low] = n[high] >> Log2SingleInt(sr - SingleInt.bit_count);
137 r[low] = n[high] >> @intCast(Log2SingleInt, sr - SingleInt.bit_count);
138138 }
139139 } else {
140140 // K X
......@@ -158,9 +158,9 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
158158 r[high] = 0;
159159 r[low] = n[high];
160160 } else {
161 r[high] = n[high] >> Log2SingleInt(sr);
162 r[low] = (n[high] << Log2SingleInt(SingleInt.bit_count - sr)) | (n[low] >> Log2SingleInt(sr));
163 q[high] = n[low] << Log2SingleInt(SingleInt.bit_count - sr);
161 r[high] = n[high] >> @intCast(Log2SingleInt, sr);
162 r[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
163 q[high] = n[low] << @intCast(Log2SingleInt, SingleInt.bit_count - sr);
164164 }
165165 }
166166 }
......@@ -184,8 +184,8 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
184184 // carry = 1;
185185 // }
186186 r_all = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
187 const s: SignedDoubleInt = SignedDoubleInt(b -% r_all -% 1) >> (DoubleInt.bit_count - 1);
188 carry = u32(s & 1);
187 const s: SignedDoubleInt = @intCast(SignedDoubleInt, b -% r_all -% 1) >> (DoubleInt.bit_count - 1);
188 carry = @intCast(u32, s & 1);
189189 r_all -= b & @bitCast(DoubleInt, s);
190190 r = @ptrCast(*[2]SingleInt, &r_all).*; // TODO issue #421
191191 }
std/unicode.zig+10-10
......@@ -35,22 +35,22 @@ pub fn utf8Encode(c: u32, out: []u8) !u3 {
3535 // - Increasing the initial shift by 6 each time
3636 // - Each time after the first shorten the shifted
3737 // value to a max of 0b111111 (63)
38 1 => out[0] = u8(c), // Can just do 0 + codepoint for initial range
38 1 => out[0] = @intCast(u8, c), // Can just do 0 + codepoint for initial range
3939 2 => {
40 out[0] = u8(0b11000000 | (c >> 6));
41 out[1] = u8(0b10000000 | (c & 0b111111));
40 out[0] = @intCast(u8, 0b11000000 | (c >> 6));
41 out[1] = @intCast(u8, 0b10000000 | (c & 0b111111));
4242 },
4343 3 => {
4444 if (0xd800 <= c and c <= 0xdfff) return error.Utf8CannotEncodeSurrogateHalf;
45 out[0] = u8(0b11100000 | (c >> 12));
46 out[1] = u8(0b10000000 | ((c >> 6) & 0b111111));
47 out[2] = u8(0b10000000 | (c & 0b111111));
45 out[0] = @intCast(u8, 0b11100000 | (c >> 12));
46 out[1] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111));
47 out[2] = @intCast(u8, 0b10000000 | (c & 0b111111));
4848 },
4949 4 => {
50 out[0] = u8(0b11110000 | (c >> 18));
51 out[1] = u8(0b10000000 | ((c >> 12) & 0b111111));
52 out[2] = u8(0b10000000 | ((c >> 6) & 0b111111));
53 out[3] = u8(0b10000000 | (c & 0b111111));
50 out[0] = @intCast(u8, 0b11110000 | (c >> 18));
51 out[1] = @intCast(u8, 0b10000000 | ((c >> 12) & 0b111111));
52 out[2] = @intCast(u8, 0b10000000 | ((c >> 6) & 0b111111));
53 out[3] = @intCast(u8, 0b10000000 | (c & 0b111111));
5454 },
5555 else => unreachable,
5656 }
std/zig/tokenizer.zig+1-1
......@@ -1128,7 +1128,7 @@ pub const Tokenizer = struct {
11281128 // check utf8-encoded character.
11291129 const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1;
11301130 if (self.index + length > self.buffer.len) {
1131 return u3(self.buffer.len - self.index);
1131 return @intCast(u3, self.buffer.len - self.index);
11321132 }
11331133 const bytes = self.buffer[self.index .. self.index + length];
11341134 switch (length) {
test/behavior.zig+1
......@@ -13,6 +13,7 @@ comptime {
1313 _ = @import("cases/bugs/656.zig");
1414 _ = @import("cases/bugs/828.zig");
1515 _ = @import("cases/bugs/920.zig");
16 _ = @import("cases/byval_arg_var.zig");
1617 _ = @import("cases/cast.zig");
1718 _ = @import("cases/const_slice_child.zig");
1819 _ = @import("cases/coroutines.zig");
test/build_examples.zig+11-1
......@@ -13,9 +13,19 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
1313 cases.addBuildFile("example/shared_library/build.zig");
1414 cases.addBuildFile("example/mix_o_files/build.zig");
1515 }
16 cases.addBuildFile("test/standalone/issue_339/build.zig");
16 if (builtin.os != builtin.Os.macosx) {
17 // TODO https://github.com/ziglang/zig/issues/1126
18 cases.addBuildFile("test/standalone/issue_339/build.zig");
19 }
1720 cases.addBuildFile("test/standalone/issue_794/build.zig");
1821 cases.addBuildFile("test/standalone/pkg_import/build.zig");
1922 cases.addBuildFile("test/standalone/use_alias/build.zig");
2023 cases.addBuildFile("test/standalone/brace_expansion/build.zig");
24 if (false) {
25 // TODO this test is disabled because it is failing on the CI server's linux. when this is fixed
26 // enable it for at least linux
27 // TODO hook up the DynLib API for windows using LoadLibraryA
28 // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it
29 cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
30 }
2131}
test/cases/bool.zig+4-4
......@@ -8,14 +8,14 @@ test "bool literals" {
88test "cast bool to int" {
99 const t = true;
1010 const f = false;
11 assert(i32(t) == i32(1));
12 assert(i32(f) == i32(0));
11 assert(@boolToInt(t) == u32(1));
12 assert(@boolToInt(f) == u32(0));
1313 nonConstCastBoolToInt(t, f);
1414}
1515
1616fn nonConstCastBoolToInt(t: bool, f: bool) void {
17 assert(i32(t) == i32(1));
18 assert(i32(f) == i32(0));
17 assert(@boolToInt(t) == u32(1));
18 assert(@boolToInt(f) == u32(0));
1919}
2020
2121test "bool cmp" {
test/cases/byval_arg_var.zig created+27
......@@ -0,0 +1,27 @@
1const std = @import("std");
2
3var result: []const u8 = "wrong";
4
5test "aoeu" {
6 start();
7 blowUpStack(10);
8
9 std.debug.assert(std.mem.eql(u8, result, "string literal"));
10}
11
12fn start() void {
13 foo("string literal");
14}
15
16fn foo(x: var) void {
17 bar(x);
18}
19
20fn bar(x: var) void {
21 result = x;
22}
23
24fn blowUpStack(x: u32) void {
25 if (x == 0) return;
26 blowUpStack(x - 1);
27}
test/cases/cast.zig+23-9
......@@ -318,14 +318,6 @@ fn testCastConstArrayRefToConstSlice() void {
318318 assert(mem.eql(u8, slice, "aoeu"));
319319}
320320
321test "var args implicitly casts by value arg to const ref" {
322 foo("hello");
323}
324
325fn foo(args: ...) void {
326 assert(@typeOf(args[0]) == *const [5]u8);
327}
328
329321test "peer type resolution: error and [N]T" {
330322 // TODO: implicit error!T to error!U where T can implicitly cast to U
331323 //assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
......@@ -351,7 +343,7 @@ fn testPeerErrorAndArray2(x: u8) error![]const u8 {
351343test "explicit cast float number literal to integer if no fraction component" {
352344 const x = i32(1e4);
353345 assert(x == 10000);
354 const y = i32(f32(1e4));
346 const y = @floatToInt(i32, f32(1e4));
355347 assert(y == 10000);
356348}
357349
......@@ -406,3 +398,25 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
406398 const x: [*]const ?[*]const u8 = &window_name;
407399 assert(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name"));
408400}
401
402test "@intCast comptime_int" {
403 const result = @intCast(i32, 1234);
404 assert(@typeOf(result) == i32);
405 assert(result == 1234);
406}
407
408test "@floatCast comptime_int and comptime_float" {
409 const result = @floatCast(f32, 1234);
410 assert(@typeOf(result) == f32);
411 assert(result == 1234.0);
412
413 const result2 = @floatCast(f32, 1234.0);
414 assert(@typeOf(result) == f32);
415 assert(result == 1234.0);
416}
417
418test "comptime_int @intToFloat" {
419 const result = @intToFloat(f32, 1234);
420 assert(@typeOf(result) == f32);
421 assert(result == 1234.0);
422}
test/cases/enum.zig+1-1
......@@ -99,7 +99,7 @@ test "int to enum" {
9999 testIntToEnumEval(3);
100100}
101101fn testIntToEnumEval(x: i32) void {
102 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
102 assert(IntToEnumNumber(@intCast(u3, x)) == IntToEnumNumber.Three);
103103}
104104const IntToEnumNumber = enum {
105105 Zero,
test/cases/eval.zig+4-4
......@@ -5,7 +5,7 @@ const builtin = @import("builtin");
55test "compile time recursion" {
66 assert(some_data.len == 21);
77}
8var some_data: [usize(fibonacci(7))]u8 = undefined;
8var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined;
99fn fibonacci(x: i32) i32 {
1010 if (x <= 1) return 1;
1111 return fibonacci(x - 1) + fibonacci(x - 2);
......@@ -356,7 +356,7 @@ const global_array = x: {
356356test "compile-time downcast when the bits fit" {
357357 comptime {
358358 const spartan_count: u16 = 255;
359 const byte = u8(spartan_count);
359 const byte = @intCast(u8, spartan_count);
360360 assert(byte == 255);
361361 }
362362}
......@@ -440,7 +440,7 @@ test "binary math operator in partially inlined function" {
440440 var b: [16]u8 = undefined;
441441
442442 for (b) |*r, i|
443 r.* = u8(i + 1);
443 r.* = @intCast(u8, i + 1);
444444
445445 copyWithPartialInline(s[0..], b[0..]);
446446 assert(s[0] == 0x1020304);
......@@ -480,7 +480,7 @@ fn generateTable(comptime T: type) [1010]T {
480480 var res: [1010]T = undefined;
481481 var i: usize = 0;
482482 while (i < 1010) : (i += 1) {
483 res[i] = T(i);
483 res[i] = @intCast(T, i);
484484 }
485485 return res;
486486}
test/cases/fn.zig+58-1
......@@ -80,7 +80,7 @@ test "function pointers" {
8080 fn4,
8181 };
8282 for (fns) |f, i| {
83 assert(f() == u32(i) + 5);
83 assert(f() == @intCast(u32, i) + 5);
8484 }
8585}
8686fn fn1() u32 {
......@@ -119,3 +119,60 @@ test "assign inline fn to const variable" {
119119}
120120
121121inline fn inlineFn() void {}
122
123test "pass by non-copying value" {
124 assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
125}
126
127const Point = struct {
128 x: i32,
129 y: i32,
130};
131
132fn addPointCoords(pt: Point) i32 {
133 return pt.x + pt.y;
134}
135
136test "pass by non-copying value through var arg" {
137 assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
138}
139
140fn addPointCoordsVar(pt: var) i32 {
141 comptime assert(@typeOf(pt) == Point);
142 return pt.x + pt.y;
143}
144
145test "pass by non-copying value as method" {
146 var pt = Point2{ .x = 1, .y = 2 };
147 assert(pt.addPointCoords() == 3);
148}
149
150const Point2 = struct {
151 x: i32,
152 y: i32,
153
154 fn addPointCoords(self: Point2) i32 {
155 return self.x + self.y;
156 }
157};
158
159test "pass by non-copying value as method, which is generic" {
160 var pt = Point3{ .x = 1, .y = 2 };
161 assert(pt.addPointCoords(i32) == 3);
162}
163
164const Point3 = struct {
165 x: i32,
166 y: i32,
167
168 fn addPointCoords(self: Point3, comptime T: type) i32 {
169 return self.x + self.y;
170 }
171};
172
173test "pass by non-copying value as method, at comptime" {
174 comptime {
175 var pt = Point2{ .x = 1, .y = 2 };
176 assert(pt.addPointCoords() == 3);
177 }
178}
test/cases/for.zig+2-2
......@@ -46,7 +46,7 @@ test "basic for loop" {
4646 buf_index += 1;
4747 }
4848 for (array) |item, index| {
49 buffer[buf_index] = u8(index);
49 buffer[buf_index] = @intCast(u8, index);
5050 buf_index += 1;
5151 }
5252 const unknown_size: []const u8 = array;
......@@ -55,7 +55,7 @@ test "basic for loop" {
5555 buf_index += 1;
5656 }
5757 for (unknown_size) |item, index| {
58 buffer[buf_index] = u8(index);
58 buffer[buf_index] = @intCast(u8, index);
5959 buf_index += 1;
6060 }
6161
test/cases/struct.zig+4-4
......@@ -365,14 +365,14 @@ test "runtime struct initialization of bitfield" {
365365 .y = x1,
366366 };
367367 const s2 = Nibbles{
368 .x = u4(x2),
369 .y = u4(x2),
368 .x = @intCast(u4, x2),
369 .y = @intCast(u4, x2),
370370 };
371371
372372 assert(s1.x == x1);
373373 assert(s1.y == x1);
374 assert(s2.x == u4(x2));
375 assert(s2.y == u4(x2));
374 assert(s2.x == @intCast(u4, x2));
375 assert(s2.y == @intCast(u4, x2));
376376}
377377
378378var x1 = u4(1);
test/cases/var_args.zig-12
......@@ -75,18 +75,6 @@ test "array of var args functions" {
7575 assert(!foos[1]());
7676}
7777
78test "pass array and slice of same array to var args should have same pointers" {
79 const array = "hi";
80 const slice: []const u8 = array;
81 return assertSlicePtrsEql(array, slice);
82}
83
84fn assertSlicePtrsEql(args: ...) void {
85 const s1 = ([]const u8)(args[0]);
86 const s2 = args[1];
87 assert(s1.ptr == s2.ptr);
88}
89
9078test "pass zero length array to var args param" {
9179 doNothingWithFirstArg("");
9280}
test/compare_output.zig+3-3
......@@ -299,7 +299,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
299299 \\export fn main() c_int {
300300 \\ var array = []u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
301301 \\
302 \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), c_ulong(array.len), @sizeOf(i32), compare_fn);
302 \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), @intCast(c_ulong, array.len), @sizeOf(i32), compare_fn);
303303 \\
304304 \\ for (array) |item, i| {
305305 \\ if (item != i) {
......@@ -331,8 +331,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
331331 \\ }
332332 \\ const small: f32 = 3.25;
333333 \\ const x: f64 = small;
334 \\ const y = i32(x);
335 \\ const z = f64(y);
334 \\ const y = @floatToInt(i32, x);
335 \\ const z = @intToFloat(f64, y);
336336 \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4));
337337 \\ return 0;
338338 \\}
test/compile_errors.zig+23-28
......@@ -1,6 +1,24 @@
11const tests = @import("tests.zig");
22
33pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "use c_void as return type of fn ptr",
6 \\export fn entry() void {
7 \\ const a: fn () c_void = undefined;
8 \\}
9 ,
10 ".tmp_source.zig:2:20: error: return type cannot be opaque",
11 );
12
13 cases.add(
14 "non int passed to @intToFloat",
15 \\export fn entry() void {
16 \\ const x = @intToFloat(f32, 1.1);
17 \\}
18 ,
19 ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'",
20 );
21
422 cases.add(
523 "use implicit casts to assign null to non-nullable pointer",
624 \\export fn entry() void {
......@@ -2215,7 +2233,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
22152233 \\ derp.init();
22162234 \\}
22172235 ,
2218 ".tmp_source.zig:14:5: error: expected type 'i32', found '*const Foo'",
2236 ".tmp_source.zig:14:5: error: expected type 'i32', found 'Foo'",
22192237 );
22202238
22212239 cases.add(
......@@ -2573,15 +2591,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
25732591 break :x tc;
25742592 });
25752593
2576 cases.add(
2577 "pass non-copyable type by value to function",
2578 \\const Point = struct { x: i32, y: i32, };
2579 \\fn foo(p: Point) void { }
2580 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
2581 ,
2582 ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value",
2583 );
2584
25852594 cases.add(
25862595 "implicit cast from array to mutable slice",
25872596 \\var global_array: [10]i32 = undefined;
......@@ -2940,10 +2949,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29402949 "cast negative value to unsigned integer",
29412950 \\comptime {
29422951 \\ const value: i32 = -1;
2943 \\ const unsigned = u32(value);
2952 \\ const unsigned = @intCast(u32, value);
29442953 \\}
29452954 ,
2946 ".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer",
2955 ".tmp_source.zig:3:22: error: attempt to cast negative value to unsigned integer",
29472956 );
29482957
29492958 cases.add(
......@@ -2972,10 +2981,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
29722981 "compile-time integer cast truncates bits",
29732982 \\comptime {
29742983 \\ const spartan_count: u16 = 300;
2975 \\ const byte = u8(spartan_count);
2984 \\ const byte = @intCast(u8, spartan_count);
29762985 \\}
29772986 ,
2978 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits",
2987 ".tmp_source.zig:3:18: error: cast from 'u16' to 'u8' truncates bits",
29792988 );
29802989
29812990 cases.add(
......@@ -4066,20 +4075,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40664075 ".tmp_source.zig:3:5: note: field 'A' has type 'i32'",
40674076 );
40684077
4069 cases.add(
4070 "self-referencing function pointer field",
4071 \\const S = struct {
4072 \\ f: fn(_: S) void,
4073 \\};
4074 \\fn f(_: S) void {
4075 \\}
4076 \\export fn entry() void {
4077 \\ var _ = S { .f = f };
4078 \\}
4079 ,
4080 ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value",
4081 );
4082
40834078 cases.add(
40844079 "taking offset of void field in struct",
40854080 \\const Empty = struct {
test/runtime_safety.zig+2-2
......@@ -188,7 +188,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
188188 \\ if (x == 0) return error.Whatever;
189189 \\}
190190 \\fn shorten_cast(x: i32) i8 {
191 \\ return i8(x);
191 \\ return @intCast(i8, x);
192192 \\}
193193 );
194194
......@@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
201201 \\ if (x == 0) return error.Whatever;
202202 \\}
203203 \\fn unsigned_cast(x: i32) u32 {
204 \\ return u32(x);
204 \\ return @intCast(u32, x);
205205 \\}
206206 );
207207
test/standalone/load_dynamic_library/add.zig created+3
......@@ -0,0 +1,3 @@
1export fn add(a: i32, b: i32) i32 {
2 return a + b;
3}
test/standalone/load_dynamic_library/build.zig created+21
......@@ -0,0 +1,21 @@
1const Builder = @import("std").build.Builder;
2
3pub fn build(b: *Builder) void {
4 const opts = b.standardReleaseOptions();
5
6 const lib = b.addSharedLibrary("add", "add.zig", b.version(1, 0, 0));
7 lib.setBuildMode(opts);
8
9 const main = b.addExecutable("main", "main.zig");
10 main.setBuildMode(opts);
11
12 const run = b.addCommand(".", b.env_map, [][]const u8{
13 main.getOutputPath(),
14 lib.getOutputPath(),
15 });
16 run.step.dependOn(&lib.step);
17 run.step.dependOn(&main.step);
18
19 const test_step = b.step("test", "Test the program");
20 test_step.dependOn(&run.step);
21}
test/standalone/load_dynamic_library/main.zig created+17
......@@ -0,0 +1,17 @@
1const std = @import("std");
2
3pub fn main() !void {
4 const args = try std.os.argsAlloc(std.debug.global_allocator);
5 defer std.os.argsFree(std.debug.global_allocator, args);
6
7 const dynlib_name = args[1];
8
9 var lib = try std.DynLib.open(std.debug.global_allocator, dynlib_name);
10 defer lib.close();
11
12 const addr = lib.lookup("add") orelse return error.SymbolNotFound;
13 const addFn = @intToPtr(extern fn (i32, i32) i32, addr);
14
15 const result = addFn(12, 34);
16 std.debug.assert(result == 46);
17}