authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-23 19:13:48+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-23 19:13:48+02:00
log03cc81665bb28eb35c8c6d4be17b5a56fa66261f
treee686671775e606c3cf1129b535f2c2487e4e6e3c
parent86d9563d1539cd7581dc120023bb830fae77ba0f
parentad0871ea4bf2dfbed07282ffe14738b5347d5d32
signaturelock-open Commit is signed but in an unrecognized format.

Merge branch 'master' into modernize-stage2


309 files changed, 8518 insertions(+), 3248 deletions(-)

README.md+2-2
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1![ZIG](https://ziglang.org/zig-logo.svg)1![ZIG](https://ziglang.org/zig-logo.svg)
22
3A general-purpose programming language designed for **robustness**,3A general-purpose programming language for maintaining **robust**, **optimal**,
4**optimality**, and **maintainability**.4and **reusable** code.
55
6## Resources6## Resources
77
build.zig+1-1
...@@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {...@@ -155,7 +155,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
155 ) catch unreachable;155 ) catch unreachable;
156 for (dep.system_libs.toSliceConst()) |lib| {156 for (dep.system_libs.toSliceConst()) |lib| {
157 const static_bare_name = if (mem.eql(u8, lib, "curses"))157 const static_bare_name = if (mem.eql(u8, lib, "curses"))
158 ([]const u8)("libncurses.a")158 @as([]const u8, "libncurses.a")
159 else159 else
160 b.fmt("lib{}.a", lib);160 b.fmt("lib{}.a", lib);
161 const static_lib_name = fs.path.join(161 const static_lib_name = fs.path.join(
ci/azure/pipelines.yml+2-2
...@@ -14,7 +14,7 @@ jobs:...@@ -14,7 +14,7 @@ jobs:
14 displayName: 'Build and test'14 displayName: 'Build and test'
15- job: BuildLinux15- job: BuildLinux
16 pool:16 pool:
17 vmImage: 'ubuntu-16.04'17 vmImage: 'ubuntu-18.04'
1818
19 timeoutInMinutes: 36019 timeoutInMinutes: 360
2020
...@@ -53,7 +53,7 @@ jobs:...@@ -53,7 +53,7 @@ jobs:
53 strategy:53 strategy:
54 maxParallel: 154 maxParallel: 1
55 pool:55 pool:
56 vmImage: 'ubuntu-16.04'56 vmImage: 'ubuntu-18.04'
57 variables:57 variables:
58 version: $[ dependencies.BuildLinux.outputs['main.version'] ]58 version: $[ dependencies.BuildLinux.outputs['main.version'] ]
59 steps:59 steps:
ci/drone/drone.yml+2
...@@ -9,6 +9,8 @@ steps:...@@ -9,6 +9,8 @@ steps:
9- name: build-and-test9- name: build-and-test
10 image: ziglang/static-base:llvm9-110 image: ziglang/static-base:llvm9-1
11 environment:11 environment:
12 SRHT_OAUTH_TOKEN:
13 from_secret: SRHT_OAUTH_TOKEN
12 AWS_ACCESS_KEY_ID:14 AWS_ACCESS_KEY_ID:
13 from_secret: AWS_ACCESS_KEY_ID15 from_secret: AWS_ACCESS_KEY_ID
14 AWS_SECRET_ACCESS_KEY:16 AWS_SECRET_ACCESS_KEY:
doc/docgen.zig+3-2
...@@ -10,8 +10,8 @@ const testing = std.testing;...@@ -10,8 +10,8 @@ const testing = std.testing;
1010
11const max_doc_file_size = 10 * 1024 * 1024;11const max_doc_file_size = 10 * 1024 * 1024;
1212
13const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();13const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt();
14const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();14const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt();
15const tmp_dir_name = "docgen_tmp";15const tmp_dir_name = "docgen_tmp";
16const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;16const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;
1717
...@@ -856,6 +856,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -856,6 +856,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
856856
857 .LineComment,857 .LineComment,
858 .DocComment,858 .DocComment,
859 .ContainerDocComment,
859 .ShebangLine,860 .ShebangLine,
860 => {861 => {
861 try out.write("<span class=\"tok-comment\">");862 try out.write("<span class=\"tok-comment\">");
doc/langref.html.in+222-85
...@@ -164,15 +164,17 @@...@@ -164,15 +164,17 @@
164 <div id="contents">164 <div id="contents">
165 {#header_open|Introduction#}165 {#header_open|Introduction#}
166 <p>166 <p>
167 Zig is a general-purpose programming language designed for <strong>robustness</strong>,167 Zig is a general-purpose programming language for maintaining <strong>robust</strong>,
168 <strong>optimality</strong>, and <strong>maintainability</strong>.168 <strong>optimal</strong>, and <strong>reusable</strong> code.
169 </p>169 </p>
170 <ul>170 <ul>
171 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>171 <li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>
172 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>172 <li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>
173 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and other programmers.173 <li><strong>Reusable</strong> - the same code works in many environments which have different
174 The language imposes a low overhead to reading code and is resilient to changing requirements174 constraints.</li>
175 and environments.</li>175 <li><strong>Maintainable</strong> - precisely communicate intent to the compiler and
176 other programmers. The language imposes a low overhead to reading code and is
177 resilient to changing requirements and environments.</li>
176 </ul>178 </ul>
177 <p>179 <p>
178 Often the most efficient way to learn something new is to see examples, so180 Often the most efficient way to learn something new is to see examples, so
...@@ -202,11 +204,8 @@...@@ -202,11 +204,8 @@
202const std = @import("std");204const std = @import("std");
203205
204pub fn main() !void {206pub fn main() !void {
205 // If this program is run without stdout attached, exit with an error.207 const stdout = &std.io.getStdOut().outStream().stream;
206 const stdout_file = try std.io.getStdOut();208 try stdout.print("Hello, {}!\n", "world");
207 // If this program encounters pipe failure when printing to stdout, exit
208 // with an error.
209 try stdout_file.write("Hello, world!\n");
210}209}
211 {#code_end#}210 {#code_end#}
212 <p>211 <p>
...@@ -712,7 +711,7 @@ test "init with undefined" {...@@ -712,7 +711,7 @@ test "init with undefined" {
712}711}
713 {#code_end#}712 {#code_end#}
714 <p>713 <p>
715 {#syntax#}undefined{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to any type.714 {#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type.
716 Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}.715 Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}.
717 {#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense716 {#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense
718 according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful717 according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful
...@@ -920,7 +919,7 @@ fn divide(a: i32, b: i32) i32 {...@@ -920,7 +919,7 @@ fn divide(a: i32, b: i32) i32 {
920 {#syntax#}f128{#endsyntax#}.919 {#syntax#}f128{#endsyntax#}.
921 </p>920 </p>
922 <p>921 <p>
923 Float literals {#link|implicitly cast|Implicit Casts#} to any floating point type,922 Float literals {#link|coerce|Type Coercion#} to any floating point type,
924 and to any {#link|integer|Integers#} type when there is no fractional component.923 and to any {#link|integer|Integers#} type when there is no fractional component.
925 </p>924 </p>
926 {#code_begin|syntax#}925 {#code_begin|syntax#}
...@@ -950,7 +949,7 @@ const nan = std.math.nan(f128);...@@ -950,7 +949,7 @@ const nan = std.math.nan(f128);
950 {#code_begin|obj|foo#}949 {#code_begin|obj|foo#}
951 {#code_release_fast#}950 {#code_release_fast#}
952const builtin = @import("builtin");951const builtin = @import("builtin");
953const big = f64(1 << 40);952const big = @as(f64, 1 << 40);
954953
955export fn foo_strict(x: f64) f64 {954export fn foo_strict(x: f64) f64 {
956 return x + big - big;955 return x + big - big;
...@@ -1652,7 +1651,7 @@ test "iterate over an array" {...@@ -1652,7 +1651,7 @@ test "iterate over an array" {
1652 for (message) |byte| {1651 for (message) |byte| {
1653 sum += byte;1652 sum += byte;
1654 }1653 }
1655 assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o'));1654 assert(sum == 'h' + 'e' + 'l' * 2 + 'o');
1656}1655}
16571656
1658// modifiable array1657// modifiable array
...@@ -1734,6 +1733,43 @@ test "array initialization with function calls" {...@@ -1734,6 +1733,43 @@ test "array initialization with function calls" {
1734 {#code_end#}1733 {#code_end#}
1735 {#see_also|for|Slices#}1734 {#see_also|for|Slices#}
17361735
1736 {#header_open|Anonymous List Literals#}
1737 <p>Similar to {#link|Enum Literals#} and {#link|Anonymous Struct Literals#}
1738 the type can be omitted from array literals:</p>
1739 {#code_begin|test|anon_list#}
1740const std = @import("std");
1741const assert = std.debug.assert;
1742
1743test "anonymous list literal syntax" {
1744 var array: [4]u8 = .{11, 22, 33, 44};
1745 assert(array[0] == 11);
1746 assert(array[1] == 22);
1747 assert(array[2] == 33);
1748 assert(array[3] == 44);
1749}
1750 {#code_end#}
1751 <p>
1752 If there is no type in the result location then an anonymous list literal actually
1753 turns into a {#link|struct#} with numbered field names:
1754 </p>
1755 {#code_begin|test|infer_list_literal#}
1756const std = @import("std");
1757const assert = std.debug.assert;
1758
1759test "fully anonymous list literal" {
1760 dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
1761}
1762
1763fn dump(args: var) void {
1764 assert(args.@"0" == 1234);
1765 assert(args.@"1" == 12.34);
1766 assert(args.@"2");
1767 assert(args.@"3"[0] == 'h');
1768 assert(args.@"3"[1] == 'i');
1769}
1770 {#code_end#}
1771 {#header_close#}
1772
1737 {#header_open|Multidimensional Arrays#}1773 {#header_open|Multidimensional Arrays#}
1738 <p>1774 <p>
1739 Mutlidimensional arrays can be created by nesting arrays:1775 Mutlidimensional arrays can be created by nesting arrays:
...@@ -2003,7 +2039,7 @@ test "variable alignment" {...@@ -2003,7 +2039,7 @@ test "variable alignment" {
2003 }2039 }
2004}2040}
2005 {#code_end#}2041 {#code_end#}
2006 <p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to a2042 <p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a
2007 {#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly2043 {#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly
2008 cast to a pointer with a smaller alignment, but not vice versa.2044 cast to a pointer with a smaller alignment, but not vice versa.
2009 </p>2045 </p>
...@@ -2019,7 +2055,7 @@ var foo: u8 align(4) = 100;...@@ -2019,7 +2055,7 @@ var foo: u8 align(4) = 100;
2019test "global variable alignment" {2055test "global variable alignment" {
2020 assert(@typeOf(&foo).alignment == 4);2056 assert(@typeOf(&foo).alignment == 4);
2021 assert(@typeOf(&foo) == *align(4) u8);2057 assert(@typeOf(&foo) == *align(4) u8);
2022 const slice = (*[1]u8)(&foo)[0..];2058 const slice = @as(*[1]u8, &foo)[0..];
2023 assert(@typeOf(slice) == []align(4) u8);2059 assert(@typeOf(slice) == []align(4) u8);
2024}2060}
20252061
...@@ -2114,7 +2150,7 @@ const fmt = @import("std").fmt;...@@ -2114,7 +2150,7 @@ const fmt = @import("std").fmt;
2114test "using slices for strings" {2150test "using slices for strings" {
2115 // Zig has no concept of strings. String literals are arrays of u8, and2151 // Zig has no concept of strings. String literals are arrays of u8, and
2116 // in general the string type is []u8 (slice of u8).2152 // in general the string type is []u8 (slice of u8).
2117 // Here we implicitly cast [5]u8 to []const u82153 // Here we coerce [5]u8 to []const u8
2118 const hello: []const u8 = "hello";2154 const hello: []const u8 = "hello";
2119 const world: []const u8 = "世界";2155 const world: []const u8 = "世界";
21202156
...@@ -2526,7 +2562,8 @@ test "overaligned pointer to packed struct" {...@@ -2526,7 +2562,8 @@ test "overaligned pointer to packed struct" {
2526 Don't worry, there will be a good solution for this use case in zig.2562 Don't worry, there will be a good solution for this use case in zig.
2527 </p>2563 </p>
2528 {#header_close#}2564 {#header_close#}
2529 {#header_open|struct Naming#}2565
2566 {#header_open|Struct Naming#}
2530 <p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p>2567 <p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p>
2531 <ul>2568 <ul>
2532 <li>If the struct is in the initialization expression of a variable, it gets named after2569 <li>If the struct is in the initialization expression of a variable, it gets named after
...@@ -2552,6 +2589,53 @@ fn List(comptime T: type) type {...@@ -2552,6 +2589,53 @@ fn List(comptime T: type) type {
2552}2589}
2553 {#code_end#}2590 {#code_end#}
2554 {#header_close#}2591 {#header_close#}
2592
2593 {#header_open|Anonymous Struct Literals#}
2594 <p>
2595 Zig allows omitting the struct type of a literal. When the result is {#link|coerced|Type Coercion#},
2596 the struct literal will directly instantiate the result location, with no copy:
2597 </p>
2598 {#code_begin|test|struct_result#}
2599const std = @import("std");
2600const assert = std.debug.assert;
2601
2602const Point = struct {x: i32, y: i32};
2603
2604test "anonymous struct literal" {
2605 var pt: Point = .{
2606 .x = 13,
2607 .y = 67,
2608 };
2609 assert(pt.x == 13);
2610 assert(pt.y == 67);
2611}
2612 {#code_end#}
2613 <p>
2614 The struct type can be inferred. Here the result location does not include a type, and
2615 so Zig infers the type:
2616 </p>
2617 {#code_begin|test|struct_anon#}
2618const std = @import("std");
2619const assert = std.debug.assert;
2620
2621test "fully anonymous struct" {
2622 dump(.{
2623 .int = @as(u32, 1234),
2624 .float = @as(f64, 12.34),
2625 .b = true,
2626 .s = "hi",
2627 });
2628}
2629
2630fn dump(args: var) void {
2631 assert(args.int == 1234);
2632 assert(args.float == 12.34);
2633 assert(args.b);
2634 assert(args.s[0] == 'h');
2635 assert(args.s[1] == 'i');
2636}
2637 {#code_end#}
2638 {#header_close#}
2555 {#see_also|comptime|@fieldParentPtr#}2639 {#see_also|comptime|@fieldParentPtr#}
2556 {#header_close#}2640 {#header_close#}
2557 {#header_open|enum#}2641 {#header_open|enum#}
...@@ -2778,7 +2862,7 @@ test "simple union" {...@@ -2778,7 +2862,7 @@ test "simple union" {
2778 This turns the union into a <em>tagged</em> union, which makes it eligible2862 This turns the union into a <em>tagged</em> union, which makes it eligible
2779 to use with {#link|switch#} expressions. One can use {#link|@TagType#} to2863 to use with {#link|switch#} expressions. One can use {#link|@TagType#} to
2780 obtain the enum type from the union type.2864 obtain the enum type from the union type.
2781 Tagged unions implicitly cast to their enum {#link|Implicit Cast: unions and enums#}2865 Tagged unions coerce to their enum {#link|Type Coercion: unions and enums#}
2782 </p>2866 </p>
2783 {#code_begin|test#}2867 {#code_begin|test#}
2784const std = @import("std");2868const std = @import("std");
...@@ -2795,7 +2879,7 @@ const ComplexType = union(ComplexTypeTag) {...@@ -2795,7 +2879,7 @@ const ComplexType = union(ComplexTypeTag) {
27952879
2796test "switch on tagged union" {2880test "switch on tagged union" {
2797 const c = ComplexType{ .Ok = 42 };2881 const c = ComplexType{ .Ok = 42 };
2798 assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);2882 assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
27992883
2800 switch (c) {2884 switch (c) {
2801 ComplexTypeTag.Ok => |value| assert(value == 42),2885 ComplexTypeTag.Ok => |value| assert(value == 42),
...@@ -2807,7 +2891,7 @@ test "@TagType" {...@@ -2807,7 +2891,7 @@ test "@TagType" {
2807 assert(@TagType(ComplexType) == ComplexTypeTag);2891 assert(@TagType(ComplexType) == ComplexTypeTag);
2808}2892}
28092893
2810test "implicit cast to enum" {2894test "coerce to enum" {
2811 const c1 = ComplexType{ .Ok = 42 };2895 const c1 = ComplexType{ .Ok = 42 };
2812 const c2 = ComplexType.NotOk;2896 const c2 = ComplexType.NotOk;
28132897
...@@ -2833,7 +2917,7 @@ const ComplexType = union(ComplexTypeTag) {...@@ -2833,7 +2917,7 @@ const ComplexType = union(ComplexTypeTag) {
28332917
2834test "modify tagged union in switch" {2918test "modify tagged union in switch" {
2835 var c = ComplexType{ .Ok = 42 };2919 var c = ComplexType{ .Ok = 42 };
2836 assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);2920 assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
28372921
2838 switch (c) {2922 switch (c) {
2839 ComplexTypeTag.Ok => |*value| value.* += 1,2923 ComplexTypeTag.Ok => |*value| value.* += 1,
...@@ -2906,6 +2990,32 @@ test "@tagName" {...@@ -2906,6 +2990,32 @@ test "@tagName" {
2906 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible2990 <p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
2907 to be in a {#link|packed struct#}.2991 to be in a {#link|packed struct#}.
2908 {#header_close#}2992 {#header_close#}
2993
2994 {#header_open|Anonymous Union Literals#}
2995 <p>{#link|Anonymous Struct Literals#} syntax can be used to initialize unions without specifying
2996 the type:</p>
2997 {#code_begin|test|anon_union#}
2998const std = @import("std");
2999const assert = std.debug.assert;
3000
3001const Number = union {
3002 int: i32,
3003 float: f64,
3004};
3005
3006test "anonymous union literal syntax" {
3007 var i: Number = .{.int = 42};
3008 var f = makeNumber();
3009 assert(i.int == 42);
3010 assert(f.float == 12.34);
3011}
3012
3013fn makeNumber() Number {
3014 return .{.float = 12.34};
3015}
3016 {#code_end#}
3017 {#header_close#}
3018
2909 {#header_close#}3019 {#header_close#}
29103020
2911 {#header_open|blocks#}3021 {#header_open|blocks#}
...@@ -3943,7 +4053,7 @@ test "fn reflection" {...@@ -3943,7 +4053,7 @@ test "fn reflection" {
3943 However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>.4053 However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>.
3944 </p>4054 </p>
3945 <p>4055 <p>
3946 You can {#link|implicitly cast|Implicit Casts#} an error from a subset to a superset:4056 You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
3947 </p>4057 </p>
3948 {#code_begin|test#}4058 {#code_begin|test#}
3949const std = @import("std");4059const std = @import("std");
...@@ -3958,7 +4068,7 @@ const AllocationError = error {...@@ -3958,7 +4068,7 @@ const AllocationError = error {
3958 OutOfMemory,4068 OutOfMemory,
3959};4069};
39604070
3961test "implicit cast subset to superset" {4071test "coerce subset to superset" {
3962 const err = foo(AllocationError.OutOfMemory);4072 const err = foo(AllocationError.OutOfMemory);
3963 std.debug.assert(err == FileOpenError.OutOfMemory);4073 std.debug.assert(err == FileOpenError.OutOfMemory);
3964}4074}
...@@ -3968,7 +4078,7 @@ fn foo(err: AllocationError) FileOpenError {...@@ -3968,7 +4078,7 @@ fn foo(err: AllocationError) FileOpenError {
3968}4078}
3969 {#code_end#}4079 {#code_end#}
3970 <p>4080 <p>
3971 But you cannot implicitly cast an error from a superset to a subset:4081 But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset:
3972 </p>4082 </p>
3973 {#code_begin|test_err|not a member of destination error set#}4083 {#code_begin|test_err|not a member of destination error set#}
3974const FileOpenError = error {4084const FileOpenError = error {
...@@ -3981,7 +4091,7 @@ const AllocationError = error {...@@ -3981,7 +4091,7 @@ const AllocationError = error {
3981 OutOfMemory,4091 OutOfMemory,
3982};4092};
39834093
3984test "implicit cast superset to subset" {4094test "coerce superset to subset" {
3985 foo(FileOpenError.OutOfMemory) catch {};4095 foo(FileOpenError.OutOfMemory) catch {};
3986}4096}
39874097
...@@ -4008,7 +4118,7 @@ const err = (error {FileNotFound}).FileNotFound;...@@ -4008,7 +4118,7 @@ const err = (error {FileNotFound}).FileNotFound;
4008 It is a superset of all other error sets and a subset of none of them.4118 It is a superset of all other error sets and a subset of none of them.
4009 </p>4119 </p>
4010 <p>4120 <p>
4011 You can implicitly cast any error set to the global one, and you can explicitly4121 You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly
4012 cast an error of the global error set to a non-global one. This inserts a language-level4122 cast an error of the global error set to a non-global one. This inserts a language-level
4013 assert to make sure the error value is in fact in the destination error set.4123 assert to make sure the error value is in fact in the destination error set.
4014 </p>4124 </p>
...@@ -4079,7 +4189,7 @@ test "parse u64" {...@@ -4079,7 +4189,7 @@ test "parse u64" {
4079 <p>4189 <p>
4080 Within the function definition, you can see some return statements that return4190 Within the function definition, you can see some return statements that return
4081 an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}.4191 an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}.
4082 Both types {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyerror!u64{#endsyntax#}.4192 Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}.
4083 </p>4193 </p>
4084 <p>4194 <p>
4085 What it looks like to use this function varies depending on what you're4195 What it looks like to use this function varies depending on what you're
...@@ -4218,10 +4328,10 @@ const assert = @import("std").debug.assert;...@@ -4218,10 +4328,10 @@ const assert = @import("std").debug.assert;
4218test "error union" {4328test "error union" {
4219 var foo: anyerror!i32 = undefined;4329 var foo: anyerror!i32 = undefined;
42204330
4221 // Implicitly cast from child type of an error union:4331 // Coerce from child type of an error union:
4222 foo = 1234;4332 foo = 1234;
42234333
4224 // Implicitly cast from an error set:4334 // Coerce from an error set:
4225 foo = error.SomeError;4335 foo = error.SomeError;
42264336
4227 // Use compile-time reflection to access the payload type of an error union:4337 // Use compile-time reflection to access the payload type of an error union:
...@@ -4598,10 +4708,10 @@ fn doAThing(optional_foo: ?*Foo) void {...@@ -4598,10 +4708,10 @@ fn doAThing(optional_foo: ?*Foo) void {
4598const assert = @import("std").debug.assert;4708const assert = @import("std").debug.assert;
45994709
4600test "optional type" {4710test "optional type" {
4601 // Declare an optional and implicitly cast from null:4711 // Declare an optional and coerce from null:
4602 var foo: ?i32 = null;4712 var foo: ?i32 = null;
46034713
4604 // Implicitly cast from child type of an optional4714 // Coerce from child type of an optional
4605 foo = 1234;4715 foo = 1234;
46064716
4607 // Use compile-time reflection to access the child type of the optional:4717 // Use compile-time reflection to access the child type of the optional:
...@@ -4644,38 +4754,38 @@ test "optional pointers" {...@@ -4644,38 +4754,38 @@ test "optional pointers" {
4644 {#header_open|Casting#}4754 {#header_open|Casting#}
4645 <p>4755 <p>
4646 A <strong>type cast</strong> converts a value of one type to another.4756 A <strong>type cast</strong> converts a value of one type to another.
4647 Zig has {#link|Implicit Casts#} for conversions that are known to be completely safe and unambiguous,4757 Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous,
4648 and {#link|Explicit Casts#} for conversions that one would not want to happen on accident.4758 and {#link|Explicit Casts#} for conversions that one would not want to happen on accident.
4649 There is also a third kind of type conversion called {#link|Peer Type Resolution#} for4759 There is also a third kind of type conversion called {#link|Peer Type Resolution#} for
4650 the case when a result type must be decided given multiple operand types.4760 the case when a result type must be decided given multiple operand types.
4651 </p>4761 </p>
4652 {#header_open|Implicit Casts#}4762 {#header_open|Type Coercion#}
4653 <p>4763 <p>
4654 An implicit cast occurs when one type is expected, but different type is provided:4764 Type coercion occurs when one type is expected, but different type is provided:
4655 </p>4765 </p>
4656 {#code_begin|test#}4766 {#code_begin|test#}
4657test "implicit cast - variable declaration" {4767test "type coercion - variable declaration" {
4658 var a: u8 = 1;4768 var a: u8 = 1;
4659 var b: u16 = a;4769 var b: u16 = a;
4660}4770}
46614771
4662test "implicit cast - function call" {4772test "type coercion - function call" {
4663 var a: u8 = 1;4773 var a: u8 = 1;
4664 foo(a);4774 foo(a);
4665}4775}
46664776
4667fn foo(b: u16) void {}4777fn foo(b: u16) void {}
46684778
4669test "implicit cast - invoke a type as a function" {4779test "type coercion - @as builtin" {
4670 var a: u8 = 1;4780 var a: u8 = 1;
4671 var b = u16(a);4781 var b = @as(u16, a);
4672}4782}
4673 {#code_end#}4783 {#code_end#}
4674 <p>4784 <p>
4675 Implicit casts are only allowed when it is completely unambiguous how to get from one type to another,4785 Type coercions are only allowed when it is completely unambiguous how to get from one type to another,
4676 and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.4786 and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.
4677 </p>4787 </p>
4678 {#header_open|Implicit Cast: Stricter Qualification#}4788 {#header_open|Type Coercion: Stricter Qualification#}
4679 <p>4789 <p>
4680 Values which have the same representation at runtime can be cast to increase the strictness4790 Values which have the same representation at runtime can be cast to increase the strictness
4681 of the qualifiers, no matter how nested the qualifiers are:4791 of the qualifiers, no matter how nested the qualifiers are:
...@@ -4690,7 +4800,7 @@ test "implicit cast - invoke a type as a function" {...@@ -4690,7 +4800,7 @@ test "implicit cast - invoke a type as a function" {
4690 These casts are no-ops at runtime since the value representation does not change.4800 These casts are no-ops at runtime since the value representation does not change.
4691 </p>4801 </p>
4692 {#code_begin|test#}4802 {#code_begin|test#}
4693test "implicit cast - const qualification" {4803test "type coercion - const qualification" {
4694 var a: i32 = 1;4804 var a: i32 = 1;
4695 var b: *i32 = &a;4805 var b: *i32 = &a;
4696 foo(b);4806 foo(b);
...@@ -4699,7 +4809,7 @@ test "implicit cast - const qualification" {...@@ -4699,7 +4809,7 @@ test "implicit cast - const qualification" {
4699fn foo(a: *const i32) void {}4809fn foo(a: *const i32) void {}
4700 {#code_end#}4810 {#code_end#}
4701 <p>4811 <p>
4702 In addition, pointers implicitly cast to const optional pointers:4812 In addition, pointers coerce to const optional pointers:
4703 </p>4813 </p>
4704 {#code_begin|test#}4814 {#code_begin|test#}
4705const std = @import("std");4815const std = @import("std");
...@@ -4713,10 +4823,10 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {...@@ -4713,10 +4823,10 @@ test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
4713}4823}
4714 {#code_end#}4824 {#code_end#}
4715 {#header_close#}4825 {#header_close#}
4716 {#header_open|Implicit Cast: Integer and Float Widening#}4826 {#header_open|Type Coercion: Integer and Float Widening#}
4717 <p>4827 <p>
4718 {#link|Integers#} implicitly cast to integer types which can represent every value of the old type, and likewise4828 {#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
4719 {#link|Floats#} implicitly cast to float types which can represent every value of the old type.4829 {#link|Floats#} coerce to float types which can represent every value of the old type.
4720 </p>4830 </p>
4721 {#code_begin|test#}4831 {#code_begin|test#}
4722const std = @import("std");4832const std = @import("std");
...@@ -4748,7 +4858,7 @@ test "float widening" {...@@ -4748,7 +4858,7 @@ test "float widening" {
4748}4858}
4749 {#code_end#}4859 {#code_end#}
4750 {#header_close#}4860 {#header_close#}
4751 {#header_open|Implicit Cast: Arrays and Pointers#}4861 {#header_open|Type Coercion: Arrays and Pointers#}
4752 {#code_begin|test#}4862 {#code_begin|test#}
4753const std = @import("std");4863const std = @import("std");
4754const assert = std.debug.assert;4864const assert = std.debug.assert;
...@@ -4797,7 +4907,7 @@ test "*[N]T to []T" {...@@ -4797,7 +4907,7 @@ test "*[N]T to []T" {
4797 assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 }));4907 assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 }));
4798}4908}
47994909
4800// Single-item pointers to arrays can be implicitly casted to4910// Single-item pointers to arrays can be coerced to
4801// unknown length pointers.4911// unknown length pointers.
4802test "*[N]T to [*]T" {4912test "*[N]T to [*]T" {
4803 var buf: [5]u8 = "hello";4913 var buf: [5]u8 = "hello";
...@@ -4823,15 +4933,15 @@ test "*T to *[1]T" {...@@ -4823,15 +4933,15 @@ test "*T to *[1]T" {
4823 {#code_end#}4933 {#code_end#}
4824 {#see_also|C Pointers#}4934 {#see_also|C Pointers#}
4825 {#header_close#}4935 {#header_close#}
4826 {#header_open|Implicit Cast: Optionals#}4936 {#header_open|Type Coercion: Optionals#}
4827 <p>4937 <p>
4828 The payload type of {#link|Optionals#}, as well as {#link|null#}, implicitly cast to the optional type.4938 The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
4829 </p>4939 </p>
4830 {#code_begin|test#}4940 {#code_begin|test#}
4831const std = @import("std");4941const std = @import("std");
4832const assert = std.debug.assert;4942const assert = std.debug.assert;
48334943
4834test "implicit casting to optionals" {4944test "coerce to optionals" {
4835 const x: ?i32 = 1234;4945 const x: ?i32 = 1234;
4836 const y: ?i32 = null;4946 const y: ?i32 = null;
48374947
...@@ -4844,7 +4954,7 @@ test "implicit casting to optionals" {...@@ -4844,7 +4954,7 @@ test "implicit casting to optionals" {
4844const std = @import("std");4954const std = @import("std");
4845const assert = std.debug.assert;4955const assert = std.debug.assert;
48464956
4847test "implicit casting to optionals wrapped in error union" {4957test "coerce to optionals wrapped in error union" {
4848 const x: anyerror!?i32 = 1234;4958 const x: anyerror!?i32 = 1234;
4849 const y: anyerror!?i32 = null;4959 const y: anyerror!?i32 = null;
48504960
...@@ -4853,15 +4963,15 @@ test "implicit casting to optionals wrapped in error union" {...@@ -4853,15 +4963,15 @@ test "implicit casting to optionals wrapped in error union" {
4853}4963}
4854 {#code_end#}4964 {#code_end#}
4855 {#header_close#}4965 {#header_close#}
4856 {#header_open|Implicit Cast: Error Unions#}4966 {#header_open|Type Coercion: Error Unions#}
4857 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}4967 <p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
4858 implicitly cast to the error union type:4968 coerce to the error union type:
4859 </p>4969 </p>
4860 {#code_begin|test#}4970 {#code_begin|test#}
4861const std = @import("std");4971const std = @import("std");
4862const assert = std.debug.assert;4972const assert = std.debug.assert;
48634973
4864test "implicit casting to error unions" {4974test "coercion to error unions" {
4865 const x: anyerror!i32 = 1234;4975 const x: anyerror!i32 = 1234;
4866 const y: anyerror!i32 = error.Failure;4976 const y: anyerror!i32 = error.Failure;
48674977
...@@ -4870,23 +4980,23 @@ test "implicit casting to error unions" {...@@ -4870,23 +4980,23 @@ test "implicit casting to error unions" {
4870}4980}
4871 {#code_end#}4981 {#code_end#}
4872 {#header_close#}4982 {#header_close#}
4873 {#header_open|Implicit Cast: Compile-Time Known Numbers#}4983 {#header_open|Type Coercion: Compile-Time Known Numbers#}
4874 <p>When a number is {#link|comptime#}-known to be representable in the destination type,4984 <p>When a number is {#link|comptime#}-known to be representable in the destination type,
4875 it may be implicitly casted:4985 it may be coerced:
4876 </p>4986 </p>
4877 {#code_begin|test#}4987 {#code_begin|test#}
4878const std = @import("std");4988const std = @import("std");
4879const assert = std.debug.assert;4989const assert = std.debug.assert;
48804990
4881test "implicit casting large integer type to smaller one when value is comptime known to fit" {4991test "coercing large integer type to smaller one when value is comptime known to fit" {
4882 const x: u64 = 255;4992 const x: u64 = 255;
4883 const y: u8 = x;4993 const y: u8 = x;
4884 assert(y == 255);4994 assert(y == 255);
4885}4995}
4886 {#code_end#}4996 {#code_end#}
4887 {#header_close#}4997 {#header_close#}
4888 {#header_open|Implicit Cast: unions and enums#}4998 {#header_open|Type Coercion: unions and enums#}
4889 <p>Tagged unions can be implicitly cast to enums, and enums can be implicitly casted to tagged unions4999 <p>Tagged unions can be coerced to enums, and enums can be coerced to tagged unions
4890 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as5000 when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
4891 {#link|void#}:5001 {#link|void#}:
4892 </p>5002 </p>
...@@ -4906,7 +5016,7 @@ const U = union(E) {...@@ -4906,7 +5016,7 @@ const U = union(E) {
4906 Three,5016 Three,
4907};5017};
49085018
4909test "implicit casting between unions and enums" {5019test "coercion between unions and enums" {
4910 var u = U{ .Two = 12.34 };5020 var u = U{ .Two = 12.34 };
4911 var e: E = u;5021 var e: E = u;
4912 assert(e == E.Two);5022 assert(e == E.Two);
...@@ -4918,20 +5028,20 @@ test "implicit casting between unions and enums" {...@@ -4918,20 +5028,20 @@ test "implicit casting between unions and enums" {
4918 {#code_end#}5028 {#code_end#}
4919 {#see_also|union|enum#}5029 {#see_also|union|enum#}
4920 {#header_close#}5030 {#header_close#}
4921 {#header_open|Implicit Cast: Zero Bit Types#}5031 {#header_open|Type Coercion: Zero Bit Types#}
4922 <p>{#link|Zero Bit Types#} may be implicitly casted to single-item {#link|Pointers#},5032 <p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#},
4923 regardless of const.</p>5033 regardless of const.</p>
4924 <p>TODO document the reasoning for this</p>5034 <p>TODO document the reasoning for this</p>
4925 <p>TODO document whether vice versa should work and why</p>5035 <p>TODO document whether vice versa should work and why</p>
4926 {#code_begin|test#}5036 {#code_begin|test#}
4927test "implicit casting of zero bit types" {5037test "coercion of zero bit types" {
4928 var x: void = {};5038 var x: void = {};
4929 var y: *void = x;5039 var y: *void = x;
4930 //var z: void = y; // TODO5040 //var z: void = y; // TODO
4931}5041}
4932 {#code_end#}5042 {#code_end#}
4933 {#header_close#}5043 {#header_close#}
4934 {#header_open|Implicit Cast: undefined#}5044 {#header_open|Type Coercion: undefined#}
4935 <p>{#link|undefined#} can be cast to any type.</p>5045 <p>{#link|undefined#} can be cast to any type.</p>
4936 {#header_close#}5046 {#header_close#}
4937 {#header_close#}5047 {#header_close#}
...@@ -4976,7 +5086,7 @@ test "implicit casting of zero bit types" {...@@ -4976,7 +5086,7 @@ test "implicit casting of zero bit types" {
4976 <li>Some {#link|binary operations|Table of Operators#}</li>5086 <li>Some {#link|binary operations|Table of Operators#}</li>
4977 </ul>5087 </ul>
4978 <p>5088 <p>
4979 This kind of type resolution chooses a type that all peer types can implicitly cast into. Here are5089 This kind of type resolution chooses a type that all peer types can coerce into. Here are
4980 some examples:5090 some examples:
4981 </p>5091 </p>
4982 {#code_begin|test#}5092 {#code_begin|test#}
...@@ -5007,8 +5117,8 @@ test "peer resolve array and const slice" {...@@ -5007,8 +5117,8 @@ test "peer resolve array and const slice" {
5007 comptime testPeerResolveArrayConstSlice(true);5117 comptime testPeerResolveArrayConstSlice(true);
5008}5118}
5009fn testPeerResolveArrayConstSlice(b: bool) void {5119fn testPeerResolveArrayConstSlice(b: bool) void {
5010 const value1 = if (b) "aoeu" else ([]const u8)("zz");5120 const value1 = if (b) "aoeu" else @as([]const u8, "zz");
5011 const value2 = if (b) ([]const u8)("zz") else "aoeu";5121 const value2 = if (b) @as([]const u8, "zz") else "aoeu";
5012 assert(mem.eql(u8, value1, "aoeu"));5122 assert(mem.eql(u8, value1, "aoeu"));
5013 assert(mem.eql(u8, value2, "zz"));5123 assert(mem.eql(u8, value2, "zz"));
5014}5124}
...@@ -5023,10 +5133,10 @@ test "peer type resolution: ?T and T" {...@@ -5023,10 +5133,10 @@ test "peer type resolution: ?T and T" {
5023}5133}
5024fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {5134fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
5025 if (c) {5135 if (c) {
5026 return if (b) null else usize(0);5136 return if (b) null else @as(usize, 0);
5027 }5137 }
50285138
5029 return usize(3);5139 return @as(usize, 3);
5030}5140}
50315141
5032test "peer type resolution: [0]u8 and []const u8" {5142test "peer type resolution: [0]u8 and []const u8" {
...@@ -5293,7 +5403,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {...@@ -5293,7 +5403,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
5293 <p>5403 <p>
5294 For example, if we were to introduce another function to the above snippet:5404 For example, if we were to introduce another function to the above snippet:
5295 </p>5405 </p>
5296 {#code_begin|test_err|cannot store runtime value in type 'type'#}5406 {#code_begin|test_err|values of type 'type' must be comptime known#}
5297fn max(comptime T: type, a: T, b: T) T {5407fn max(comptime T: type, a: T, b: T) T {
5298 return if (a > b) a else b;5408 return if (a > b) a else b;
5299}5409}
...@@ -5815,7 +5925,7 @@ test "printf too many arguments" {...@@ -5815,7 +5925,7 @@ test "printf too many arguments" {
5815 </p>5925 </p>
5816 <p>5926 <p>
5817 Zig doesn't care whether the format argument is a string literal,5927 Zig doesn't care whether the format argument is a string literal,
5818 only that it is a compile-time known value that is implicitly castable to a {#syntax#}[]const u8{#endsyntax#}:5928 only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}:
5819 </p>5929 </p>
5820 {#code_begin|exe|printf#}5930 {#code_begin|exe|printf#}
5821const warn = @import("std").debug.warn;5931const warn = @import("std").debug.warn;
...@@ -6185,7 +6295,7 @@ fn func() void {...@@ -6185,7 +6295,7 @@ fn func() void {
6185 </p>6295 </p>
6186 <p>6296 <p>
6187 {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that6297 {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
6188 implicitly casts to {#syntax#}anyframe->T{#endsyntax#}.6298 coerces to {#syntax#}anyframe->T{#endsyntax#}.
6189 </p>6299 </p>
6190 <p>6300 <p>
6191 There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.6301 There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.
...@@ -6445,6 +6555,14 @@ comptime {...@@ -6445,6 +6555,14 @@ comptime {
6445 </p>6555 </p>
6446 {#header_close#}6556 {#header_close#}
64476557
6558 {#header_open|@as#}
6559 <pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre>
6560 <p>
6561 Performs {#link|Type Coercion#}. This cast is allowed when the conversion is unambiguous and safe,
6562 and is the preferred way to convert between types, whenever possible.
6563 </p>
6564 {#header_close#}
6565
6448 {#header_open|@asyncCall#}6566 {#header_open|@asyncCall#}
6449 <pre>{#syntax#}@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: ...) anyframe->T{#endsyntax#}</pre>6567 <pre>{#syntax#}@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: ...) anyframe->T{#endsyntax#}</pre>
6450 <p>6568 <p>
...@@ -6493,14 +6611,14 @@ async fn func(y: *i32) void {...@@ -6493,14 +6611,14 @@ async fn func(y: *i32) void {
6493 This builtin function atomically dereferences a pointer and returns the value.6611 This builtin function atomically dereferences a pointer and returns the value.
6494 </p>6612 </p>
6495 <p>6613 <p>
6496 {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#},6614 {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}
6497 or an integer whose bit count meets these requirements:6615 an integer whose bit count meets these requirements:
6498 </p>6616 </p>
6499 <ul>6617 <ul>
6500 <li>At least 8</li>6618 <li>At least 8</li>
6501 <li>At most the same as usize</li>6619 <li>At most the same as usize</li>
6502 <li>Power of 2</li>6620 <li>Power of 2</li>
6503 </ul>6621 </ul> or an enum with a valid integer tag type.
6504 <p>6622 <p>
6505 TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe6623 TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
6506 we can remove this restriction6624 we can remove this restriction
...@@ -6541,6 +6659,25 @@ async fn func(y: *i32) void {...@@ -6541,6 +6659,25 @@ async fn func(y: *i32) void {
6541 <li>{#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.</li>6659 <li>{#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.</li>
6542 </ul>6660 </ul>
6543 {#header_close#}6661 {#header_close#}
6662 {#header_open|@atomicStore#}
6663 <pre>{#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void{#endsyntax#}</pre>
6664 <p>
6665 This builtin function atomically stores a value.
6666 </p>
6667 <p>
6668 {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}
6669 an integer whose bit count meets these requirements:
6670 </p>
6671 <ul>
6672 <li>At least 8</li>
6673 <li>At most the same as usize</li>
6674 <li>Power of 2</li>
6675 </ul> or an enum with a valid integer tag type.
6676 <p>
6677 TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
6678 we can remove this restriction
6679 </p>
6680 {#header_close#}
6544 {#header_open|@bitCast#}6681 {#header_open|@bitCast#}
6545 <pre>{#syntax#}@bitCast(comptime DestType: type, value: var) DestType{#endsyntax#}</pre>6682 <pre>{#syntax#}@bitCast(comptime DestType: type, value: var) DestType{#endsyntax#}</pre>
6546 <p>6683 <p>
...@@ -7108,7 +7245,7 @@ test "field access by string" {...@@ -7108,7 +7245,7 @@ test "field access by string" {
7108 <pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre>7245 <pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre>
7109 <p>7246 <p>
7110 This function returns a pointer to the frame for a given function. This type7247 This function returns a pointer to the frame for a given function. This type
7111 can be {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyframe->T{#endsyntax#} and7248 can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and
7112 to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type7249 to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type
7113 of the function in scope.7250 of the function in scope.
7114 </p>7251 </p>
...@@ -7827,7 +7964,7 @@ test "vector @splat" {...@@ -7827,7 +7964,7 @@ test "vector @splat" {
7827 const scalar: u32 = 5;7964 const scalar: u32 = 5;
7828 const result = @splat(4, scalar);7965 const result = @splat(4, scalar);
7829 comptime assert(@typeOf(result) == @Vector(4, u32));7966 comptime assert(@typeOf(result) == @Vector(4, u32));
7830 assert(std.mem.eql(u32, ([4]u32)(result), [_]u32{ 5, 5, 5, 5 }));7967 assert(std.mem.eql(u32, @as([4]u32, result), [_]u32{ 5, 5, 5, 5 }));
7831}7968}
7832 {#code_end#}7969 {#code_end#}
7833 <p>7970 <p>
...@@ -8025,7 +8162,7 @@ test "integer truncation" {...@@ -8025,7 +8162,7 @@ test "integer truncation" {
8025 </p>8162 </p>
8026 <p>8163 <p>
8027 If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},8164 If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
8028 then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.8165 then this is semantically equivalent to {#link|Type Coercion#}.
8029 </p>8166 </p>
8030 {#header_close#}8167 {#header_close#}
80318168
...@@ -8529,7 +8666,7 @@ pub fn main() void {...@@ -8529,7 +8666,7 @@ pub fn main() void {
8529 {#header_close#}8666 {#header_close#}
8530 {#header_open|Cast Truncates Data#}8667 {#header_open|Cast Truncates Data#}
8531 <p>At compile-time:</p>8668 <p>At compile-time:</p>
8532 {#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#}8669 {#code_begin|test_err|integer value 300 cannot be coerced to type 'u8'#}
8533comptime {8670comptime {
8534 const spartan_count: u16 = 300;8671 const spartan_count: u16 = 300;
8535 const byte = @intCast(u8, spartan_count);8672 const byte = @intCast(u8, spartan_count);
...@@ -8665,7 +8802,7 @@ test "wraparound addition and subtraction" {...@@ -8665,7 +8802,7 @@ test "wraparound addition and subtraction" {
8665 <p>At compile-time:</p>8802 <p>At compile-time:</p>
8666 {#code_begin|test_err|operation caused overflow#}8803 {#code_begin|test_err|operation caused overflow#}
8667comptime {8804comptime {
8668 const x = @shlExact(u8(0b01010101), 2);8805 const x = @shlExact(@as(u8, 0b01010101), 2);
8669}8806}
8670 {#code_end#}8807 {#code_end#}
8671 <p>At runtime:</p>8808 <p>At runtime:</p>
...@@ -8683,7 +8820,7 @@ pub fn main() void {...@@ -8683,7 +8820,7 @@ pub fn main() void {
8683 <p>At compile-time:</p>8820 <p>At compile-time:</p>
8684 {#code_begin|test_err|exact shift shifted out 1 bits#}8821 {#code_begin|test_err|exact shift shifted out 1 bits#}
8685comptime {8822comptime {
8686 const x = @shrExact(u8(0b10101010), 2);8823 const x = @shrExact(@as(u8, 0b10101010), 2);
8687}8824}
8688 {#code_end#}8825 {#code_end#}
8689 <p>At runtime:</p>8826 <p>At runtime:</p>
...@@ -9535,8 +9672,8 @@ const c = @cImport({...@@ -9535,8 +9672,8 @@ const c = @cImport({
9535 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>9672 <p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
9536 <ul>9673 <ul>
9537 <li>Supports all the syntax of the other two pointer types.</li>9674 <li>Supports all the syntax of the other two pointer types.</li>
9538 <li>Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}.9675 <li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
9539 When a C pointer is implicitly casted to a non-optional pointer, safety-checked9676 When a C pointer is coerced to a non-optional pointer, safety-checked
9540 {#link|Undefined Behavior#} occurs if the address is 0.9677 {#link|Undefined Behavior#} occurs if the address is 0.
9541 </li>9678 </li>
9542 <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked9679 <li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
...@@ -9544,7 +9681,7 @@ const c = @cImport({...@@ -9544,7 +9681,7 @@ const c = @cImport({
9544 null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer9681 null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
9545 is unnecessary as one can use normal {#link|Optional Pointers#}.9682 is unnecessary as one can use normal {#link|Optional Pointers#}.
9546 </li>9683 </li>
9547 <li>Supports {#link|implicit casting|Implicit Casts#} to and from integers.</li>9684 <li>Supports {#link|Type Coercion#} to and from integers.</li>
9548 <li>Supports comparison with integers.</li>9685 <li>Supports comparison with integers.</li>
9549 <li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}9686 <li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}
9550 please!</li>9687 please!</li>
lib/std/array_list.zig+8-8
...@@ -344,18 +344,18 @@ test "std.ArrayList.orderedRemove" {...@@ -344,18 +344,18 @@ test "std.ArrayList.orderedRemove" {
344 try list.append(7);344 try list.append(7);
345345
346 //remove from middle346 //remove from middle
347 testing.expectEqual(i32(4), list.orderedRemove(3));347 testing.expectEqual(@as(i32, 4), list.orderedRemove(3));
348 testing.expectEqual(i32(5), list.at(3));348 testing.expectEqual(@as(i32, 5), list.at(3));
349 testing.expectEqual(usize(6), list.len);349 testing.expectEqual(@as(usize, 6), list.len);
350350
351 //remove from end351 //remove from end
352 testing.expectEqual(i32(7), list.orderedRemove(5));352 testing.expectEqual(@as(i32, 7), list.orderedRemove(5));
353 testing.expectEqual(usize(5), list.len);353 testing.expectEqual(@as(usize, 5), list.len);
354354
355 //remove from front355 //remove from front
356 testing.expectEqual(i32(1), list.orderedRemove(0));356 testing.expectEqual(@as(i32, 1), list.orderedRemove(0));
357 testing.expectEqual(i32(2), list.at(0));357 testing.expectEqual(@as(i32, 2), list.at(0));
358 testing.expectEqual(usize(4), list.len);358 testing.expectEqual(@as(usize, 4), list.len);
359}359}
360360
361test "std.ArrayList.swapRemove" {361test "std.ArrayList.swapRemove" {
lib/std/ascii.zig+11-11
...@@ -129,26 +129,26 @@ const combinedTable = init: {...@@ -129,26 +129,26 @@ const combinedTable = init: {
129 comptime var i = 0;129 comptime var i = 0;
130 inline while (i < 128) : (i += 1) {130 inline while (i < 128) : (i += 1) {
131 table[i] =131 table[i] =
132 u8(alpha[i]) << @enumToInt(tIndex.Alpha) |132 @as(u8, alpha[i]) << @enumToInt(tIndex.Alpha) |
133 u8(hex[i]) << @enumToInt(tIndex.Hex) |133 @as(u8, hex[i]) << @enumToInt(tIndex.Hex) |
134 u8(space[i]) << @enumToInt(tIndex.Space) |134 @as(u8, space[i]) << @enumToInt(tIndex.Space) |
135 u8(digit[i]) << @enumToInt(tIndex.Digit) |135 @as(u8, digit[i]) << @enumToInt(tIndex.Digit) |
136 u8(lower[i]) << @enumToInt(tIndex.Lower) |136 @as(u8, lower[i]) << @enumToInt(tIndex.Lower) |
137 u8(upper[i]) << @enumToInt(tIndex.Upper) |137 @as(u8, upper[i]) << @enumToInt(tIndex.Upper) |
138 u8(punct[i]) << @enumToInt(tIndex.Punct) |138 @as(u8, punct[i]) << @enumToInt(tIndex.Punct) |
139 u8(graph[i]) << @enumToInt(tIndex.Graph);139 @as(u8, graph[i]) << @enumToInt(tIndex.Graph);
140 }140 }
141 mem.set(u8, table[128..256], 0);141 mem.set(u8, table[128..256], 0);
142 break :init table;142 break :init table;
143};143};
144144
145fn inTable(c: u8, t: tIndex) bool {145fn inTable(c: u8, t: tIndex) bool {
146 return (combinedTable[c] & (u8(1) << @enumToInt(t))) != 0;146 return (combinedTable[c] & (@as(u8, 1) << @enumToInt(t))) != 0;
147}147}
148148
149pub fn isAlNum(c: u8) bool {149pub fn isAlNum(c: u8) bool {
150 return (combinedTable[c] & ((u8(1) << @enumToInt(tIndex.Alpha)) |150 return (combinedTable[c] & ((@as(u8, 1) << @enumToInt(tIndex.Alpha)) |
151 u8(1) << @enumToInt(tIndex.Digit))) != 0;151 @as(u8, 1) << @enumToInt(tIndex.Digit))) != 0;
152}152}
153153
154pub fn isAlpha(c: u8) bool {154pub fn isAlpha(c: u8) bool {
lib/std/atomic/queue.zig+3-3
...@@ -199,7 +199,7 @@ test "std.atomic.Queue" {...@@ -199,7 +199,7 @@ test "std.atomic.Queue" {
199199
200 for (putters) |t|200 for (putters) |t|
201 t.wait();201 t.wait();
202 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);202 @atomicStore(u8, &context.puts_done, 1, AtomicOrder.SeqCst);
203 for (getters) |t|203 for (getters) |t|
204 t.wait();204 t.wait();
205205
...@@ -214,8 +214,8 @@ test "std.atomic.Queue" {...@@ -214,8 +214,8 @@ test "std.atomic.Queue" {
214 std.debug.panic(214 std.debug.panic(
215 "failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",215 "failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",
216 context.get_count,216 context.get_count,
217 u32(puts_per_thread),217 @as(u32, puts_per_thread),
218 u32(put_thread_count),218 @as(u32, put_thread_count),
219 );219 );
220 }220 }
221}221}
lib/std/atomic/stack.zig+4-4
...@@ -11,7 +11,7 @@ pub fn Stack(comptime T: type) type {...@@ -11,7 +11,7 @@ pub fn Stack(comptime T: type) type {
11 root: ?*Node,11 root: ?*Node,
12 lock: @typeOf(lock_init),12 lock: @typeOf(lock_init),
1313
14 const lock_init = if (builtin.single_threaded) {} else u8(0);14 const lock_init = if (builtin.single_threaded) {} else @as(u8, 0);
1515
16 pub const Self = @This();16 pub const Self = @This();
1717
...@@ -128,7 +128,7 @@ test "std.atomic.stack" {...@@ -128,7 +128,7 @@ test "std.atomic.stack" {
128128
129 for (putters) |t|129 for (putters) |t|
130 t.wait();130 t.wait();
131 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);131 @atomicStore(u8, &context.puts_done, 1, AtomicOrder.SeqCst);
132 for (getters) |t|132 for (getters) |t|
133 t.wait();133 t.wait();
134 }134 }
...@@ -141,8 +141,8 @@ test "std.atomic.stack" {...@@ -141,8 +141,8 @@ test "std.atomic.stack" {
141 std.debug.panic(141 std.debug.panic(
142 "failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",142 "failure\nget_count:{} != puts_per_thread:{} * put_thread_count:{}",
143 context.get_count,143 context.get_count,
144 u32(puts_per_thread),144 @as(u32, puts_per_thread),
145 u32(put_thread_count),145 @as(u32, put_thread_count),
146 );146 );
147 }147 }
148}148}
lib/std/bloom_filter.zig+11-11
...@@ -28,7 +28,7 @@ pub fn BloomFilter(...@@ -28,7 +28,7 @@ pub fn BloomFilter(
28 assert(n_items > 0);28 assert(n_items > 0);
29 assert(math.isPowerOfTwo(n_items));29 assert(math.isPowerOfTwo(n_items));
30 assert(K > 0);30 assert(K > 0);
31 const cellEmpty = if (Cell == bool) false else Cell(0);31 const cellEmpty = if (Cell == bool) false else @as(Cell, 0);
32 const cellMax = if (Cell == bool) true else math.maxInt(Cell);32 const cellMax = if (Cell == bool) true else math.maxInt(Cell);
33 const n_bytes = (n_items * comptime std.meta.bitCount(Cell)) / 8;33 const n_bytes = (n_items * comptime std.meta.bitCount(Cell)) / 8;
34 assert(n_bytes > 0);34 assert(n_bytes > 0);
...@@ -137,7 +137,7 @@ pub fn BloomFilter(...@@ -137,7 +137,7 @@ pub fn BloomFilter(
137 var i: usize = 0;137 var i: usize = 0;
138 while (i < n_items) : (i += 1) {138 while (i < n_items) : (i += 1) {
139 const cell = self.getCell(@intCast(Index, i));139 const cell = self.getCell(@intCast(Index, i));
140 n += if (if (Cell == bool) cell else cell > 0) Index(1) else Index(0);140 n += if (if (Cell == bool) cell else cell > 0) @as(Index, 1) else @as(Index, 0);
141 }141 }
142 }142 }
143 return n;143 return n;
...@@ -161,7 +161,7 @@ fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {...@@ -161,7 +161,7 @@ fn hashFunc(out: []u8, Ki: usize, in: []const u8) void {
161161
162test "std.BloomFilter" {162test "std.BloomFilter" {
163 inline for ([_]type{ bool, u1, u2, u3, u4 }) |Cell| {163 inline for ([_]type{ bool, u1, u2, u3, u4 }) |Cell| {
164 const emptyCell = if (Cell == bool) false else Cell(0);164 const emptyCell = if (Cell == bool) false else @as(Cell, 0);
165 const BF = BloomFilter(128 * 8, 8, Cell, builtin.endian, hashFunc);165 const BF = BloomFilter(128 * 8, 8, Cell, builtin.endian, hashFunc);
166 var bf = BF{};166 var bf = BF{};
167 var i: usize = undefined;167 var i: usize = undefined;
...@@ -170,8 +170,8 @@ test "std.BloomFilter" {...@@ -170,8 +170,8 @@ test "std.BloomFilter" {
170 while (i < BF.items) : (i += 1) {170 while (i < BF.items) : (i += 1) {
171 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));171 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
172 }172 }
173 testing.expectEqual(BF.Index(0), bf.popCount());173 testing.expectEqual(@as(BF.Index, 0), bf.popCount());
174 testing.expectEqual(f64(0), bf.estimateItems());174 testing.expectEqual(@as(f64, 0), bf.estimateItems());
175 // fill in a few items175 // fill in a few items
176 bf.incrementCell(42);176 bf.incrementCell(42);
177 bf.incrementCell(255);177 bf.incrementCell(255);
...@@ -196,8 +196,8 @@ test "std.BloomFilter" {...@@ -196,8 +196,8 @@ test "std.BloomFilter" {
196 while (i < BF.items) : (i += 1) {196 while (i < BF.items) : (i += 1) {
197 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));197 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
198 }198 }
199 testing.expectEqual(BF.Index(0), bf.popCount());199 testing.expectEqual(@as(BF.Index, 0), bf.popCount());
200 testing.expectEqual(f64(0), bf.estimateItems());200 testing.expectEqual(@as(f64, 0), bf.estimateItems());
201201
202 // Lets add a string202 // Lets add a string
203 bf.add("foo");203 bf.add("foo");
...@@ -218,8 +218,8 @@ test "std.BloomFilter" {...@@ -218,8 +218,8 @@ test "std.BloomFilter" {
218 while (i < BF.items) : (i += 1) {218 while (i < BF.items) : (i += 1) {
219 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));219 testing.expectEqual(emptyCell, bf.getCell(@intCast(BF.Index, i)));
220 }220 }
221 testing.expectEqual(BF.Index(0), bf.popCount());221 testing.expectEqual(@as(BF.Index, 0), bf.popCount());
222 testing.expectEqual(f64(0), bf.estimateItems());222 testing.expectEqual(@as(f64, 0), bf.estimateItems());
223223
224 comptime var teststrings = [_][]const u8{224 comptime var teststrings = [_][]const u8{
225 "foo",225 "foo",
...@@ -246,12 +246,12 @@ test "std.BloomFilter" {...@@ -246,12 +246,12 @@ test "std.BloomFilter" {
246 inline for (teststrings) |str| {246 inline for (teststrings) |str| {
247 testing.expectEqual(true, larger_bf.contains(str));247 testing.expectEqual(true, larger_bf.contains(str));
248 }248 }
249 testing.expectEqual(u12(bf.popCount()) * (4096 / 1024), larger_bf.popCount());249 testing.expectEqual(@as(u12, bf.popCount()) * (4096 / 1024), larger_bf.popCount());
250250
251 const smaller_bf = bf.resize(64);251 const smaller_bf = bf.resize(64);
252 inline for (teststrings) |str| {252 inline for (teststrings) |str| {
253 testing.expectEqual(true, smaller_bf.contains(str));253 testing.expectEqual(true, smaller_bf.contains(str));
254 }254 }
255 testing.expect(bf.popCount() <= u10(smaller_bf.popCount()) * (1024 / 64));255 testing.expect(bf.popCount() <= @as(u10, smaller_bf.popCount()) * (1024 / 64));
256 }256 }
257}257}
lib/std/build.zig+82-1
...@@ -53,7 +53,7 @@ pub const Builder = struct {...@@ -53,7 +53,7 @@ pub const Builder = struct {
53 release_mode: ?builtin.Mode,53 release_mode: ?builtin.Mode,
54 is_release: bool,54 is_release: bool,
55 override_lib_dir: ?[]const u8,55 override_lib_dir: ?[]const u8,
5656 vcpkg_root: VcpkgRoot,
57 pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,57 pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
5858
59 const PkgConfigError = error{59 const PkgConfigError = error{
...@@ -159,6 +159,7 @@ pub const Builder = struct {...@@ -159,6 +159,7 @@ pub const Builder = struct {
159 .is_release = false,159 .is_release = false,
160 .override_lib_dir = null,160 .override_lib_dir = null,
161 .install_path = undefined,161 .install_path = undefined,
162 .vcpkg_root = VcpkgRoot{ .Unattempted = {} },
162 };163 };
163 try self.top_level_steps.append(&self.install_tls);164 try self.top_level_steps.append(&self.install_tls);
164 try self.top_level_steps.append(&self.uninstall_tls);165 try self.top_level_steps.append(&self.uninstall_tls);
...@@ -957,6 +958,7 @@ pub const Builder = struct {...@@ -957,6 +958,7 @@ pub const Builder = struct {
957 error.ProcessTerminated => error.PkgConfigCrashed,958 error.ProcessTerminated => error.PkgConfigCrashed,
958 error.ExitCodeFailure => error.PkgConfigFailed,959 error.ExitCodeFailure => error.PkgConfigFailed,
959 error.FileNotFound => error.PkgConfigNotInstalled,960 error.FileNotFound => error.PkgConfigNotInstalled,
961 error.InvalidName => error.PkgConfigNotInstalled,
960 error.PkgConfigInvalidOutput => error.PkgConfigInvalidOutput,962 error.PkgConfigInvalidOutput => error.PkgConfigInvalidOutput,
961 else => return err,963 else => return err,
962 };964 };
...@@ -1046,6 +1048,7 @@ pub const LibExeObjStep = struct {...@@ -1046,6 +1048,7 @@ pub const LibExeObjStep = struct {
1046 output_dir: ?[]const u8,1048 output_dir: ?[]const u8,
1047 need_system_paths: bool,1049 need_system_paths: bool,
1048 is_linking_libc: bool = false,1050 is_linking_libc: bool = false,
1051 vcpkg_bin_path: ?[]const u8 = null,
10491052
1050 installed_path: ?[]const u8,1053 installed_path: ?[]const u8,
1051 install_step: ?*InstallArtifactStep,1054 install_step: ?*InstallArtifactStep,
...@@ -1264,6 +1267,11 @@ pub const LibExeObjStep = struct {...@@ -1264,6 +1267,11 @@ pub const LibExeObjStep = struct {
1264 // option is supplied.1267 // option is supplied.
1265 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));1268 const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", exe.step.name));
1266 run_step.addArtifactArg(exe);1269 run_step.addArtifactArg(exe);
1270
1271 if (exe.vcpkg_bin_path) |path| {
1272 run_step.addPathDir(path);
1273 }
1274
1267 return run_step;1275 return run_step;
1268 }1276 }
12691277
...@@ -1569,6 +1577,43 @@ pub const LibExeObjStep = struct {...@@ -1569,6 +1577,43 @@ pub const LibExeObjStep = struct {
1569 }) catch unreachable;1577 }) catch unreachable;
1570 }1578 }
15711579
1580 /// If Vcpkg was found on the system, it will be added to include and lib
1581 /// paths for the specified target.
1582 pub fn addVcpkgPaths(self: *LibExeObjStep, linkage: VcpkgLinkage) !void {
1583 // Ideally in the Unattempted case we would call the function recursively
1584 // after findVcpkgRoot and have only one switch statement, but the compiler
1585 // cannot resolve the error set.
1586 switch (self.builder.vcpkg_root) {
1587 .Unattempted => {
1588 self.builder.vcpkg_root = if (try findVcpkgRoot(self.builder.allocator)) |root|
1589 VcpkgRoot{ .Found = root }
1590 else
1591 .NotFound;
1592 },
1593 .NotFound => return error.VcpkgNotFound,
1594 .Found => {},
1595 }
1596
1597 switch (self.builder.vcpkg_root) {
1598 .Unattempted => unreachable,
1599 .NotFound => return error.VcpkgNotFound,
1600 .Found => |root| {
1601 const allocator = self.builder.allocator;
1602 const triplet = try Target.vcpkgTriplet(allocator, self.target, linkage);
1603 defer self.builder.allocator.free(triplet);
1604
1605 const include_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "include" });
1606 errdefer allocator.free(include_path);
1607 try self.include_dirs.append(IncludeDir{ .RawPath = include_path });
1608
1609 const lib_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "lib" });
1610 try self.lib_paths.append(lib_path);
1611
1612 self.vcpkg_bin_path = try fs.path.join(allocator, [_][]const u8{ root, "installed", triplet, "bin" });
1613 },
1614 }
1615 }
1616
1572 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {1617 pub fn setExecCmd(self: *LibExeObjStep, args: []const ?[]const u8) void {
1573 assert(self.kind == Kind.Test);1618 assert(self.kind == Kind.Test);
1574 self.exec_cmd_args = args;1619 self.exec_cmd_args = args;
...@@ -2341,6 +2386,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj...@@ -2341,6 +2386,42 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
2341 };2386 };
2342}2387}
23432388
2389/// Returned slice must be freed by the caller.
2390fn findVcpkgRoot(allocator: *Allocator) !?[]const u8 {
2391 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
2392 defer allocator.free(appdata_path);
2393
2394 const path_file = try fs.path.join(allocator, [_][]const u8{ appdata_path, "vcpkg.path.txt" });
2395 defer allocator.free(path_file);
2396
2397 const file = fs.File.openRead(path_file) catch return null;
2398 defer file.close();
2399
2400 const size = @intCast(usize, try file.getEndPos());
2401 const vcpkg_path = try allocator.alloc(u8, size);
2402 const size_read = try file.read(vcpkg_path);
2403 std.debug.assert(size == size_read);
2404
2405 return vcpkg_path;
2406}
2407
2408const VcpkgRoot = union(VcpkgRootStatus) {
2409 Unattempted: void,
2410 NotFound: void,
2411 Found: []const u8,
2412};
2413
2414const VcpkgRootStatus = enum {
2415 Unattempted,
2416 NotFound,
2417 Found,
2418};
2419
2420pub const VcpkgLinkage = enum {
2421 Static,
2422 Dynamic,
2423};
2424
2344pub const InstallDir = enum {2425pub const InstallDir = enum {
2345 Prefix,2426 Prefix,
2346 Lib,2427 Lib,
lib/std/builtin.zig+2-31
...@@ -90,40 +90,11 @@ pub const Mode = enum {...@@ -90,40 +90,11 @@ pub const Mode = enum {
90 ReleaseSmall,90 ReleaseSmall,
91};91};
9292
93/// This data structure is used by the Zig language code generation and93pub const TypeId = @TagType(TypeInfo);
94/// therefore must be kept in sync with the compiler implementation.
95pub const TypeId = enum {
96 Type,
97 Void,
98 Bool,
99 NoReturn,
100 Int,
101 Float,
102 Pointer,
103 Array,
104 Struct,
105 ComptimeFloat,
106 ComptimeInt,
107 Undefined,
108 Null,
109 Optional,
110 ErrorUnion,
111 ErrorSet,
112 Enum,
113 Union,
114 Fn,
115 BoundFn,
116 ArgTuple,
117 Opaque,
118 Frame,
119 AnyFrame,
120 Vector,
121 EnumLiteral,
122};
12394
124/// This data structure is used by the Zig language code generation and95/// This data structure is used by the Zig language code generation and
125/// therefore must be kept in sync with the compiler implementation.96/// therefore must be kept in sync with the compiler implementation.
126pub const TypeInfo = union(TypeId) {97pub const TypeInfo = union(enum) {
127 Type: void,98 Type: void,
128 Void: void,99 Void: void,
129 Bool: void,100 Bool: void,
lib/std/c.zig+23-1
...@@ -8,9 +8,16 @@ pub usingnamespace switch (builtin.os) {...@@ -8,9 +8,16 @@ pub usingnamespace switch (builtin.os) {
8 .linux => @import("c/linux.zig"),8 .linux => @import("c/linux.zig"),
9 .windows => @import("c/windows.zig"),9 .windows => @import("c/windows.zig"),
10 .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),10 .macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),
11 .freebsd => @import("c/freebsd.zig"),11 .freebsd, .kfreebsd => @import("c/freebsd.zig"),
12 .netbsd => @import("c/netbsd.zig"),12 .netbsd => @import("c/netbsd.zig"),
13 .dragonfly => @import("c/dragonfly.zig"),13 .dragonfly => @import("c/dragonfly.zig"),
14 .openbsd => @import("c/openbsd.zig"),
15 .haiku => @import("c/haiku.zig"),
16 .hermit => @import("c/hermit.zig"),
17 .solaris => @import("c/solaris.zig"),
18 .fuchsia => @import("c/fuchsia.zig"),
19 .minix => @import("c/minix.zig"),
20 .emscripten => @import("c/emscripten.zig"),
14 else => struct {},21 else => struct {},
15};22};
1623
...@@ -203,3 +210,18 @@ pub extern "c" fn dn_expand(...@@ -203,3 +210,18 @@ pub extern "c" fn dn_expand(
203 exp_dn: [*]u8,210 exp_dn: [*]u8,
204 length: c_int,211 length: c_int,
205) c_int;212) c_int;
213
214pub extern "c" fn sched_yield() c_int;
215
216pub const PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{};
217pub extern "c" fn pthread_mutex_lock(mutex: *pthread_mutex_t) c_int;
218pub extern "c" fn pthread_mutex_unlock(mutex: *pthread_mutex_t) c_int;
219pub extern "c" fn pthread_mutex_destroy(mutex: *pthread_mutex_t) c_int;
220
221pub const PTHREAD_COND_INITIALIZER = pthread_cond_t{};
222pub extern "c" fn pthread_cond_wait(noalias cond: *pthread_cond_t, noalias mutex: *pthread_mutex_t) c_int;
223pub extern "c" fn pthread_cond_signal(cond: *pthread_cond_t) c_int;
224pub extern "c" fn pthread_cond_destroy(cond: *pthread_cond_t) c_int;
225
226pub const pthread_t = *@OpaqueType();
227pub const FILE = @OpaqueType();
lib/std/c/darwin.zig+17-1
...@@ -53,7 +53,7 @@ pub extern "c" fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clo...@@ -53,7 +53,7 @@ pub extern "c" fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clo
53pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;53pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;
5454
55pub fn sigaddset(set: *sigset_t, signo: u5) void {55pub fn sigaddset(set: *sigset_t, signo: u5) void {
56 set.* |= u32(1) << (signo - 1);56 set.* |= @as(u32, 1) << (signo - 1);
57}57}
5858
59pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;59pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
...@@ -112,3 +112,19 @@ pub const EAI_PROTOCOL = 13;...@@ -112,3 +112,19 @@ pub const EAI_PROTOCOL = 13;
112/// argument buffer overflow112/// argument buffer overflow
113pub const EAI_OVERFLOW = 14;113pub const EAI_OVERFLOW = 14;
114pub const EAI_MAX = 15;114pub const EAI_MAX = 15;
115
116pub const pthread_mutex_t = extern struct {
117 __sig: c_long = 0x32AAABA7,
118 __opaque: [__PTHREAD_MUTEX_SIZE__]u8 = [_]u8{0} ** __PTHREAD_MUTEX_SIZE__,
119};
120pub const pthread_cond_t = extern struct {
121 __sig: c_long = 0x3CB0B1BB,
122 __opaque: [__PTHREAD_COND_SIZE__]u8 = [_]u8{0} ** __PTHREAD_COND_SIZE__,
123};
124const __PTHREAD_MUTEX_SIZE__ = if (@sizeOf(usize) == 8) 56 else 40;
125const __PTHREAD_COND_SIZE__ = if (@sizeOf(usize) == 8) 40 else 24;
126
127pub const pthread_attr_t = extern struct {
128 __sig: c_long,
129 __opaque: [56]u8,
130};
lib/std/c/dragonfly.zig+12-1
...@@ -1,6 +1,5 @@...@@ -1,6 +1,5 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2usingnamespace std.c;2usingnamespace std.c;
3
4extern "c" threadlocal var errno: c_int;3extern "c" threadlocal var errno: c_int;
5pub fn _errno() *c_int {4pub fn _errno() *c_int {
6 return &errno;5 return &errno;
...@@ -12,3 +11,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize...@@ -12,3 +11,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize
1211
13pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;12pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
14pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;13pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
14
15pub const pthread_mutex_t = extern struct {
16 inner: ?*c_void = null,
17};
18pub const pthread_cond_t = extern struct {
19 inner: ?*c_void = null,
20};
21
22pub const pthread_attr_t = extern struct { // copied from freebsd
23 __size: [56]u8,
24 __align: c_long,
25};
lib/std/c/emscripten.zig created+8
...@@ -0,0 +1,8 @@
1pub const pthread_mutex_t = extern struct {
2 size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(4) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
3};
4pub const pthread_cond_t = extern struct {
5 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
6};
7const __SIZEOF_PTHREAD_COND_T = 48;
8const __SIZEOF_PTHREAD_MUTEX_T = 28;
lib/std/c/freebsd.zig+12
...@@ -10,3 +10,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize...@@ -10,3 +10,15 @@ pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize
1010
11pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;11pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
12pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;12pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
13
14pub const pthread_mutex_t = extern struct {
15 inner: ?*c_void = null,
16};
17pub const pthread_cond_t = extern struct {
18 inner: ?*c_void = null,
19};
20
21pub const pthread_attr_t = extern struct {
22 __size: [56]u8,
23 __align: c_long,
24};
lib/std/c/fuchsia.zig created+8
...@@ -0,0 +1,8 @@
1pub const pthread_mutex_t = extern struct {
2 size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
3};
4pub const pthread_cond_t = extern struct {
5 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
6};
7const __SIZEOF_PTHREAD_COND_T = 48;
8const __SIZEOF_PTHREAD_MUTEX_T = 40;
lib/std/c/haiku.zig created+14
...@@ -0,0 +1,14 @@
1pub const pthread_mutex_t = extern struct {
2 flags: u32 = 0,
3 lock: i32 = 0,
4 unused: i32 = -42,
5 owner: i32 = -1,
6 owner_count: i32 = 0,
7};
8pub const pthread_cond_t = extern struct {
9 flags: u32 = 0,
10 unused: i32 = -42,
11 mutex: ?*c_void = null,
12 waiter_count: i32 = 0,
13 lock: i32 = 0,
14};
lib/std/c/hermit.zig created+6
...@@ -0,0 +1,6 @@
1pub const pthread_mutex_t = extern struct {
2 inner: usize = ~usize(0),
3};
4pub const pthread_cond_t = extern struct {
5 inner: usize = ~usize(0),
6};
lib/std/c/linux.zig+23
...@@ -75,3 +75,26 @@ pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize...@@ -75,3 +75,26 @@ pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize
75pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;75pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
7676
77pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;77pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
78
79pub const pthread_attr_t = extern struct {
80 __size: [56]u8,
81 __align: c_long,
82};
83
84pub const pthread_mutex_t = extern struct {
85 size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
86};
87pub const pthread_cond_t = extern struct {
88 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
89};
90const __SIZEOF_PTHREAD_COND_T = 48;
91const __SIZEOF_PTHREAD_MUTEX_T = if (builtin.os == .fuchsia) 40 else switch (builtin.abi) {
92 .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
93 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
94 .aarch64 => 48,
95 .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
96 .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
97 else => if (@sizeOf(usize) == 8) 40 else 24,
98 },
99 else => unreachable,
100};
lib/std/c/minix.zig created+18
...@@ -0,0 +1,18 @@
1const builtin = @import("builtin");
2pub const pthread_mutex_t = extern struct {
3 size: [__SIZEOF_PTHREAD_MUTEX_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_MUTEX_T,
4};
5pub const pthread_cond_t = extern struct {
6 size: [__SIZEOF_PTHREAD_COND_T]u8 align(@alignOf(usize)) = [_]u8{0} ** __SIZEOF_PTHREAD_COND_T,
7};
8const __SIZEOF_PTHREAD_COND_T = 48;
9const __SIZEOF_PTHREAD_MUTEX_T = switch (builtin.abi) {
10 .musl, .musleabi, .musleabihf => if (@sizeOf(usize) == 8) 40 else 24,
11 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => switch (builtin.arch) {
12 .aarch64 => 48,
13 .x86_64 => if (builtin.abi == .gnux32) 40 else 32,
14 .mips64, .powerpc64, .powerpc64le, .sparcv9 => 40,
15 else => if (@sizeOf(usize) == 8) 40 else 24,
16 },
17 else => unreachable,
18};
lib/std/c/netbsd.zig+29
...@@ -6,3 +6,32 @@ pub const _errno = __errno;...@@ -6,3 +6,32 @@ pub const _errno = __errno;
66
7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;8pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
9
10pub const pthread_mutex_t = extern struct {
11 ptm_magic: c_uint = 0x33330003,
12 ptm_errorcheck: padded_spin_t = 0,
13 ptm_unused: padded_spin_t = 0,
14 ptm_owner: usize = 0,
15 ptm_waiters: ?*u8 = null,
16 ptm_recursed: c_uint = 0,
17 ptm_spare2: ?*c_void = null,
18};
19pub const pthread_cond_t = extern struct {
20 ptc_magic: c_uint = 0x55550005,
21 ptc_lock: pthread_spin_t = 0,
22 ptc_waiters_first: ?*u8 = null,
23 ptc_waiters_last: ?*u8 = null,
24 ptc_mutex: ?*pthread_mutex_t = null,
25 ptc_private: ?*c_void = null,
26};
27const pthread_spin_t = if (builtin.arch == .arm or .arch == .powerpc) c_int else u8;
28const padded_spin_t = switch (builtin.arch) {
29 .sparc, .sparcel, .sparcv9, .i386, .x86_64, .le64 => u32,
30 else => spin_t,
31};
32
33pub const pthread_attr_t = extern struct {
34 pta_magic: u32,
35 pta_flags: c_int,
36 pta_private: *c_void,
37};
lib/std/c/openbsd.zig created+6
...@@ -0,0 +1,6 @@
1pub const pthread_mutex_t = extern struct {
2 inner: ?*c_void = null,
3};
4pub const pthread_cond_t = extern struct {
5 inner: ?*c_void = null,
6};
lib/std/c/solaris.zig created+15
...@@ -0,0 +1,15 @@
1pub const pthread_mutex_t = extern struct {
2 __pthread_mutex_flag1: u16 = 0,
3 __pthread_mutex_flag2: u8 = 0,
4 __pthread_mutex_ceiling: u8 = 0,
5 __pthread_mutex_type: u16 = 0,
6 __pthread_mutex_magic: u16 = 0x4d58,
7 __pthread_mutex_lock: u64 = 0,
8 __pthread_mutex_data: u64 = 0,
9};
10pub const pthread_cond_t = extern struct {
11 __pthread_cond_flag: u32 = 0,
12 __pthread_cond_type: u16 = 0,
13 __pthread_cond_magic: u16 = 0x4356,
14 __pthread_cond_data: u64 = 0,
15};
lib/std/child_process.zig+78-19
...@@ -50,8 +50,20 @@ pub const ChildProcess = struct {...@@ -50,8 +50,20 @@ pub const ChildProcess = struct {
50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,
5252
53 pub const SpawnError = error{OutOfMemory} || os.ExecveError || os.SetIdError ||53 pub const SpawnError = error{
54 os.ChangeCurDirError || windows.CreateProcessError;54 OutOfMemory,
55
56 /// POSIX-only. `StdIo.Ignore` was selected and opening `/dev/null` returned ENODEV.
57 NoDevice,
58
59 /// Windows-only. One of:
60 /// * `cwd` was provided and it could not be re-encoded into UTF16LE, or
61 /// * The `PATH` or `PATHEXT` environment variable contained invalid UTF-8.
62 InvalidUtf8,
63
64 /// Windows-only. `cwd` was provided, but the path did not exist when spawning the child process.
65 CurrentWorkingDirectoryUnlinked,
66 } || os.ExecveError || os.SetIdError || os.ChangeCurDirError || windows.CreateProcessError || windows.WaitForSingleObjectError;
5567
56 pub const Term = union(enum) {68 pub const Term = union(enum) {
57 Exited: u32,69 Exited: u32,
...@@ -102,7 +114,7 @@ pub const ChildProcess = struct {...@@ -102,7 +114,7 @@ pub const ChildProcess = struct {
102 }114 }
103115
104 /// On success must call `kill` or `wait`.116 /// On success must call `kill` or `wait`.
105 pub fn spawn(self: *ChildProcess) !void {117 pub fn spawn(self: *ChildProcess) SpawnError!void {
106 if (builtin.os == .windows) {118 if (builtin.os == .windows) {
107 return self.spawnWindows();119 return self.spawnWindows();
108 } else {120 } else {
...@@ -110,7 +122,7 @@ pub const ChildProcess = struct {...@@ -110,7 +122,7 @@ pub const ChildProcess = struct {
110 }122 }
111 }123 }
112124
113 pub fn spawnAndWait(self: *ChildProcess) !Term {125 pub fn spawnAndWait(self: *ChildProcess) SpawnError!Term {
114 try self.spawn();126 try self.spawn();
115 return self.wait();127 return self.wait();
116 }128 }
...@@ -162,7 +174,13 @@ pub const ChildProcess = struct {...@@ -162,7 +174,13 @@ pub const ChildProcess = struct {
162174
163 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.175 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
164 /// If it succeeds, the caller owns result.stdout and result.stderr memory.176 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
165 pub fn exec(allocator: *mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, env_map: ?*const BufMap, max_output_size: usize) !ExecResult {177 pub fn exec(
178 allocator: *mem.Allocator,
179 argv: []const []const u8,
180 cwd: ?[]const u8,
181 env_map: ?*const BufMap,
182 max_output_size: usize,
183 ) !ExecResult {
166 const child = try ChildProcess.init(argv, allocator);184 const child = try ChildProcess.init(argv, allocator);
167 defer child.deinit();185 defer child.deinit();
168186
...@@ -219,7 +237,7 @@ pub const ChildProcess = struct {...@@ -219,7 +237,7 @@ pub const ChildProcess = struct {
219 fn waitUnwrappedWindows(self: *ChildProcess) !void {237 fn waitUnwrappedWindows(self: *ChildProcess) !void {
220 const result = windows.WaitForSingleObject(self.handle, windows.INFINITE);238 const result = windows.WaitForSingleObject(self.handle, windows.INFINITE);
221239
222 self.term = (SpawnError!Term)(x: {240 self.term = @as(SpawnError!Term, x: {
223 var exit_code: windows.DWORD = undefined;241 var exit_code: windows.DWORD = undefined;
224 if (windows.kernel32.GetExitCodeProcess(self.handle, &exit_code) == 0) {242 if (windows.kernel32.GetExitCodeProcess(self.handle, &exit_code) == 0) {
225 break :x Term{ .Unknown = 0 };243 break :x Term{ .Unknown = 0 };
...@@ -292,7 +310,7 @@ pub const ChildProcess = struct {...@@ -292,7 +310,7 @@ pub const ChildProcess = struct {
292 Term{ .Unknown = status };310 Term{ .Unknown = status };
293 }311 }
294312
295 fn spawnPosix(self: *ChildProcess) !void {313 fn spawnPosix(self: *ChildProcess) SpawnError!void {
296 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe() else undefined;314 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe() else undefined;
297 errdefer if (self.stdin_behavior == StdIo.Pipe) {315 errdefer if (self.stdin_behavior == StdIo.Pipe) {
298 destroyPipe(stdin_pipe);316 destroyPipe(stdin_pipe);
...@@ -309,7 +327,16 @@ pub const ChildProcess = struct {...@@ -309,7 +327,16 @@ pub const ChildProcess = struct {
309 };327 };
310328
311 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);329 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
312 const dev_null_fd = if (any_ignore) try os.openC(c"/dev/null", os.O_RDWR, 0) else undefined;330 const dev_null_fd = if (any_ignore)
331 os.openC(c"/dev/null", os.O_RDWR, 0) catch |err| switch (err) {
332 error.PathAlreadyExists => unreachable,
333 error.NoSpaceLeft => unreachable,
334 error.FileTooBig => unreachable,
335 error.DeviceBusy => unreachable,
336 else => |e| return e,
337 }
338 else
339 undefined;
313 defer {340 defer {
314 if (any_ignore) os.close(dev_null_fd);341 if (any_ignore) os.close(dev_null_fd);
315 }342 }
...@@ -403,7 +430,7 @@ pub const ChildProcess = struct {...@@ -403,7 +430,7 @@ pub const ChildProcess = struct {
403 }430 }
404 }431 }
405432
406 fn spawnWindows(self: *ChildProcess) !void {433 fn spawnWindows(self: *ChildProcess) SpawnError!void {
407 const saAttr = windows.SECURITY_ATTRIBUTES{434 const saAttr = windows.SECURITY_ATTRIBUTES{
408 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),435 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
409 .bInheritHandle = windows.TRUE,436 .bInheritHandle = windows.TRUE,
...@@ -412,11 +439,28 @@ pub const ChildProcess = struct {...@@ -412,11 +439,28 @@ pub const ChildProcess = struct {
412439
413 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);440 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
414441
415 const nul_handle = if (any_ignore) blk: {442 const nul_handle = if (any_ignore)
416 break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null);443 windows.CreateFile(
417 } else blk: {444 "NUL",
418 break :blk undefined;445 windows.GENERIC_READ,
419 };446 windows.FILE_SHARE_READ,
447 null,
448 windows.OPEN_EXISTING,
449 windows.FILE_ATTRIBUTE_NORMAL,
450 null,
451 ) catch |err| switch (err) {
452 error.SharingViolation => unreachable, // not possible for "NUL"
453 error.PathAlreadyExists => unreachable, // not possible for "NUL"
454 error.PipeBusy => unreachable, // not possible for "NUL"
455 error.InvalidUtf8 => unreachable, // not possible for "NUL"
456 error.BadPathName => unreachable, // not possible for "NUL"
457 error.FileNotFound => unreachable, // not possible for "NUL"
458 error.AccessDenied => unreachable, // not possible for "NUL"
459 error.NameTooLong => unreachable, // not possible for "NUL"
460 else => |e| return e,
461 }
462 else
463 undefined;
420 defer {464 defer {
421 if (any_ignore) os.close(nul_handle);465 if (any_ignore) os.close(nul_handle);
422 }466 }
...@@ -542,10 +586,25 @@ pub const ChildProcess = struct {...@@ -542,10 +586,25 @@ pub const ChildProcess = struct {
542 windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {586 windowsCreateProcess(app_name_w.ptr, cmd_line_w.ptr, envp_ptr, cwd_w_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
543 if (no_path_err != error.FileNotFound) return no_path_err;587 if (no_path_err != error.FileNotFound) return no_path_err;
544588
545 const PATH = try process.getEnvVarOwned(self.allocator, "PATH");589 var free_path = true;
546 defer self.allocator.free(PATH);590 const PATH = process.getEnvVarOwned(self.allocator, "PATH") catch |err| switch (err) {
547 const PATHEXT = try process.getEnvVarOwned(self.allocator, "PATHEXT");591 error.EnvironmentVariableNotFound => blk: {
548 defer self.allocator.free(PATHEXT);592 free_path = false;
593 break :blk "";
594 },
595 else => |e| return e,
596 };
597 defer if (free_path) self.allocator.free(PATH);
598
599 var free_path_ext = true;
600 const PATHEXT = process.getEnvVarOwned(self.allocator, "PATHEXT") catch |err| switch (err) {
601 error.EnvironmentVariableNotFound => blk: {
602 free_path_ext = false;
603 break :blk "";
604 },
605 else => |e| return e,
606 };
607 defer if (free_path_ext) self.allocator.free(PATHEXT);
549608
550 var it = mem.tokenize(PATH, ";");609 var it = mem.tokenize(PATH, ";");
551 retry: while (it.next()) |search_path| {610 retry: while (it.next()) |search_path| {
...@@ -717,7 +776,7 @@ fn destroyPipe(pipe: [2]os.fd_t) void {...@@ -717,7 +776,7 @@ fn destroyPipe(pipe: [2]os.fd_t) void {
717// Child of fork calls this to report an error to the fork parent.776// Child of fork calls this to report an error to the fork parent.
718// Then the child exits.777// Then the child exits.
719fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {778fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
720 writeIntFd(fd, ErrInt(@errorToInt(err))) catch {};779 writeIntFd(fd, @as(ErrInt, @errorToInt(err))) catch {};
721 os.exit(1);780 os.exit(1);
722}781}
723782
lib/std/coff.zig+1-1
...@@ -179,7 +179,7 @@ pub const Coff = struct {...@@ -179,7 +179,7 @@ pub const Coff = struct {
179 if (byte != 0 and i == buffer.len)179 if (byte != 0 and i == buffer.len)
180 return error.NameTooLong;180 return error.NameTooLong;
181181
182 return i;182 return @as(usize, i);
183 }183 }
184184
185 pub fn loadSections(self: *Coff) !void {185 pub fn loadSections(self: *Coff) !void {
lib/std/crypto/aes.zig+10-10
...@@ -6,7 +6,7 @@ const testing = std.testing;...@@ -6,7 +6,7 @@ const testing = std.testing;
66
7// Apply sbox0 to each byte in w.7// Apply sbox0 to each byte in w.
8fn subw(w: u32) u32 {8fn subw(w: u32) u32 {
9 return u32(sbox0[w >> 24]) << 24 | u32(sbox0[w >> 16 & 0xff]) << 16 | u32(sbox0[w >> 8 & 0xff]) << 8 | u32(sbox0[w & 0xff]);9 return @as(u32, sbox0[w >> 24]) << 24 | @as(u32, sbox0[w >> 16 & 0xff]) << 16 | @as(u32, sbox0[w >> 8 & 0xff]) << 8 | @as(u32, sbox0[w & 0xff]);
10}10}
1111
12fn rotw(w: u32) u32 {12fn rotw(w: u32) u32 {
...@@ -48,10 +48,10 @@ fn encryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {...@@ -48,10 +48,10 @@ fn encryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {
48 }48 }
4949
50 // Last round uses s-box directly and XORs to produce output.50 // Last round uses s-box directly and XORs to produce output.
51 s0 = u32(sbox0[t0 >> 24]) << 24 | u32(sbox0[t1 >> 16 & 0xff]) << 16 | u32(sbox0[t2 >> 8 & 0xff]) << 8 | u32(sbox0[t3 & 0xff]);51 s0 = @as(u32, sbox0[t0 >> 24]) << 24 | @as(u32, sbox0[t1 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t2 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t3 & 0xff]);
52 s1 = u32(sbox0[t1 >> 24]) << 24 | u32(sbox0[t2 >> 16 & 0xff]) << 16 | u32(sbox0[t3 >> 8 & 0xff]) << 8 | u32(sbox0[t0 & 0xff]);52 s1 = @as(u32, sbox0[t1 >> 24]) << 24 | @as(u32, sbox0[t2 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t3 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t0 & 0xff]);
53 s2 = u32(sbox0[t2 >> 24]) << 24 | u32(sbox0[t3 >> 16 & 0xff]) << 16 | u32(sbox0[t0 >> 8 & 0xff]) << 8 | u32(sbox0[t1 & 0xff]);53 s2 = @as(u32, sbox0[t2 >> 24]) << 24 | @as(u32, sbox0[t3 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t0 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t1 & 0xff]);
54 s3 = u32(sbox0[t3 >> 24]) << 24 | u32(sbox0[t0 >> 16 & 0xff]) << 16 | u32(sbox0[t1 >> 8 & 0xff]) << 8 | u32(sbox0[t2 & 0xff]);54 s3 = @as(u32, sbox0[t3 >> 24]) << 24 | @as(u32, sbox0[t0 >> 16 & 0xff]) << 16 | @as(u32, sbox0[t1 >> 8 & 0xff]) << 8 | @as(u32, sbox0[t2 & 0xff]);
5555
56 s0 ^= xk[k + 0];56 s0 ^= xk[k + 0];
57 s1 ^= xk[k + 1];57 s1 ^= xk[k + 1];
...@@ -99,10 +99,10 @@ pub fn decryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {...@@ -99,10 +99,10 @@ pub fn decryptBlock(xk: []const u32, dst: []u8, src: []const u8) void {
99 }99 }
100100
101 // Last round uses s-box directly and XORs to produce output.101 // Last round uses s-box directly and XORs to produce output.
102 s0 = u32(sbox1[t0 >> 24]) << 24 | u32(sbox1[t3 >> 16 & 0xff]) << 16 | u32(sbox1[t2 >> 8 & 0xff]) << 8 | u32(sbox1[t1 & 0xff]);102 s0 = @as(u32, sbox1[t0 >> 24]) << 24 | @as(u32, sbox1[t3 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t2 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t1 & 0xff]);
103 s1 = u32(sbox1[t1 >> 24]) << 24 | u32(sbox1[t0 >> 16 & 0xff]) << 16 | u32(sbox1[t3 >> 8 & 0xff]) << 8 | u32(sbox1[t2 & 0xff]);103 s1 = @as(u32, sbox1[t1 >> 24]) << 24 | @as(u32, sbox1[t0 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t3 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t2 & 0xff]);
104 s2 = u32(sbox1[t2 >> 24]) << 24 | u32(sbox1[t1 >> 16 & 0xff]) << 16 | u32(sbox1[t0 >> 8 & 0xff]) << 8 | u32(sbox1[t3 & 0xff]);104 s2 = @as(u32, sbox1[t2 >> 24]) << 24 | @as(u32, sbox1[t1 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t0 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t3 & 0xff]);
105 s3 = u32(sbox1[t3 >> 24]) << 24 | u32(sbox1[t2 >> 16 & 0xff]) << 16 | u32(sbox1[t1 >> 8 & 0xff]) << 8 | u32(sbox1[t0 & 0xff]);105 s3 = @as(u32, sbox1[t3 >> 24]) << 24 | @as(u32, sbox1[t2 >> 16 & 0xff]) << 16 | @as(u32, sbox1[t1 >> 8 & 0xff]) << 8 | @as(u32, sbox1[t0 & 0xff]);
106106
107 s0 ^= xk[k + 0];107 s0 ^= xk[k + 0];
108 s1 ^= xk[k + 1];108 s1 ^= xk[k + 1];
...@@ -256,7 +256,7 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {...@@ -256,7 +256,7 @@ fn expandKey(key: []const u8, enc: []u32, dec: []u32) void {
256 while (i < enc.len) : (i += 1) {256 while (i < enc.len) : (i += 1) {
257 var t = enc[i - 1];257 var t = enc[i - 1];
258 if (i % nk == 0) {258 if (i % nk == 0) {
259 t = subw(rotw(t)) ^ (u32(powx[i / nk - 1]) << 24);259 t = subw(rotw(t)) ^ (@as(u32, powx[i / nk - 1]) << 24);
260 } else if (nk > 6 and i % nk == 4) {260 } else if (nk > 6 and i % nk == 4) {
261 t = subw(t);261 t = subw(t);
262 }262 }
lib/std/crypto/benchmark.zig+1-3
...@@ -131,9 +131,7 @@ fn printPad(stdout: var, s: []const u8) !void {...@@ -131,9 +131,7 @@ fn printPad(stdout: var, s: []const u8) !void {
131}131}
132132
133pub fn main() !void {133pub fn main() !void {
134 var stdout_file = try std.io.getStdOut();134 const stdout = &std.io.getStdOut().outStream().stream;
135 var stdout_out_stream = stdout_file.outStream();
136 const stdout = &stdout_out_stream.stream;
137135
138 var buffer: [1024]u8 = undefined;136 var buffer: [1024]u8 = undefined;
139 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);137 var fixed = std.heap.FixedBufferAllocator.init(buffer[0..]);
lib/std/crypto/blake2.zig+8-8
...@@ -164,13 +164,13 @@ fn Blake2s(comptime out_len: usize) type {...@@ -164,13 +164,13 @@ fn Blake2s(comptime out_len: usize) type {
164 inline while (j < 10) : (j += 1) {164 inline while (j < 10) : (j += 1) {
165 inline for (rounds) |r| {165 inline for (rounds) |r| {
166 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];166 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
167 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));167 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], @as(usize, 16));
168 v[r.c] = v[r.c] +% v[r.d];168 v[r.c] = v[r.c] +% v[r.d];
169 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));169 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], @as(usize, 12));
170 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];170 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
171 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));171 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], @as(usize, 8));
172 v[r.c] = v[r.c] +% v[r.d];172 v[r.c] = v[r.c] +% v[r.d];
173 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));173 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], @as(usize, 7));
174 }174 }
175 }175 }
176176
...@@ -398,13 +398,13 @@ fn Blake2b(comptime out_len: usize) type {...@@ -398,13 +398,13 @@ fn Blake2b(comptime out_len: usize) type {
398 inline while (j < 12) : (j += 1) {398 inline while (j < 12) : (j += 1) {
399 inline for (rounds) |r| {399 inline for (rounds) |r| {
400 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];400 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
401 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));401 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], @as(usize, 32));
402 v[r.c] = v[r.c] +% v[r.d];402 v[r.c] = v[r.c] +% v[r.d];
403 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));403 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], @as(usize, 24));
404 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];404 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
405 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));405 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], @as(usize, 16));
406 v[r.c] = v[r.c] +% v[r.d];406 v[r.c] = v[r.c] +% v[r.d];
407 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));407 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], @as(usize, 63));
408 }408 }
409 }409 }
410410
lib/std/crypto/chacha20.zig+4-4
...@@ -49,13 +49,13 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void {...@@ -49,13 +49,13 @@ fn salsa20_wordtobyte(out: []u8, input: [16]u32) void {
49 // two-round cycles49 // two-round cycles
50 inline for (rounds) |r| {50 inline for (rounds) |r| {
51 x[r.a] +%= x[r.b];51 x[r.a] +%= x[r.b];
52 x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], u32(16));52 x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], @as(u32, 16));
53 x[r.c] +%= x[r.d];53 x[r.c] +%= x[r.d];
54 x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], u32(12));54 x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], @as(u32, 12));
55 x[r.a] +%= x[r.b];55 x[r.a] +%= x[r.b];
56 x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], u32(8));56 x[r.d] = std.math.rotl(u32, x[r.d] ^ x[r.a], @as(u32, 8));
57 x[r.c] +%= x[r.d];57 x[r.c] +%= x[r.d];
58 x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], u32(7));58 x[r.b] = std.math.rotl(u32, x[r.b] ^ x[r.c], @as(u32, 7));
59 }59 }
60 }60 }
6161
lib/std/crypto/gimli.zig+4-4
...@@ -34,9 +34,9 @@ pub const State = struct {...@@ -34,9 +34,9 @@ pub const State = struct {
3434
35 pub fn permute(self: *Self) void {35 pub fn permute(self: *Self) void {
36 const state = &self.data;36 const state = &self.data;
37 var round = u32(24);37 var round = @as(u32, 24);
38 while (round > 0) : (round -= 1) {38 while (round > 0) : (round -= 1) {
39 var column = usize(0);39 var column = @as(usize, 0);
40 while (column < 4) : (column += 1) {40 while (column < 4) : (column += 1) {
41 const x = math.rotl(u32, state[column], 24);41 const x = math.rotl(u32, state[column], 24);
42 const y = math.rotl(u32, state[4 + column], 9);42 const y = math.rotl(u32, state[4 + column], 9);
...@@ -61,7 +61,7 @@ pub const State = struct {...@@ -61,7 +61,7 @@ pub const State = struct {
61 }61 }
6262
63 pub fn squeeze(self: *Self, out: []u8) void {63 pub fn squeeze(self: *Self, out: []u8) void {
64 var i = usize(0);64 var i = @as(usize, 0);
65 while (i + RATE <= out.len) : (i += RATE) {65 while (i + RATE <= out.len) : (i += RATE) {
66 self.permute();66 self.permute();
67 mem.copy(u8, out[i..], self.toSliceConst()[0..RATE]);67 mem.copy(u8, out[i..], self.toSliceConst()[0..RATE]);
...@@ -79,7 +79,7 @@ test "permute" {...@@ -79,7 +79,7 @@ test "permute" {
79 var state = State{79 var state = State{
80 .data = blk: {80 .data = blk: {
81 var input: [12]u32 = undefined;81 var input: [12]u32 = undefined;
82 var i = u32(0);82 var i = @as(u32, 0);
83 while (i < 12) : (i += 1) {83 while (i < 12) : (i += 1) {
84 input[i] = i * i * i + i *% 0x9e3779b9;84 input[i] = i * i * i + i *% 0x9e3779b9;
85 }85 }
lib/std/crypto/md5.zig+4-4
...@@ -126,10 +126,10 @@ pub const Md5 = struct {...@@ -126,10 +126,10 @@ pub const Md5 = struct {
126 while (i < 16) : (i += 1) {126 while (i < 16) : (i += 1) {
127 // NOTE: Performing or's separately improves perf by ~10%127 // NOTE: Performing or's separately improves perf by ~10%
128 s[i] = 0;128 s[i] = 0;
129 s[i] |= u32(b[i * 4 + 0]);129 s[i] |= @as(u32, b[i * 4 + 0]);
130 s[i] |= u32(b[i * 4 + 1]) << 8;130 s[i] |= @as(u32, b[i * 4 + 1]) << 8;
131 s[i] |= u32(b[i * 4 + 2]) << 16;131 s[i] |= @as(u32, b[i * 4 + 2]) << 16;
132 s[i] |= u32(b[i * 4 + 3]) << 24;132 s[i] |= @as(u32, b[i * 4 + 3]) << 24;
133 }133 }
134134
135 var v: [4]u32 = [_]u32{135 var v: [4]u32 = [_]u32{
lib/std/crypto/poly1305.zig+6-6
...@@ -87,11 +87,11 @@ pub const Poly1305 = struct {...@@ -87,11 +87,11 @@ pub const Poly1305 = struct {
87 // ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff87 // ctx->h <= 4_ffffffff_ffffffff_ffffffff_ffffffff
88 fn polyBlock(ctx: *Self) void {88 fn polyBlock(ctx: *Self) void {
89 // s = h + c, without carry propagation89 // s = h + c, without carry propagation
90 const s0 = u64(ctx.h[0]) + ctx.c[0]; // s0 <= 1_fffffffe90 const s0 = @as(u64, ctx.h[0]) + ctx.c[0]; // s0 <= 1_fffffffe
91 const s1 = u64(ctx.h[1]) + ctx.c[1]; // s1 <= 1_fffffffe91 const s1 = @as(u64, ctx.h[1]) + ctx.c[1]; // s1 <= 1_fffffffe
92 const s2 = u64(ctx.h[2]) + ctx.c[2]; // s2 <= 1_fffffffe92 const s2 = @as(u64, ctx.h[2]) + ctx.c[2]; // s2 <= 1_fffffffe
93 const s3 = u64(ctx.h[3]) + ctx.c[3]; // s3 <= 1_fffffffe93 const s3 = @as(u64, ctx.h[3]) + ctx.c[3]; // s3 <= 1_fffffffe
94 const s4 = u64(ctx.h[4]) + ctx.c[4]; // s4 <= 594 const s4 = @as(u64, ctx.h[4]) + ctx.c[4]; // s4 <= 5
9595
96 // Local all the things!96 // Local all the things!
97 const r0 = ctx.r[0]; // r0 <= 0fffffff97 const r0 = ctx.r[0]; // r0 <= 0fffffff
...@@ -197,7 +197,7 @@ pub const Poly1305 = struct {...@@ -197,7 +197,7 @@ pub const Poly1305 = struct {
197197
198 // check if we should subtract 2^130-5 by performing the198 // check if we should subtract 2^130-5 by performing the
199 // corresponding carry propagation.199 // corresponding carry propagation.
200 const _u0 = u64(5) + ctx.h[0]; // <= 1_00000004200 const _u0 = @as(u64, 5) + ctx.h[0]; // <= 1_00000004
201 const _u1 = (_u0 >> 32) + ctx.h[1]; // <= 1_00000000201 const _u1 = (_u0 >> 32) + ctx.h[1]; // <= 1_00000000
202 const _u2 = (_u1 >> 32) + ctx.h[2]; // <= 1_00000000202 const _u2 = (_u1 >> 32) + ctx.h[2]; // <= 1_00000000
203 const _u3 = (_u2 >> 32) + ctx.h[3]; // <= 1_00000000203 const _u3 = (_u2 >> 32) + ctx.h[3]; // <= 1_00000000
lib/std/crypto/sha1.zig+15-15
...@@ -146,10 +146,10 @@ pub const Sha1 = struct {...@@ -146,10 +146,10 @@ pub const Sha1 = struct {
146 Rp(0, 1, 2, 3, 4, 15),146 Rp(0, 1, 2, 3, 4, 15),
147 };147 };
148 inline for (round0a) |r| {148 inline for (round0a) |r| {
149 s[r.i] = (u32(b[r.i * 4 + 0]) << 24) | (u32(b[r.i * 4 + 1]) << 16) | (u32(b[r.i * 4 + 2]) << 8) | (u32(b[r.i * 4 + 3]) << 0);149 s[r.i] = (@as(u32, b[r.i * 4 + 0]) << 24) | (@as(u32, b[r.i * 4 + 1]) << 16) | (@as(u32, b[r.i * 4 + 2]) << 8) | (@as(u32, b[r.i * 4 + 3]) << 0);
150150
151 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));151 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
152 v[r.b] = math.rotl(u32, v[r.b], u32(30));152 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
153 }153 }
154154
155 const round0b = comptime [_]RoundParam{155 const round0b = comptime [_]RoundParam{
...@@ -160,10 +160,10 @@ pub const Sha1 = struct {...@@ -160,10 +160,10 @@ pub const Sha1 = struct {
160 };160 };
161 inline for (round0b) |r| {161 inline for (round0b) |r| {
162 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];162 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
163 s[r.i & 0xf] = math.rotl(u32, t, u32(1));163 s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
164164
165 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));165 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x5A827999 +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) | (~v[r.b] & v[r.d]));
166 v[r.b] = math.rotl(u32, v[r.b], u32(30));166 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
167 }167 }
168168
169 const round1 = comptime [_]RoundParam{169 const round1 = comptime [_]RoundParam{
...@@ -190,10 +190,10 @@ pub const Sha1 = struct {...@@ -190,10 +190,10 @@ pub const Sha1 = struct {
190 };190 };
191 inline for (round1) |r| {191 inline for (round1) |r| {
192 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];192 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
193 s[r.i & 0xf] = math.rotl(u32, t, u32(1));193 s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
194194
195 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);195 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x6ED9EBA1 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
196 v[r.b] = math.rotl(u32, v[r.b], u32(30));196 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
197 }197 }
198198
199 const round2 = comptime [_]RoundParam{199 const round2 = comptime [_]RoundParam{
...@@ -220,10 +220,10 @@ pub const Sha1 = struct {...@@ -220,10 +220,10 @@ pub const Sha1 = struct {
220 };220 };
221 inline for (round2) |r| {221 inline for (round2) |r| {
222 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];222 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
223 s[r.i & 0xf] = math.rotl(u32, t, u32(1));223 s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
224224
225 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));225 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0x8F1BBCDC +% s[r.i & 0xf] +% ((v[r.b] & v[r.c]) ^ (v[r.b] & v[r.d]) ^ (v[r.c] & v[r.d]));
226 v[r.b] = math.rotl(u32, v[r.b], u32(30));226 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
227 }227 }
228228
229 const round3 = comptime [_]RoundParam{229 const round3 = comptime [_]RoundParam{
...@@ -250,10 +250,10 @@ pub const Sha1 = struct {...@@ -250,10 +250,10 @@ pub const Sha1 = struct {
250 };250 };
251 inline for (round3) |r| {251 inline for (round3) |r| {
252 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];252 const t = s[(r.i - 3) & 0xf] ^ s[(r.i - 8) & 0xf] ^ s[(r.i - 14) & 0xf] ^ s[(r.i - 16) & 0xf];
253 s[r.i & 0xf] = math.rotl(u32, t, u32(1));253 s[r.i & 0xf] = math.rotl(u32, t, @as(u32, 1));
254254
255 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], u32(5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);255 v[r.e] = v[r.e] +% math.rotl(u32, v[r.a], @as(u32, 5)) +% 0xCA62C1D6 +% s[r.i & 0xf] +% (v[r.b] ^ v[r.c] ^ v[r.d]);
256 v[r.b] = math.rotl(u32, v[r.b], u32(30));256 v[r.b] = math.rotl(u32, v[r.b], @as(u32, 30));
257 }257 }
258258
259 d.s[0] +%= v[0];259 d.s[0] +%= v[0];
lib/std/crypto/sha2.zig+20-18
...@@ -180,13 +180,13 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -180,13 +180,13 @@ fn Sha2_32(comptime params: Sha2Params32) type {
180 var i: usize = 0;180 var i: usize = 0;
181 while (i < 16) : (i += 1) {181 while (i < 16) : (i += 1) {
182 s[i] = 0;182 s[i] = 0;
183 s[i] |= u32(b[i * 4 + 0]) << 24;183 s[i] |= @as(u32, b[i * 4 + 0]) << 24;
184 s[i] |= u32(b[i * 4 + 1]) << 16;184 s[i] |= @as(u32, b[i * 4 + 1]) << 16;
185 s[i] |= u32(b[i * 4 + 2]) << 8;185 s[i] |= @as(u32, b[i * 4 + 2]) << 8;
186 s[i] |= u32(b[i * 4 + 3]) << 0;186 s[i] |= @as(u32, b[i * 4 + 3]) << 0;
187 }187 }
188 while (i < 64) : (i += 1) {188 while (i < 64) : (i += 1) {
189 s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u32, s[i - 15], u32(7)) ^ math.rotr(u32, s[i - 15], u32(18)) ^ (s[i - 15] >> 3)) +% (math.rotr(u32, s[i - 2], u32(17)) ^ math.rotr(u32, s[i - 2], u32(19)) ^ (s[i - 2] >> 10));189 s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u32, s[i - 15], @as(u32, 7)) ^ math.rotr(u32, s[i - 15], @as(u32, 18)) ^ (s[i - 15] >> 3)) +% (math.rotr(u32, s[i - 2], @as(u32, 17)) ^ math.rotr(u32, s[i - 2], @as(u32, 19)) ^ (s[i - 2] >> 10));
190 }190 }
191191
192 var v: [8]u32 = [_]u32{192 var v: [8]u32 = [_]u32{
...@@ -267,11 +267,11 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -267,11 +267,11 @@ fn Sha2_32(comptime params: Sha2Params32) type {
267 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),267 Rp256(1, 2, 3, 4, 5, 6, 7, 0, 63, 0xC67178F2),
268 };268 };
269 inline for (round0) |r| {269 inline for (round0) |r| {
270 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], u32(6)) ^ math.rotr(u32, v[r.e], u32(11)) ^ math.rotr(u32, v[r.e], u32(25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];270 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.e], @as(u32, 6)) ^ math.rotr(u32, v[r.e], @as(u32, 11)) ^ math.rotr(u32, v[r.e], @as(u32, 25))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
271271
272 v[r.d] = v[r.d] +% v[r.h];272 v[r.d] = v[r.d] +% v[r.h];
273273
274 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.a], u32(2)) ^ math.rotr(u32, v[r.a], u32(13)) ^ math.rotr(u32, v[r.a], u32(22))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));274 v[r.h] = v[r.h] +% (math.rotr(u32, v[r.a], @as(u32, 2)) ^ math.rotr(u32, v[r.a], @as(u32, 13)) ^ math.rotr(u32, v[r.a], @as(u32, 22))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
275 }275 }
276276
277 d.s[0] +%= v[0];277 d.s[0] +%= v[0];
...@@ -522,17 +522,19 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -522,17 +522,19 @@ fn Sha2_64(comptime params: Sha2Params64) type {
522 var i: usize = 0;522 var i: usize = 0;
523 while (i < 16) : (i += 1) {523 while (i < 16) : (i += 1) {
524 s[i] = 0;524 s[i] = 0;
525 s[i] |= u64(b[i * 8 + 0]) << 56;525 s[i] |= @as(u64, b[i * 8 + 0]) << 56;
526 s[i] |= u64(b[i * 8 + 1]) << 48;526 s[i] |= @as(u64, b[i * 8 + 1]) << 48;
527 s[i] |= u64(b[i * 8 + 2]) << 40;527 s[i] |= @as(u64, b[i * 8 + 2]) << 40;
528 s[i] |= u64(b[i * 8 + 3]) << 32;528 s[i] |= @as(u64, b[i * 8 + 3]) << 32;
529 s[i] |= u64(b[i * 8 + 4]) << 24;529 s[i] |= @as(u64, b[i * 8 + 4]) << 24;
530 s[i] |= u64(b[i * 8 + 5]) << 16;530 s[i] |= @as(u64, b[i * 8 + 5]) << 16;
531 s[i] |= u64(b[i * 8 + 6]) << 8;531 s[i] |= @as(u64, b[i * 8 + 6]) << 8;
532 s[i] |= u64(b[i * 8 + 7]) << 0;532 s[i] |= @as(u64, b[i * 8 + 7]) << 0;
533 }533 }
534 while (i < 80) : (i += 1) {534 while (i < 80) : (i += 1) {
535 s[i] = s[i - 16] +% s[i - 7] +% (math.rotr(u64, s[i - 15], u64(1)) ^ math.rotr(u64, s[i - 15], u64(8)) ^ (s[i - 15] >> 7)) +% (math.rotr(u64, s[i - 2], u64(19)) ^ math.rotr(u64, s[i - 2], u64(61)) ^ (s[i - 2] >> 6));535 s[i] = s[i - 16] +% s[i - 7] +%
536 (math.rotr(u64, s[i - 15], @as(u64, 1)) ^ math.rotr(u64, s[i - 15], @as(u64, 8)) ^ (s[i - 15] >> 7)) +%
537 (math.rotr(u64, s[i - 2], @as(u64, 19)) ^ math.rotr(u64, s[i - 2], @as(u64, 61)) ^ (s[i - 2] >> 6));
536 }538 }
537539
538 var v: [8]u64 = [_]u64{540 var v: [8]u64 = [_]u64{
...@@ -629,11 +631,11 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -629,11 +631,11 @@ fn Sha2_64(comptime params: Sha2Params64) type {
629 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),631 Rp512(1, 2, 3, 4, 5, 6, 7, 0, 79, 0x6C44198C4A475817),
630 };632 };
631 inline for (round0) |r| {633 inline for (round0) |r| {
632 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], u64(14)) ^ math.rotr(u64, v[r.e], u64(18)) ^ math.rotr(u64, v[r.e], u64(41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];634 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.e], @as(u64, 14)) ^ math.rotr(u64, v[r.e], @as(u64, 18)) ^ math.rotr(u64, v[r.e], @as(u64, 41))) +% (v[r.g] ^ (v[r.e] & (v[r.f] ^ v[r.g]))) +% r.k +% s[r.i];
633635
634 v[r.d] = v[r.d] +% v[r.h];636 v[r.d] = v[r.d] +% v[r.h];
635637
636 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.a], u64(28)) ^ math.rotr(u64, v[r.a], u64(34)) ^ math.rotr(u64, v[r.a], u64(39))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));638 v[r.h] = v[r.h] +% (math.rotr(u64, v[r.a], @as(u64, 28)) ^ math.rotr(u64, v[r.a], @as(u64, 34)) ^ math.rotr(u64, v[r.a], @as(u64, 39))) +% ((v[r.a] & (v[r.b] | v[r.c])) | (v[r.b] & v[r.c]));
637 }639 }
638640
639 d.s[0] +%= v[0];641 d.s[0] +%= v[0];
lib/std/crypto/sha3.zig+1-1
...@@ -133,7 +133,7 @@ fn keccak_f(comptime F: usize, d: []u8) void {...@@ -133,7 +133,7 @@ fn keccak_f(comptime F: usize, d: []u8) void {
133 }133 }
134 x = 0;134 x = 0;
135 inline while (x < 5) : (x += 1) {135 inline while (x < 5) : (x += 1) {
136 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], usize(1));136 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], @as(usize, 1));
137 y = 0;137 y = 0;
138 inline while (y < 5) : (y += 1) {138 inline while (y < 5) : (y += 1) {
139 s[x + y * 5] ^= t[0];139 s[x + y * 5] ^= t[0];
lib/std/crypto/x25519.zig+33-33
...@@ -199,9 +199,9 @@ const Fe = struct {...@@ -199,9 +199,9 @@ const Fe = struct {
199 inline fn carryRound(c: []i64, t: []i64, comptime i: comptime_int, comptime shift: comptime_int, comptime mult: comptime_int) void {199 inline fn carryRound(c: []i64, t: []i64, comptime i: comptime_int, comptime shift: comptime_int, comptime mult: comptime_int) void {
200 const j = (i + 1) % 10;200 const j = (i + 1) % 10;
201201
202 c[i] = (t[i] + (i64(1) << shift)) >> (shift + 1);202 c[i] = (t[i] + (@as(i64, 1) << shift)) >> (shift + 1);
203 t[j] += c[i] * mult;203 t[j] += c[i] * mult;
204 t[i] -= c[i] * (i64(1) << (shift + 1));204 t[i] -= c[i] * (@as(i64, 1) << (shift + 1));
205 }205 }
206206
207 fn carry1(h: *Fe, t: []i64) void {207 fn carry1(h: *Fe, t: []i64) void {
...@@ -256,15 +256,15 @@ const Fe = struct {...@@ -256,15 +256,15 @@ const Fe = struct {
256 var t: [10]i64 = undefined;256 var t: [10]i64 = undefined;
257257
258 t[0] = readIntSliceLittle(u32, s[0..4]);258 t[0] = readIntSliceLittle(u32, s[0..4]);
259 t[1] = u32(readIntSliceLittle(u24, s[4..7])) << 6;259 t[1] = @as(u32, readIntSliceLittle(u24, s[4..7])) << 6;
260 t[2] = u32(readIntSliceLittle(u24, s[7..10])) << 5;260 t[2] = @as(u32, readIntSliceLittle(u24, s[7..10])) << 5;
261 t[3] = u32(readIntSliceLittle(u24, s[10..13])) << 3;261 t[3] = @as(u32, readIntSliceLittle(u24, s[10..13])) << 3;
262 t[4] = u32(readIntSliceLittle(u24, s[13..16])) << 2;262 t[4] = @as(u32, readIntSliceLittle(u24, s[13..16])) << 2;
263 t[5] = readIntSliceLittle(u32, s[16..20]);263 t[5] = readIntSliceLittle(u32, s[16..20]);
264 t[6] = u32(readIntSliceLittle(u24, s[20..23])) << 7;264 t[6] = @as(u32, readIntSliceLittle(u24, s[20..23])) << 7;
265 t[7] = u32(readIntSliceLittle(u24, s[23..26])) << 5;265 t[7] = @as(u32, readIntSliceLittle(u24, s[23..26])) << 5;
266 t[8] = u32(readIntSliceLittle(u24, s[26..29])) << 4;266 t[8] = @as(u32, readIntSliceLittle(u24, s[26..29])) << 4;
267 t[9] = (u32(readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2;267 t[9] = (@as(u32, readIntSliceLittle(u24, s[29..32])) & 0x7fffff) << 2;
268268
269 carry1(h, t[0..]);269 carry1(h, t[0..]);
270 }270 }
...@@ -273,7 +273,7 @@ const Fe = struct {...@@ -273,7 +273,7 @@ const Fe = struct {
273 var t: [10]i64 = undefined;273 var t: [10]i64 = undefined;
274274
275 for (t[0..]) |_, i| {275 for (t[0..]) |_, i| {
276 t[i] = i64(f.b[i]) * g;276 t[i] = @as(i64, f.b[i]) * g;
277 }277 }
278278
279 carry1(h, t[0..]);279 carry1(h, t[0..]);
...@@ -305,16 +305,16 @@ const Fe = struct {...@@ -305,16 +305,16 @@ const Fe = struct {
305 // t's become h305 // t's become h
306 var t: [10]i64 = undefined;306 var t: [10]i64 = undefined;
307307
308 t[0] = f[0] * i64(g[0]) + F[1] * i64(G[9]) + f[2] * i64(G[8]) + F[3] * i64(G[7]) + f[4] * i64(G[6]) + F[5] * i64(G[5]) + f[6] * i64(G[4]) + F[7] * i64(G[3]) + f[8] * i64(G[2]) + F[9] * i64(G[1]);308 t[0] = f[0] * @as(i64, g[0]) + F[1] * @as(i64, G[9]) + f[2] * @as(i64, G[8]) + F[3] * @as(i64, G[7]) + f[4] * @as(i64, G[6]) + F[5] * @as(i64, G[5]) + f[6] * @as(i64, G[4]) + F[7] * @as(i64, G[3]) + f[8] * @as(i64, G[2]) + F[9] * @as(i64, G[1]);
309 t[1] = f[0] * i64(g[1]) + f[1] * i64(g[0]) + f[2] * i64(G[9]) + f[3] * i64(G[8]) + f[4] * i64(G[7]) + f[5] * i64(G[6]) + f[6] * i64(G[5]) + f[7] * i64(G[4]) + f[8] * i64(G[3]) + f[9] * i64(G[2]);309 t[1] = f[0] * @as(i64, g[1]) + f[1] * @as(i64, g[0]) + f[2] * @as(i64, G[9]) + f[3] * @as(i64, G[8]) + f[4] * @as(i64, G[7]) + f[5] * @as(i64, G[6]) + f[6] * @as(i64, G[5]) + f[7] * @as(i64, G[4]) + f[8] * @as(i64, G[3]) + f[9] * @as(i64, G[2]);
310 t[2] = f[0] * i64(g[2]) + F[1] * i64(g[1]) + f[2] * i64(g[0]) + F[3] * i64(G[9]) + f[4] * i64(G[8]) + F[5] * i64(G[7]) + f[6] * i64(G[6]) + F[7] * i64(G[5]) + f[8] * i64(G[4]) + F[9] * i64(G[3]);310 t[2] = f[0] * @as(i64, g[2]) + F[1] * @as(i64, g[1]) + f[2] * @as(i64, g[0]) + F[3] * @as(i64, G[9]) + f[4] * @as(i64, G[8]) + F[5] * @as(i64, G[7]) + f[6] * @as(i64, G[6]) + F[7] * @as(i64, G[5]) + f[8] * @as(i64, G[4]) + F[9] * @as(i64, G[3]);
311 t[3] = f[0] * i64(g[3]) + f[1] * i64(g[2]) + f[2] * i64(g[1]) + f[3] * i64(g[0]) + f[4] * i64(G[9]) + f[5] * i64(G[8]) + f[6] * i64(G[7]) + f[7] * i64(G[6]) + f[8] * i64(G[5]) + f[9] * i64(G[4]);311 t[3] = f[0] * @as(i64, g[3]) + f[1] * @as(i64, g[2]) + f[2] * @as(i64, g[1]) + f[3] * @as(i64, g[0]) + f[4] * @as(i64, G[9]) + f[5] * @as(i64, G[8]) + f[6] * @as(i64, G[7]) + f[7] * @as(i64, G[6]) + f[8] * @as(i64, G[5]) + f[9] * @as(i64, G[4]);
312 t[4] = f[0] * i64(g[4]) + F[1] * i64(g[3]) + f[2] * i64(g[2]) + F[3] * i64(g[1]) + f[4] * i64(g[0]) + F[5] * i64(G[9]) + f[6] * i64(G[8]) + F[7] * i64(G[7]) + f[8] * i64(G[6]) + F[9] * i64(G[5]);312 t[4] = f[0] * @as(i64, g[4]) + F[1] * @as(i64, g[3]) + f[2] * @as(i64, g[2]) + F[3] * @as(i64, g[1]) + f[4] * @as(i64, g[0]) + F[5] * @as(i64, G[9]) + f[6] * @as(i64, G[8]) + F[7] * @as(i64, G[7]) + f[8] * @as(i64, G[6]) + F[9] * @as(i64, G[5]);
313 t[5] = f[0] * i64(g[5]) + f[1] * i64(g[4]) + f[2] * i64(g[3]) + f[3] * i64(g[2]) + f[4] * i64(g[1]) + f[5] * i64(g[0]) + f[6] * i64(G[9]) + f[7] * i64(G[8]) + f[8] * i64(G[7]) + f[9] * i64(G[6]);313 t[5] = f[0] * @as(i64, g[5]) + f[1] * @as(i64, g[4]) + f[2] * @as(i64, g[3]) + f[3] * @as(i64, g[2]) + f[4] * @as(i64, g[1]) + f[5] * @as(i64, g[0]) + f[6] * @as(i64, G[9]) + f[7] * @as(i64, G[8]) + f[8] * @as(i64, G[7]) + f[9] * @as(i64, G[6]);
314 t[6] = f[0] * i64(g[6]) + F[1] * i64(g[5]) + f[2] * i64(g[4]) + F[3] * i64(g[3]) + f[4] * i64(g[2]) + F[5] * i64(g[1]) + f[6] * i64(g[0]) + F[7] * i64(G[9]) + f[8] * i64(G[8]) + F[9] * i64(G[7]);314 t[6] = f[0] * @as(i64, g[6]) + F[1] * @as(i64, g[5]) + f[2] * @as(i64, g[4]) + F[3] * @as(i64, g[3]) + f[4] * @as(i64, g[2]) + F[5] * @as(i64, g[1]) + f[6] * @as(i64, g[0]) + F[7] * @as(i64, G[9]) + f[8] * @as(i64, G[8]) + F[9] * @as(i64, G[7]);
315 t[7] = f[0] * i64(g[7]) + f[1] * i64(g[6]) + f[2] * i64(g[5]) + f[3] * i64(g[4]) + f[4] * i64(g[3]) + f[5] * i64(g[2]) + f[6] * i64(g[1]) + f[7] * i64(g[0]) + f[8] * i64(G[9]) + f[9] * i64(G[8]);315 t[7] = f[0] * @as(i64, g[7]) + f[1] * @as(i64, g[6]) + f[2] * @as(i64, g[5]) + f[3] * @as(i64, g[4]) + f[4] * @as(i64, g[3]) + f[5] * @as(i64, g[2]) + f[6] * @as(i64, g[1]) + f[7] * @as(i64, g[0]) + f[8] * @as(i64, G[9]) + f[9] * @as(i64, G[8]);
316 t[8] = f[0] * i64(g[8]) + F[1] * i64(g[7]) + f[2] * i64(g[6]) + F[3] * i64(g[5]) + f[4] * i64(g[4]) + F[5] * i64(g[3]) + f[6] * i64(g[2]) + F[7] * i64(g[1]) + f[8] * i64(g[0]) + F[9] * i64(G[9]);316 t[8] = f[0] * @as(i64, g[8]) + F[1] * @as(i64, g[7]) + f[2] * @as(i64, g[6]) + F[3] * @as(i64, g[5]) + f[4] * @as(i64, g[4]) + F[5] * @as(i64, g[3]) + f[6] * @as(i64, g[2]) + F[7] * @as(i64, g[1]) + f[8] * @as(i64, g[0]) + F[9] * @as(i64, G[9]);
317 t[9] = f[0] * i64(g[9]) + f[1] * i64(g[8]) + f[2] * i64(g[7]) + f[3] * i64(g[6]) + f[4] * i64(g[5]) + f[5] * i64(g[4]) + f[6] * i64(g[3]) + f[7] * i64(g[2]) + f[8] * i64(g[1]) + f[9] * i64(g[0]);317 t[9] = f[0] * @as(i64, g[9]) + f[1] * @as(i64, g[8]) + f[2] * @as(i64, g[7]) + f[3] * @as(i64, g[6]) + f[4] * @as(i64, g[5]) + f[5] * @as(i64, g[4]) + f[6] * @as(i64, g[3]) + f[7] * @as(i64, g[2]) + f[8] * @as(i64, g[1]) + f[9] * @as(i64, g[0]);
318318
319 carry2(h, t[0..]);319 carry2(h, t[0..]);
320 }320 }
...@@ -348,16 +348,16 @@ const Fe = struct {...@@ -348,16 +348,16 @@ const Fe = struct {
348348
349 var t: [10]i64 = undefined;349 var t: [10]i64 = undefined;
350350
351 t[0] = f0 * i64(f0) + f1_2 * i64(f9_38) + f2_2 * i64(f8_19) + f3_2 * i64(f7_38) + f4_2 * i64(f6_19) + f5 * i64(f5_38);351 t[0] = f0 * @as(i64, f0) + f1_2 * @as(i64, f9_38) + f2_2 * @as(i64, f8_19) + f3_2 * @as(i64, f7_38) + f4_2 * @as(i64, f6_19) + f5 * @as(i64, f5_38);
352 t[1] = f0_2 * i64(f1) + f2 * i64(f9_38) + f3_2 * i64(f8_19) + f4 * i64(f7_38) + f5_2 * i64(f6_19);352 t[1] = f0_2 * @as(i64, f1) + f2 * @as(i64, f9_38) + f3_2 * @as(i64, f8_19) + f4 * @as(i64, f7_38) + f5_2 * @as(i64, f6_19);
353 t[2] = f0_2 * i64(f2) + f1_2 * i64(f1) + f3_2 * i64(f9_38) + f4_2 * i64(f8_19) + f5_2 * i64(f7_38) + f6 * i64(f6_19);353 t[2] = f0_2 * @as(i64, f2) + f1_2 * @as(i64, f1) + f3_2 * @as(i64, f9_38) + f4_2 * @as(i64, f8_19) + f5_2 * @as(i64, f7_38) + f6 * @as(i64, f6_19);
354 t[3] = f0_2 * i64(f3) + f1_2 * i64(f2) + f4 * i64(f9_38) + f5_2 * i64(f8_19) + f6 * i64(f7_38);354 t[3] = f0_2 * @as(i64, f3) + f1_2 * @as(i64, f2) + f4 * @as(i64, f9_38) + f5_2 * @as(i64, f8_19) + f6 * @as(i64, f7_38);
355 t[4] = f0_2 * i64(f4) + f1_2 * i64(f3_2) + f2 * i64(f2) + f5_2 * i64(f9_38) + f6_2 * i64(f8_19) + f7 * i64(f7_38);355 t[4] = f0_2 * @as(i64, f4) + f1_2 * @as(i64, f3_2) + f2 * @as(i64, f2) + f5_2 * @as(i64, f9_38) + f6_2 * @as(i64, f8_19) + f7 * @as(i64, f7_38);
356 t[5] = f0_2 * i64(f5) + f1_2 * i64(f4) + f2_2 * i64(f3) + f6 * i64(f9_38) + f7_2 * i64(f8_19);356 t[5] = f0_2 * @as(i64, f5) + f1_2 * @as(i64, f4) + f2_2 * @as(i64, f3) + f6 * @as(i64, f9_38) + f7_2 * @as(i64, f8_19);
357 t[6] = f0_2 * i64(f6) + f1_2 * i64(f5_2) + f2_2 * i64(f4) + f3_2 * i64(f3) + f7_2 * i64(f9_38) + f8 * i64(f8_19);357 t[6] = f0_2 * @as(i64, f6) + f1_2 * @as(i64, f5_2) + f2_2 * @as(i64, f4) + f3_2 * @as(i64, f3) + f7_2 * @as(i64, f9_38) + f8 * @as(i64, f8_19);
358 t[7] = f0_2 * i64(f7) + f1_2 * i64(f6) + f2_2 * i64(f5) + f3_2 * i64(f4) + f8 * i64(f9_38);358 t[7] = f0_2 * @as(i64, f7) + f1_2 * @as(i64, f6) + f2_2 * @as(i64, f5) + f3_2 * @as(i64, f4) + f8 * @as(i64, f9_38);
359 t[8] = f0_2 * i64(f8) + f1_2 * i64(f7_2) + f2_2 * i64(f6) + f3_2 * i64(f5_2) + f4 * i64(f4) + f9 * i64(f9_38);359 t[8] = f0_2 * @as(i64, f8) + f1_2 * @as(i64, f7_2) + f2_2 * @as(i64, f6) + f3_2 * @as(i64, f5_2) + f4 * @as(i64, f4) + f9 * @as(i64, f9_38);
360 t[9] = f0_2 * i64(f9) + f1_2 * i64(f8) + f2_2 * i64(f7) + f3_2 * i64(f6) + f4 * i64(f5_2);360 t[9] = f0_2 * @as(i64, f9) + f1_2 * @as(i64, f8) + f2_2 * @as(i64, f7) + f3_2 * @as(i64, f6) + f4 * @as(i64, f5_2);
361361
362 carry2(h, t[0..]);362 carry2(h, t[0..]);
363 }363 }
...@@ -500,7 +500,7 @@ const Fe = struct {...@@ -500,7 +500,7 @@ const Fe = struct {
500 if (i + 1 < 10) {500 if (i + 1 < 10) {
501 t[i + 1] += c[i];501 t[i + 1] += c[i];
502 }502 }
503 t[i] -= c[i] * (i32(1) << shift);503 t[i] -= c[i] * (@as(i32, 1) << shift);
504 }504 }
505505
506 fn toBytes(s: []u8, h: *const Fe) void {506 fn toBytes(s: []u8, h: *const Fe) void {
...@@ -511,7 +511,7 @@ const Fe = struct {...@@ -511,7 +511,7 @@ const Fe = struct {
511 t[i] = h.b[i];511 t[i] = h.b[i];
512 }512 }
513513
514 var q = (19 * t[9] + ((i32(1) << 24))) >> 25;514 var q = (19 * t[9] + ((@as(i32, 1) << 24))) >> 25;
515 {515 {
516 var i: usize = 0;516 var i: usize = 0;
517 while (i < 5) : (i += 1) {517 while (i < 5) : (i += 1) {
lib/std/debug.zig+31-18
...@@ -45,18 +45,19 @@ var stderr_file_out_stream: File.OutStream = undefined;...@@ -45,18 +45,19 @@ var stderr_file_out_stream: File.OutStream = undefined;
4545
46var stderr_stream: ?*io.OutStream(File.WriteError) = null;46var stderr_stream: ?*io.OutStream(File.WriteError) = null;
47var stderr_mutex = std.Mutex.init();47var stderr_mutex = std.Mutex.init();
48
48pub fn warn(comptime fmt: []const u8, args: ...) void {49pub fn warn(comptime fmt: []const u8, args: ...) void {
49 const held = stderr_mutex.acquire();50 const held = stderr_mutex.acquire();
50 defer held.release();51 defer held.release();
51 const stderr = getStderrStream() catch return;52 const stderr = getStderrStream();
52 stderr.print(fmt, args) catch return;53 stderr.print(fmt, args) catch return;
53}54}
5455
55pub fn getStderrStream() !*io.OutStream(File.WriteError) {56pub fn getStderrStream() *io.OutStream(File.WriteError) {
56 if (stderr_stream) |st| {57 if (stderr_stream) |st| {
57 return st;58 return st;
58 } else {59 } else {
59 stderr_file = try io.getStdErr();60 stderr_file = io.getStdErr();
60 stderr_file_out_stream = stderr_file.outStream();61 stderr_file_out_stream = stderr_file.outStream();
61 const st = &stderr_file_out_stream.stream;62 const st = &stderr_file_out_stream.stream;
62 stderr_stream = st;63 stderr_stream = st;
...@@ -64,6 +65,10 @@ pub fn getStderrStream() !*io.OutStream(File.WriteError) {...@@ -64,6 +65,10 @@ pub fn getStderrStream() !*io.OutStream(File.WriteError) {
64 }65 }
65}66}
6667
68pub fn getStderrMutex() *std.Mutex {
69 return &stderr_mutex;
70}
71
67/// TODO multithreaded awareness72/// TODO multithreaded awareness
68var self_debug_info: ?DebugInfo = null;73var self_debug_info: ?DebugInfo = null;
6974
...@@ -85,7 +90,7 @@ fn wantTtyColor() bool {...@@ -85,7 +90,7 @@ fn wantTtyColor() bool {
85/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.90/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
86/// TODO multithreaded awareness91/// TODO multithreaded awareness
87pub fn dumpCurrentStackTrace(start_addr: ?usize) void {92pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
88 const stderr = getStderrStream() catch return;93 const stderr = getStderrStream();
89 if (builtin.strip_debug_info) {94 if (builtin.strip_debug_info) {
90 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;95 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
91 return;96 return;
...@@ -104,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {...@@ -104,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
104/// unbuffered, and ignores any error returned.109/// unbuffered, and ignores any error returned.
105/// TODO multithreaded awareness110/// TODO multithreaded awareness
106pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {111pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
107 const stderr = getStderrStream() catch return;112 const stderr = getStderrStream();
108 if (builtin.strip_debug_info) {113 if (builtin.strip_debug_info) {
109 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;114 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
110 return;115 return;
...@@ -177,7 +182,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace...@@ -177,7 +182,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace
177/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.182/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
178/// TODO multithreaded awareness183/// TODO multithreaded awareness
179pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {184pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
180 const stderr = getStderrStream() catch return;185 const stderr = getStderrStream();
181 if (builtin.strip_debug_info) {186 if (builtin.strip_debug_info) {
182 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;187 stderr.print("Unable to dump stack trace: debug info stripped\n") catch return;
183 return;188 return;
...@@ -232,7 +237,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c...@@ -232,7 +237,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
232 // which first called panic can finish printing a stack trace.237 // which first called panic can finish printing a stack trace.
233 os.abort();238 os.abort();
234 }239 }
235 const stderr = getStderrStream() catch os.abort();240 const stderr = getStderrStream();
236 stderr.print(format ++ "\n", args) catch os.abort();241 stderr.print(format ++ "\n", args) catch os.abort();
237 if (trace) |t| {242 if (trace) |t| {
238 dumpStackTrace(t.*);243 dumpStackTrace(t.*);
...@@ -1003,7 +1008,7 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {...@@ -1003,7 +1008,7 @@ fn readSparseBitVector(stream: var, allocator: *mem.Allocator) ![]usize {
1003 const word = try stream.readIntLittle(u32);1008 const word = try stream.readIntLittle(u32);
1004 var bit_i: u5 = 0;1009 var bit_i: u5 = 0;
1005 while (true) : (bit_i += 1) {1010 while (true) : (bit_i += 1) {
1006 if (word & (u32(1) << bit_i) != 0) {1011 if (word & (@as(u32, 1) << bit_i) != 0) {
1007 try list.append(word_i * 32 + bit_i);1012 try list.append(word_i * 32 + bit_i);
1008 }1013 }
1009 if (bit_i == maxInt(u5)) break;1014 if (bit_i == maxInt(u5)) break;
...@@ -1551,13 +1556,14 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo...@@ -1551,13 +1556,14 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
15511556
1552// TODO the noasyncs here are workarounds1557// TODO the noasyncs here are workarounds
1553fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {1558fn parseFormValueDwarfOffsetSize(in_stream: var, is_64: bool) !u64 {
1554 return if (is_64) try noasync in_stream.readIntLittle(u64) else u64(try noasync in_stream.readIntLittle(u32));1559 return if (is_64) try noasync in_stream.readIntLittle(u64) else @as(u64, try noasync in_stream.readIntLittle(u32));
1555}1560}
15561561
1557// TODO the noasyncs here are workarounds1562// TODO the noasyncs here are workarounds
1558fn parseFormValueTargetAddrSize(in_stream: var) !u64 {1563fn parseFormValueTargetAddrSize(in_stream: var) !u64 {
1559 if (@sizeOf(usize) == 4) {1564 if (@sizeOf(usize) == 4) {
1560 return u64(try noasync in_stream.readIntLittle(u32));1565 // TODO this cast should not be needed
1566 return @as(u64, try noasync in_stream.readIntLittle(u32));
1561 } else if (@sizeOf(usize) == 8) {1567 } else if (@sizeOf(usize) == 8) {
1562 return noasync in_stream.readIntLittle(u64);1568 return noasync in_stream.readIntLittle(u64);
1563 } else {1569 } else {
...@@ -1705,7 +1711,12 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u...@@ -1705,7 +1711,12 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
1705 const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx);1711 const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx);
17061712
1707 gop.kv.value = MachOFile{1713 gop.kv.value = MachOFile{
1708 .bytes = try std.io.readFileAllocAligned(di.ofiles.allocator, ofile_path, @alignOf(macho.mach_header_64)),1714 .bytes = try std.fs.Dir.cwd().readFileAllocAligned(
1715 di.ofiles.allocator,
1716 ofile_path,
1717 maxInt(usize),
1718 @alignOf(macho.mach_header_64),
1719 ),
1709 .sect_debug_info = null,1720 .sect_debug_info = null,
1710 .sect_debug_line = null,1721 .sect_debug_line = null,
1711 };1722 };
...@@ -1841,7 +1852,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u...@@ -1841,7 +1852,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u
1841 // special opcodes1852 // special opcodes
1842 const adjusted_opcode = opcode - opcode_base;1853 const adjusted_opcode = opcode - opcode_base;
1843 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);1854 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
1844 const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);1855 const inc_line = @as(i32, line_base) + @as(i32, adjusted_opcode % line_range);
1845 prog.line += inc_line;1856 prog.line += inc_line;
1846 prog.address += inc_addr;1857 prog.address += inc_addr;
1847 if (try prog.checkLineMatch()) |info| return info;1858 if (try prog.checkLineMatch()) |info| return info;
...@@ -1908,7 +1919,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr...@@ -1908,7 +1919,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr
1908 if (unit_length == 0) {1919 if (unit_length == 0) {
1909 return error.MissingDebugInfo;1920 return error.MissingDebugInfo;
1910 }1921 }
1911 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));1922 const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
19121923
1913 const version = try di.dwarf_in_stream.readInt(u16, di.endian);1924 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
1914 // TODO support 3 and 51925 // TODO support 3 and 5
...@@ -2007,7 +2018,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr...@@ -2007,7 +2018,7 @@ fn getLineNumberInfoDwarf(di: *DwarfInfo, compile_unit: CompileUnit, target_addr
2007 // special opcodes2018 // special opcodes
2008 const adjusted_opcode = opcode - opcode_base;2019 const adjusted_opcode = opcode - opcode_base;
2009 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);2020 const inc_addr = minimum_instruction_length * (adjusted_opcode / line_range);
2010 const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);2021 const inc_line = @as(i32, line_base) + @as(i32, adjusted_opcode % line_range);
2011 prog.line += inc_line;2022 prog.line += inc_line;
2012 prog.address += inc_addr;2023 prog.address += inc_addr;
2013 if (try prog.checkLineMatch()) |info| return info;2024 if (try prog.checkLineMatch()) |info| return info;
...@@ -2088,7 +2099,7 @@ fn scanAllFunctions(di: *DwarfInfo) !void {...@@ -2088,7 +2099,7 @@ fn scanAllFunctions(di: *DwarfInfo) !void {
2088 var is_64: bool = undefined;2099 var is_64: bool = undefined;
2089 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);2100 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
2090 if (unit_length == 0) return;2101 if (unit_length == 0) return;
2091 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));2102 const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
20922103
2093 const version = try di.dwarf_in_stream.readInt(u16, di.endian);2104 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
2094 if (version < 2 or version > 5) return error.InvalidDebugInfo;2105 if (version < 2 or version > 5) return error.InvalidDebugInfo;
...@@ -2190,7 +2201,7 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {...@@ -2190,7 +2201,7 @@ fn scanAllCompileUnits(di: *DwarfInfo) !void {
2190 var is_64: bool = undefined;2201 var is_64: bool = undefined;
2191 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);2202 const unit_length = try readInitialLength(@typeOf(di.dwarf_in_stream.readFn).ReturnType.ErrorSet, di.dwarf_in_stream, &is_64);
2192 if (unit_length == 0) return;2203 if (unit_length == 0) return;
2193 const next_offset = unit_length + (if (is_64) usize(12) else usize(4));2204 const next_offset = unit_length + (if (is_64) @as(usize, 12) else @as(usize, 4));
21942205
2195 const version = try di.dwarf_in_stream.readInt(u16, di.endian);2206 const version = try di.dwarf_in_stream.readInt(u16, di.endian);
2196 if (version < 2 or version > 5) return error.InvalidDebugInfo;2207 if (version < 2 or version > 5) return error.InvalidDebugInfo;
...@@ -2307,7 +2318,8 @@ fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {...@@ -2307,7 +2318,8 @@ fn readInitialLengthMem(ptr: *[*]const u8, is_64: *bool) !u64 {
2307 } else {2318 } else {
2308 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;2319 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
2309 ptr.* += 4;2320 ptr.* += 4;
2310 return u64(first_32_bits);2321 // TODO this cast should not be needed
2322 return @as(u64, first_32_bits);
2311 }2323 }
2312}2324}
23132325
...@@ -2324,7 +2336,8 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)...@@ -2324,7 +2336,8 @@ fn readInitialLength(comptime E: type, in_stream: *io.InStream(E), is_64: *bool)
2324 return in_stream.readIntLittle(u64);2336 return in_stream.readIntLittle(u64);
2325 } else {2337 } else {
2326 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;2338 if (first_32_bits >= 0xfffffff0) return error.InvalidDebugInfo;
2327 return u64(first_32_bits);2339 // TODO this cast should not be needed
2340 return @as(u64, first_32_bits);
2328 }2341 }
2329}2342}
23302343
lib/std/debug/leb128.zig+3-3
...@@ -62,13 +62,13 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {...@@ -62,13 +62,13 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {
62 var shift: usize = 0;62 var shift: usize = 0;
6363
64 while (true) {64 while (true) {
65 const byte = u8(try in_stream.readByte());65 const byte: u8 = try in_stream.readByte();
6666
67 if (shift > T.bit_count)67 if (shift > T.bit_count)
68 return error.Overflow;68 return error.Overflow;
6969
70 var operand: UT = undefined;70 var operand: UT = undefined;
71 if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {71 if (@shlWithOverflow(UT, @as(UT, byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
72 if (byte != 0x7f)72 if (byte != 0x7f)
73 return error.Overflow;73 return error.Overflow;
74 }74 }
...@@ -101,7 +101,7 @@ pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {...@@ -101,7 +101,7 @@ pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
101 return error.Overflow;101 return error.Overflow;
102102
103 var operand: UT = undefined;103 var operand: UT = undefined;
104 if (@shlWithOverflow(UT, UT(byte & 0x7f), @intCast(ShiftT, shift), &operand)) {104 if (@shlWithOverflow(UT, @as(UT, byte & 0x7f), @intCast(ShiftT, shift), &operand)) {
105 if (byte != 0x7f)105 if (byte != 0x7f)
106 return error.Overflow;106 return error.Overflow;
107 }107 }
lib/std/dynamic_library.zig+2-2
...@@ -215,8 +215,8 @@ pub const ElfLib = struct {...@@ -215,8 +215,8 @@ pub const ElfLib = struct {
215215
216 var i: usize = 0;216 var i: usize = 0;
217 while (i < self.hashtab[1]) : (i += 1) {217 while (i < self.hashtab[1]) : (i += 1) {
218 if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;218 if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info & 0xf) & OK_TYPES)) continue;
219 if (0 == (u32(1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;219 if (0 == (@as(u32, 1) << @intCast(u5, self.syms[i].st_info >> 4) & OK_BINDS)) continue;
220 if (0 == self.syms[i].st_shndx) continue;220 if (0 == self.syms[i].st_shndx) continue;
221 if (!mem.eql(u8, name, mem.toSliceConst(u8, self.strings + self.syms[i].st_name))) continue;221 if (!mem.eql(u8, name, mem.toSliceConst(u8, self.strings + self.syms[i].st_name))) continue;
222 if (maybe_versym) |versym| {222 if (maybe_versym) |versym| {
lib/std/elf.zig+12-12
...@@ -441,9 +441,9 @@ pub const Elf = struct {...@@ -441,9 +441,9 @@ pub const Elf = struct {
441 elf.program_header_offset = try in.readInt(u64, elf.endian);441 elf.program_header_offset = try in.readInt(u64, elf.endian);
442 elf.section_header_offset = try in.readInt(u64, elf.endian);442 elf.section_header_offset = try in.readInt(u64, elf.endian);
443 } else {443 } else {
444 elf.entry_addr = u64(try in.readInt(u32, elf.endian));444 elf.entry_addr = @as(u64, try in.readInt(u32, elf.endian));
445 elf.program_header_offset = u64(try in.readInt(u32, elf.endian));445 elf.program_header_offset = @as(u64, try in.readInt(u32, elf.endian));
446 elf.section_header_offset = u64(try in.readInt(u32, elf.endian));446 elf.section_header_offset = @as(u64, try in.readInt(u32, elf.endian));
447 }447 }
448448
449 // skip over flags449 // skip over flags
...@@ -458,13 +458,13 @@ pub const Elf = struct {...@@ -458,13 +458,13 @@ pub const Elf = struct {
458 const ph_entry_count = try in.readInt(u16, elf.endian);458 const ph_entry_count = try in.readInt(u16, elf.endian);
459 const sh_entry_size = try in.readInt(u16, elf.endian);459 const sh_entry_size = try in.readInt(u16, elf.endian);
460 const sh_entry_count = try in.readInt(u16, elf.endian);460 const sh_entry_count = try in.readInt(u16, elf.endian);
461 elf.string_section_index = usize(try in.readInt(u16, elf.endian));461 elf.string_section_index = @as(usize, try in.readInt(u16, elf.endian));
462462
463 if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;463 if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;
464464
465 const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count);465 const sh_byte_count = @as(u64, sh_entry_size) * @as(u64, sh_entry_count);
466 const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count);466 const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count);
467 const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count);467 const ph_byte_count = @as(u64, ph_entry_size) * @as(u64, ph_entry_count);
468 const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count);468 const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count);
469469
470 const stream_end = try seekable_stream.getEndPos();470 const stream_end = try seekable_stream.getEndPos();
...@@ -499,14 +499,14 @@ pub const Elf = struct {...@@ -499,14 +499,14 @@ pub const Elf = struct {
499 // TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ?499 // TODO (multiple occurrences) allow implicit cast from %u32 -> %u64 ?
500 elf_section.name = try in.readInt(u32, elf.endian);500 elf_section.name = try in.readInt(u32, elf.endian);
501 elf_section.sh_type = try in.readInt(u32, elf.endian);501 elf_section.sh_type = try in.readInt(u32, elf.endian);
502 elf_section.flags = u64(try in.readInt(u32, elf.endian));502 elf_section.flags = @as(u64, try in.readInt(u32, elf.endian));
503 elf_section.addr = u64(try in.readInt(u32, elf.endian));503 elf_section.addr = @as(u64, try in.readInt(u32, elf.endian));
504 elf_section.offset = u64(try in.readInt(u32, elf.endian));504 elf_section.offset = @as(u64, try in.readInt(u32, elf.endian));
505 elf_section.size = u64(try in.readInt(u32, elf.endian));505 elf_section.size = @as(u64, try in.readInt(u32, elf.endian));
506 elf_section.link = try in.readInt(u32, elf.endian);506 elf_section.link = try in.readInt(u32, elf.endian);
507 elf_section.info = try in.readInt(u32, elf.endian);507 elf_section.info = try in.readInt(u32, elf.endian);
508 elf_section.addr_align = u64(try in.readInt(u32, elf.endian));508 elf_section.addr_align = @as(u64, try in.readInt(u32, elf.endian));
509 elf_section.ent_size = u64(try in.readInt(u32, elf.endian));509 elf_section.ent_size = @as(u64, try in.readInt(u32, elf.endian));
510 }510 }
511 }511 }
512512
lib/std/event/channel.zig+2-2
...@@ -161,7 +161,7 @@ pub fn Channel(comptime T: type) type {...@@ -161,7 +161,7 @@ pub fn Channel(comptime T: type) type {
161161
162 fn dispatch(self: *SelfChannel) void {162 fn dispatch(self: *SelfChannel) void {
163 // set the "need dispatch" flag163 // set the "need dispatch" flag
164 _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 1, .SeqCst);164 @atomicStore(u8, &self.need_dispatch, 1, .SeqCst);
165165
166 lock: while (true) {166 lock: while (true) {
167 // set the lock flag167 // set the lock flag
...@@ -169,7 +169,7 @@ pub fn Channel(comptime T: type) type {...@@ -169,7 +169,7 @@ pub fn Channel(comptime T: type) type {
169 if (prev_lock != 0) return;169 if (prev_lock != 0) return;
170170
171 // clear the need_dispatch flag since we're about to do it171 // clear the need_dispatch flag since we're about to do it
172 _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 0, .SeqCst);172 @atomicStore(u8, &self.need_dispatch, 0, .SeqCst);
173173
174 while (true) {174 while (true) {
175 one_dispatch: {175 one_dispatch: {
lib/std/event/fs.zig+8-5
...@@ -328,11 +328,11 @@ pub fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize {...@@ -328,11 +328,11 @@ pub fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize {
328 windows.ERROR.IO_PENDING => unreachable,328 windows.ERROR.IO_PENDING => unreachable,
329 windows.ERROR.OPERATION_ABORTED => return error.OperationAborted,329 windows.ERROR.OPERATION_ABORTED => return error.OperationAborted,
330 windows.ERROR.BROKEN_PIPE => return error.BrokenPipe,330 windows.ERROR.BROKEN_PIPE => return error.BrokenPipe,
331 windows.ERROR.HANDLE_EOF => return usize(bytes_transferred),331 windows.ERROR.HANDLE_EOF => return @as(usize, bytes_transferred),
332 else => |err| return windows.unexpectedError(err),332 else => |err| return windows.unexpectedError(err),
333 }333 }
334 }334 }
335 return usize(bytes_transferred);335 return @as(usize, bytes_transferred);
336}336}
337337
338/// iovecs must live until preadv frame completes338/// iovecs must live until preadv frame completes
...@@ -415,7 +415,8 @@ pub fn openPosix(...@@ -415,7 +415,8 @@ pub fn openPosix(
415pub fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t {415pub fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t {
416 switch (builtin.os) {416 switch (builtin.os) {
417 .macosx, .linux, .freebsd, .netbsd, .dragonfly => {417 .macosx, .linux, .freebsd, .netbsd, .dragonfly => {
418 const flags = os.O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;418 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
419 const flags = O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;
419 return openPosix(loop, path, flags, File.default_mode);420 return openPosix(loop, path, flags, File.default_mode);
420 },421 },
421422
...@@ -448,7 +449,8 @@ pub fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.OpenEr...@@ -448,7 +449,8 @@ pub fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.OpenEr
448 .netbsd,449 .netbsd,
449 .dragonfly,450 .dragonfly,
450 => {451 => {
451 const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;452 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
453 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;
452 return openPosix(loop, path, flags, File.default_mode);454 return openPosix(loop, path, flags, File.default_mode);
453 },455 },
454 .windows => return windows.CreateFile(456 .windows => return windows.CreateFile(
...@@ -472,7 +474,8 @@ pub fn openReadWrite(...@@ -472,7 +474,8 @@ pub fn openReadWrite(
472) File.OpenError!fd_t {474) File.OpenError!fd_t {
473 switch (builtin.os) {475 switch (builtin.os) {
474 .macosx, .linux, .freebsd, .netbsd, .dragonfly => {476 .macosx, .linux, .freebsd, .netbsd, .dragonfly => {
475 const flags = os.O_LARGEFILE | os.O_RDWR | os.O_CREAT | os.O_CLOEXEC;477 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
478 const flags = O_LARGEFILE | os.O_RDWR | os.O_CREAT | os.O_CLOEXEC;
476 return openPosix(loop, path, flags, mode);479 return openPosix(loop, path, flags, mode);
477 },480 },
478481
lib/std/event/future.zig+13-12
...@@ -12,12 +12,13 @@ pub fn Future(comptime T: type) type {...@@ -12,12 +12,13 @@ pub fn Future(comptime T: type) type {
12 return struct {12 return struct {
13 lock: Lock,13 lock: Lock,
14 data: T,14 data: T,
15 available: Available,
1516
16 /// TODO make this an enum17 const Available = enum(u8) {
17 /// 0 - not started18 NotStarted,
18 /// 1 - started19 Started,
19 /// 2 - finished20 Finished,
20 available: u8,21 };
2122
22 const Self = @This();23 const Self = @This();
23 const Queue = std.atomic.Queue(anyframe);24 const Queue = std.atomic.Queue(anyframe);
...@@ -34,7 +35,7 @@ pub fn Future(comptime T: type) type {...@@ -34,7 +35,7 @@ pub fn Future(comptime T: type) type {
34 /// available.35 /// available.
35 /// Thread-safe.36 /// Thread-safe.
36 pub async fn get(self: *Self) *T {37 pub async fn get(self: *Self) *T {
37 if (@atomicLoad(u8, &self.available, .SeqCst) == 2) {38 if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
38 return &self.data;39 return &self.data;
39 }40 }
40 const held = self.lock.acquire();41 const held = self.lock.acquire();
...@@ -46,7 +47,7 @@ pub fn Future(comptime T: type) type {...@@ -46,7 +47,7 @@ pub fn Future(comptime T: type) type {
46 /// Gets the data without waiting for it. If it's available, a pointer is47 /// Gets the data without waiting for it. If it's available, a pointer is
47 /// returned. Otherwise, null is returned.48 /// returned. Otherwise, null is returned.
48 pub fn getOrNull(self: *Self) ?*T {49 pub fn getOrNull(self: *Self) ?*T {
49 if (@atomicLoad(u8, &self.available, .SeqCst) == 2) {50 if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
50 return &self.data;51 return &self.data;
51 } else {52 } else {
52 return null;53 return null;
...@@ -59,14 +60,14 @@ pub fn Future(comptime T: type) type {...@@ -59,14 +60,14 @@ pub fn Future(comptime T: type) type {
59 /// It's not required to call start() before resolve() but it can be useful since60 /// It's not required to call start() before resolve() but it can be useful since
60 /// this method is thread-safe.61 /// this method is thread-safe.
61 pub async fn start(self: *Self) ?*T {62 pub async fn start(self: *Self) ?*T {
62 const state = @cmpxchgStrong(u8, &self.available, 0, 1, .SeqCst, .SeqCst) orelse return null;63 const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
63 switch (state) {64 switch (state) {
64 1 => {65 .Started => {
65 const held = self.lock.acquire();66 const held = self.lock.acquire();
66 held.release();67 held.release();
67 return &self.data;68 return &self.data;
68 },69 },
69 2 => return &self.data,70 .Finished => return &self.data,
70 else => unreachable,71 else => unreachable,
71 }72 }
72 }73 }
...@@ -74,8 +75,8 @@ pub fn Future(comptime T: type) type {...@@ -74,8 +75,8 @@ pub fn Future(comptime T: type) type {
74 /// Make the data become available. May be called only once.75 /// Make the data become available. May be called only once.
75 /// Before calling this, modify the `data` property.76 /// Before calling this, modify the `data` property.
76 pub fn resolve(self: *Self) void {77 pub fn resolve(self: *Self) void {
77 const prev = @atomicRmw(u8, &self.available, .Xchg, 2, .SeqCst);78 const prev = @atomicRmw(Available, &self.available, .Xchg, .Finished, .SeqCst);
78 assert(prev == 0 or prev == 1); // resolve() called twice79 assert(prev != .Finished); // resolve() called twice
79 Lock.Held.release(Lock.Held{ .lock = &self.lock });80 Lock.Held.release(Lock.Held{ .lock = &self.lock });
80 }81 }
81 };82 };
lib/std/event/group.zig+34-7
...@@ -8,7 +8,7 @@ const Allocator = std.mem.Allocator;...@@ -8,7 +8,7 @@ const Allocator = std.mem.Allocator;
8pub fn Group(comptime ReturnType: type) type {8pub fn Group(comptime ReturnType: type) type {
9 return struct {9 return struct {
10 frame_stack: Stack,10 frame_stack: Stack,
11 alloc_stack: Stack,11 alloc_stack: AllocStack,
12 lock: Lock,12 lock: Lock,
13 allocator: *Allocator,13 allocator: *Allocator,
1414
...@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {...@@ -19,11 +19,17 @@ pub fn Group(comptime ReturnType: type) type {
19 else => void,19 else => void,
20 };20 };
21 const Stack = std.atomic.Stack(anyframe->ReturnType);21 const Stack = std.atomic.Stack(anyframe->ReturnType);
22 const AllocStack = std.atomic.Stack(Node);
23
24 pub const Node = struct {
25 bytes: []const u8 = [0]u8{},
26 handle: anyframe->ReturnType,
27 };
2228
23 pub fn init(allocator: *Allocator) Self {29 pub fn init(allocator: *Allocator) Self {
24 return Self{30 return Self{
25 .frame_stack = Stack.init(),31 .frame_stack = Stack.init(),
26 .alloc_stack = Stack.init(),32 .alloc_stack = AllocStack.init(),
27 .lock = Lock.init(),33 .lock = Lock.init(),
28 .allocator = allocator,34 .allocator = allocator,
29 };35 };
...@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {...@@ -31,10 +37,12 @@ pub fn Group(comptime ReturnType: type) type {
3137
32 /// Add a frame to the group. Thread-safe.38 /// Add a frame to the group. Thread-safe.
33 pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {39 pub fn add(self: *Self, handle: anyframe->ReturnType) (error{OutOfMemory}!void) {
34 const node = try self.allocator.create(Stack.Node);40 const node = try self.allocator.create(AllocStack.Node);
35 node.* = Stack.Node{41 node.* = AllocStack.Node{
36 .next = undefined,42 .next = undefined,
37 .data = handle,43 .data = Node{
44 .handle = handle,
45 },
38 };46 };
39 self.alloc_stack.push(node);47 self.alloc_stack.push(node);
40 }48 }
...@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {...@@ -48,6 +56,24 @@ pub fn Group(comptime ReturnType: type) type {
48 self.frame_stack.push(node);56 self.frame_stack.push(node);
49 }57 }
5058
59 /// This is equivalent to adding a frame to the group but the memory of its frame is
60 /// allocated by the group and freed by `wait`.
61 /// `func` must be async and have return type `ReturnType`.
62 /// Thread-safe.
63 pub fn call(self: *Self, comptime func: var, args: ...) error{OutOfMemory}!void {
64 var frame = try self.allocator.create(@Frame(func));
65 const node = try self.allocator.create(AllocStack.Node);
66 node.* = AllocStack.Node{
67 .next = undefined,
68 .data = Node{
69 .handle = frame,
70 .bytes = @sliceToBytes((*[1]@Frame(func))(frame)[0..]),
71 },
72 };
73 frame.* = async func(args);
74 self.alloc_stack.push(node);
75 }
76
51 /// Wait for all the calls and promises of the group to complete.77 /// Wait for all the calls and promises of the group to complete.
52 /// Thread-safe.78 /// Thread-safe.
53 /// Safe to call any number of times.79 /// Safe to call any number of times.
...@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {...@@ -67,8 +93,7 @@ pub fn Group(comptime ReturnType: type) type {
67 }93 }
68 }94 }
69 while (self.alloc_stack.pop()) |node| {95 while (self.alloc_stack.pop()) |node| {
70 const handle = node.data;96 const handle = node.data.handle;
71 self.allocator.destroy(node);
72 if (Error == void) {97 if (Error == void) {
73 await handle;98 await handle;
74 } else {99 } else {
...@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {...@@ -76,6 +101,8 @@ pub fn Group(comptime ReturnType: type) type {
76 result = err;101 result = err;
77 };102 };
78 }103 }
104 self.allocator.free(node.data.bytes);
105 self.allocator.destroy(node);
79 }106 }
80 return result;107 return result;
81 }108 }
lib/std/event/lock.zig+5-5
...@@ -31,8 +31,8 @@ pub const Lock = struct {...@@ -31,8 +31,8 @@ pub const Lock = struct {
31 }31 }
3232
33 // We need to release the lock.33 // We need to release the lock.
34 _ = @atomicRmw(u8, &self.lock.queue_empty_bit, .Xchg, 1, .SeqCst);34 @atomicStore(u8, &self.lock.queue_empty_bit, 1, .SeqCst);
35 _ = @atomicRmw(u8, &self.lock.shared_bit, .Xchg, 0, .SeqCst);35 @atomicStore(u8, &self.lock.shared_bit, 0, .SeqCst);
3636
37 // There might be a queue item. If we know the queue is empty, we can be done,37 // There might be a queue item. If we know the queue is empty, we can be done,
38 // because the other actor will try to obtain the lock.38 // because the other actor will try to obtain the lock.
...@@ -56,8 +56,8 @@ pub const Lock = struct {...@@ -56,8 +56,8 @@ pub const Lock = struct {
56 }56 }
5757
58 // Release the lock again.58 // Release the lock again.
59 _ = @atomicRmw(u8, &self.lock.queue_empty_bit, .Xchg, 1, .SeqCst);59 @atomicStore(u8, &self.lock.queue_empty_bit, 1, .SeqCst);
60 _ = @atomicRmw(u8, &self.lock.shared_bit, .Xchg, 0, .SeqCst);60 @atomicStore(u8, &self.lock.shared_bit, 0, .SeqCst);
6161
62 // Find out if we can be done.62 // Find out if we can be done.
63 if (@atomicLoad(u8, &self.lock.queue_empty_bit, .SeqCst) == 1) {63 if (@atomicLoad(u8, &self.lock.queue_empty_bit, .SeqCst) == 1) {
...@@ -101,7 +101,7 @@ pub const Lock = struct {...@@ -101,7 +101,7 @@ pub const Lock = struct {
101101
102 // We set this bit so that later we can rely on the fact, that if queue_empty_bit is 1, some actor102 // We set this bit so that later we can rely on the fact, that if queue_empty_bit is 1, some actor
103 // will attempt to grab the lock.103 // will attempt to grab the lock.
104 _ = @atomicRmw(u8, &self.queue_empty_bit, .Xchg, 0, .SeqCst);104 @atomicStore(u8, &self.queue_empty_bit, 0, .SeqCst);
105105
106 const old_bit = @atomicRmw(u8, &self.shared_bit, .Xchg, 1, .SeqCst);106 const old_bit = @atomicRmw(u8, &self.shared_bit, .Xchg, 1, .SeqCst);
107 if (old_bit == 0) {107 if (old_bit == 0) {
lib/std/event/loop.zig+15-37
...@@ -266,7 +266,7 @@ pub const Loop = struct {...@@ -266,7 +266,7 @@ pub const Loop = struct {
266 },266 },
267 };267 };
268268
269 const empty_kevs = ([*]os.Kevent)(undefined)[0..0];269 const empty_kevs = &[0]os.Kevent{};
270270
271 for (self.eventfd_resume_nodes) |*eventfd_node, i| {271 for (self.eventfd_resume_nodes) |*eventfd_node, i| {
272 eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{272 eventfd_node.* = std.atomic.Stack(ResumeNode.EventFd).Node{
...@@ -289,7 +289,7 @@ pub const Loop = struct {...@@ -289,7 +289,7 @@ pub const Loop = struct {
289 .next = undefined,289 .next = undefined,
290 };290 };
291 self.available_eventfd_resume_nodes.push(eventfd_node);291 self.available_eventfd_resume_nodes.push(eventfd_node);
292 const kevent_array = (*const [1]os.Kevent)(&eventfd_node.data.kevent);292 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.data.kevent);
293 _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);293 _ = try os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null);
294 eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE;294 eventfd_node.data.kevent.flags = os.EV_CLEAR | os.EV_ENABLE;
295 eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER;295 eventfd_node.data.kevent.fflags = os.NOTE_TRIGGER;
...@@ -305,7 +305,7 @@ pub const Loop = struct {...@@ -305,7 +305,7 @@ pub const Loop = struct {
305 .data = 0,305 .data = 0,
306 .udata = @ptrToInt(&self.final_resume_node),306 .udata = @ptrToInt(&self.final_resume_node),
307 };307 };
308 const final_kev_arr = (*const [1]os.Kevent)(&self.os_data.final_kevent);308 const final_kev_arr = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
309 _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);309 _ = try os.kevent(self.os_data.kqfd, final_kev_arr, empty_kevs, null);
310 self.os_data.final_kevent.flags = os.EV_ENABLE;310 self.os_data.final_kevent.flags = os.EV_ENABLE;
311 self.os_data.final_kevent.fflags = os.NOTE_TRIGGER;311 self.os_data.final_kevent.fflags = os.NOTE_TRIGGER;
...@@ -572,8 +572,8 @@ pub const Loop = struct {...@@ -572,8 +572,8 @@ pub const Loop = struct {
572 eventfd_node.base.handle = next_tick_node.data;572 eventfd_node.base.handle = next_tick_node.data;
573 switch (builtin.os) {573 switch (builtin.os) {
574 .macosx, .freebsd, .netbsd, .dragonfly => {574 .macosx, .freebsd, .netbsd, .dragonfly => {
575 const kevent_array = (*const [1]os.Kevent)(&eventfd_node.kevent);575 const kevent_array = @as(*const [1]os.Kevent, &eventfd_node.kevent);
576 const empty_kevs = ([*]os.Kevent)(undefined)[0..0];576 const empty_kevs = &[0]os.Kevent{};
577 _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {577 _ = os.kevent(self.os_data.kqfd, kevent_array, empty_kevs, null) catch {
578 self.next_tick_queue.unget(next_tick_node);578 self.next_tick_queue.unget(next_tick_node);
579 self.available_eventfd_resume_nodes.push(resume_stack_node);579 self.available_eventfd_resume_nodes.push(resume_stack_node);
...@@ -645,12 +645,6 @@ pub const Loop = struct {...@@ -645,12 +645,6 @@ pub const Loop = struct {
645 }645 }
646 }646 }
647647
648 /// This is equivalent to function call, except it calls `startCpuBoundOperation` first.
649 pub fn call(comptime func: var, args: ...) @typeOf(func).ReturnType {
650 startCpuBoundOperation();
651 return func(args);
652 }
653
654 /// Yielding lets the event loop run, starting any unstarted async operations.648 /// Yielding lets the event loop run, starting any unstarted async operations.
655 /// Note that async operations automatically start when a function yields for any other reason,649 /// Note that async operations automatically start when a function yields for any other reason,
656 /// for example, when async I/O is performed. This function is intended to be used only when650 /// for example, when async I/O is performed. This function is intended to be used only when
...@@ -695,8 +689,8 @@ pub const Loop = struct {...@@ -695,8 +689,8 @@ pub const Loop = struct {
695 },689 },
696 .macosx, .freebsd, .netbsd, .dragonfly => {690 .macosx, .freebsd, .netbsd, .dragonfly => {
697 self.posixFsRequest(&self.os_data.fs_end_request);691 self.posixFsRequest(&self.os_data.fs_end_request);
698 const final_kevent = (*const [1]os.Kevent)(&self.os_data.final_kevent);692 const final_kevent = @as(*const [1]os.Kevent, &self.os_data.final_kevent);
699 const empty_kevs = ([*]os.Kevent)(undefined)[0..0];693 const empty_kevs = &[0]os.Kevent{};
700 // cannot fail because we already added it and this just enables it694 // cannot fail because we already added it and this just enables it
701 _ = os.kevent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable;695 _ = os.kevent(self.os_data.kqfd, final_kevent, empty_kevs, null) catch unreachable;
702 return;696 return;
...@@ -753,7 +747,7 @@ pub const Loop = struct {...@@ -753,7 +747,7 @@ pub const Loop = struct {
753 },747 },
754 .macosx, .freebsd, .netbsd, .dragonfly => {748 .macosx, .freebsd, .netbsd, .dragonfly => {
755 var eventlist: [1]os.Kevent = undefined;749 var eventlist: [1]os.Kevent = undefined;
756 const empty_kevs = ([*]os.Kevent)(undefined)[0..0];750 const empty_kevs = &[0]os.Kevent{};
757 const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;751 const count = os.kevent(self.os_data.kqfd, empty_kevs, eventlist[0..], null) catch unreachable;
758 for (eventlist[0..count]) |ev| {752 for (eventlist[0..count]) |ev| {
759 const resume_node = @intToPtr(*ResumeNode, ev.udata);753 const resume_node = @intToPtr(*ResumeNode, ev.udata);
...@@ -815,12 +809,12 @@ pub const Loop = struct {...@@ -815,12 +809,12 @@ pub const Loop = struct {
815 self.os_data.fs_queue.put(request_node);809 self.os_data.fs_queue.put(request_node);
816 switch (builtin.os) {810 switch (builtin.os) {
817 .macosx, .freebsd, .netbsd, .dragonfly => {811 .macosx, .freebsd, .netbsd, .dragonfly => {
818 const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wake);812 const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wake);
819 const empty_kevs = ([*]os.Kevent)(undefined)[0..0];813 const empty_kevs = &[0]os.Kevent{};
820 _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;814 _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, empty_kevs, null) catch unreachable;
821 },815 },
822 .linux => {816 .linux => {
823 _ = @atomicRmw(i32, &self.os_data.fs_queue_item, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);817 @atomicStore(i32, &self.os_data.fs_queue_item, 1, AtomicOrder.SeqCst);
824 const rc = os.linux.futex_wake(&self.os_data.fs_queue_item, os.linux.FUTEX_WAKE, 1);818 const rc = os.linux.futex_wake(&self.os_data.fs_queue_item, os.linux.FUTEX_WAKE, 1);
825 switch (os.linux.getErrno(rc)) {819 switch (os.linux.getErrno(rc)) {
826 0 => {},820 0 => {},
...@@ -843,7 +837,7 @@ pub const Loop = struct {...@@ -843,7 +837,7 @@ pub const Loop = struct {
843 fn posixFsRun(self: *Loop) void {837 fn posixFsRun(self: *Loop) void {
844 while (true) {838 while (true) {
845 if (builtin.os == .linux) {839 if (builtin.os == .linux) {
846 _ = @atomicRmw(i32, &self.os_data.fs_queue_item, .Xchg, 0, .SeqCst);840 @atomicStore(i32, &self.os_data.fs_queue_item, 0, .SeqCst);
847 }841 }
848 while (self.os_data.fs_queue.get()) |node| {842 while (self.os_data.fs_queue.get()) |node| {
849 switch (node.data.msg) {843 switch (node.data.msg) {
...@@ -862,7 +856,8 @@ pub const Loop = struct {...@@ -862,7 +856,8 @@ pub const Loop = struct {
862 },856 },
863 .Close => |*msg| noasync os.close(msg.fd),857 .Close => |*msg| noasync os.close(msg.fd),
864 .WriteFile => |*msg| blk: {858 .WriteFile => |*msg| blk: {
865 const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT |859 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
860 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT |
866 os.O_CLOEXEC | os.O_TRUNC;861 os.O_CLOEXEC | os.O_TRUNC;
867 const fd = noasync os.openC(msg.path.ptr, flags, msg.mode) catch |err| {862 const fd = noasync os.openC(msg.path.ptr, flags, msg.mode) catch |err| {
868 msg.result = err;863 msg.result = err;
...@@ -890,7 +885,7 @@ pub const Loop = struct {...@@ -890,7 +885,7 @@ pub const Loop = struct {
890 }885 }
891 },886 },
892 .macosx, .freebsd, .netbsd, .dragonfly => {887 .macosx, .freebsd, .netbsd, .dragonfly => {
893 const fs_kevs = (*const [1]os.Kevent)(&self.os_data.fs_kevent_wait);888 const fs_kevs = @as(*const [1]os.Kevent, &self.os_data.fs_kevent_wait);
894 var out_kevs: [1]os.Kevent = undefined;889 var out_kevs: [1]os.Kevent = undefined;
895 _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;890 _ = os.kevent(self.os_data.fs_kqfd, fs_kevs, out_kevs[0..], null) catch unreachable;
896 },891 },
...@@ -942,23 +937,6 @@ test "std.event.Loop - basic" {...@@ -942,23 +937,6 @@ test "std.event.Loop - basic" {
942 loop.run();937 loop.run();
943}938}
944939
945test "std.event.Loop - call" {
946 // https://github.com/ziglang/zig/issues/1908
947 if (builtin.single_threaded) return error.SkipZigTest;
948
949 var loop: Loop = undefined;
950 try loop.initMultiThreaded();
951 defer loop.deinit();
952
953 var did_it = false;
954 var handle = async Loop.call(testEventLoop);
955 var handle2 = async Loop.call(testEventLoop2, &handle, &did_it);
956
957 loop.run();
958
959 testing.expect(did_it);
960}
961
962async fn testEventLoop() i32 {940async fn testEventLoop() i32 {
963 return 1234;941 return 1234;
964}942}
lib/std/event/rwlock.zig+22-22
...@@ -13,17 +13,17 @@ const Loop = std.event.Loop;...@@ -13,17 +13,17 @@ const Loop = std.event.Loop;
13/// When a write lock is held, it will not be released until the writer queue is empty.13/// When a write lock is held, it will not be released until the writer queue is empty.
14/// TODO: make this API also work in blocking I/O mode14/// TODO: make this API also work in blocking I/O mode
15pub const RwLock = struct {15pub const RwLock = struct {
16 shared_state: u8, // TODO make this an enum16 shared_state: State,
17 writer_queue: Queue,17 writer_queue: Queue,
18 reader_queue: Queue,18 reader_queue: Queue,
19 writer_queue_empty_bit: u8, // TODO make this a bool19 writer_queue_empty_bit: u8, // TODO make this a bool
20 reader_queue_empty_bit: u8, // TODO make this a bool20 reader_queue_empty_bit: u8, // TODO make this a bool
21 reader_lock_count: usize,21 reader_lock_count: usize,
2222
23 const State = struct {23 const State = enum(u8) {
24 const Unlocked = 0;24 Unlocked,
25 const WriteLock = 1;25 WriteLock,
26 const ReadLock = 2;26 ReadLock,
27 };27 };
2828
29 const Queue = std.atomic.Queue(anyframe);29 const Queue = std.atomic.Queue(anyframe);
...@@ -40,8 +40,8 @@ pub const RwLock = struct {...@@ -40,8 +40,8 @@ pub const RwLock = struct {
40 return;40 return;
41 }41 }
4242
43 _ = @atomicRmw(u8, &self.lock.reader_queue_empty_bit, .Xchg, 1, .SeqCst);43 @atomicStore(u8, &self.lock.reader_queue_empty_bit, 1, .SeqCst);
44 if (@cmpxchgStrong(u8, &self.lock.shared_state, State.ReadLock, State.Unlocked, .SeqCst, .SeqCst) != null) {44 if (@cmpxchgStrong(State, &self.lock.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
45 // Didn't unlock. Someone else's problem.45 // Didn't unlock. Someone else's problem.
46 return;46 return;
47 }47 }
...@@ -64,15 +64,15 @@ pub const RwLock = struct {...@@ -64,15 +64,15 @@ pub const RwLock = struct {
64 // We need to release the write lock. Check if any readers are waiting to grab the lock.64 // We need to release the write lock. Check if any readers are waiting to grab the lock.
65 if (@atomicLoad(u8, &self.lock.reader_queue_empty_bit, .SeqCst) == 0) {65 if (@atomicLoad(u8, &self.lock.reader_queue_empty_bit, .SeqCst) == 0) {
66 // Switch to a read lock.66 // Switch to a read lock.
67 _ = @atomicRmw(u8, &self.lock.shared_state, .Xchg, State.ReadLock, .SeqCst);67 @atomicStore(State, &self.lock.shared_state, .ReadLock, .SeqCst);
68 while (self.lock.reader_queue.get()) |node| {68 while (self.lock.reader_queue.get()) |node| {
69 global_event_loop.onNextTick(node);69 global_event_loop.onNextTick(node);
70 }70 }
71 return;71 return;
72 }72 }
7373
74 _ = @atomicRmw(u8, &self.lock.writer_queue_empty_bit, .Xchg, 1, .SeqCst);74 @atomicStore(u8, &self.lock.writer_queue_empty_bit, 1, .SeqCst);
75 _ = @atomicRmw(u8, &self.lock.shared_state, .Xchg, State.Unlocked, .SeqCst);75 @atomicStore(State, &self.lock.shared_state, .Unlocked, .SeqCst);
7676
77 self.lock.commonPostUnlock();77 self.lock.commonPostUnlock();
78 }78 }
...@@ -80,7 +80,7 @@ pub const RwLock = struct {...@@ -80,7 +80,7 @@ pub const RwLock = struct {
8080
81 pub fn init() RwLock {81 pub fn init() RwLock {
82 return RwLock{82 return RwLock{
83 .shared_state = State.Unlocked,83 .shared_state = .Unlocked,
84 .writer_queue = Queue.init(),84 .writer_queue = Queue.init(),
85 .writer_queue_empty_bit = 1,85 .writer_queue_empty_bit = 1,
86 .reader_queue = Queue.init(),86 .reader_queue = Queue.init(),
...@@ -92,7 +92,7 @@ pub const RwLock = struct {...@@ -92,7 +92,7 @@ pub const RwLock = struct {
92 /// Must be called when not locked. Not thread safe.92 /// Must be called when not locked. Not thread safe.
93 /// All calls to acquire() and release() must complete before calling deinit().93 /// All calls to acquire() and release() must complete before calling deinit().
94 pub fn deinit(self: *RwLock) void {94 pub fn deinit(self: *RwLock) void {
95 assert(self.shared_state == State.Unlocked);95 assert(self.shared_state == .Unlocked);
96 while (self.writer_queue.get()) |node| resume node.data;96 while (self.writer_queue.get()) |node| resume node.data;
97 while (self.reader_queue.get()) |node| resume node.data;97 while (self.reader_queue.get()) |node| resume node.data;
98 }98 }
...@@ -113,10 +113,10 @@ pub const RwLock = struct {...@@ -113,10 +113,10 @@ pub const RwLock = struct {
113113
114 // We set this bit so that later we can rely on the fact, that if reader_queue_empty_bit is 1,114 // We set this bit so that later we can rely on the fact, that if reader_queue_empty_bit is 1,
115 // some actor will attempt to grab the lock.115 // some actor will attempt to grab the lock.
116 _ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 0, .SeqCst);116 @atomicStore(u8, &self.reader_queue_empty_bit, 0, .SeqCst);
117117
118 // Here we don't care if we are the one to do the locking or if it was already locked for reading.118 // Here we don't care if we are the one to do the locking or if it was already locked for reading.
119 const have_read_lock = if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.ReadLock, .SeqCst, .SeqCst)) |old_state| old_state == State.ReadLock else true;119 const have_read_lock = if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .ReadLock, .SeqCst, .SeqCst)) |old_state| old_state == .ReadLock else true;
120 if (have_read_lock) {120 if (have_read_lock) {
121 // Give out all the read locks.121 // Give out all the read locks.
122 if (self.reader_queue.get()) |first_node| {122 if (self.reader_queue.get()) |first_node| {
...@@ -144,10 +144,10 @@ pub const RwLock = struct {...@@ -144,10 +144,10 @@ pub const RwLock = struct {
144144
145 // We set this bit so that later we can rely on the fact, that if writer_queue_empty_bit is 1,145 // We set this bit so that later we can rely on the fact, that if writer_queue_empty_bit is 1,
146 // some actor will attempt to grab the lock.146 // some actor will attempt to grab the lock.
147 _ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 0, .SeqCst);147 @atomicStore(u8, &self.writer_queue_empty_bit, 0, .SeqCst);
148148
149 // Here we must be the one to acquire the write lock. It cannot already be locked.149 // Here we must be the one to acquire the write lock. It cannot already be locked.
150 if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.WriteLock, .SeqCst, .SeqCst) == null) {150 if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .WriteLock, .SeqCst, .SeqCst) == null) {
151 // We now have a write lock.151 // We now have a write lock.
152 if (self.writer_queue.get()) |node| {152 if (self.writer_queue.get()) |node| {
153 // Whether this node is us or someone else, we tail resume it.153 // Whether this node is us or someone else, we tail resume it.
...@@ -166,7 +166,7 @@ pub const RwLock = struct {...@@ -166,7 +166,7 @@ pub const RwLock = struct {
166 // But if there's a writer_queue item or a reader_queue item,166 // But if there's a writer_queue item or a reader_queue item,
167 // we are the actor which must loop and attempt to grab the lock again.167 // we are the actor which must loop and attempt to grab the lock again.
168 if (@atomicLoad(u8, &self.writer_queue_empty_bit, .SeqCst) == 0) {168 if (@atomicLoad(u8, &self.writer_queue_empty_bit, .SeqCst) == 0) {
169 if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.WriteLock, .SeqCst, .SeqCst) != null) {169 if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .WriteLock, .SeqCst, .SeqCst) != null) {
170 // We did not obtain the lock. Great, the queues are someone else's problem.170 // We did not obtain the lock. Great, the queues are someone else's problem.
171 return;171 return;
172 }172 }
...@@ -176,13 +176,13 @@ pub const RwLock = struct {...@@ -176,13 +176,13 @@ pub const RwLock = struct {
176 return;176 return;
177 }177 }
178 // Release the lock again.178 // Release the lock again.
179 _ = @atomicRmw(u8, &self.writer_queue_empty_bit, .Xchg, 1, .SeqCst);179 @atomicStore(u8, &self.writer_queue_empty_bit, 1, .SeqCst);
180 _ = @atomicRmw(u8, &self.shared_state, .Xchg, State.Unlocked, .SeqCst);180 @atomicStore(State, &self.shared_state, .Unlocked, .SeqCst);
181 continue;181 continue;
182 }182 }
183183
184 if (@atomicLoad(u8, &self.reader_queue_empty_bit, .SeqCst) == 0) {184 if (@atomicLoad(u8, &self.reader_queue_empty_bit, .SeqCst) == 0) {
185 if (@cmpxchgStrong(u8, &self.shared_state, State.Unlocked, State.ReadLock, .SeqCst, .SeqCst) != null) {185 if (@cmpxchgStrong(State, &self.shared_state, .Unlocked, .ReadLock, .SeqCst, .SeqCst) != null) {
186 // We did not obtain the lock. Great, the queues are someone else's problem.186 // We did not obtain the lock. Great, the queues are someone else's problem.
187 return;187 return;
188 }188 }
...@@ -195,8 +195,8 @@ pub const RwLock = struct {...@@ -195,8 +195,8 @@ pub const RwLock = struct {
195 return;195 return;
196 }196 }
197 // Release the lock again.197 // Release the lock again.
198 _ = @atomicRmw(u8, &self.reader_queue_empty_bit, .Xchg, 1, .SeqCst);198 @atomicStore(u8, &self.reader_queue_empty_bit, 1, .SeqCst);
199 if (@cmpxchgStrong(u8, &self.shared_state, State.ReadLock, State.Unlocked, .SeqCst, .SeqCst) != null) {199 if (@cmpxchgStrong(State, &self.shared_state, .ReadLock, .Unlocked, .SeqCst, .SeqCst) != null) {
200 // Didn't unlock. Someone else's problem.200 // Didn't unlock. Someone else's problem.
201 return;201 return;
202 }202 }
lib/std/fifo.zig+13-13
...@@ -257,7 +257,7 @@ test "ByteFifo" {...@@ -257,7 +257,7 @@ test "ByteFifo" {
257 defer fifo.deinit();257 defer fifo.deinit();
258258
259 try fifo.write("HELLO");259 try fifo.write("HELLO");
260 testing.expectEqual(usize(5), fifo.readableLength());260 testing.expectEqual(@as(usize, 5), fifo.readableLength());
261 testing.expectEqualSlices(u8, "HELLO", fifo.readableSlice(0));261 testing.expectEqualSlices(u8, "HELLO", fifo.readableSlice(0));
262262
263 {263 {
...@@ -265,34 +265,34 @@ test "ByteFifo" {...@@ -265,34 +265,34 @@ test "ByteFifo" {
265 while (i < 5) : (i += 1) {265 while (i < 5) : (i += 1) {
266 try fifo.write([_]u8{try fifo.peekItem(i)});266 try fifo.write([_]u8{try fifo.peekItem(i)});
267 }267 }
268 testing.expectEqual(usize(10), fifo.readableLength());268 testing.expectEqual(@as(usize, 10), fifo.readableLength());
269 testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0));269 testing.expectEqualSlices(u8, "HELLOHELLO", fifo.readableSlice(0));
270 }270 }
271271
272 {272 {
273 testing.expectEqual(u8('H'), try fifo.readItem());273 testing.expectEqual(@as(u8, 'H'), try fifo.readItem());
274 testing.expectEqual(u8('E'), try fifo.readItem());274 testing.expectEqual(@as(u8, 'E'), try fifo.readItem());
275 testing.expectEqual(u8('L'), try fifo.readItem());275 testing.expectEqual(@as(u8, 'L'), try fifo.readItem());
276 testing.expectEqual(u8('L'), try fifo.readItem());276 testing.expectEqual(@as(u8, 'L'), try fifo.readItem());
277 testing.expectEqual(u8('O'), try fifo.readItem());277 testing.expectEqual(@as(u8, 'O'), try fifo.readItem());
278 }278 }
279 testing.expectEqual(usize(5), fifo.readableLength());279 testing.expectEqual(@as(usize, 5), fifo.readableLength());
280280
281 { // Writes that wrap around281 { // Writes that wrap around
282 testing.expectEqual(usize(11), fifo.writableLength());282 testing.expectEqual(@as(usize, 11), fifo.writableLength());
283 testing.expectEqual(usize(6), fifo.writableSlice(0).len);283 testing.expectEqual(@as(usize, 6), fifo.writableSlice(0).len);
284 fifo.writeAssumeCapacity("6<chars<11");284 fifo.writeAssumeCapacity("6<chars<11");
285 testing.expectEqualSlices(u8, "HELLO6<char", fifo.readableSlice(0));285 testing.expectEqualSlices(u8, "HELLO6<char", fifo.readableSlice(0));
286 testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(11));286 testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(11));
287 fifo.discard(11);287 fifo.discard(11);
288 testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(0));288 testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(0));
289 fifo.discard(4);289 fifo.discard(4);
290 testing.expectEqual(usize(0), fifo.readableLength());290 testing.expectEqual(@as(usize, 0), fifo.readableLength());
291 }291 }
292292
293 {293 {
294 const buf = try fifo.writeableWithSize(12);294 const buf = try fifo.writeableWithSize(12);
295 testing.expectEqual(usize(12), buf.len);295 testing.expectEqual(@as(usize, 12), buf.len);
296 var i: u8 = 0;296 var i: u8 = 0;
297 while (i < 10) : (i += 1) {297 while (i < 10) : (i += 1) {
298 buf[i] = i + 'a';298 buf[i] = i + 'a';
...@@ -313,6 +313,6 @@ test "ByteFifo" {...@@ -313,6 +313,6 @@ test "ByteFifo" {
313 try fifo.print("{}, {}!", "Hello", "World");313 try fifo.print("{}, {}!", "Hello", "World");
314 var result: [30]u8 = undefined;314 var result: [30]u8 = undefined;
315 testing.expectEqualSlices(u8, "Hello, World!", fifo.read(&result));315 testing.expectEqualSlices(u8, "Hello, World!", fifo.read(&result));
316 testing.expectEqual(usize(0), fifo.readableLength());316 testing.expectEqual(@as(usize, 0), fifo.readableLength());
317 }317 }
318}318}
lib/std/fmt.zig+67-63
...@@ -167,6 +167,10 @@ pub fn format(...@@ -167,6 +167,10 @@ pub fn format(
167 '}' => {167 '}' => {
168 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);168 const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
169169
170 if (arg_to_print >= args.len) {
171 @compileError("Too few arguments");
172 }
173
170 try formatType(174 try formatType(
171 args[arg_to_print],175 args[arg_to_print],
172 fmt[0..0],176 fmt[0..0],
...@@ -378,10 +382,10 @@ pub fn formatType(...@@ -378,10 +382,10 @@ pub fn formatType(
378 const info = @typeInfo(T).Union;382 const info = @typeInfo(T).Union;
379 if (info.tag_type) |UnionTagType| {383 if (info.tag_type) |UnionTagType| {
380 try output(context, "{ .");384 try output(context, "{ .");
381 try output(context, @tagName(UnionTagType(value)));385 try output(context, @tagName(@as(UnionTagType, value)));
382 try output(context, " = ");386 try output(context, " = ");
383 inline for (info.fields) |u_field| {387 inline for (info.fields) |u_field| {
384 if (@enumToInt(UnionTagType(value)) == u_field.enum_field.?.value) {388 if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
385 try formatType(@field(value, u_field.name), "", options, context, Errors, output, max_depth - 1);389 try formatType(@field(value, u_field.name), "", options, context, Errors, output, max_depth - 1);
386 }390 }
387 }391 }
...@@ -499,7 +503,7 @@ pub fn formatIntValue(...@@ -499,7 +503,7 @@ pub fn formatIntValue(
499503
500 const int_value = if (@typeOf(value) == comptime_int) blk: {504 const int_value = if (@typeOf(value) == comptime_int) blk: {
501 const Int = math.IntFittingRange(value, value);505 const Int = math.IntFittingRange(value, value);
502 break :blk Int(value);506 break :blk @as(Int, value);
503 } else507 } else
504 value;508 value;
505509
...@@ -508,7 +512,7 @@ pub fn formatIntValue(...@@ -508,7 +512,7 @@ pub fn formatIntValue(
508 uppercase = false;512 uppercase = false;
509 } else if (comptime std.mem.eql(u8, fmt, "c")) {513 } else if (comptime std.mem.eql(u8, fmt, "c")) {
510 if (@typeOf(int_value).bit_count <= 8) {514 if (@typeOf(int_value).bit_count <= 8) {
511 return formatAsciiChar(u8(int_value), options, context, Errors, output);515 return formatAsciiChar(@as(u8, int_value), options, context, Errors, output);
512 } else {516 } else {
513 @compileError("Cannot print integer that is larger than 8 bits as a ascii");517 @compileError("Cannot print integer that is larger than 8 bits as a ascii");
514 }518 }
...@@ -574,7 +578,7 @@ pub fn formatAsciiChar(...@@ -574,7 +578,7 @@ pub fn formatAsciiChar(
574 comptime Errors: type,578 comptime Errors: type,
575 output: fn (@typeOf(context), []const u8) Errors!void,579 output: fn (@typeOf(context), []const u8) Errors!void,
576) Errors!void {580) Errors!void {
577 return output(context, (*const [1]u8)(&c)[0..]);581 return output(context, @as(*const [1]u8, &c)[0..]);
578}582}
579583
580pub fn formatBuf(584pub fn formatBuf(
...@@ -590,7 +594,7 @@ pub fn formatBuf(...@@ -590,7 +594,7 @@ pub fn formatBuf(
590 var leftover_padding = if (width > buf.len) (width - buf.len) else return;594 var leftover_padding = if (width > buf.len) (width - buf.len) else return;
591 const pad_byte: u8 = options.fill;595 const pad_byte: u8 = options.fill;
592 while (leftover_padding > 0) : (leftover_padding -= 1) {596 while (leftover_padding > 0) : (leftover_padding -= 1) {
593 try output(context, (*const [1]u8)(&pad_byte)[0..1]);597 try output(context, @as(*const [1]u8, &pad_byte)[0..1]);
594 }598 }
595}599}
596600
...@@ -664,7 +668,7 @@ pub fn formatFloatScientific(...@@ -664,7 +668,7 @@ pub fn formatFloatScientific(
664 try output(context, float_decimal.digits[0..1]);668 try output(context, float_decimal.digits[0..1]);
665 try output(context, ".");669 try output(context, ".");
666 if (float_decimal.digits.len > 1) {670 if (float_decimal.digits.len > 1) {
667 const num_digits = if (@typeOf(value) == f32) math.min(usize(9), float_decimal.digits.len) else float_decimal.digits.len;671 const num_digits = if (@typeOf(value) == f32) math.min(@as(usize, 9), float_decimal.digits.len) else float_decimal.digits.len;
668672
669 try output(context, float_decimal.digits[1..num_digits]);673 try output(context, float_decimal.digits[1..num_digits]);
670 } else {674 } else {
...@@ -699,7 +703,7 @@ pub fn formatFloatDecimal(...@@ -699,7 +703,7 @@ pub fn formatFloatDecimal(
699 comptime Errors: type,703 comptime Errors: type,
700 output: fn (@typeOf(context), []const u8) Errors!void,704 output: fn (@typeOf(context), []const u8) Errors!void,
701) Errors!void {705) Errors!void {
702 var x = f64(value);706 var x = @as(f64, value);
703707
704 // Errol doesn't handle these special cases.708 // Errol doesn't handle these special cases.
705 if (math.signbit(x)) {709 if (math.signbit(x)) {
...@@ -888,7 +892,7 @@ pub fn formatInt(...@@ -888,7 +892,7 @@ pub fn formatInt(
888) Errors!void {892) Errors!void {
889 const int_value = if (@typeOf(value) == comptime_int) blk: {893 const int_value = if (@typeOf(value) == comptime_int) blk: {
890 const Int = math.IntFittingRange(value, value);894 const Int = math.IntFittingRange(value, value);
891 break :blk Int(value);895 break :blk @as(Int, value);
892 } else896 } else
893 value;897 value;
894898
...@@ -917,14 +921,14 @@ fn formatIntSigned(...@@ -917,14 +921,14 @@ fn formatIntSigned(
917 const uint = @IntType(false, @typeOf(value).bit_count);921 const uint = @IntType(false, @typeOf(value).bit_count);
918 if (value < 0) {922 if (value < 0) {
919 const minus_sign: u8 = '-';923 const minus_sign: u8 = '-';
920 try output(context, (*const [1]u8)(&minus_sign)[0..]);924 try output(context, @as(*const [1]u8, &minus_sign)[0..]);
921 const new_value = @intCast(uint, -(value + 1)) + 1;925 const new_value = @intCast(uint, -(value + 1)) + 1;
922 return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);926 return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);
923 } else if (options.width == null or options.width.? == 0) {927 } else if (options.width == null or options.width.? == 0) {
924 return formatIntUnsigned(@intCast(uint, value), base, uppercase, options, context, Errors, output);928 return formatIntUnsigned(@intCast(uint, value), base, uppercase, options, context, Errors, output);
925 } else {929 } else {
926 const plus_sign: u8 = '+';930 const plus_sign: u8 = '+';
927 try output(context, (*const [1]u8)(&plus_sign)[0..]);931 try output(context, @as(*const [1]u8, &plus_sign)[0..]);
928 const new_value = @intCast(uint, value);932 const new_value = @intCast(uint, value);
929 return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);933 return formatIntUnsigned(new_value, base, uppercase, new_options, context, Errors, output);
930 }934 }
...@@ -962,7 +966,7 @@ fn formatIntUnsigned(...@@ -962,7 +966,7 @@ fn formatIntUnsigned(
962 const zero_byte: u8 = options.fill;966 const zero_byte: u8 = options.fill;
963 var leftover_padding = padding - index;967 var leftover_padding = padding - index;
964 while (true) {968 while (true) {
965 try output(context, (*const [1]u8)(&zero_byte)[0..]);969 try output(context, @as(*const [1]u8, &zero_byte)[0..]);
966 leftover_padding -= 1;970 leftover_padding -= 1;
967 if (leftover_padding == 0) break;971 if (leftover_padding == 0) break;
968 }972 }
...@@ -994,7 +998,7 @@ fn formatIntCallback(context: *FormatIntBuf, bytes: []const u8) (error{}!void) {...@@ -994,7 +998,7 @@ fn formatIntCallback(context: *FormatIntBuf, bytes: []const u8) (error{}!void) {
994998
995pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {999pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
996 if (!T.is_signed) return parseUnsigned(T, buf, radix);1000 if (!T.is_signed) return parseUnsigned(T, buf, radix);
997 if (buf.len == 0) return T(0);1001 if (buf.len == 0) return @as(T, 0);
998 if (buf[0] == '-') {1002 if (buf[0] == '-') {
999 return math.negate(try parseUnsigned(T, buf[1..], radix));1003 return math.negate(try parseUnsigned(T, buf[1..], radix));
1000 } else if (buf[0] == '+') {1004 } else if (buf[0] == '+') {
...@@ -1084,7 +1088,7 @@ pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {...@@ -1084,7 +1088,7 @@ pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) {
1084fn digitToChar(digit: u8, uppercase: bool) u8 {1088fn digitToChar(digit: u8, uppercase: bool) u8 {
1085 return switch (digit) {1089 return switch (digit) {
1086 0...9 => digit + '0',1090 0...9 => digit + '0',
1087 10...35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),1091 10...35 => digit + ((if (uppercase) @as(u8, 'A') else @as(u8, 'a')) - 10),
1088 else => unreachable,1092 else => unreachable,
1089 };1093 };
1090}1094}
...@@ -1130,19 +1134,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {...@@ -1130,19 +1134,19 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
1130test "bufPrintInt" {1134test "bufPrintInt" {
1131 var buffer: [100]u8 = undefined;1135 var buffer: [100]u8 = undefined;
1132 const buf = buffer[0..];1136 const buf = buffer[0..];
1133 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));1137 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 2, false, FormatOptions{}), "-101111000110000101001110"));
1134 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 10, false, FormatOptions{}), "-12345678"));1138 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 10, false, FormatOptions{}), "-12345678"));
1135 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, false, FormatOptions{}), "-bc614e"));1139 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, false, FormatOptions{}), "-bc614e"));
1136 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-12345678), 16, true, FormatOptions{}), "-BC614E"));1140 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -12345678), 16, true, FormatOptions{}), "-BC614E"));
11371141
1138 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(12345678), 10, true, FormatOptions{}), "12345678"));1142 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 12345678), 10, true, FormatOptions{}), "12345678"));
11391143
1140 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(666), 10, false, FormatOptions{ .width = 6 }), " 666"));1144 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 666), 10, false, FormatOptions{ .width = 6 }), " 666"));
1141 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234"));1145 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 6 }), " 1234"));
1142 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, u32(0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));1146 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(u32, 0x1234), 16, false, FormatOptions{ .width = 1 }), "1234"));
11431147
1144 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(42), 10, false, FormatOptions{ .width = 3 }), "+42"));1148 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, 42), 10, false, FormatOptions{ .width = 3 }), "+42"));
1145 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, FormatOptions{ .width = 3 }), "-42"));1149 testing.expect(mem.eql(u8, bufPrintIntToSlice(buf, @as(i32, -42), 10, false, FormatOptions{ .width = 3 }), "-42"));
1146}1150}
11471151
1148fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: FormatOptions) []u8 {1152fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, options: FormatOptions) []u8 {
...@@ -1204,8 +1208,8 @@ test "int.specifier" {...@@ -1204,8 +1208,8 @@ test "int.specifier" {
1204}1208}
12051209
1206test "int.padded" {1210test "int.padded" {
1207 try testFmt("u8: ' 1'", "u8: '{:4}'", u8(1));1211 try testFmt("u8: ' 1'", "u8: '{:4}'", @as(u8, 1));
1208 try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", u8(1));1212 try testFmt("u8: 'xxx1'", "u8: '{:x<4}'", @as(u8, 1));
1209}1213}
12101214
1211test "buffer" {1215test "buffer" {
...@@ -1283,8 +1287,8 @@ test "filesize" {...@@ -1283,8 +1287,8 @@ test "filesize" {
1283 // TODO https://github.com/ziglang/zig/issues/32891287 // TODO https://github.com/ziglang/zig/issues/3289
1284 return error.SkipZigTest;1288 return error.SkipZigTest;
1285 }1289 }
1286 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));1290 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", @as(usize, 63 * 1024 * 1024));
1287 try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", usize(63 * 1024 * 1024));1291 try testFmt("file size: 66.06MB\n", "file size: {B:.2}\n", @as(usize, 63 * 1024 * 1024));
1288}1292}
12891293
1290test "struct" {1294test "struct" {
...@@ -1321,10 +1325,10 @@ test "float.scientific" {...@@ -1321,10 +1325,10 @@ test "float.scientific" {
1321 // TODO https://github.com/ziglang/zig/issues/32891325 // TODO https://github.com/ziglang/zig/issues/3289
1322 return error.SkipZigTest;1326 return error.SkipZigTest;
1323 }1327 }
1324 try testFmt("f32: 1.34000003e+00", "f32: {e}", f32(1.34));1328 try testFmt("f32: 1.34000003e+00", "f32: {e}", @as(f32, 1.34));
1325 try testFmt("f32: 1.23400001e+01", "f32: {e}", f32(12.34));1329 try testFmt("f32: 1.23400001e+01", "f32: {e}", @as(f32, 12.34));
1326 try testFmt("f64: -1.234e+11", "f64: {e}", f64(-12.34e10));1330 try testFmt("f64: -1.234e+11", "f64: {e}", @as(f64, -12.34e10));
1327 try testFmt("f64: 9.99996e-40", "f64: {e}", f64(9.999960e-40));1331 try testFmt("f64: 9.99996e-40", "f64: {e}", @as(f64, 9.999960e-40));
1328}1332}
13291333
1330test "float.scientific.precision" {1334test "float.scientific.precision" {
...@@ -1332,12 +1336,12 @@ test "float.scientific.precision" {...@@ -1332,12 +1336,12 @@ test "float.scientific.precision" {
1332 // TODO https://github.com/ziglang/zig/issues/32891336 // TODO https://github.com/ziglang/zig/issues/3289
1333 return error.SkipZigTest;1337 return error.SkipZigTest;
1334 }1338 }
1335 try testFmt("f64: 1.40971e-42", "f64: {e:.5}", f64(1.409706e-42));1339 try testFmt("f64: 1.40971e-42", "f64: {e:.5}", @as(f64, 1.409706e-42));
1336 try testFmt("f64: 1.00000e-09", "f64: {e:.5}", f64(@bitCast(f32, u32(814313563))));1340 try testFmt("f64: 1.00000e-09", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 814313563))));
1337 try testFmt("f64: 7.81250e-03", "f64: {e:.5}", f64(@bitCast(f32, u32(1006632960))));1341 try testFmt("f64: 7.81250e-03", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 1006632960))));
1338 // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.1342 // libc rounds 1.000005e+05 to 1.00000e+05 but zig does 1.00001e+05.
1339 // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.1343 // In fact, libc doesn't round a lot of 5 cases up when one past the precision point.
1340 try testFmt("f64: 1.00001e+05", "f64: {e:.5}", f64(@bitCast(f32, u32(1203982400))));1344 try testFmt("f64: 1.00001e+05", "f64: {e:.5}", @as(f64, @bitCast(f32, @as(u32, 1203982400))));
1341}1345}
13421346
1343test "float.special" {1347test "float.special" {
...@@ -1360,21 +1364,21 @@ test "float.decimal" {...@@ -1360,21 +1364,21 @@ test "float.decimal" {
1360 // TODO https://github.com/ziglang/zig/issues/32891364 // TODO https://github.com/ziglang/zig/issues/3289
1361 return error.SkipZigTest;1365 return error.SkipZigTest;
1362 }1366 }
1363 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", f64(1.52314e+29));1367 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", @as(f64, 1.52314e+29));
1364 try testFmt("f32: 1.1", "f32: {d:.1}", f32(1.1234));1368 try testFmt("f32: 1.1", "f32: {d:.1}", @as(f32, 1.1234));
1365 try testFmt("f32: 1234.57", "f32: {d:.2}", f32(1234.567));1369 try testFmt("f32: 1234.57", "f32: {d:.2}", @as(f32, 1234.567));
1366 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).1370 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
1367 // -11.12339... is rounded back up to -11.12341371 // -11.12339... is rounded back up to -11.1234
1368 try testFmt("f32: -11.1234", "f32: {d:.4}", f32(-11.1234));1372 try testFmt("f32: -11.1234", "f32: {d:.4}", @as(f32, -11.1234));
1369 try testFmt("f32: 91.12345", "f32: {d:.5}", f32(91.12345));1373 try testFmt("f32: 91.12345", "f32: {d:.5}", @as(f32, 91.12345));
1370 try testFmt("f64: 91.1234567890", "f64: {d:.10}", f64(91.12345678901235));1374 try testFmt("f64: 91.1234567890", "f64: {d:.10}", @as(f64, 91.12345678901235));
1371 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(0.0));1375 try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 0.0));
1372 try testFmt("f64: 6", "f64: {d:.0}", f64(5.700));1376 try testFmt("f64: 6", "f64: {d:.0}", @as(f64, 5.700));
1373 try testFmt("f64: 10.0", "f64: {d:.1}", f64(9.999));1377 try testFmt("f64: 10.0", "f64: {d:.1}", @as(f64, 9.999));
1374 try testFmt("f64: 1.000", "f64: {d:.3}", f64(1.0));1378 try testFmt("f64: 1.000", "f64: {d:.3}", @as(f64, 1.0));
1375 try testFmt("f64: 0.00030000", "f64: {d:.8}", f64(0.0003));1379 try testFmt("f64: 0.00030000", "f64: {d:.8}", @as(f64, 0.0003));
1376 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(1.40130e-45));1380 try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 1.40130e-45));
1377 try testFmt("f64: 0.00000", "f64: {d:.5}", f64(9.999960e-40));1381 try testFmt("f64: 0.00000", "f64: {d:.5}", @as(f64, 9.999960e-40));
1378}1382}
13791383
1380test "float.libc.sanity" {1384test "float.libc.sanity" {
...@@ -1382,22 +1386,22 @@ test "float.libc.sanity" {...@@ -1382,22 +1386,22 @@ test "float.libc.sanity" {
1382 // TODO https://github.com/ziglang/zig/issues/32891386 // TODO https://github.com/ziglang/zig/issues/3289
1383 return error.SkipZigTest;1387 return error.SkipZigTest;
1384 }1388 }
1385 try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(916964781))));1389 try testFmt("f64: 0.00001", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 916964781))));
1386 try testFmt("f64: 0.00001", "f64: {d:.5}", f64(@bitCast(f32, u32(925353389))));1390 try testFmt("f64: 0.00001", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 925353389))));
1387 try testFmt("f64: 0.10000", "f64: {d:.5}", f64(@bitCast(f32, u32(1036831278))));1391 try testFmt("f64: 0.10000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1036831278))));
1388 try testFmt("f64: 1.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1065353133))));1392 try testFmt("f64: 1.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1065353133))));
1389 try testFmt("f64: 10.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1092616192))));1393 try testFmt("f64: 10.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1092616192))));
13901394
1391 // libc differences1395 // libc differences
1392 //1396 //
1393 // This is 0.015625 exactly according to gdb. We thus round down,1397 // This is 0.015625 exactly according to gdb. We thus round down,
1394 // however glibc rounds up for some reason. This occurs for all1398 // however glibc rounds up for some reason. This occurs for all
1395 // floats of the form x.yyyy25 on a precision point.1399 // floats of the form x.yyyy25 on a precision point.
1396 try testFmt("f64: 0.01563", "f64: {d:.5}", f64(@bitCast(f32, u32(1015021568))));1400 try testFmt("f64: 0.01563", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1015021568))));
1397 // errol3 rounds to ... 630 but libc rounds to ...632. Grisu31401 // errol3 rounds to ... 630 but libc rounds to ...632. Grisu3
1398 // also rounds to 630 so I'm inclined to believe libc is not1402 // also rounds to 630 so I'm inclined to believe libc is not
1399 // optimal here.1403 // optimal here.
1400 try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", f64(@bitCast(f32, u32(1518338049))));1404 try testFmt("f64: 18014400656965630.00000", "f64: {d:.5}", @as(f64, @bitCast(f32, @as(u32, 1518338049))));
1401}1405}
14021406
1403test "custom" {1407test "custom" {
...@@ -1673,17 +1677,17 @@ test "formatType max_depth" {...@@ -1673,17 +1677,17 @@ test "formatType max_depth" {
1673}1677}
16741678
1675test "positional" {1679test "positional" {
1676 try testFmt("2 1 0", "{2} {1} {0}", usize(0), usize(1), usize(2));1680 try testFmt("2 1 0", "{2} {1} {0}", @as(usize, 0), @as(usize, 1), @as(usize, 2));
1677 try testFmt("2 1 0", "{2} {1} {}", usize(0), usize(1), usize(2));1681 try testFmt("2 1 0", "{2} {1} {}", @as(usize, 0), @as(usize, 1), @as(usize, 2));
1678 try testFmt("0 0", "{0} {0}", usize(0));1682 try testFmt("0 0", "{0} {0}", @as(usize, 0));
1679 try testFmt("0 1", "{} {1}", usize(0), usize(1));1683 try testFmt("0 1", "{} {1}", @as(usize, 0), @as(usize, 1));
1680 try testFmt("1 0 0 1", "{1} {} {0} {}", usize(0), usize(1));1684 try testFmt("1 0 0 1", "{1} {} {0} {}", @as(usize, 0), @as(usize, 1));
1681}1685}
16821686
1683test "positional with specifier" {1687test "positional with specifier" {
1684 try testFmt("10.0", "{0d:.1}", f64(9.999));1688 try testFmt("10.0", "{0d:.1}", @as(f64, 9.999));
1685}1689}
16861690
1687test "positional/alignment/width/precision" {1691test "positional/alignment/width/precision" {
1688 try testFmt("10.0", "{0d: >3.1}", f64(9.999));1692 try testFmt("10.0", "{0d: >3.1}", @as(f64, 9.999));
1689}1693}
lib/std/fmt/errol.zig+2-2
...@@ -296,7 +296,7 @@ fn hpMul10(hp: *HP) void {...@@ -296,7 +296,7 @@ fn hpMul10(hp: *HP) void {
296/// @buf: The output buffer.296/// @buf: The output buffer.
297/// &return: The exponent.297/// &return: The exponent.
298fn errolInt(val: f64, buffer: []u8) FloatDecimal {298fn errolInt(val: f64, buffer: []u8) FloatDecimal {
299 const pow19 = u128(1e19);299 const pow19 = @as(u128, 1e19);
300300
301 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));301 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
302302
...@@ -670,7 +670,7 @@ fn fpeint(from: f64) u128 {...@@ -670,7 +670,7 @@ fn fpeint(from: f64) u128 {
670 const bits = @bitCast(u64, from);670 const bits = @bitCast(u64, from);
671 assert((bits & ((1 << 52) - 1)) == 0);671 assert((bits & ((1 << 52) - 1)) == 0);
672672
673 return u128(1) << @truncate(u7, (bits >> 52) -% 1023);673 return @as(u128, 1) << @truncate(u7, (bits >> 52) -% 1023);
674}674}
675675
676/// Given two different integers with the same length in terms of the number676/// Given two different integers with the same length in terms of the number
lib/std/fmt/parse_float.zig+10-10
...@@ -59,29 +59,29 @@ const Z96 = struct {...@@ -59,29 +59,29 @@ const Z96 = struct {
5959
60 // d += s60 // d += s
61 inline fn add(d: *Z96, s: Z96) void {61 inline fn add(d: *Z96, s: Z96) void {
62 var w = u64(d.d0) + u64(s.d0);62 var w = @as(u64, d.d0) + @as(u64, s.d0);
63 d.d0 = @truncate(u32, w);63 d.d0 = @truncate(u32, w);
6464
65 w >>= 32;65 w >>= 32;
66 w += u64(d.d1) + u64(s.d1);66 w += @as(u64, d.d1) + @as(u64, s.d1);
67 d.d1 = @truncate(u32, w);67 d.d1 = @truncate(u32, w);
6868
69 w >>= 32;69 w >>= 32;
70 w += u64(d.d2) + u64(s.d2);70 w += @as(u64, d.d2) + @as(u64, s.d2);
71 d.d2 = @truncate(u32, w);71 d.d2 = @truncate(u32, w);
72 }72 }
7373
74 // d -= s74 // d -= s
75 inline fn sub(d: *Z96, s: Z96) void {75 inline fn sub(d: *Z96, s: Z96) void {
76 var w = u64(d.d0) -% u64(s.d0);76 var w = @as(u64, d.d0) -% @as(u64, s.d0);
77 d.d0 = @truncate(u32, w);77 d.d0 = @truncate(u32, w);
7878
79 w >>= 32;79 w >>= 32;
80 w += u64(d.d1) -% u64(s.d1);80 w += @as(u64, d.d1) -% @as(u64, s.d1);
81 d.d1 = @truncate(u32, w);81 d.d1 = @truncate(u32, w);
8282
83 w >>= 32;83 w >>= 32;
84 w += u64(d.d2) -% u64(s.d2);84 w += @as(u64, d.d2) -% @as(u64, s.d2);
85 d.d2 = @truncate(u32, w);85 d.d2 = @truncate(u32, w);
86 }86 }
87};87};
...@@ -160,7 +160,7 @@ fn convertRepr(comptime T: type, n: FloatRepr) T {...@@ -160,7 +160,7 @@ fn convertRepr(comptime T: type, n: FloatRepr) T {
160 break :blk if (n.negative) f64_minus_zero else f64_plus_zero;160 break :blk if (n.negative) f64_minus_zero else f64_plus_zero;
161 } else if (s.d2 != 0) {161 } else if (s.d2 != 0) {
162 const binexs2 = @intCast(u64, binary_exponent) << 52;162 const binexs2 = @intCast(u64, binary_exponent) << 52;
163 const rr = (u64(s.d2 & ~mask28) << 24) | ((u64(s.d1) + 128) >> 8) | binexs2;163 const rr = (@as(u64, s.d2 & ~mask28) << 24) | ((@as(u64, s.d1) + 128) >> 8) | binexs2;
164 break :blk if (n.negative) rr | (1 << 63) else rr;164 break :blk if (n.negative) rr | (1 << 63) else rr;
165 } else {165 } else {
166 break :blk 0;166 break :blk 0;
...@@ -375,7 +375,7 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T {...@@ -375,7 +375,7 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T {
375 return switch (try parseRepr(s, &r)) {375 return switch (try parseRepr(s, &r)) {
376 ParseResult.Ok => convertRepr(T, r),376 ParseResult.Ok => convertRepr(T, r),
377 ParseResult.PlusZero => 0.0,377 ParseResult.PlusZero => 0.0,
378 ParseResult.MinusZero => -T(0.0),378 ParseResult.MinusZero => -@as(T, 0.0),
379 ParseResult.PlusInf => std.math.inf(T),379 ParseResult.PlusInf => std.math.inf(T),
380 ParseResult.MinusInf => -std.math.inf(T),380 ParseResult.MinusInf => -std.math.inf(T),
381 };381 };
...@@ -426,8 +426,8 @@ test "fmt.parseFloat" {...@@ -426,8 +426,8 @@ test "fmt.parseFloat" {
426 expect(approxEq(T, try parseFloat(T, "1234e-2"), 12.34, epsilon));426 expect(approxEq(T, try parseFloat(T, "1234e-2"), 12.34, epsilon));
427427
428 expect(approxEq(T, try parseFloat(T, "123142.1"), 123142.1, epsilon));428 expect(approxEq(T, try parseFloat(T, "123142.1"), 123142.1, epsilon));
429 expect(approxEq(T, try parseFloat(T, "-123142.1124"), T(-123142.1124), epsilon));429 expect(approxEq(T, try parseFloat(T, "-123142.1124"), @as(T, -123142.1124), epsilon));
430 expect(approxEq(T, try parseFloat(T, "0.7062146892655368"), T(0.7062146892655368), epsilon));430 expect(approxEq(T, try parseFloat(T, "0.7062146892655368"), @as(T, 0.7062146892655368), epsilon));
431 }431 }
432 }432 }
433}433}
lib/std/fs.zig+104-11
...@@ -6,6 +6,7 @@ const base64 = std.base64;...@@ -6,6 +6,7 @@ const base64 = std.base64;
6const crypto = std.crypto;6const crypto = std.crypto;
7const Allocator = std.mem.Allocator;7const Allocator = std.mem.Allocator;
8const assert = std.debug.assert;8const assert = std.debug.assert;
9const math = std.math;
910
10pub const path = @import("fs/path.zig");11pub const path = @import("fs/path.zig");
11pub const File = @import("fs/file.zig").File;12pub const File = @import("fs/file.zig").File;
...@@ -584,7 +585,7 @@ pub const Dir = struct {...@@ -584,7 +585,7 @@ pub const Dir = struct {
584 .FileBothDirectoryInformation,585 .FileBothDirectoryInformation,
585 w.FALSE,586 w.FALSE,
586 null,587 null,
587 if (self.first) w.BOOLEAN(w.TRUE) else w.BOOLEAN(w.FALSE),588 if (self.first) @as(w.BOOLEAN, w.TRUE) else @as(w.BOOLEAN, w.FALSE),
588 );589 );
589 self.first = false;590 self.first = false;
590 if (io.Information == 0) return null;591 if (io.Information == 0) return null;
...@@ -698,17 +699,81 @@ pub const Dir = struct {...@@ -698,17 +699,81 @@ pub const Dir = struct {
698699
699 /// Call `File.close` on the result when done.700 /// Call `File.close` on the result when done.
700 pub fn openRead(self: Dir, sub_path: []const u8) File.OpenError!File {701 pub fn openRead(self: Dir, sub_path: []const u8) File.OpenError!File {
702 if (builtin.os == .windows) {
703 const path_w = try os.windows.sliceToPrefixedFileW(sub_path);
704 return self.openReadW(&path_w);
705 }
701 const path_c = try os.toPosixPath(sub_path);706 const path_c = try os.toPosixPath(sub_path);
702 return self.openReadC(&path_c);707 return self.openReadC(&path_c);
703 }708 }
704709
705 /// Call `File.close` on the result when done.710 /// Call `File.close` on the result when done.
706 pub fn openReadC(self: Dir, sub_path: [*]const u8) File.OpenError!File {711 pub fn openReadC(self: Dir, sub_path: [*]const u8) File.OpenError!File {
707 const flags = os.O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;712 if (builtin.os == .windows) {
713 const path_w = try os.windows.cStrToPrefixedFileW(sub_path);
714 return self.openReadW(&path_w);
715 }
716 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
717 const flags = O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;
708 const fd = try os.openatC(self.fd, sub_path, flags, 0);718 const fd = try os.openatC(self.fd, sub_path, flags, 0);
709 return File.openHandle(fd);719 return File.openHandle(fd);
710 }720 }
711721
722 pub fn openReadW(self: Dir, sub_path_w: [*]const u16) File.OpenError!File {
723 const w = os.windows;
724
725 var result = File{ .handle = undefined };
726
727 const path_len_bytes = math.cast(u16, mem.toSliceConst(u16, sub_path_w).len * 2) catch |err| switch (err) {
728 error.Overflow => return error.NameTooLong,
729 };
730 var nt_name = w.UNICODE_STRING{
731 .Length = path_len_bytes,
732 .MaximumLength = path_len_bytes,
733 .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)),
734 };
735 var attr = w.OBJECT_ATTRIBUTES{
736 .Length = @sizeOf(w.OBJECT_ATTRIBUTES),
737 .RootDirectory = if (path.isAbsoluteW(sub_path_w)) null else self.fd,
738 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
739 .ObjectName = &nt_name,
740 .SecurityDescriptor = null,
741 .SecurityQualityOfService = null,
742 };
743 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
744 return error.IsDir;
745 }
746 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
747 return error.IsDir;
748 }
749 var io: w.IO_STATUS_BLOCK = undefined;
750 const rc = w.ntdll.NtCreateFile(
751 &result.handle,
752 w.GENERIC_READ | w.SYNCHRONIZE,
753 &attr,
754 &io,
755 null,
756 w.FILE_ATTRIBUTE_NORMAL,
757 w.FILE_SHARE_READ,
758 w.FILE_OPEN,
759 w.FILE_NON_DIRECTORY_FILE | w.FILE_SYNCHRONOUS_IO_NONALERT,
760 null,
761 0,
762 );
763 switch (rc) {
764 w.STATUS.SUCCESS => return result,
765 w.STATUS.OBJECT_NAME_INVALID => unreachable,
766 w.STATUS.OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
767 w.STATUS.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
768 w.STATUS.INVALID_PARAMETER => unreachable,
769 w.STATUS.SHARING_VIOLATION => return error.SharingViolation,
770 w.STATUS.ACCESS_DENIED => return error.AccessDenied,
771 w.STATUS.PIPE_BUSY => return error.PipeBusy,
772 w.STATUS.OBJECT_PATH_SYNTAX_BAD => unreachable,
773 else => return w.unexpectedStatus(rc),
774 }
775 }
776
712 /// Call `close` on the result when done.777 /// Call `close` on the result when done.
713 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {778 pub fn openDir(self: Dir, sub_path: []const u8) OpenError!Dir {
714 if (builtin.os == .windows) {779 if (builtin.os == .windows) {
...@@ -866,6 +931,34 @@ pub const Dir = struct {...@@ -866,6 +931,34 @@ pub const Dir = struct {
866 return os.readlinkatC(self.fd, sub_path_c, buffer);931 return os.readlinkatC(self.fd, sub_path_c, buffer);
867 }932 }
868933
934 /// On success, caller owns returned buffer.
935 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
936 pub fn readFileAlloc(self: Dir, allocator: *mem.Allocator, file_path: []const u8, max_bytes: usize) ![]u8 {
937 return self.readFileAllocAligned(allocator, file_path, max_bytes, @alignOf(u8));
938 }
939
940 /// On success, caller owns returned buffer.
941 /// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
942 pub fn readFileAllocAligned(
943 self: Dir,
944 allocator: *mem.Allocator,
945 file_path: []const u8,
946 max_bytes: usize,
947 comptime A: u29,
948 ) ![]align(A) u8 {
949 var file = try self.openRead(file_path);
950 defer file.close();
951
952 const size = math.cast(usize, try file.getEndPos()) catch math.maxInt(usize);
953 if (size > max_bytes) return error.FileTooBig;
954
955 const buf = try allocator.alignedAlloc(u8, A, size);
956 errdefer allocator.free(buf);
957
958 try file.inStream().stream.readNoEof(buf);
959 return buf;
960 }
961
869 pub const DeleteTreeError = error{962 pub const DeleteTreeError = error{
870 AccessDenied,963 AccessDenied,
871 FileTooBig,964 FileTooBig,
...@@ -1100,7 +1193,7 @@ pub const Walker = struct {...@@ -1100,7 +1193,7 @@ pub const Walker = struct {
1100 }1193 }
11011194
1102 pub fn deinit(self: *Walker) void {1195 pub fn deinit(self: *Walker) void {
1103 while (self.stack.popOrNull()) |*item| item.dir_it.close();1196 while (self.stack.popOrNull()) |*item| item.dir_it.dir.close();
1104 self.stack.deinit();1197 self.stack.deinit();
1105 self.name_buffer.deinit();1198 self.name_buffer.deinit();
1106 }1199 }
...@@ -1150,9 +1243,9 @@ pub fn openSelfExe() OpenSelfExeError!File {...@@ -1150,9 +1243,9 @@ pub fn openSelfExe() OpenSelfExeError!File {
1150 return File.openReadC(c"/proc/self/exe");1243 return File.openReadC(c"/proc/self/exe");
1151 }1244 }
1152 if (builtin.os == .windows) {1245 if (builtin.os == .windows) {
1153 var buf: [os.windows.PATH_MAX_WIDE]u16 = undefined;1246 const wide_slice = selfExePathW();
1154 const wide_slice = try selfExePathW(&buf);1247 const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);
1155 return File.openReadW(wide_slice.ptr);1248 return Dir.cwd().openReadW(&prefixed_path_w);
1156 }1249 }
1157 var buf: [MAX_PATH_BYTES]u8 = undefined;1250 var buf: [MAX_PATH_BYTES]u8 = undefined;
1158 const self_exe_path = try selfExePath(&buf);1251 const self_exe_path = try selfExePath(&buf);
...@@ -1203,8 +1296,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {...@@ -1203,8 +1296,7 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1203 return mem.toSlice(u8, out_buffer);1296 return mem.toSlice(u8, out_buffer);
1204 },1297 },
1205 .windows => {1298 .windows => {
1206 var utf16le_buf: [os.windows.PATH_MAX_WIDE]u16 = undefined;1299 const utf16le_slice = selfExePathW();
1207 const utf16le_slice = try selfExePathW(&utf16le_buf);
1208 // Trust that Windows gives us valid UTF-16LE.1300 // Trust that Windows gives us valid UTF-16LE.
1209 const end_index = std.unicode.utf16leToUtf8(out_buffer, utf16le_slice) catch unreachable;1301 const end_index = std.unicode.utf16leToUtf8(out_buffer, utf16le_slice) catch unreachable;
1210 return out_buffer[0..end_index];1302 return out_buffer[0..end_index];
...@@ -1213,9 +1305,10 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {...@@ -1213,9 +1305,10 @@ pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) SelfExePathError![]u8 {
1213 }1305 }
1214}1306}
12151307
1216/// Same as `selfExePath` except the result is UTF16LE-encoded.1308/// The result is UTF16LE-encoded.
1217pub fn selfExePathW(out_buffer: *[os.windows.PATH_MAX_WIDE]u16) SelfExePathError![]u16 {1309pub fn selfExePathW() []const u16 {
1218 return os.windows.GetModuleFileNameW(null, out_buffer, out_buffer.len);1310 const image_path_name = &os.windows.peb().ProcessParameters.ImagePathName;
1311 return mem.toSliceConst(u16, image_path_name.Buffer);
1219}1312}
12201313
1221/// `selfExeDirPath` except allocates the result on the heap.1314/// `selfExeDirPath` except allocates the result on the heap.
lib/std/fs/file.zig+24-32
...@@ -25,42 +25,23 @@ pub const File = struct {...@@ -25,42 +25,23 @@ pub const File = struct {
2525
26 pub const OpenError = windows.CreateFileError || os.OpenError;26 pub const OpenError = windows.CreateFileError || os.OpenError;
2727
28 /// Call close to clean up.28 /// Deprecated; call `std.fs.Dir.openRead` directly.
29 pub fn openRead(path: []const u8) OpenError!File {29 pub fn openRead(path: []const u8) OpenError!File {
30 if (builtin.os == .windows) {30 return std.fs.Dir.cwd().openRead(path);
31 const path_w = try windows.sliceToPrefixedFileW(path);
32 return openReadW(&path_w);
33 }
34 const path_c = try os.toPosixPath(path);
35 return openReadC(&path_c);
36 }31 }
3732
38 /// `openRead` except with a null terminated path33 /// Deprecated; call `std.fs.Dir.openReadC` directly.
39 pub fn openReadC(path: [*]const u8) OpenError!File {34 pub fn openReadC(path_c: [*]const u8) OpenError!File {
40 if (builtin.os == .windows) {35 return std.fs.Dir.cwd().openReadC(path_c);
41 const path_w = try windows.cStrToPrefixedFileW(path);
42 return openReadW(&path_w);
43 }
44 const flags = os.O_LARGEFILE | os.O_RDONLY | os.O_CLOEXEC;
45 const fd = try os.openC(path, flags, 0);
46 return openHandle(fd);
47 }36 }
4837
49 /// `openRead` except with a null terminated UTF16LE encoded path38 /// Deprecated; call `std.fs.Dir.openReadW` directly.
50 pub fn openReadW(path_w: [*]const u16) OpenError!File {39 pub fn openReadW(path_w: [*]const u16) OpenError!File {
51 const handle = try windows.CreateFileW(40 return std.fs.Dir.cwd().openReadW(path_w);
52 path_w,
53 windows.GENERIC_READ,
54 windows.FILE_SHARE_READ,
55 null,
56 windows.OPEN_EXISTING,
57 windows.FILE_ATTRIBUTE_NORMAL,
58 null,
59 );
60 return openHandle(handle);
61 }41 }
6242
63 /// Calls `openWriteMode` with `default_mode` for the mode.43 /// Calls `openWriteMode` with `default_mode` for the mode.
44 /// TODO: deprecate this and move it to `std.fs.Dir`.
64 pub fn openWrite(path: []const u8) OpenError!File {45 pub fn openWrite(path: []const u8) OpenError!File {
65 return openWriteMode(path, default_mode);46 return openWriteMode(path, default_mode);
66 }47 }
...@@ -68,6 +49,7 @@ pub const File = struct {...@@ -68,6 +49,7 @@ pub const File = struct {
68 /// If the path does not exist it will be created.49 /// If the path does not exist it will be created.
69 /// If a file already exists in the destination it will be truncated.50 /// If a file already exists in the destination it will be truncated.
70 /// Call close to clean up.51 /// Call close to clean up.
52 /// TODO: deprecate this and move it to `std.fs.Dir`.
71 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {53 pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
72 if (builtin.os == .windows) {54 if (builtin.os == .windows) {
73 const path_w = try windows.sliceToPrefixedFileW(path);55 const path_w = try windows.sliceToPrefixedFileW(path);
...@@ -78,17 +60,20 @@ pub const File = struct {...@@ -78,17 +60,20 @@ pub const File = struct {
78 }60 }
7961
80 /// Same as `openWriteMode` except `path` is null-terminated.62 /// Same as `openWriteMode` except `path` is null-terminated.
63 /// TODO: deprecate this and move it to `std.fs.Dir`.
81 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {64 pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {
82 if (builtin.os == .windows) {65 if (builtin.os == .windows) {
83 const path_w = try windows.cStrToPrefixedFileW(path);66 const path_w = try windows.cStrToPrefixedFileW(path);
84 return openWriteModeW(&path_w, file_mode);67 return openWriteModeW(&path_w, file_mode);
85 }68 }
86 const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;69 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
70 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;
87 const fd = try os.openC(path, flags, file_mode);71 const fd = try os.openC(path, flags, file_mode);
88 return openHandle(fd);72 return openHandle(fd);
89 }73 }
9074
91 /// Same as `openWriteMode` except `path` is null-terminated and UTF16LE encoded75 /// Same as `openWriteMode` except `path` is null-terminated and UTF16LE encoded
76 /// TODO: deprecate this and move it to `std.fs.Dir`.
92 pub fn openWriteModeW(path_w: [*]const u16, file_mode: Mode) OpenError!File {77 pub fn openWriteModeW(path_w: [*]const u16, file_mode: Mode) OpenError!File {
93 const handle = try windows.CreateFileW(78 const handle = try windows.CreateFileW(
94 path_w,79 path_w,
...@@ -105,6 +90,7 @@ pub const File = struct {...@@ -105,6 +90,7 @@ pub const File = struct {
105 /// If the path does not exist it will be created.90 /// If the path does not exist it will be created.
106 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists91 /// If a file already exists in the destination this returns OpenError.PathAlreadyExists
107 /// Call close to clean up.92 /// Call close to clean up.
93 /// TODO: deprecate this and move it to `std.fs.Dir`.
108 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {94 pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
109 if (builtin.os == .windows) {95 if (builtin.os == .windows) {
110 const path_w = try windows.sliceToPrefixedFileW(path);96 const path_w = try windows.sliceToPrefixedFileW(path);
...@@ -114,16 +100,19 @@ pub const File = struct {...@@ -114,16 +100,19 @@ pub const File = struct {
114 return openWriteNoClobberC(&path_c, file_mode);100 return openWriteNoClobberC(&path_c, file_mode);
115 }101 }
116102
103 /// TODO: deprecate this and move it to `std.fs.Dir`.
117 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {104 pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {
118 if (builtin.os == .windows) {105 if (builtin.os == .windows) {
119 const path_w = try windows.cStrToPrefixedFileW(path);106 const path_w = try windows.cStrToPrefixedFileW(path);
120 return openWriteNoClobberW(&path_w, file_mode);107 return openWriteNoClobberW(&path_w, file_mode);
121 }108 }
122 const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_EXCL;109 const O_LARGEFILE = if (@hasDecl(os, "O_LARGEFILE")) os.O_LARGEFILE else 0;
110 const flags = O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_EXCL;
123 const fd = try os.openC(path, flags, file_mode);111 const fd = try os.openC(path, flags, file_mode);
124 return openHandle(fd);112 return openHandle(fd);
125 }113 }
126114
115 /// TODO: deprecate this and move it to `std.fs.Dir`.
127 pub fn openWriteNoClobberW(path_w: [*]const u16, file_mode: Mode) OpenError!File {116 pub fn openWriteNoClobberW(path_w: [*]const u16, file_mode: Mode) OpenError!File {
128 const handle = try windows.CreateFileW(117 const handle = try windows.CreateFileW(
129 path_w,118 path_w,
...@@ -146,16 +135,19 @@ pub const File = struct {...@@ -146,16 +135,19 @@ pub const File = struct {
146 /// In general it is recommended to avoid this function. For example,135 /// In general it is recommended to avoid this function. For example,
147 /// instead of testing if a file exists and then opening it, just136 /// instead of testing if a file exists and then opening it, just
148 /// open it and handle the error for file not found.137 /// open it and handle the error for file not found.
138 /// TODO: deprecate this and move it to `std.fs.Dir`.
149 pub fn access(path: []const u8) !void {139 pub fn access(path: []const u8) !void {
150 return os.access(path, os.F_OK);140 return os.access(path, os.F_OK);
151 }141 }
152142
153 /// Same as `access` except the parameter is null-terminated.143 /// Same as `access` except the parameter is null-terminated.
144 /// TODO: deprecate this and move it to `std.fs.Dir`.
154 pub fn accessC(path: [*]const u8) !void {145 pub fn accessC(path: [*]const u8) !void {
155 return os.accessC(path, os.F_OK);146 return os.accessC(path, os.F_OK);
156 }147 }
157148
158 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.149 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
150 /// TODO: deprecate this and move it to `std.fs.Dir`.
159 pub fn accessW(path: [*]const u16) !void {151 pub fn accessW(path: [*]const u16) !void {
160 return os.accessW(path, os.F_OK);152 return os.accessW(path, os.F_OK);
161 }153 }
...@@ -272,9 +264,9 @@ pub const File = struct {...@@ -272,9 +264,9 @@ pub const File = struct {
272 return Stat{264 return Stat{
273 .size = @bitCast(u64, st.size),265 .size = @bitCast(u64, st.size),
274 .mode = st.mode,266 .mode = st.mode,
275 .atime = i64(atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,267 .atime = @as(i64, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec,
276 .mtime = i64(mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,268 .mtime = @as(i64, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec,
277 .ctime = i64(ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,269 .ctime = @as(i64, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec,
278 };270 };
279 }271 }
280272
lib/std/fs/path.zig+1-1
...@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) bool {...@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) bool {
32/// This is different from mem.join in that the separator will not be repeated if32/// This is different from mem.join in that the separator will not be repeated if
33/// it is found at the end or beginning of a pair of consecutive paths.33/// it is found at the end or beginning of a pair of consecutive paths.
34fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u8 {34fn joinSep(allocator: *Allocator, separator: u8, paths: []const []const u8) ![]u8 {
35 if (paths.len == 0) return (([*]u8)(undefined))[0..0];35 if (paths.len == 0) return &[0]u8{};
3636
37 const total_len = blk: {37 const total_len = blk: {
38 var sum: usize = paths[0].len;38 var sum: usize = paths[0].len;
lib/std/hash/auto_hash.zig+7-7
...@@ -306,7 +306,7 @@ test "hash struct deep" {...@@ -306,7 +306,7 @@ test "hash struct deep" {
306test "testHash optional" {306test "testHash optional" {
307 const a: ?u32 = 123;307 const a: ?u32 = 123;
308 const b: ?u32 = null;308 const b: ?u32 = null;
309 testing.expectEqual(testHash(a), testHash(u32(123)));309 testing.expectEqual(testHash(a), testHash(@as(u32, 123)));
310 testing.expect(testHash(a) != testHash(b));310 testing.expect(testHash(a) != testHash(b));
311 testing.expectEqual(testHash(b), 0);311 testing.expectEqual(testHash(b), 0);
312}312}
...@@ -315,9 +315,9 @@ test "testHash array" {...@@ -315,9 +315,9 @@ test "testHash array" {
315 const a = [_]u32{ 1, 2, 3 };315 const a = [_]u32{ 1, 2, 3 };
316 const h = testHash(a);316 const h = testHash(a);
317 var hasher = Wyhash.init(0);317 var hasher = Wyhash.init(0);
318 autoHash(&hasher, u32(1));318 autoHash(&hasher, @as(u32, 1));
319 autoHash(&hasher, u32(2));319 autoHash(&hasher, @as(u32, 2));
320 autoHash(&hasher, u32(3));320 autoHash(&hasher, @as(u32, 3));
321 testing.expectEqual(h, hasher.final());321 testing.expectEqual(h, hasher.final());
322}322}
323323
...@@ -330,9 +330,9 @@ test "testHash struct" {...@@ -330,9 +330,9 @@ test "testHash struct" {
330 const f = Foo{};330 const f = Foo{};
331 const h = testHash(f);331 const h = testHash(f);
332 var hasher = Wyhash.init(0);332 var hasher = Wyhash.init(0);
333 autoHash(&hasher, u32(1));333 autoHash(&hasher, @as(u32, 1));
334 autoHash(&hasher, u32(2));334 autoHash(&hasher, @as(u32, 2));
335 autoHash(&hasher, u32(3));335 autoHash(&hasher, @as(u32, 3));
336 testing.expectEqual(h, hasher.final());336 testing.expectEqual(h, hasher.final());
337}337}
338338
lib/std/hash/cityhash.zig+4-4
...@@ -214,7 +214,7 @@ pub const CityHash64 = struct {...@@ -214,7 +214,7 @@ pub const CityHash64 = struct {
214 }214 }
215215
216 fn hashLen0To16(str: []const u8) u64 {216 fn hashLen0To16(str: []const u8) u64 {
217 const len: u64 = u64(str.len);217 const len: u64 = @as(u64, str.len);
218 if (len >= 8) {218 if (len >= 8) {
219 const mul: u64 = k2 +% len *% 2;219 const mul: u64 = k2 +% len *% 2;
220 const a: u64 = fetch64(str.ptr) +% k2;220 const a: u64 = fetch64(str.ptr) +% k2;
...@@ -240,7 +240,7 @@ pub const CityHash64 = struct {...@@ -240,7 +240,7 @@ pub const CityHash64 = struct {
240 }240 }
241241
242 fn hashLen17To32(str: []const u8) u64 {242 fn hashLen17To32(str: []const u8) u64 {
243 const len: u64 = u64(str.len);243 const len: u64 = @as(u64, str.len);
244 const mul: u64 = k2 +% len *% 2;244 const mul: u64 = k2 +% len *% 2;
245 const a: u64 = fetch64(str.ptr) *% k1;245 const a: u64 = fetch64(str.ptr) *% k1;
246 const b: u64 = fetch64(str.ptr + 8);246 const b: u64 = fetch64(str.ptr + 8);
...@@ -251,7 +251,7 @@ pub const CityHash64 = struct {...@@ -251,7 +251,7 @@ pub const CityHash64 = struct {
251 }251 }
252252
253 fn hashLen33To64(str: []const u8) u64 {253 fn hashLen33To64(str: []const u8) u64 {
254 const len: u64 = u64(str.len);254 const len: u64 = @as(u64, str.len);
255 const mul: u64 = k2 +% len *% 2;255 const mul: u64 = k2 +% len *% 2;
256 const a: u64 = fetch64(str.ptr) *% k2;256 const a: u64 = fetch64(str.ptr) *% k2;
257 const b: u64 = fetch64(str.ptr + 8);257 const b: u64 = fetch64(str.ptr + 8);
...@@ -305,7 +305,7 @@ pub const CityHash64 = struct {...@@ -305,7 +305,7 @@ pub const CityHash64 = struct {
305 return hashLen33To64(str);305 return hashLen33To64(str);
306 }306 }
307307
308 var len: u64 = u64(str.len);308 var len: u64 = @as(u64, str.len);
309309
310 var x: u64 = fetch64(str.ptr + str.len - 40);310 var x: u64 = fetch64(str.ptr + str.len - 40);
311 var y: u64 = fetch64(str.ptr + str.len - 16) +% fetch64(str.ptr + str.len - 56);311 var y: u64 = fetch64(str.ptr + str.len - 16) +% fetch64(str.ptr + str.len - 56);
lib/std/hash/crc.zig+4-4
...@@ -65,10 +65,10 @@ pub fn Crc32WithPoly(comptime poly: u32) type {...@@ -65,10 +65,10 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
65 const p = input[i .. i + 8];65 const p = input[i .. i + 8];
6666
67 // Unrolling this way gives ~50Mb/s increase67 // Unrolling this way gives ~50Mb/s increase
68 self.crc ^= (u32(p[0]) << 0);68 self.crc ^= (@as(u32, p[0]) << 0);
69 self.crc ^= (u32(p[1]) << 8);69 self.crc ^= (@as(u32, p[1]) << 8);
70 self.crc ^= (u32(p[2]) << 16);70 self.crc ^= (@as(u32, p[2]) << 16);
71 self.crc ^= (u32(p[3]) << 24);71 self.crc ^= (@as(u32, p[3]) << 24);
7272
73 self.crc =73 self.crc =
74 lookup_tables[0][p[7]] ^74 lookup_tables[0][p[7]] ^
lib/std/hash/murmur.zig+1-1
...@@ -98,7 +98,7 @@ pub const Murmur2_64 = struct {...@@ -98,7 +98,7 @@ pub const Murmur2_64 = struct {
9898
99 pub fn hashWithSeed(str: []const u8, seed: u64) u64 {99 pub fn hashWithSeed(str: []const u8, seed: u64) u64 {
100 const m: u64 = 0xc6a4a7935bd1e995;100 const m: u64 = 0xc6a4a7935bd1e995;
101 const len = u64(str.len);101 const len = @as(u64, str.len);
102 var h1: u64 = seed ^ (len *% m);102 var h1: u64 = seed ^ (len *% m);
103 for (@ptrCast([*]allowzero align(1) const u64, str.ptr)[0..@intCast(usize, len >> 3)]) |v| {103 for (@ptrCast([*]allowzero align(1) const u64, str.ptr)[0..@intCast(usize, len >> 3)]) |v| {
104 var k1: u64 = v;104 var k1: u64 = v;
lib/std/hash/siphash.zig+7-7
...@@ -102,7 +102,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round...@@ -102,7 +102,7 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
102 }102 }
103103
104 const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3;104 const b2 = self.v0 ^ self.v1 ^ self.v2 ^ self.v3;
105 return (u128(b2) << 64) | b1;105 return (@as(u128, b2) << 64) | b1;
106 }106 }
107107
108 fn round(self: *Self, b: []const u8) void {108 fn round(self: *Self, b: []const u8) void {
...@@ -121,19 +121,19 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round...@@ -121,19 +121,19 @@ fn SipHashStateless(comptime T: type, comptime c_rounds: usize, comptime d_round
121121
122 fn sipRound(d: *Self) void {122 fn sipRound(d: *Self) void {
123 d.v0 +%= d.v1;123 d.v0 +%= d.v1;
124 d.v1 = math.rotl(u64, d.v1, u64(13));124 d.v1 = math.rotl(u64, d.v1, @as(u64, 13));
125 d.v1 ^= d.v0;125 d.v1 ^= d.v0;
126 d.v0 = math.rotl(u64, d.v0, u64(32));126 d.v0 = math.rotl(u64, d.v0, @as(u64, 32));
127 d.v2 +%= d.v3;127 d.v2 +%= d.v3;
128 d.v3 = math.rotl(u64, d.v3, u64(16));128 d.v3 = math.rotl(u64, d.v3, @as(u64, 16));
129 d.v3 ^= d.v2;129 d.v3 ^= d.v2;
130 d.v0 +%= d.v3;130 d.v0 +%= d.v3;
131 d.v3 = math.rotl(u64, d.v3, u64(21));131 d.v3 = math.rotl(u64, d.v3, @as(u64, 21));
132 d.v3 ^= d.v0;132 d.v3 ^= d.v0;
133 d.v2 +%= d.v1;133 d.v2 +%= d.v1;
134 d.v1 = math.rotl(u64, d.v1, u64(17));134 d.v1 = math.rotl(u64, d.v1, @as(u64, 17));
135 d.v1 ^= d.v2;135 d.v1 ^= d.v2;
136 d.v2 = math.rotl(u64, d.v2, u64(32));136 d.v2 = math.rotl(u64, d.v2, @as(u64, 32));
137 }137 }
138138
139 pub fn hash(key: []const u8, input: []const u8) T {139 pub fn hash(key: []const u8, input: []const u8) T {
lib/std/hash_map.zig+1-1
...@@ -402,7 +402,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3...@@ -402,7 +402,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3
402 }402 }
403403
404 fn keyToIndex(hm: Self, key: K) usize {404 fn keyToIndex(hm: Self, key: K) usize {
405 return hm.constrainIndex(usize(hash(key)));405 return hm.constrainIndex(@as(usize, hash(key)));
406 }406 }
407407
408 fn constrainIndex(hm: Self, i: usize) usize {408 fn constrainIndex(hm: Self, i: usize) usize {
lib/std/heap.zig+5-7
...@@ -41,8 +41,7 @@ var direct_allocator_state = Allocator{...@@ -41,8 +41,7 @@ var direct_allocator_state = Allocator{
4141
42const DirectAllocator = struct {42const DirectAllocator = struct {
43 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {43 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
44 if (n == 0)44 if (n == 0) return &[0]u8{};
45 return (([*]u8)(undefined))[0..0];
4645
47 if (builtin.os == .windows) {46 if (builtin.os == .windows) {
48 const w = os.windows;47 const w = os.windows;
...@@ -261,8 +260,7 @@ pub const HeapAllocator = switch (builtin.os) {...@@ -261,8 +260,7 @@ pub const HeapAllocator = switch (builtin.os) {
261260
262 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {261 fn alloc(allocator: *Allocator, n: usize, alignment: u29) error{OutOfMemory}![]u8 {
263 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);262 const self = @fieldParentPtr(HeapAllocator, "allocator", allocator);
264 if (n == 0)263 if (n == 0) return &[0]u8{};
265 return (([*]u8)(undefined))[0..0];
266264
267 const amt = n + alignment + @sizeOf(usize);265 const amt = n + alignment + @sizeOf(usize);
268 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);266 const optional_heap_handle = @atomicLoad(?HeapHandle, &self.heap_handle, builtin.AtomicOrder.SeqCst);
...@@ -677,7 +675,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type {...@@ -677,7 +675,7 @@ pub fn StackFallbackAllocator(comptime size: usize) type {
677 ) catch {675 ) catch {
678 const result = try self.fallback_allocator.reallocFn(676 const result = try self.fallback_allocator.reallocFn(
679 self.fallback_allocator,677 self.fallback_allocator,
680 ([*]u8)(undefined)[0..0],678 &[0]u8{},
681 undefined,679 undefined,
682 new_size,680 new_size,
683 new_align,681 new_align,
...@@ -895,10 +893,10 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo...@@ -895,10 +893,10 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
895 if (mem.page_size << 2 > maxInt(usize)) return;893 if (mem.page_size << 2 > maxInt(usize)) return;
896894
897 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));895 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));
898 const large_align = u29(mem.page_size << 2);896 const large_align = @as(u29, mem.page_size << 2);
899897
900 var align_mask: usize = undefined;898 var align_mask: usize = undefined;
901 _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask);899 _ = @shlWithOverflow(usize, ~@as(usize, 0), @as(USizeShift, @ctz(u29, large_align)), &align_mask);
902900
903 var slice = try allocator.alignedAlloc(u8, large_align, 500);901 var slice = try allocator.alignedAlloc(u8, large_align, 500);
904 testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));902 testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
lib/std/http/headers.zig+5-5
...@@ -399,7 +399,7 @@ test "Headers.iterator" {...@@ -399,7 +399,7 @@ test "Headers.iterator" {
399 }399 }
400 count += 1;400 count += 1;
401 }401 }
402 testing.expectEqual(i32(2), count);402 testing.expectEqual(@as(i32, 2), count);
403}403}
404404
405test "Headers.contains" {405test "Headers.contains" {
...@@ -420,10 +420,10 @@ test "Headers.delete" {...@@ -420,10 +420,10 @@ test "Headers.delete" {
420 try h.append("cookie", "somevalue", null);420 try h.append("cookie", "somevalue", null);
421421
422 testing.expectEqual(false, h.delete("not-present"));422 testing.expectEqual(false, h.delete("not-present"));
423 testing.expectEqual(usize(3), h.count());423 testing.expectEqual(@as(usize, 3), h.count());
424424
425 testing.expectEqual(true, h.delete("foo"));425 testing.expectEqual(true, h.delete("foo"));
426 testing.expectEqual(usize(2), h.count());426 testing.expectEqual(@as(usize, 2), h.count());
427 {427 {
428 const e = h.at(0);428 const e = h.at(0);
429 testing.expectEqualSlices(u8, "baz", e.name);429 testing.expectEqualSlices(u8, "baz", e.name);
...@@ -448,7 +448,7 @@ test "Headers.orderedRemove" {...@@ -448,7 +448,7 @@ test "Headers.orderedRemove" {
448 try h.append("cookie", "somevalue", null);448 try h.append("cookie", "somevalue", null);
449449
450 h.orderedRemove(0);450 h.orderedRemove(0);
451 testing.expectEqual(usize(2), h.count());451 testing.expectEqual(@as(usize, 2), h.count());
452 {452 {
453 const e = h.at(0);453 const e = h.at(0);
454 testing.expectEqualSlices(u8, "baz", e.name);454 testing.expectEqualSlices(u8, "baz", e.name);
...@@ -471,7 +471,7 @@ test "Headers.swapRemove" {...@@ -471,7 +471,7 @@ test "Headers.swapRemove" {
471 try h.append("cookie", "somevalue", null);471 try h.append("cookie", "somevalue", null);
472472
473 h.swapRemove(0);473 h.swapRemove(0);
474 testing.expectEqual(usize(2), h.count());474 testing.expectEqual(@as(usize, 2), h.count());
475 {475 {
476 const e = h.at(0);476 const e = h.at(0);
477 testing.expectEqualSlices(u8, "cookie", e.name);477 testing.expectEqualSlices(u8, "cookie", e.name);
lib/std/io.zig+26-48
...@@ -34,28 +34,23 @@ else...@@ -34,28 +34,23 @@ else
34 Mode.blocking;34 Mode.blocking;
35pub const is_async = mode != .blocking;35pub const is_async = mode != .blocking;
3636
37pub const GetStdIoError = os.windows.GetStdHandleError;37pub fn getStdOut() File {
38
39pub fn getStdOut() GetStdIoError!File {
40 if (builtin.os == .windows) {38 if (builtin.os == .windows) {
41 const handle = try os.windows.GetStdHandle(os.windows.STD_OUTPUT_HANDLE);39 return File.openHandle(os.windows.peb().ProcessParameters.hStdOutput);
42 return File.openHandle(handle);
43 }40 }
44 return File.openHandle(os.STDOUT_FILENO);41 return File.openHandle(os.STDOUT_FILENO);
45}42}
4643
47pub fn getStdErr() GetStdIoError!File {44pub fn getStdErr() File {
48 if (builtin.os == .windows) {45 if (builtin.os == .windows) {
49 const handle = try os.windows.GetStdHandle(os.windows.STD_ERROR_HANDLE);46 return File.openHandle(os.windows.peb().ProcessParameters.hStdError);
50 return File.openHandle(handle);
51 }47 }
52 return File.openHandle(os.STDERR_FILENO);48 return File.openHandle(os.STDERR_FILENO);
53}49}
5450
55pub fn getStdIn() GetStdIoError!File {51pub fn getStdIn() File {
56 if (builtin.os == .windows) {52 if (builtin.os == .windows) {
57 const handle = try os.windows.GetStdHandle(os.windows.STD_INPUT_HANDLE);53 return File.openHandle(os.windows.peb().ProcessParameters.hStdInput);
58 return File.openHandle(handle);
59 }54 }
60 return File.openHandle(os.STDIN_FILENO);55 return File.openHandle(os.STDIN_FILENO);
61}56}
...@@ -74,24 +69,9 @@ pub fn writeFile(path: []const u8, data: []const u8) !void {...@@ -74,24 +69,9 @@ pub fn writeFile(path: []const u8, data: []const u8) !void {
74}69}
7570
76/// On success, caller owns returned buffer.71/// On success, caller owns returned buffer.
77/// TODO move this to `std.fs` and add a version to `std.fs.Dir`.72/// This function is deprecated; use `std.fs.Dir.readFileAlloc`.
78pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 {73pub fn readFileAlloc(allocator: *mem.Allocator, path: []const u8) ![]u8 {
79 return readFileAllocAligned(allocator, path, @alignOf(u8));74 return fs.Dir.cwd().readFileAlloc(allocator, path, math.maxInt(usize));
80}
81
82/// On success, caller owns returned buffer.
83/// TODO move this to `std.fs` and add a version to `std.fs.Dir`.
84pub fn readFileAllocAligned(allocator: *mem.Allocator, path: []const u8, comptime A: u29) ![]align(A) u8 {
85 var file = try File.openRead(path);
86 defer file.close();
87
88 const size = try math.cast(usize, try file.getEndPos());
89 const buf = try allocator.alignedAlloc(u8, A, size);
90 errdefer allocator.free(buf);
91
92 var adapter = file.inStream();
93 try adapter.stream.readNoEof(buf[0..size]);
94 return buf;
95}75}
9676
97pub fn BufferedInStream(comptime Error: type) type {77pub fn BufferedInStream(comptime Error: type) type {
...@@ -353,21 +333,21 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {...@@ -353,21 +333,21 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
353 const Buf = @IntType(false, buf_bit_count);333 const Buf = @IntType(false, buf_bit_count);
354 const BufShift = math.Log2Int(Buf);334 const BufShift = math.Log2Int(Buf);
355335
356 out_bits.* = usize(0);336 out_bits.* = @as(usize, 0);
357 if (U == u0 or bits == 0) return 0;337 if (U == u0 or bits == 0) return 0;
358 var out_buffer = Buf(0);338 var out_buffer = @as(Buf, 0);
359339
360 if (self.bit_count > 0) {340 if (self.bit_count > 0) {
361 const n = if (self.bit_count >= bits) @intCast(u3, bits) else self.bit_count;341 const n = if (self.bit_count >= bits) @intCast(u3, bits) else self.bit_count;
362 const shift = u7_bit_count - n;342 const shift = u7_bit_count - n;
363 switch (endian) {343 switch (endian) {
364 builtin.Endian.Big => {344 builtin.Endian.Big => {
365 out_buffer = Buf(self.bit_buffer >> shift);345 out_buffer = @as(Buf, self.bit_buffer >> shift);
366 self.bit_buffer <<= n;346 self.bit_buffer <<= n;
367 },347 },
368 builtin.Endian.Little => {348 builtin.Endian.Little => {
369 const value = (self.bit_buffer << shift) >> shift;349 const value = (self.bit_buffer << shift) >> shift;
370 out_buffer = Buf(value);350 out_buffer = @as(Buf, value);
371 self.bit_buffer >>= n;351 self.bit_buffer >>= n;
372 },352 },
373 }353 }
...@@ -393,28 +373,28 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {...@@ -393,28 +373,28 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
393 if (n >= u8_bit_count) {373 if (n >= u8_bit_count) {
394 out_buffer <<= @intCast(u3, u8_bit_count - 1);374 out_buffer <<= @intCast(u3, u8_bit_count - 1);
395 out_buffer <<= 1;375 out_buffer <<= 1;
396 out_buffer |= Buf(next_byte);376 out_buffer |= @as(Buf, next_byte);
397 out_bits.* += u8_bit_count;377 out_bits.* += u8_bit_count;
398 continue;378 continue;
399 }379 }
400380
401 const shift = @intCast(u3, u8_bit_count - n);381 const shift = @intCast(u3, u8_bit_count - n);
402 out_buffer <<= @intCast(BufShift, n);382 out_buffer <<= @intCast(BufShift, n);
403 out_buffer |= Buf(next_byte >> shift);383 out_buffer |= @as(Buf, next_byte >> shift);
404 out_bits.* += n;384 out_bits.* += n;
405 self.bit_buffer = @truncate(u7, next_byte << @intCast(u3, n - 1));385 self.bit_buffer = @truncate(u7, next_byte << @intCast(u3, n - 1));
406 self.bit_count = shift;386 self.bit_count = shift;
407 },387 },
408 builtin.Endian.Little => {388 builtin.Endian.Little => {
409 if (n >= u8_bit_count) {389 if (n >= u8_bit_count) {
410 out_buffer |= Buf(next_byte) << @intCast(BufShift, out_bits.*);390 out_buffer |= @as(Buf, next_byte) << @intCast(BufShift, out_bits.*);
411 out_bits.* += u8_bit_count;391 out_bits.* += u8_bit_count;
412 continue;392 continue;
413 }393 }
414394
415 const shift = @intCast(u3, u8_bit_count - n);395 const shift = @intCast(u3, u8_bit_count - n);
416 const value = (next_byte << shift) >> shift;396 const value = (next_byte << shift) >> shift;
417 out_buffer |= Buf(value) << @intCast(BufShift, out_bits.*);397 out_buffer |= @as(Buf, value) << @intCast(BufShift, out_bits.*);
418 out_bits.* += n;398 out_bits.* += n;
419 self.bit_buffer = @truncate(u7, next_byte >> @intCast(u3, n));399 self.bit_buffer = @truncate(u7, next_byte >> @intCast(u3, n));
420 self.bit_count = shift;400 self.bit_count = shift;
...@@ -434,7 +414,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {...@@ -434,7 +414,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
434 var self = @fieldParentPtr(Self, "stream", self_stream);414 var self = @fieldParentPtr(Self, "stream", self_stream);
435415
436 var out_bits: usize = undefined;416 var out_bits: usize = undefined;
437 var out_bits_total = usize(0);417 var out_bits_total = @as(usize, 0);
438 //@NOTE: I'm not sure this is a good idea, maybe alignToByte should be forced418 //@NOTE: I'm not sure this is a good idea, maybe alignToByte should be forced
439 if (self.bit_count > 0) {419 if (self.bit_count > 0) {
440 for (buffer) |*b, i| {420 for (buffer) |*b, i| {
...@@ -598,7 +578,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr...@@ -598,7 +578,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr
598 self.index = 0;578 self.index = 0;
599 }579 }
600580
601 fn writeFn(out_stream: *Stream, bytes: []const u8) !void {581 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
602 const self = @fieldParentPtr(Self, "stream", out_stream);582 const self = @fieldParentPtr(Self, "stream", out_stream);
603583
604 if (bytes.len >= self.buffer.len) {584 if (bytes.len >= self.buffer.len) {
...@@ -814,8 +794,7 @@ pub const BufferedAtomicFile = struct {...@@ -814,8 +794,7 @@ pub const BufferedAtomicFile = struct {
814};794};
815795
816pub fn readLine(buf: *std.Buffer) ![]u8 {796pub fn readLine(buf: *std.Buffer) ![]u8 {
817 var stdin = try getStdIn();797 var stdin_stream = getStdIn().inStream();
818 var stdin_stream = stdin.inStream();
819 return readLineFrom(&stdin_stream.stream, buf);798 return readLineFrom(&stdin_stream.stream, buf);
820}799}
821800
...@@ -856,8 +835,7 @@ test "io.readLineFrom" {...@@ -856,8 +835,7 @@ test "io.readLineFrom" {
856}835}
857836
858pub fn readLineSlice(slice: []u8) ![]u8 {837pub fn readLineSlice(slice: []u8) ![]u8 {
859 var stdin = try getStdIn();838 var stdin_stream = getStdIn().inStream();
860 var stdin_stream = stdin.inStream();
861 return readLineSliceFrom(&stdin_stream.stream, slice);839 return readLineSliceFrom(&stdin_stream.stream, slice);
862}840}
863841
...@@ -949,14 +927,14 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -949,14 +927,14 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
949 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));927 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));
950 }928 }
951929
952 var result = U(0);930 var result = @as(U, 0);
953 for (buffer) |byte, i| {931 for (buffer) |byte, i| {
954 switch (endian) {932 switch (endian) {
955 builtin.Endian.Big => {933 builtin.Endian.Big => {
956 result = (result << u8_bit_count) | byte;934 result = (result << u8_bit_count) | byte;
957 },935 },
958 builtin.Endian.Little => {936 builtin.Endian.Little => {
959 result |= U(byte) << @intCast(Log2U, u8_bit_count * i);937 result |= @as(U, byte) << @intCast(Log2U, u8_bit_count * i);
960 },938 },
961 }939 }
962 }940 }
...@@ -1050,7 +1028,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1050,7 +1028,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1050 return;1028 return;
1051 }1029 }
10521030
1053 ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe1031 ptr.* = @as(OC, undefined); //make it non-null so the following .? is guaranteed safe
1054 const val_ptr = &ptr.*.?;1032 const val_ptr = &ptr.*.?;
1055 try self.deserializeInto(val_ptr);1033 try self.deserializeInto(val_ptr);
1056 },1034 },
...@@ -1154,7 +1132,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1154,7 +1132,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
11541132
1155 switch (@typeId(T)) {1133 switch (@typeId(T)) {
1156 builtin.TypeId.Void => return,1134 builtin.TypeId.Void => return,
1157 builtin.TypeId.Bool => try self.serializeInt(u1(@boolToInt(value))),1135 builtin.TypeId.Bool => try self.serializeInt(@as(u1, @boolToInt(value))),
1158 builtin.TypeId.Float, builtin.TypeId.Int => try self.serializeInt(value),1136 builtin.TypeId.Float, builtin.TypeId.Int => try self.serializeInt(value),
1159 builtin.TypeId.Struct => {1137 builtin.TypeId.Struct => {
1160 const info = @typeInfo(T);1138 const info = @typeInfo(T);
...@@ -1197,10 +1175,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1197,10 +1175,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1197 },1175 },
1198 builtin.TypeId.Optional => {1176 builtin.TypeId.Optional => {
1199 if (value == null) {1177 if (value == null) {
1200 try self.serializeInt(u1(@boolToInt(false)));1178 try self.serializeInt(@as(u1, @boolToInt(false)));
1201 return;1179 return;
1202 }1180 }
1203 try self.serializeInt(u1(@boolToInt(true)));1181 try self.serializeInt(@as(u1, @boolToInt(true)));
12041182
1205 const OC = comptime meta.Child(T);1183 const OC = comptime meta.Child(T);
1206 const val_ptr = &value.?;1184 const val_ptr = &value.?;
lib/std/io/out_stream.zig+2-2
...@@ -40,12 +40,12 @@ pub fn OutStream(comptime WriteError: type) type {...@@ -40,12 +40,12 @@ pub fn OutStream(comptime WriteError: type) type {
40 }40 }
4141
42 pub fn writeByte(self: *Self, byte: u8) Error!void {42 pub fn writeByte(self: *Self, byte: u8) Error!void {
43 const slice = (*const [1]u8)(&byte)[0..];43 const slice = @as(*const [1]u8, &byte)[0..];
44 return self.writeFn(self, slice);44 return self.writeFn(self, slice);
45 }45 }
4646
47 pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void {47 pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void {
48 const slice = (*const [1]u8)(&byte)[0..];48 const slice = @as(*const [1]u8, &byte)[0..];
49 var i: usize = 0;49 var i: usize = 0;
50 while (i < n) : (i += 1) {50 while (i < n) : (i += 1) {
51 try self.writeFn(self, slice);51 try self.writeFn(self, slice);
lib/std/io/test.zig+32-32
...@@ -226,49 +226,49 @@ test "BitOutStream" {...@@ -226,49 +226,49 @@ test "BitOutStream" {
226 const OutError = io.SliceOutStream.Error;226 const OutError = io.SliceOutStream.Error;
227 var bit_stream_be = io.BitOutStream(builtin.Endian.Big, OutError).init(&mem_out_be.stream);227 var bit_stream_be = io.BitOutStream(builtin.Endian.Big, OutError).init(&mem_out_be.stream);
228228
229 try bit_stream_be.writeBits(u2(1), 1);229 try bit_stream_be.writeBits(@as(u2, 1), 1);
230 try bit_stream_be.writeBits(u5(2), 2);230 try bit_stream_be.writeBits(@as(u5, 2), 2);
231 try bit_stream_be.writeBits(u128(3), 3);231 try bit_stream_be.writeBits(@as(u128, 3), 3);
232 try bit_stream_be.writeBits(u8(4), 4);232 try bit_stream_be.writeBits(@as(u8, 4), 4);
233 try bit_stream_be.writeBits(u9(5), 5);233 try bit_stream_be.writeBits(@as(u9, 5), 5);
234 try bit_stream_be.writeBits(u1(1), 1);234 try bit_stream_be.writeBits(@as(u1, 1), 1);
235235
236 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);236 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001011);
237237
238 mem_out_be.pos = 0;238 mem_out_be.pos = 0;
239239
240 try bit_stream_be.writeBits(u15(0b110011010000101), 15);240 try bit_stream_be.writeBits(@as(u15, 0b110011010000101), 15);
241 try bit_stream_be.flushBits();241 try bit_stream_be.flushBits();
242 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);242 expect(mem_be[0] == 0b11001101 and mem_be[1] == 0b00001010);
243243
244 mem_out_be.pos = 0;244 mem_out_be.pos = 0;
245 try bit_stream_be.writeBits(u32(0b110011010000101), 16);245 try bit_stream_be.writeBits(@as(u32, 0b110011010000101), 16);
246 expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);246 expect(mem_be[0] == 0b01100110 and mem_be[1] == 0b10000101);
247247
248 try bit_stream_be.writeBits(u0(0), 0);248 try bit_stream_be.writeBits(@as(u0, 0), 0);
249249
250 var mem_out_le = io.SliceOutStream.init(mem_le[0..]);250 var mem_out_le = io.SliceOutStream.init(mem_le[0..]);
251 var bit_stream_le = io.BitOutStream(builtin.Endian.Little, OutError).init(&mem_out_le.stream);251 var bit_stream_le = io.BitOutStream(builtin.Endian.Little, OutError).init(&mem_out_le.stream);
252252
253 try bit_stream_le.writeBits(u2(1), 1);253 try bit_stream_le.writeBits(@as(u2, 1), 1);
254 try bit_stream_le.writeBits(u5(2), 2);254 try bit_stream_le.writeBits(@as(u5, 2), 2);
255 try bit_stream_le.writeBits(u128(3), 3);255 try bit_stream_le.writeBits(@as(u128, 3), 3);
256 try bit_stream_le.writeBits(u8(4), 4);256 try bit_stream_le.writeBits(@as(u8, 4), 4);
257 try bit_stream_le.writeBits(u9(5), 5);257 try bit_stream_le.writeBits(@as(u9, 5), 5);
258 try bit_stream_le.writeBits(u1(1), 1);258 try bit_stream_le.writeBits(@as(u1, 1), 1);
259259
260 expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);260 expect(mem_le[0] == 0b00011101 and mem_le[1] == 0b10010101);
261261
262 mem_out_le.pos = 0;262 mem_out_le.pos = 0;
263 try bit_stream_le.writeBits(u15(0b110011010000101), 15);263 try bit_stream_le.writeBits(@as(u15, 0b110011010000101), 15);
264 try bit_stream_le.flushBits();264 try bit_stream_le.flushBits();
265 expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);265 expect(mem_le[0] == 0b10000101 and mem_le[1] == 0b01100110);
266266
267 mem_out_le.pos = 0;267 mem_out_le.pos = 0;
268 try bit_stream_le.writeBits(u32(0b1100110100001011), 16);268 try bit_stream_le.writeBits(@as(u32, 0b1100110100001011), 16);
269 expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);269 expect(mem_le[0] == 0b00001011 and mem_le[1] == 0b11001101);
270270
271 try bit_stream_le.writeBits(u0(0), 0);271 try bit_stream_le.writeBits(@as(u0, 0), 0);
272}272}
273273
274test "BitStreams with File Stream" {274test "BitStreams with File Stream" {
...@@ -282,12 +282,12 @@ test "BitStreams with File Stream" {...@@ -282,12 +282,12 @@ test "BitStreams with File Stream" {
282 const OutError = File.WriteError;282 const OutError = File.WriteError;
283 var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream);283 var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream);
284284
285 try bit_stream.writeBits(u2(1), 1);285 try bit_stream.writeBits(@as(u2, 1), 1);
286 try bit_stream.writeBits(u5(2), 2);286 try bit_stream.writeBits(@as(u5, 2), 2);
287 try bit_stream.writeBits(u128(3), 3);287 try bit_stream.writeBits(@as(u128, 3), 3);
288 try bit_stream.writeBits(u8(4), 4);288 try bit_stream.writeBits(@as(u8, 4), 4);
289 try bit_stream.writeBits(u9(5), 5);289 try bit_stream.writeBits(@as(u9, 5), 5);
290 try bit_stream.writeBits(u1(1), 1);290 try bit_stream.writeBits(@as(u1, 1), 1);
291 try bit_stream.flushBits();291 try bit_stream.flushBits();
292 }292 }
293 {293 {
...@@ -345,8 +345,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi...@@ -345,8 +345,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
345 inline while (i <= max_test_bitsize) : (i += 1) {345 inline while (i <= max_test_bitsize) : (i += 1) {
346 const U = @IntType(false, i);346 const U = @IntType(false, i);
347 const S = @IntType(true, i);347 const S = @IntType(true, i);
348 try serializer.serializeInt(U(i));348 try serializer.serializeInt(@as(U, i));
349 if (i != 0) try serializer.serializeInt(S(-1)) else try serializer.serialize(S(0));349 if (i != 0) try serializer.serializeInt(@as(S, -1)) else try serializer.serialize(@as(S, 0));
350 }350 }
351 try serializer.flush();351 try serializer.flush();
352352
...@@ -356,8 +356,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi...@@ -356,8 +356,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
356 const S = @IntType(true, i);356 const S = @IntType(true, i);
357 const x = try deserializer.deserializeInt(U);357 const x = try deserializer.deserializeInt(U);
358 const y = try deserializer.deserializeInt(S);358 const y = try deserializer.deserializeInt(S);
359 expect(x == U(i));359 expect(x == @as(U, i));
360 if (i != 0) expect(y == S(-1)) else expect(y == 0);360 if (i != 0) expect(y == @as(S, -1)) else expect(y == 0);
361 }361 }
362362
363 const u8_bit_count = comptime meta.bitCount(u8);363 const u8_bit_count = comptime meta.bitCount(u8);
...@@ -577,11 +577,11 @@ fn testBadData(comptime endian: builtin.Endian, comptime packing: io.Packing) !v...@@ -577,11 +577,11 @@ fn testBadData(comptime endian: builtin.Endian, comptime packing: io.Packing) !v
577 var in_stream = &in.stream;577 var in_stream = &in.stream;
578 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);578 var deserializer = io.Deserializer(endian, packing, InError).init(in_stream);
579579
580 try serializer.serialize(u14(3));580 try serializer.serialize(@as(u14, 3));
581 expectError(error.InvalidEnumTag, deserializer.deserialize(A));581 expectError(error.InvalidEnumTag, deserializer.deserialize(A));
582 out.pos = 0;582 out.pos = 0;
583 try serializer.serialize(u14(3));583 try serializer.serialize(@as(u14, 3));
584 try serializer.serialize(u14(88));584 try serializer.serialize(@as(u14, 88));
585 expectError(error.InvalidEnumTag, deserializer.deserialize(C));585 expectError(error.InvalidEnumTag, deserializer.deserialize(C));
586}586}
587587
...@@ -603,7 +603,7 @@ test "c out stream" {...@@ -603,7 +603,7 @@ test "c out stream" {
603 }603 }
604604
605 const out_stream = &io.COutStream.init(out_file).stream;605 const out_stream = &io.COutStream.init(out_file).stream;
606 try out_stream.print("hi: {}\n", i32(123));606 try out_stream.print("hi: {}\n", @as(i32, 123));
607}607}
608608
609test "File seek ops" {609test "File seek ops" {
lib/std/json.zig+25-105
...@@ -1012,119 +1012,39 @@ pub const Value = union(enum) {...@@ -1012,119 +1012,39 @@ pub const Value = union(enum) {
1012 Object: ObjectMap,1012 Object: ObjectMap,
10131013
1014 pub fn dump(self: Value) void {1014 pub fn dump(self: Value) void {
1015 switch (self) {1015 var held = std.debug.getStderrMutex().acquire();
1016 Value.Null => {1016 defer held.release();
1017 debug.warn("null");1017
1018 },1018 const stderr = std.debug.getStderrStream();
1019 Value.Bool => |inner| {1019 self.dumpStream(stderr, 1024) catch return;
1020 debug.warn("{}", inner);
1021 },
1022 Value.Integer => |inner| {
1023 debug.warn("{}", inner);
1024 },
1025 Value.Float => |inner| {
1026 debug.warn("{:.5}", inner);
1027 },
1028 Value.String => |inner| {
1029 debug.warn("\"{}\"", inner);
1030 },
1031 Value.Array => |inner| {
1032 var not_first = false;
1033 debug.warn("[");
1034 for (inner.toSliceConst()) |value| {
1035 if (not_first) {
1036 debug.warn(",");
1037 }
1038 not_first = true;
1039 value.dump();
1040 }
1041 debug.warn("]");
1042 },
1043 Value.Object => |inner| {
1044 var not_first = false;
1045 debug.warn("{{");
1046 var it = inner.iterator();
1047
1048 while (it.next()) |entry| {
1049 if (not_first) {
1050 debug.warn(",");
1051 }
1052 not_first = true;
1053 debug.warn("\"{}\":", entry.key);
1054 entry.value.dump();
1055 }
1056 debug.warn("}}");
1057 },
1058 }
1059 }1020 }
10601021
1061 pub fn dumpIndent(self: Value, indent: usize) void {1022 pub fn dumpIndent(self: Value, comptime indent: usize) void {
1062 if (indent == 0) {1023 if (indent == 0) {
1063 self.dump();1024 self.dump();
1064 } else {1025 } else {
1065 self.dumpIndentLevel(indent, 0);1026 var held = std.debug.getStderrMutex().acquire();
1027 defer held.release();
1028
1029 const stderr = std.debug.getStderrStream();
1030 self.dumpStreamIndent(indent, stderr, 1024) catch return;
1066 }1031 }
1067 }1032 }
10681033
1069 fn dumpIndentLevel(self: Value, indent: usize, level: usize) void {1034 pub fn dumpStream(self: @This(), stream: var, comptime max_depth: usize) !void {
1070 switch (self) {1035 var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
1071 Value.Null => {1036 w.newline = "";
1072 debug.warn("null");1037 w.one_indent = "";
1073 },1038 w.space = "";
1074 Value.Bool => |inner| {1039 try w.emitJson(self);
1075 debug.warn("{}", inner);
1076 },
1077 Value.Integer => |inner| {
1078 debug.warn("{}", inner);
1079 },
1080 Value.Float => |inner| {
1081 debug.warn("{:.5}", inner);
1082 },
1083 Value.String => |inner| {
1084 debug.warn("\"{}\"", inner);
1085 },
1086 Value.Array => |inner| {
1087 var not_first = false;
1088 debug.warn("[\n");
1089
1090 for (inner.toSliceConst()) |value| {
1091 if (not_first) {
1092 debug.warn(",\n");
1093 }
1094 not_first = true;
1095 padSpace(level + indent);
1096 value.dumpIndentLevel(indent, level + indent);
1097 }
1098 debug.warn("\n");
1099 padSpace(level);
1100 debug.warn("]");
1101 },
1102 Value.Object => |inner| {
1103 var not_first = false;
1104 debug.warn("{{\n");
1105 var it = inner.iterator();
1106
1107 while (it.next()) |entry| {
1108 if (not_first) {
1109 debug.warn(",\n");
1110 }
1111 not_first = true;
1112 padSpace(level + indent);
1113 debug.warn("\"{}\": ", entry.key);
1114 entry.value.dumpIndentLevel(indent, level + indent);
1115 }
1116 debug.warn("\n");
1117 padSpace(level);
1118 debug.warn("}}");
1119 },
1120 }
1121 }1040 }
11221041
1123 fn padSpace(indent: usize) void {1042 pub fn dumpStreamIndent(self: @This(), comptime indent: usize, stream: var, comptime max_depth: usize) !void {
1124 var i: usize = 0;1043 var one_indent = " " ** indent;
1125 while (i < indent) : (i += 1) {1044
1126 debug.warn(" ");1045 var w = std.json.WriteStream(@typeOf(stream).Child, max_depth).init(stream);
1127 }1046 w.one_indent = one_indent;
1047 try w.emitJson(self);
1128 }1048 }
1129};1049};
11301050
...@@ -1423,7 +1343,7 @@ test "write json then parse it" {...@@ -1423,7 +1343,7 @@ test "write json then parse it" {
1423 try jw.emitBool(true);1343 try jw.emitBool(true);
14241344
1425 try jw.objectField("int");1345 try jw.objectField("int");
1426 try jw.emitNumber(i32(1234));1346 try jw.emitNumber(@as(i32, 1234));
14271347
1428 try jw.objectField("array");1348 try jw.objectField("array");
1429 try jw.beginArray();1349 try jw.beginArray();
...@@ -1432,7 +1352,7 @@ test "write json then parse it" {...@@ -1432,7 +1352,7 @@ test "write json then parse it" {
1432 try jw.emitNull();1352 try jw.emitNull();
14331353
1434 try jw.arrayElem();1354 try jw.arrayElem();
1435 try jw.emitNumber(f64(12.34));1355 try jw.emitNumber(@as(f64, 12.34));
14361356
1437 try jw.endArray();1357 try jw.endArray();
14381358
lib/std/json/write_stream.zig+5-1
...@@ -27,6 +27,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {...@@ -27,6 +27,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
27 /// The string used as a newline character.27 /// The string used as a newline character.
28 newline: []const u8 = "\n",28 newline: []const u8 = "\n",
2929
30 /// The string used as spacing.
31 space: []const u8 = " ",
32
30 stream: *OutStream,33 stream: *OutStream,
31 state_index: usize,34 state_index: usize,
32 state: [max_depth]State,35 state: [max_depth]State,
...@@ -87,7 +90,8 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {...@@ -87,7 +90,8 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
87 self.pushState(.Value);90 self.pushState(.Value);
88 try self.indent();91 try self.indent();
89 try self.writeEscapedString(name);92 try self.writeEscapedString(name);
90 try self.stream.write(": ");93 try self.stream.write(":");
94 try self.stream.write(self.space);
91 },95 },
92 }96 }
93 }97 }
lib/std/lazy_init.zig+14-12
...@@ -1,24 +1,26 @@...@@ -1,24 +1,26 @@
1const std = @import("std.zig");1const std = @import("std.zig");
2const builtin = @import("builtin");
3const assert = std.debug.assert;2const assert = std.debug.assert;
4const testing = std.testing;3const testing = std.testing;
5const AtomicRmwOp = builtin.AtomicRmwOp;
6const AtomicOrder = builtin.AtomicOrder;
74
8/// Thread-safe initialization of global data.5/// Thread-safe initialization of global data.
9/// TODO use a mutex instead of a spinlock6/// TODO use a mutex instead of a spinlock
10pub fn lazyInit(comptime T: type) LazyInit(T) {7pub fn lazyInit(comptime T: type) LazyInit(T) {
11 return LazyInit(T){8 return LazyInit(T){
12 .data = undefined,9 .data = undefined,
13 .state = 0,
14 };10 };
15}11}
1612
17fn LazyInit(comptime T: type) type {13fn LazyInit(comptime T: type) type {
18 return struct {14 return struct {
19 state: u8, // TODO make this an enum15 state: State = .NotResolved,
20 data: Data,16 data: Data,
2117
18 const State = enum(u8) {
19 NotResolved,
20 Resolving,
21 Resolved,
22 };
23
22 const Self = @This();24 const Self = @This();
2325
24 // TODO this isn't working for void, investigate and then remove this special case26 // TODO this isn't working for void, investigate and then remove this special case
...@@ -30,16 +32,16 @@ fn LazyInit(comptime T: type) type {...@@ -30,16 +32,16 @@ fn LazyInit(comptime T: type) type {
30 /// perform the initialization and then call resolve().32 /// perform the initialization and then call resolve().
31 pub fn get(self: *Self) ?Ptr {33 pub fn get(self: *Self) ?Ptr {
32 while (true) {34 while (true) {
33 var state = @cmpxchgWeak(u8, &self.state, 0, 1, AtomicOrder.SeqCst, AtomicOrder.SeqCst) orelse return null;35 var state = @cmpxchgWeak(State, &self.state, .NotResolved, .Resolving, .SeqCst, .SeqCst) orelse return null;
34 switch (state) {36 switch (state) {
35 0 => continue,37 .NotResolved => continue,
36 1 => {38 .Resolving => {
37 // TODO mutex instead of a spinlock39 // TODO mutex instead of a spinlock
38 continue;40 continue;
39 },41 },
40 2 => {42 .Resolved => {
41 if (@sizeOf(T) == 0) {43 if (@sizeOf(T) == 0) {
42 return T(undefined);44 return @as(T, undefined);
43 } else {45 } else {
44 return &self.data;46 return &self.data;
45 }47 }
...@@ -50,8 +52,8 @@ fn LazyInit(comptime T: type) type {...@@ -50,8 +52,8 @@ fn LazyInit(comptime T: type) type {
50 }52 }
5153
52 pub fn resolve(self: *Self) void {54 pub fn resolve(self: *Self) void {
53 const prev = @atomicRmw(u8, &self.state, AtomicRmwOp.Xchg, 2, AtomicOrder.SeqCst);55 const prev = @atomicRmw(State, &self.state, .Xchg, .Resolved, .SeqCst);
54 assert(prev == 1); // resolve() called twice56 assert(prev != .Resolved); // resolve() called twice
55 }57 }
56 };58 };
57}59}
lib/std/math.zig+83-80
...@@ -10,6 +10,9 @@ pub const e = 2.71828182845904523536028747135266249775724709369995;...@@ -10,6 +10,9 @@ pub const e = 2.71828182845904523536028747135266249775724709369995;
10/// Archimedes' constant (π)10/// Archimedes' constant (π)
11pub const pi = 3.14159265358979323846264338327950288419716939937510;11pub const pi = 3.14159265358979323846264338327950288419716939937510;
1212
13/// Circle constant (τ)
14pub const tau = 2 * pi;
15
13/// log2(e)16/// log2(e)
14pub const log2e = 1.442695040888963407359924681001892137;17pub const log2e = 1.442695040888963407359924681001892137;
1518
...@@ -44,10 +47,10 @@ pub const sqrt2 = 1.414213562373095048801688724209698079;...@@ -44,10 +47,10 @@ pub const sqrt2 = 1.414213562373095048801688724209698079;
44pub const sqrt1_2 = 0.707106781186547524400844362104849039;47pub const sqrt1_2 = 0.707106781186547524400844362104849039;
4548
46// From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128)49// From a small c++ [program using boost float128](https://github.com/winksaville/cpp_boost_float128)
47pub const f128_true_min = @bitCast(f128, u128(0x00000000000000000000000000000001));50pub const f128_true_min = @bitCast(f128, @as(u128, 0x00000000000000000000000000000001));
48pub const f128_min = @bitCast(f128, u128(0x00010000000000000000000000000000));51pub const f128_min = @bitCast(f128, @as(u128, 0x00010000000000000000000000000000));
49pub const f128_max = @bitCast(f128, u128(0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));52pub const f128_max = @bitCast(f128, @as(u128, 0x7FFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF));
50pub const f128_epsilon = @bitCast(f128, u128(0x3F8F0000000000000000000000000000));53pub const f128_epsilon = @bitCast(f128, @as(u128, 0x3F8F0000000000000000000000000000));
51pub const f128_toint = 1.0 / f128_epsilon;54pub const f128_toint = 1.0 / f128_epsilon;
5255
53// float.h details56// float.h details
...@@ -69,28 +72,28 @@ pub const f16_max = 65504;...@@ -69,28 +72,28 @@ pub const f16_max = 65504;
69pub const f16_epsilon = 0.0009765625; // 2**-1072pub const f16_epsilon = 0.0009765625; // 2**-10
70pub const f16_toint = 1.0 / f16_epsilon;73pub const f16_toint = 1.0 / f16_epsilon;
7174
72pub const nan_u16 = u16(0x7C01);75pub const nan_u16 = @as(u16, 0x7C01);
73pub const nan_f16 = @bitCast(f16, nan_u16);76pub const nan_f16 = @bitCast(f16, nan_u16);
7477
75pub const inf_u16 = u16(0x7C00);78pub const inf_u16 = @as(u16, 0x7C00);
76pub const inf_f16 = @bitCast(f16, inf_u16);79pub const inf_f16 = @bitCast(f16, inf_u16);
7780
78pub const nan_u32 = u32(0x7F800001);81pub const nan_u32 = @as(u32, 0x7F800001);
79pub const nan_f32 = @bitCast(f32, nan_u32);82pub const nan_f32 = @bitCast(f32, nan_u32);
8083
81pub const inf_u32 = u32(0x7F800000);84pub const inf_u32 = @as(u32, 0x7F800000);
82pub const inf_f32 = @bitCast(f32, inf_u32);85pub const inf_f32 = @bitCast(f32, inf_u32);
8386
84pub const nan_u64 = u64(0x7FF << 52) | 1;87pub const nan_u64 = @as(u64, 0x7FF << 52) | 1;
85pub const nan_f64 = @bitCast(f64, nan_u64);88pub const nan_f64 = @bitCast(f64, nan_u64);
8689
87pub const inf_u64 = u64(0x7FF << 52);90pub const inf_u64 = @as(u64, 0x7FF << 52);
88pub const inf_f64 = @bitCast(f64, inf_u64);91pub const inf_f64 = @bitCast(f64, inf_u64);
8992
90pub const nan_u128 = u128(0x7fff0000000000000000000000000001);93pub const nan_u128 = @as(u128, 0x7fff0000000000000000000000000001);
91pub const nan_f128 = @bitCast(f128, nan_u128);94pub const nan_f128 = @bitCast(f128, nan_u128);
9295
93pub const inf_u128 = u128(0x7fff0000000000000000000000000000);96pub const inf_u128 = @as(u128, 0x7fff0000000000000000000000000000);
94pub const inf_f128 = @bitCast(f128, inf_u128);97pub const inf_f128 = @bitCast(f128, inf_u128);
9598
96pub const nan = @import("math/nan.zig").nan;99pub const nan = @import("math/nan.zig").nan;
...@@ -248,7 +251,7 @@ pub fn Min(comptime A: type, comptime B: type) type {...@@ -248,7 +251,7 @@ pub fn Min(comptime A: type, comptime B: type) type {
248 },251 },
249 else => {},252 else => {},
250 }253 }
251 return @typeOf(A(0) + B(0));254 return @typeOf(@as(A, 0) + @as(B, 0));
252}255}
253256
254/// Returns the smaller number. When one of the parameter's type's full range fits in the other,257/// Returns the smaller number. When one of the parameter's type's full range fits in the other,
...@@ -273,7 +276,7 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) {...@@ -273,7 +276,7 @@ pub fn min(x: var, y: var) Min(@typeOf(x), @typeOf(y)) {
273}276}
274277
275test "math.min" {278test "math.min" {
276 testing.expect(min(i32(-1), i32(2)) == -1);279 testing.expect(min(@as(i32, -1), @as(i32, 2)) == -1);
277 {280 {
278 var a: u16 = 999;281 var a: u16 = 999;
279 var b: u32 = 10;282 var b: u32 = 10;
...@@ -309,7 +312,7 @@ pub fn max(x: var, y: var) @typeOf(x + y) {...@@ -309,7 +312,7 @@ pub fn max(x: var, y: var) @typeOf(x + y) {
309}312}
310313
311test "math.max" {314test "math.max" {
312 testing.expect(max(i32(-1), i32(2)) == 2);315 testing.expect(max(@as(i32, -1), @as(i32, 2)) == 2);
313}316}
314317
315pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {318pub fn mul(comptime T: type, a: T, b: T) (error{Overflow}!T) {
...@@ -352,10 +355,10 @@ pub fn shl(comptime T: type, a: T, shift_amt: var) T {...@@ -352,10 +355,10 @@ pub fn shl(comptime T: type, a: T, shift_amt: var) T {
352}355}
353356
354test "math.shl" {357test "math.shl" {
355 testing.expect(shl(u8, 0b11111111, usize(3)) == 0b11111000);358 testing.expect(shl(u8, 0b11111111, @as(usize, 3)) == 0b11111000);
356 testing.expect(shl(u8, 0b11111111, usize(8)) == 0);359 testing.expect(shl(u8, 0b11111111, @as(usize, 8)) == 0);
357 testing.expect(shl(u8, 0b11111111, usize(9)) == 0);360 testing.expect(shl(u8, 0b11111111, @as(usize, 9)) == 0);
358 testing.expect(shl(u8, 0b11111111, isize(-2)) == 0b00111111);361 testing.expect(shl(u8, 0b11111111, @as(isize, -2)) == 0b00111111);
359 testing.expect(shl(u8, 0b11111111, 3) == 0b11111000);362 testing.expect(shl(u8, 0b11111111, 3) == 0b11111000);
360 testing.expect(shl(u8, 0b11111111, 8) == 0);363 testing.expect(shl(u8, 0b11111111, 8) == 0);
361 testing.expect(shl(u8, 0b11111111, 9) == 0);364 testing.expect(shl(u8, 0b11111111, 9) == 0);
...@@ -380,10 +383,10 @@ pub fn shr(comptime T: type, a: T, shift_amt: var) T {...@@ -380,10 +383,10 @@ pub fn shr(comptime T: type, a: T, shift_amt: var) T {
380}383}
381384
382test "math.shr" {385test "math.shr" {
383 testing.expect(shr(u8, 0b11111111, usize(3)) == 0b00011111);386 testing.expect(shr(u8, 0b11111111, @as(usize, 3)) == 0b00011111);
384 testing.expect(shr(u8, 0b11111111, usize(8)) == 0);387 testing.expect(shr(u8, 0b11111111, @as(usize, 8)) == 0);
385 testing.expect(shr(u8, 0b11111111, usize(9)) == 0);388 testing.expect(shr(u8, 0b11111111, @as(usize, 9)) == 0);
386 testing.expect(shr(u8, 0b11111111, isize(-2)) == 0b11111100);389 testing.expect(shr(u8, 0b11111111, @as(isize, -2)) == 0b11111100);
387 testing.expect(shr(u8, 0b11111111, 3) == 0b00011111);390 testing.expect(shr(u8, 0b11111111, 3) == 0b00011111);
388 testing.expect(shr(u8, 0b11111111, 8) == 0);391 testing.expect(shr(u8, 0b11111111, 8) == 0);
389 testing.expect(shr(u8, 0b11111111, 9) == 0);392 testing.expect(shr(u8, 0b11111111, 9) == 0);
...@@ -402,11 +405,11 @@ pub fn rotr(comptime T: type, x: T, r: var) T {...@@ -402,11 +405,11 @@ pub fn rotr(comptime T: type, x: T, r: var) T {
402}405}
403406
404test "math.rotr" {407test "math.rotr" {
405 testing.expect(rotr(u8, 0b00000001, usize(0)) == 0b00000001);408 testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
406 testing.expect(rotr(u8, 0b00000001, usize(9)) == 0b10000000);409 testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000);
407 testing.expect(rotr(u8, 0b00000001, usize(8)) == 0b00000001);410 testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001);
408 testing.expect(rotr(u8, 0b00000001, usize(4)) == 0b00010000);411 testing.expect(rotr(u8, 0b00000001, @as(usize, 4)) == 0b00010000);
409 testing.expect(rotr(u8, 0b00000001, isize(-1)) == 0b00000010);412 testing.expect(rotr(u8, 0b00000001, @as(isize, -1)) == 0b00000010);
410}413}
411414
412/// Rotates left. Only unsigned values can be rotated.415/// Rotates left. Only unsigned values can be rotated.
...@@ -421,11 +424,11 @@ pub fn rotl(comptime T: type, x: T, r: var) T {...@@ -421,11 +424,11 @@ pub fn rotl(comptime T: type, x: T, r: var) T {
421}424}
422425
423test "math.rotl" {426test "math.rotl" {
424 testing.expect(rotl(u8, 0b00000001, usize(0)) == 0b00000001);427 testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001);
425 testing.expect(rotl(u8, 0b00000001, usize(9)) == 0b00000010);428 testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010);
426 testing.expect(rotl(u8, 0b00000001, usize(8)) == 0b00000001);429 testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001);
427 testing.expect(rotl(u8, 0b00000001, usize(4)) == 0b00010000);430 testing.expect(rotl(u8, 0b00000001, @as(usize, 4)) == 0b00010000);
428 testing.expect(rotl(u8, 0b00000001, isize(-1)) == 0b10000000);431 testing.expect(rotl(u8, 0b00000001, @as(isize, -1)) == 0b10000000);
429}432}
430433
431pub fn Log2Int(comptime T: type) type {434pub fn Log2Int(comptime T: type) type {
...@@ -532,8 +535,8 @@ test "math.absInt" {...@@ -532,8 +535,8 @@ test "math.absInt" {
532 comptime testAbsInt();535 comptime testAbsInt();
533}536}
534fn testAbsInt() void {537fn testAbsInt() void {
535 testing.expect((absInt(i32(-10)) catch unreachable) == 10);538 testing.expect((absInt(@as(i32, -10)) catch unreachable) == 10);
536 testing.expect((absInt(i32(10)) catch unreachable) == 10);539 testing.expect((absInt(@as(i32, 10)) catch unreachable) == 10);
537}540}
538541
539pub const absFloat = fabs;542pub const absFloat = fabs;
...@@ -543,8 +546,8 @@ test "math.absFloat" {...@@ -543,8 +546,8 @@ test "math.absFloat" {
543 comptime testAbsFloat();546 comptime testAbsFloat();
544}547}
545fn testAbsFloat() void {548fn testAbsFloat() void {
546 testing.expect(absFloat(f32(-10.05)) == 10.05);549 testing.expect(absFloat(@as(f32, -10.05)) == 10.05);
547 testing.expect(absFloat(f32(10.05)) == 10.05);550 testing.expect(absFloat(@as(f32, 10.05)) == 10.05);
548}551}
549552
550pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {553pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
...@@ -679,14 +682,14 @@ pub fn absCast(x: var) t: {...@@ -679,14 +682,14 @@ pub fn absCast(x: var) t: {
679}682}
680683
681test "math.absCast" {684test "math.absCast" {
682 testing.expect(absCast(i32(-999)) == 999);685 testing.expect(absCast(@as(i32, -999)) == 999);
683 testing.expect(@typeOf(absCast(i32(-999))) == u32);686 testing.expect(@typeOf(absCast(@as(i32, -999))) == u32);
684687
685 testing.expect(absCast(i32(999)) == 999);688 testing.expect(absCast(@as(i32, 999)) == 999);
686 testing.expect(@typeOf(absCast(i32(999))) == u32);689 testing.expect(@typeOf(absCast(@as(i32, 999))) == u32);
687690
688 testing.expect(absCast(i32(minInt(i32))) == -minInt(i32));691 testing.expect(absCast(@as(i32, minInt(i32))) == -minInt(i32));
689 testing.expect(@typeOf(absCast(i32(minInt(i32)))) == u32);692 testing.expect(@typeOf(absCast(@as(i32, minInt(i32)))) == u32);
690693
691 testing.expect(absCast(-999) == 999);694 testing.expect(absCast(-999) == 999);
692}695}
...@@ -705,13 +708,13 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {...@@ -705,13 +708,13 @@ pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
705}708}
706709
707test "math.negateCast" {710test "math.negateCast" {
708 testing.expect((negateCast(u32(999)) catch unreachable) == -999);711 testing.expect((negateCast(@as(u32, 999)) catch unreachable) == -999);
709 testing.expect(@typeOf(negateCast(u32(999)) catch unreachable) == i32);712 testing.expect(@typeOf(negateCast(@as(u32, 999)) catch unreachable) == i32);
710713
711 testing.expect((negateCast(u32(-minInt(i32))) catch unreachable) == minInt(i32));714 testing.expect((negateCast(@as(u32, -minInt(i32))) catch unreachable) == minInt(i32));
712 testing.expect(@typeOf(negateCast(u32(-minInt(i32))) catch unreachable) == i32);715 testing.expect(@typeOf(negateCast(@as(u32, -minInt(i32))) catch unreachable) == i32);
713716
714 testing.expectError(error.Overflow, negateCast(u32(maxInt(i32) + 10)));717 testing.expectError(error.Overflow, negateCast(@as(u32, maxInt(i32) + 10)));
715}718}
716719
717/// Cast an integer to a different integer type. If the value doesn't fit,720/// Cast an integer to a different integer type. If the value doesn't fit,
...@@ -729,13 +732,13 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {...@@ -729,13 +732,13 @@ pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
729}732}
730733
731test "math.cast" {734test "math.cast" {
732 testing.expectError(error.Overflow, cast(u8, u32(300)));735 testing.expectError(error.Overflow, cast(u8, @as(u32, 300)));
733 testing.expectError(error.Overflow, cast(i8, i32(-200)));736 testing.expectError(error.Overflow, cast(i8, @as(i32, -200)));
734 testing.expectError(error.Overflow, cast(u8, i8(-1)));737 testing.expectError(error.Overflow, cast(u8, @as(i8, -1)));
735 testing.expectError(error.Overflow, cast(u64, i8(-1)));738 testing.expectError(error.Overflow, cast(u64, @as(i8, -1)));
736739
737 testing.expect((try cast(u8, u32(255))) == u8(255));740 testing.expect((try cast(u8, @as(u32, 255))) == @as(u8, 255));
738 testing.expect(@typeOf(try cast(u8, u32(255))) == u8);741 testing.expect(@typeOf(try cast(u8, @as(u32, 255))) == u8);
739}742}
740743
741pub const AlignCastError = error{UnalignedMemory};744pub const AlignCastError = error{UnalignedMemory};
...@@ -786,9 +789,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T...@@ -786,9 +789,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
786 comptime assert(@typeId(T) == builtin.TypeId.Int);789 comptime assert(@typeId(T) == builtin.TypeId.Int);
787 comptime assert(!T.is_signed);790 comptime assert(!T.is_signed);
788 assert(value != 0);791 assert(value != 0);
789 comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);792 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
790 comptime const shiftType = std.math.Log2Int(promotedType);793 comptime const shiftType = std.math.Log2Int(PromotedType);
791 return promotedType(1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));794 return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
792}795}
793796
794/// Returns the next power of two (if the value is not already a power of two).797/// Returns the next power of two (if the value is not already a power of two).
...@@ -797,8 +800,8 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T...@@ -797,8 +800,8 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
797pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {800pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {
798 comptime assert(@typeId(T) == builtin.TypeId.Int);801 comptime assert(@typeId(T) == builtin.TypeId.Int);
799 comptime assert(!T.is_signed);802 comptime assert(!T.is_signed);
800 comptime const promotedType = @IntType(T.is_signed, T.bit_count + 1);803 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);
801 comptime const overflowBit = promotedType(1) << T.bit_count;804 comptime const overflowBit = @as(PromotedType, 1) << T.bit_count;
802 var x = ceilPowerOfTwoPromote(T, value);805 var x = ceilPowerOfTwoPromote(T, value);
803 if (overflowBit & x != 0) {806 if (overflowBit & x != 0) {
804 return error.Overflow;807 return error.Overflow;
...@@ -812,15 +815,15 @@ test "math.ceilPowerOfTwoPromote" {...@@ -812,15 +815,15 @@ test "math.ceilPowerOfTwoPromote" {
812}815}
813816
814fn testCeilPowerOfTwoPromote() void {817fn testCeilPowerOfTwoPromote() void {
815 testing.expectEqual(u33(1), ceilPowerOfTwoPromote(u32, 1));818 testing.expectEqual(@as(u33, 1), ceilPowerOfTwoPromote(u32, 1));
816 testing.expectEqual(u33(2), ceilPowerOfTwoPromote(u32, 2));819 testing.expectEqual(@as(u33, 2), ceilPowerOfTwoPromote(u32, 2));
817 testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 63));820 testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 63));
818 testing.expectEqual(u33(64), ceilPowerOfTwoPromote(u32, 64));821 testing.expectEqual(@as(u33, 64), ceilPowerOfTwoPromote(u32, 64));
819 testing.expectEqual(u33(128), ceilPowerOfTwoPromote(u32, 65));822 testing.expectEqual(@as(u33, 128), ceilPowerOfTwoPromote(u32, 65));
820 testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 7));823 testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 7));
821 testing.expectEqual(u6(8), ceilPowerOfTwoPromote(u5, 8));824 testing.expectEqual(@as(u6, 8), ceilPowerOfTwoPromote(u5, 8));
822 testing.expectEqual(u6(16), ceilPowerOfTwoPromote(u5, 9));825 testing.expectEqual(@as(u6, 16), ceilPowerOfTwoPromote(u5, 9));
823 testing.expectEqual(u5(16), ceilPowerOfTwoPromote(u4, 9));826 testing.expectEqual(@as(u5, 16), ceilPowerOfTwoPromote(u4, 9));
824}827}
825828
826test "math.ceilPowerOfTwo" {829test "math.ceilPowerOfTwo" {
...@@ -829,14 +832,14 @@ test "math.ceilPowerOfTwo" {...@@ -829,14 +832,14 @@ test "math.ceilPowerOfTwo" {
829}832}
830833
831fn testCeilPowerOfTwo() !void {834fn testCeilPowerOfTwo() !void {
832 testing.expectEqual(u32(1), try ceilPowerOfTwo(u32, 1));835 testing.expectEqual(@as(u32, 1), try ceilPowerOfTwo(u32, 1));
833 testing.expectEqual(u32(2), try ceilPowerOfTwo(u32, 2));836 testing.expectEqual(@as(u32, 2), try ceilPowerOfTwo(u32, 2));
834 testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 63));837 testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 63));
835 testing.expectEqual(u32(64), try ceilPowerOfTwo(u32, 64));838 testing.expectEqual(@as(u32, 64), try ceilPowerOfTwo(u32, 64));
836 testing.expectEqual(u32(128), try ceilPowerOfTwo(u32, 65));839 testing.expectEqual(@as(u32, 128), try ceilPowerOfTwo(u32, 65));
837 testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 7));840 testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 7));
838 testing.expectEqual(u5(8), try ceilPowerOfTwo(u5, 8));841 testing.expectEqual(@as(u5, 8), try ceilPowerOfTwo(u5, 8));
839 testing.expectEqual(u5(16), try ceilPowerOfTwo(u5, 9));842 testing.expectEqual(@as(u5, 16), try ceilPowerOfTwo(u5, 9));
840 testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9));843 testing.expectError(error.Overflow, ceilPowerOfTwo(u4, 9));
841}844}
842845
...@@ -848,7 +851,7 @@ pub fn log2_int(comptime T: type, x: T) Log2Int(T) {...@@ -848,7 +851,7 @@ pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
848pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {851pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {
849 assert(x != 0);852 assert(x != 0);
850 const log2_val = log2_int(T, x);853 const log2_val = log2_int(T, x);
851 if (T(1) << log2_val == x)854 if (@as(T, 1) << log2_val == x)
852 return log2_val;855 return log2_val;
853 return log2_val + 1;856 return log2_val + 1;
854}857}
...@@ -870,8 +873,8 @@ pub fn lossyCast(comptime T: type, value: var) T {...@@ -870,8 +873,8 @@ pub fn lossyCast(comptime T: type, value: var) T {
870 switch (@typeInfo(@typeOf(value))) {873 switch (@typeInfo(@typeOf(value))) {
871 builtin.TypeId.Int => return @intToFloat(T, value),874 builtin.TypeId.Int => return @intToFloat(T, value),
872 builtin.TypeId.Float => return @floatCast(T, value),875 builtin.TypeId.Float => return @floatCast(T, value),
873 builtin.TypeId.ComptimeInt => return T(value),876 builtin.TypeId.ComptimeInt => return @as(T, value),
874 builtin.TypeId.ComptimeFloat => return T(value),877 builtin.TypeId.ComptimeFloat => return @as(T, value),
875 else => @compileError("bad type"),878 else => @compileError("bad type"),
876 }879 }
877}880}
...@@ -944,7 +947,7 @@ test "max value type" {...@@ -944,7 +947,7 @@ test "max value type" {
944947
945pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) {948pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) {
946 const ResultInt = @IntType(T.is_signed, T.bit_count * 2);949 const ResultInt = @IntType(T.is_signed, T.bit_count * 2);
947 return ResultInt(a) * ResultInt(b);950 return @as(ResultInt, a) * @as(ResultInt, b);
948}951}
949952
950test "math.mulWide" {953test "math.mulWide" {
lib/std/math/acos.zig+2-2
...@@ -149,8 +149,8 @@ fn acos64(x: f64) f64 {...@@ -149,8 +149,8 @@ fn acos64(x: f64) f64 {
149}149}
150150
151test "math.acos" {151test "math.acos" {
152 expect(acos(f32(0.0)) == acos32(0.0));152 expect(acos(@as(f32, 0.0)) == acos32(0.0));
153 expect(acos(f64(0.0)) == acos64(0.0));153 expect(acos(@as(f64, 0.0)) == acos64(0.0));
154}154}
155155
156test "math.acos32" {156test "math.acos32" {
lib/std/math/acosh.zig+2-2
...@@ -61,8 +61,8 @@ fn acosh64(x: f64) f64 {...@@ -61,8 +61,8 @@ fn acosh64(x: f64) f64 {
61}61}
6262
63test "math.acosh" {63test "math.acosh" {
64 expect(acosh(f32(1.5)) == acosh32(1.5));64 expect(acosh(@as(f32, 1.5)) == acosh32(1.5));
65 expect(acosh(f64(1.5)) == acosh64(1.5));65 expect(acosh(@as(f64, 1.5)) == acosh64(1.5));
66}66}
6767
68test "math.acosh32" {68test "math.acosh32" {
lib/std/math/asin.zig+2-2
...@@ -142,8 +142,8 @@ fn asin64(x: f64) f64 {...@@ -142,8 +142,8 @@ fn asin64(x: f64) f64 {
142}142}
143143
144test "math.asin" {144test "math.asin" {
145 expect(asin(f32(0.0)) == asin32(0.0));145 expect(asin(@as(f32, 0.0)) == asin32(0.0));
146 expect(asin(f64(0.0)) == asin64(0.0));146 expect(asin(@as(f64, 0.0)) == asin64(0.0));
147}147}
148148
149test "math.asin32" {149test "math.asin32" {
lib/std/math/asinh.zig+2-2
...@@ -89,8 +89,8 @@ fn asinh64(x: f64) f64 {...@@ -89,8 +89,8 @@ fn asinh64(x: f64) f64 {
89}89}
9090
91test "math.asinh" {91test "math.asinh" {
92 expect(asinh(f32(0.0)) == asinh32(0.0));92 expect(asinh(@as(f32, 0.0)) == asinh32(0.0));
93 expect(asinh(f64(0.0)) == asinh64(0.0));93 expect(asinh(@as(f64, 0.0)) == asinh64(0.0));
94}94}
9595
96test "math.asinh32" {96test "math.asinh32" {
lib/std/math/atan.zig+2-2
...@@ -212,8 +212,8 @@ fn atan64(x_: f64) f64 {...@@ -212,8 +212,8 @@ fn atan64(x_: f64) f64 {
212}212}
213213
214test "math.atan" {214test "math.atan" {
215 expect(@bitCast(u32, atan(f32(0.2))) == @bitCast(u32, atan32(0.2)));215 expect(@bitCast(u32, atan(@as(f32, 0.2))) == @bitCast(u32, atan32(0.2)));
216 expect(atan(f64(0.2)) == atan64(0.2));216 expect(atan(@as(f64, 0.2)) == atan64(0.2));
217}217}
218218
219test "math.atan32" {219test "math.atan32" {
lib/std/math/atanh.zig+2-2
...@@ -84,8 +84,8 @@ fn atanh_64(x: f64) f64 {...@@ -84,8 +84,8 @@ fn atanh_64(x: f64) f64 {
84}84}
8585
86test "math.atanh" {86test "math.atanh" {
87 expect(atanh(f32(0.0)) == atanh_32(0.0));87 expect(atanh(@as(f32, 0.0)) == atanh_32(0.0));
88 expect(atanh(f64(0.0)) == atanh_64(0.0));88 expect(atanh(@as(f64, 0.0)) == atanh_64(0.0));
89}89}
9090
91test "math.atanh_32" {91test "math.atanh_32" {
lib/std/math/big/int.zig+11-11
...@@ -261,7 +261,7 @@ pub const Int = struct {...@@ -261,7 +261,7 @@ pub const Int = struct {
261 /// the minus sign. This is used for determining the number of characters needed to print the261 /// the minus sign. This is used for determining the number of characters needed to print the
262 /// value. It is inexact and may exceed the given value by ~1-2 bytes.262 /// value. It is inexact and may exceed the given value by ~1-2 bytes.
263 pub fn sizeInBase(self: Int, base: usize) usize {263 pub fn sizeInBase(self: Int, base: usize) usize {
264 const bit_count = usize(@boolToInt(!self.isPositive())) + self.bitCountAbs();264 const bit_count = @as(usize, @boolToInt(!self.isPositive())) + self.bitCountAbs();
265 return (bit_count / math.log2(base)) + 1;265 return (bit_count / math.log2(base)) + 1;
266 }266 }
267267
...@@ -281,7 +281,7 @@ pub const Int = struct {...@@ -281,7 +281,7 @@ pub const Int = struct {
281 var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);281 var w_value: UT = if (value < 0) @intCast(UT, -value) else @intCast(UT, value);
282282
283 if (info.bits <= Limb.bit_count) {283 if (info.bits <= Limb.bit_count) {
284 self.limbs[0] = Limb(w_value);284 self.limbs[0] = @as(Limb, w_value);
285 self.metadata += 1;285 self.metadata += 1;
286 } else {286 } else {
287 var i: usize = 0;287 var i: usize = 0;
...@@ -453,7 +453,7 @@ pub const Int = struct {...@@ -453,7 +453,7 @@ pub const Int = struct {
453 for (self.limbs[0..self.len()]) |limb| {453 for (self.limbs[0..self.len()]) |limb| {
454 var shift: usize = 0;454 var shift: usize = 0;
455 while (shift < Limb.bit_count) : (shift += base_shift) {455 while (shift < Limb.bit_count) : (shift += base_shift) {
456 const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & Limb(base - 1));456 const r = @intCast(u8, (limb >> @intCast(Log2Limb, shift)) & @as(Limb, base - 1));
457 const ch = try digitToChar(r, base);457 const ch = try digitToChar(r, base);
458 try digits.append(ch);458 try digits.append(ch);
459 }459 }
...@@ -560,7 +560,7 @@ pub const Int = struct {...@@ -560,7 +560,7 @@ pub const Int = struct {
560 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.560 /// Returns -1, 0, 1 if a < b, a == b or a > b respectively.
561 pub fn cmp(a: Int, b: Int) i8 {561 pub fn cmp(a: Int, b: Int) i8 {
562 if (a.isPositive() != b.isPositive()) {562 if (a.isPositive() != b.isPositive()) {
563 return if (a.isPositive()) i8(1) else -1;563 return if (a.isPositive()) @as(i8, 1) else -1;
564 } else {564 } else {
565 const r = cmpAbs(a, b);565 const r = cmpAbs(a, b);
566 return if (a.isPositive()) r else -r;566 return if (a.isPositive()) r else -r;
...@@ -785,7 +785,7 @@ pub const Int = struct {...@@ -785,7 +785,7 @@ pub const Int = struct {
785 const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));785 const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1));
786786
787 // r2 = b * c787 // r2 = b * c
788 const bc = DoubleLimb(math.mulWide(Limb, b, c));788 const bc = @as(DoubleLimb, math.mulWide(Limb, b, c));
789 const r2 = @truncate(Limb, bc);789 const r2 = @truncate(Limb, bc);
790 const c2 = @truncate(Limb, bc >> Limb.bit_count);790 const c2 = @truncate(Limb, bc >> Limb.bit_count);
791791
...@@ -1084,7 +1084,7 @@ pub const Int = struct {...@@ -1084,7 +1084,7 @@ pub const Int = struct {
1084 rem.* = 0;1084 rem.* = 0;
1085 for (a) |_, ri| {1085 for (a) |_, ri| {
1086 const i = a.len - ri - 1;1086 const i = a.len - ri - 1;
1087 const pdiv = ((DoubleLimb(rem.*) << Limb.bit_count) | a[i]);1087 const pdiv = ((@as(DoubleLimb, rem.*) << Limb.bit_count) | a[i]);
10881088
1089 if (pdiv == 0) {1089 if (pdiv == 0) {
1090 quo[i] = 0;1090 quo[i] = 0;
...@@ -1143,9 +1143,9 @@ pub const Int = struct {...@@ -1143,9 +1143,9 @@ pub const Int = struct {
1143 if (x.limbs[i] == y.limbs[t]) {1143 if (x.limbs[i] == y.limbs[t]) {
1144 q.limbs[i - t - 1] = maxInt(Limb);1144 q.limbs[i - t - 1] = maxInt(Limb);
1145 } else {1145 } else {
1146 const num = (DoubleLimb(x.limbs[i]) << Limb.bit_count) | DoubleLimb(x.limbs[i - 1]);1146 const num = (@as(DoubleLimb, x.limbs[i]) << Limb.bit_count) | @as(DoubleLimb, x.limbs[i - 1]);
1147 const z = @intCast(Limb, num / DoubleLimb(y.limbs[t]));1147 const z = @intCast(Limb, num / @as(DoubleLimb, y.limbs[t]));
1148 q.limbs[i - t - 1] = if (z > maxInt(Limb)) maxInt(Limb) else Limb(z);1148 q.limbs[i - t - 1] = if (z > maxInt(Limb)) maxInt(Limb) else @as(Limb, z);
1149 }1149 }
11501150
1151 // 3.21151 // 3.2
...@@ -1362,7 +1362,7 @@ test "big.int comptime_int set" {...@@ -1362,7 +1362,7 @@ test "big.int comptime_int set" {
13621362
1363 comptime var i: usize = 0;1363 comptime var i: usize = 0;
1364 inline while (i < s_limb_count) : (i += 1) {1364 inline while (i < s_limb_count) : (i += 1) {
1365 const result = Limb(s & maxInt(Limb));1365 const result = @as(Limb, s & maxInt(Limb));
1366 s >>= Limb.bit_count / 2;1366 s >>= Limb.bit_count / 2;
1367 s >>= Limb.bit_count / 2;1367 s >>= Limb.bit_count / 2;
1368 testing.expect(a.limbs[i] == result);1368 testing.expect(a.limbs[i] == result);
...@@ -1377,7 +1377,7 @@ test "big.int comptime_int set negative" {...@@ -1377,7 +1377,7 @@ test "big.int comptime_int set negative" {
1377}1377}
13781378
1379test "big.int int set unaligned small" {1379test "big.int int set unaligned small" {
1380 var a = try Int.initSet(al, u7(45));1380 var a = try Int.initSet(al, @as(u7, 45));
13811381
1382 testing.expect(a.limbs[0] == 45);1382 testing.expect(a.limbs[0] == 45);
1383 testing.expect(a.isPositive() == true);1383 testing.expect(a.isPositive() == true);
lib/std/math/cbrt.zig+5-5
...@@ -54,11 +54,11 @@ fn cbrt32(x: f32) f32 {...@@ -54,11 +54,11 @@ fn cbrt32(x: f32) f32 {
54 // first step newton to 16 bits54 // first step newton to 16 bits
55 var t: f64 = @bitCast(f32, u);55 var t: f64 = @bitCast(f32, u);
56 var r: f64 = t * t * t;56 var r: f64 = t * t * t;
57 t = t * (f64(x) + x + r) / (x + r + r);57 t = t * (@as(f64, x) + x + r) / (x + r + r);
5858
59 // second step newton to 47 bits59 // second step newton to 47 bits
60 r = t * t * t;60 r = t * t * t;
61 t = t * (f64(x) + x + r) / (x + r + r);61 t = t * (@as(f64, x) + x + r) / (x + r + r);
6262
63 return @floatCast(f32, t);63 return @floatCast(f32, t);
64}64}
...@@ -97,7 +97,7 @@ fn cbrt64(x: f64) f64 {...@@ -97,7 +97,7 @@ fn cbrt64(x: f64) f64 {
97 }97 }
9898
99 u &= 1 << 63;99 u &= 1 << 63;
100 u |= u64(hx) << 32;100 u |= @as(u64, hx) << 32;
101 var t = @bitCast(f64, u);101 var t = @bitCast(f64, u);
102102
103 // cbrt to 23 bits103 // cbrt to 23 bits
...@@ -120,8 +120,8 @@ fn cbrt64(x: f64) f64 {...@@ -120,8 +120,8 @@ fn cbrt64(x: f64) f64 {
120}120}
121121
122test "math.cbrt" {122test "math.cbrt" {
123 expect(cbrt(f32(0.0)) == cbrt32(0.0));123 expect(cbrt(@as(f32, 0.0)) == cbrt32(0.0));
124 expect(cbrt(f64(0.0)) == cbrt64(0.0));124 expect(cbrt(@as(f64, 0.0)) == cbrt64(0.0));
125}125}
126126
127test "math.cbrt32" {127test "math.cbrt32" {
lib/std/math/ceil.zig+3-3
...@@ -37,7 +37,7 @@ fn ceil32(x: f32) f32 {...@@ -37,7 +37,7 @@ fn ceil32(x: f32) f32 {
37 if (e >= 23) {37 if (e >= 23) {
38 return x;38 return x;
39 } else if (e >= 0) {39 } else if (e >= 0) {
40 m = u32(0x007FFFFF) >> @intCast(u5, e);40 m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
41 if (u & m == 0) {41 if (u & m == 0) {
42 return x;42 return x;
43 }43 }
...@@ -87,8 +87,8 @@ fn ceil64(x: f64) f64 {...@@ -87,8 +87,8 @@ fn ceil64(x: f64) f64 {
87}87}
8888
89test "math.ceil" {89test "math.ceil" {
90 expect(ceil(f32(0.0)) == ceil32(0.0));90 expect(ceil(@as(f32, 0.0)) == ceil32(0.0));
91 expect(ceil(f64(0.0)) == ceil64(0.0));91 expect(ceil(@as(f64, 0.0)) == ceil64(0.0));
92}92}
9393
94test "math.ceil32" {94test "math.ceil32" {
lib/std/math/complex.zig+4-4
...@@ -133,8 +133,8 @@ test "complex.div" {...@@ -133,8 +133,8 @@ test "complex.div" {
133 const b = Complex(f32).new(2, 7);133 const b = Complex(f32).new(2, 7);
134 const c = a.div(b);134 const c = a.div(b);
135135
136 testing.expect(math.approxEq(f32, c.re, f32(31) / 53, epsilon) and136 testing.expect(math.approxEq(f32, c.re, @as(f32, 31) / 53, epsilon) and
137 math.approxEq(f32, c.im, f32(-29) / 53, epsilon));137 math.approxEq(f32, c.im, @as(f32, -29) / 53, epsilon));
138}138}
139139
140test "complex.conjugate" {140test "complex.conjugate" {
...@@ -148,8 +148,8 @@ test "complex.reciprocal" {...@@ -148,8 +148,8 @@ test "complex.reciprocal" {
148 const a = Complex(f32).new(5, 3);148 const a = Complex(f32).new(5, 3);
149 const c = a.reciprocal();149 const c = a.reciprocal();
150150
151 testing.expect(math.approxEq(f32, c.re, f32(5) / 34, epsilon) and151 testing.expect(math.approxEq(f32, c.re, @as(f32, 5) / 34, epsilon) and
152 math.approxEq(f32, c.im, f32(-3) / 34, epsilon));152 math.approxEq(f32, c.im, @as(f32, -3) / 34, epsilon));
153}153}
154154
155test "complex.magnitude" {155test "complex.magnitude" {
lib/std/math/complex/acos.zig+1-1
...@@ -8,7 +8,7 @@ const Complex = cmath.Complex;...@@ -8,7 +8,7 @@ const Complex = cmath.Complex;
8pub fn acos(z: var) Complex(@typeOf(z.re)) {8pub fn acos(z: var) Complex(@typeOf(z.re)) {
9 const T = @typeOf(z.re);9 const T = @typeOf(z.re);
10 const q = cmath.asin(z);10 const q = cmath.asin(z);
11 return Complex(T).new(T(math.pi) / 2 - q.re, -q.im);11 return Complex(T).new(@as(T, math.pi) / 2 - q.re, -q.im);
12}12}
1313
14const epsilon = 0.0001;14const epsilon = 0.0001;
lib/std/math/complex/ldexp.zig+2-2
...@@ -59,13 +59,13 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {...@@ -59,13 +59,13 @@ fn frexp_exp64(x: f64, expt: *i32) f64 {
59 expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k;59 expt.* = @intCast(i32, hx >> 20) - (0x3ff + 1023) + k;
6060
61 const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);61 const high_word = (hx & 0xfffff) | ((0x3ff + 1023) << 20);
62 return @bitCast(f64, (u64(high_word) << 32) | lx);62 return @bitCast(f64, (@as(u64, high_word) << 32) | lx);
63}63}
6464
65fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {65fn ldexp_cexp64(z: Complex(f64), expt: i32) Complex(f64) {
66 var ex_expt: i32 = undefined;66 var ex_expt: i32 = undefined;
67 const exp_x = frexp_exp64(z.re, &ex_expt);67 const exp_x = frexp_exp64(z.re, &ex_expt);
68 const exptf = i64(expt + ex_expt);68 const exptf = @as(i64, expt + ex_expt);
6969
70 const half_expt1 = @divTrunc(exptf, 2);70 const half_expt1 = @divTrunc(exptf, 2);
71 const scale1 = @bitCast(f64, (0x3ff + half_expt1) << 20);71 const scale1 = @bitCast(f64, (0x3ff + half_expt1) << 20);
lib/std/math/complex/sqrt.zig+2-2
...@@ -52,8 +52,8 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {...@@ -52,8 +52,8 @@ fn sqrt32(z: Complex(f32)) Complex(f32) {
52 // y = nan special case is handled fine below52 // y = nan special case is handled fine below
5353
54 // double-precision avoids overflow with correct rounding.54 // double-precision avoids overflow with correct rounding.
55 const dx = f64(x);55 const dx = @as(f64, x);
56 const dy = f64(y);56 const dy = @as(f64, y);
5757
58 if (dx >= 0) {58 if (dx >= 0) {
59 const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5);59 const t = math.sqrt((dx + math.hypot(f64, dx, dy)) * 0.5);
lib/std/math/complex/tanh.zig+1-1
...@@ -76,7 +76,7 @@ fn tanh64(z: Complex(f64)) Complex(f64) {...@@ -76,7 +76,7 @@ fn tanh64(z: Complex(f64)) Complex(f64) {
76 return Complex(f64).new(x, r);76 return Complex(f64).new(x, r);
77 }77 }
7878
79 const xx = @bitCast(f64, (u64(hx - 0x40000000) << 32) | lx);79 const xx = @bitCast(f64, (@as(u64, hx - 0x40000000) << 32) | lx);
80 const r = if (math.isInf(y)) y else math.sin(y) * math.cos(y);80 const r = if (math.isInf(y)) y else math.sin(y) * math.cos(y);
81 return Complex(f64).new(xx, math.copysign(f64, 0, r));81 return Complex(f64).new(xx, math.copysign(f64, 0, r));
82 }82 }
lib/std/math/copysign.zig+3-3
...@@ -24,7 +24,7 @@ fn copysign16(x: f16, y: f16) f16 {...@@ -24,7 +24,7 @@ fn copysign16(x: f16, y: f16) f16 {
24 const uy = @bitCast(u16, y);24 const uy = @bitCast(u16, y);
2525
26 const h1 = ux & (maxInt(u16) / 2);26 const h1 = ux & (maxInt(u16) / 2);
27 const h2 = uy & (u16(1) << 15);27 const h2 = uy & (@as(u16, 1) << 15);
28 return @bitCast(f16, h1 | h2);28 return @bitCast(f16, h1 | h2);
29}29}
3030
...@@ -33,7 +33,7 @@ fn copysign32(x: f32, y: f32) f32 {...@@ -33,7 +33,7 @@ fn copysign32(x: f32, y: f32) f32 {
33 const uy = @bitCast(u32, y);33 const uy = @bitCast(u32, y);
3434
35 const h1 = ux & (maxInt(u32) / 2);35 const h1 = ux & (maxInt(u32) / 2);
36 const h2 = uy & (u32(1) << 31);36 const h2 = uy & (@as(u32, 1) << 31);
37 return @bitCast(f32, h1 | h2);37 return @bitCast(f32, h1 | h2);
38}38}
3939
...@@ -42,7 +42,7 @@ fn copysign64(x: f64, y: f64) f64 {...@@ -42,7 +42,7 @@ fn copysign64(x: f64, y: f64) f64 {
42 const uy = @bitCast(u64, y);42 const uy = @bitCast(u64, y);
4343
44 const h1 = ux & (maxInt(u64) / 2);44 const h1 = ux & (maxInt(u64) / 2);
45 const h2 = uy & (u64(1) << 63);45 const h2 = uy & (@as(u64, 1) << 63);
46 return @bitCast(f64, h1 | h2);46 return @bitCast(f64, h1 | h2);
47}47}
4848
lib/std/math/cos.zig+2-2
...@@ -83,8 +83,8 @@ fn cos_(comptime T: type, x_: T) T {...@@ -83,8 +83,8 @@ fn cos_(comptime T: type, x_: T) T {
83}83}
8484
85test "math.cos" {85test "math.cos" {
86 expect(cos(f32(0.0)) == cos_(f32, 0.0));86 expect(cos(@as(f32, 0.0)) == cos_(f32, 0.0));
87 expect(cos(f64(0.0)) == cos_(f64, 0.0));87 expect(cos(@as(f64, 0.0)) == cos_(f64, 0.0));
88}88}
8989
90test "math.cos32" {90test "math.cos32" {
lib/std/math/cosh.zig+2-2
...@@ -88,8 +88,8 @@ fn cosh64(x: f64) f64 {...@@ -88,8 +88,8 @@ fn cosh64(x: f64) f64 {
88}88}
8989
90test "math.cosh" {90test "math.cosh" {
91 expect(cosh(f32(1.5)) == cosh32(1.5));91 expect(cosh(@as(f32, 1.5)) == cosh32(1.5));
92 expect(cosh(f64(1.5)) == cosh64(1.5));92 expect(cosh(@as(f64, 1.5)) == cosh64(1.5));
93}93}
9494
95test "math.cosh32" {95test "math.cosh32" {
lib/std/math/exp.zig+3-3
...@@ -134,7 +134,7 @@ fn exp64(x_: f64) f64 {...@@ -134,7 +134,7 @@ fn exp64(x_: f64) f64 {
134 }134 }
135 if (x < -708.39641853226410622) {135 if (x < -708.39641853226410622) {
136 // underflow if x != -inf136 // underflow if x != -inf
137 // math.forceEval(f32(-0x1.0p-149 / x));137 // math.forceEval(@as(f32, -0x1.0p-149 / x));
138 if (x < -745.13321910194110842) {138 if (x < -745.13321910194110842) {
139 return 0;139 return 0;
140 }140 }
...@@ -183,8 +183,8 @@ fn exp64(x_: f64) f64 {...@@ -183,8 +183,8 @@ fn exp64(x_: f64) f64 {
183}183}
184184
185test "math.exp" {185test "math.exp" {
186 assert(exp(f32(0.0)) == exp32(0.0));186 assert(exp(@as(f32, 0.0)) == exp32(0.0));
187 assert(exp(f64(0.0)) == exp64(0.0));187 assert(exp(@as(f64, 0.0)) == exp64(0.0));
188}188}
189189
190test "math.exp32" {190test "math.exp32" {
lib/std/math/exp2.zig+3-3
...@@ -85,7 +85,7 @@ fn exp2_32(x: f32) f32 {...@@ -85,7 +85,7 @@ fn exp2_32(x: f32) f32 {
85 const k = i_0 / tblsiz;85 const k = i_0 / tblsiz;
86 // NOTE: musl relies on undefined overflow shift behaviour. Appears that this produces the86 // NOTE: musl relies on undefined overflow shift behaviour. Appears that this produces the
87 // intended result but should confirm how GCC/Clang handle this to ensure.87 // intended result but should confirm how GCC/Clang handle this to ensure.
88 const uk = @bitCast(f64, u64(0x3FF + k) << 52);88 const uk = @bitCast(f64, @as(u64, 0x3FF + k) << 52);
89 i_0 &= tblsiz - 1;89 i_0 &= tblsiz - 1;
90 uf -= redux;90 uf -= redux;
9191
...@@ -421,8 +421,8 @@ fn exp2_64(x: f64) f64 {...@@ -421,8 +421,8 @@ fn exp2_64(x: f64) f64 {
421}421}
422422
423test "math.exp2" {423test "math.exp2" {
424 expect(exp2(f32(0.8923)) == exp2_32(0.8923));424 expect(exp2(@as(f32, 0.8923)) == exp2_32(0.8923));
425 expect(exp2(f64(0.8923)) == exp2_64(0.8923));425 expect(exp2(@as(f64, 0.8923)) == exp2_64(0.8923));
426}426}
427427
428test "math.exp2_32" {428test "math.exp2_32" {
lib/std/math/expm1.zig+2-2
...@@ -287,8 +287,8 @@ fn expm1_64(x_: f64) f64 {...@@ -287,8 +287,8 @@ fn expm1_64(x_: f64) f64 {
287}287}
288288
289test "math.exp1m" {289test "math.exp1m" {
290 expect(expm1(f32(0.0)) == expm1_32(0.0));290 expect(expm1(@as(f32, 0.0)) == expm1_32(0.0));
291 expect(expm1(f64(0.0)) == expm1_64(0.0));291 expect(expm1(@as(f64, 0.0)) == expm1_64(0.0));
292}292}
293293
294test "math.expm1_32" {294test "math.expm1_32" {
lib/std/math/expo2.zig+1-1
...@@ -30,6 +30,6 @@ fn expo2d(x: f64) f64 {...@@ -30,6 +30,6 @@ fn expo2d(x: f64) f64 {
30 const kln2 = 0x1.62066151ADD8BP+10;30 const kln2 = 0x1.62066151ADD8BP+10;
3131
32 const u = (0x3FF + k / 2) << 20;32 const u = (0x3FF + k / 2) << 20;
33 const scale = @bitCast(f64, u64(u) << 32);33 const scale = @bitCast(f64, @as(u64, u) << 32);
34 return math.exp(x - kln2) * scale * scale;34 return math.exp(x - kln2) * scale * scale;
35}35}
lib/std/math/fabs.zig+4-4
...@@ -50,10 +50,10 @@ fn fabs128(x: f128) f128 {...@@ -50,10 +50,10 @@ fn fabs128(x: f128) f128 {
50}50}
5151
52test "math.fabs" {52test "math.fabs" {
53 expect(fabs(f16(1.0)) == fabs16(1.0));53 expect(fabs(@as(f16, 1.0)) == fabs16(1.0));
54 expect(fabs(f32(1.0)) == fabs32(1.0));54 expect(fabs(@as(f32, 1.0)) == fabs32(1.0));
55 expect(fabs(f64(1.0)) == fabs64(1.0));55 expect(fabs(@as(f64, 1.0)) == fabs64(1.0));
56 expect(fabs(f128(1.0)) == fabs128(1.0));56 expect(fabs(@as(f128, 1.0)) == fabs128(1.0));
57}57}
5858
59test "math.fabs16" {59test "math.fabs16" {
lib/std/math/floor.zig+5-5
...@@ -40,7 +40,7 @@ fn floor16(x: f16) f16 {...@@ -40,7 +40,7 @@ fn floor16(x: f16) f16 {
40 }40 }
4141
42 if (e >= 0) {42 if (e >= 0) {
43 m = u16(1023) >> @intCast(u4, e);43 m = @as(u16, 1023) >> @intCast(u4, e);
44 if (u & m == 0) {44 if (u & m == 0) {
45 return x;45 return x;
46 }46 }
...@@ -74,7 +74,7 @@ fn floor32(x: f32) f32 {...@@ -74,7 +74,7 @@ fn floor32(x: f32) f32 {
74 }74 }
7575
76 if (e >= 0) {76 if (e >= 0) {
77 m = u32(0x007FFFFF) >> @intCast(u5, e);77 m = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
78 if (u & m == 0) {78 if (u & m == 0) {
79 return x;79 return x;
80 }80 }
...@@ -123,9 +123,9 @@ fn floor64(x: f64) f64 {...@@ -123,9 +123,9 @@ fn floor64(x: f64) f64 {
123}123}
124124
125test "math.floor" {125test "math.floor" {
126 expect(floor(f16(1.3)) == floor16(1.3));126 expect(floor(@as(f16, 1.3)) == floor16(1.3));
127 expect(floor(f32(1.3)) == floor32(1.3));127 expect(floor(@as(f32, 1.3)) == floor32(1.3));
128 expect(floor(f64(1.3)) == floor64(1.3));128 expect(floor(@as(f64, 1.3)) == floor64(1.3));
129}129}
130130
131test "math.floor16" {131test "math.floor16" {
lib/std/math/fma.zig+1-1
...@@ -18,7 +18,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) T {...@@ -18,7 +18,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) T {
18}18}
1919
20fn fma32(x: f32, y: f32, z: f32) f32 {20fn fma32(x: f32, y: f32, z: f32) f32 {
21 const xy = f64(x) * y;21 const xy = @as(f64, x) * y;
22 const xy_z = xy + z;22 const xy_z = xy + z;
23 const u = @bitCast(u64, xy_z);23 const u = @bitCast(u64, xy_z);
24 const e = (u >> 52) & 0x7FF;24 const e = (u >> 52) & 0x7FF;
lib/std/math/frexp.zig+2-2
...@@ -108,11 +108,11 @@ fn frexp64(x: f64) frexp64_result {...@@ -108,11 +108,11 @@ fn frexp64(x: f64) frexp64_result {
108}108}
109109
110test "math.frexp" {110test "math.frexp" {
111 const a = frexp(f32(1.3));111 const a = frexp(@as(f32, 1.3));
112 const b = frexp32(1.3);112 const b = frexp32(1.3);
113 expect(a.significand == b.significand and a.exponent == b.exponent);113 expect(a.significand == b.significand and a.exponent == b.exponent);
114114
115 const c = frexp(f64(1.3));115 const c = frexp(@as(f64, 1.3));
116 const d = frexp64(1.3);116 const d = frexp64(1.3);
117 expect(c.significand == d.significand and c.exponent == d.exponent);117 expect(c.significand == d.significand and c.exponent == d.exponent);
118}118}
lib/std/math/hypot.zig+1-1
...@@ -56,7 +56,7 @@ fn hypot32(x: f32, y: f32) f32 {...@@ -56,7 +56,7 @@ fn hypot32(x: f32, y: f32) f32 {
56 yy *= 0x1.0p-90;56 yy *= 0x1.0p-90;
57 }57 }
5858
59 return z * math.sqrt(@floatCast(f32, f64(x) * x + f64(y) * y));59 return z * math.sqrt(@floatCast(f32, @as(f64, x) * x + @as(f64, y) * y));
60}60}
6161
62fn sq(hi: *f64, lo: *f64, x: f64) void {62fn sq(hi: *f64, lo: *f64, x: f64) void {
lib/std/math/ilogb.zig+3-3
...@@ -26,7 +26,7 @@ pub fn ilogb(x: var) i32 {...@@ -26,7 +26,7 @@ pub fn ilogb(x: var) i32 {
26}26}
2727
28// NOTE: Should these be exposed publicly?28// NOTE: Should these be exposed publicly?
29const fp_ilogbnan = -1 - i32(maxInt(u32) >> 1);29const fp_ilogbnan = -1 - @as(i32, maxInt(u32) >> 1);
30const fp_ilogb0 = fp_ilogbnan;30const fp_ilogb0 = fp_ilogbnan;
3131
32fn ilogb32(x: f32) i32 {32fn ilogb32(x: f32) i32 {
...@@ -101,8 +101,8 @@ fn ilogb64(x: f64) i32 {...@@ -101,8 +101,8 @@ fn ilogb64(x: f64) i32 {
101}101}
102102
103test "math.ilogb" {103test "math.ilogb" {
104 expect(ilogb(f32(0.2)) == ilogb32(0.2));104 expect(ilogb(@as(f32, 0.2)) == ilogb32(0.2));
105 expect(ilogb(f64(0.2)) == ilogb64(0.2));105 expect(ilogb(@as(f64, 0.2)) == ilogb64(0.2));
106}106}
107107
108test "math.ilogb32" {108test "math.ilogb32" {
lib/std/math/isfinite.zig+6-6
...@@ -26,12 +26,12 @@ pub fn isFinite(x: var) bool {...@@ -26,12 +26,12 @@ pub fn isFinite(x: var) bool {
26}26}
2727
28test "math.isFinite" {28test "math.isFinite" {
29 expect(isFinite(f16(0.0)));29 expect(isFinite(@as(f16, 0.0)));
30 expect(isFinite(f16(-0.0)));30 expect(isFinite(@as(f16, -0.0)));
31 expect(isFinite(f32(0.0)));31 expect(isFinite(@as(f32, 0.0)));
32 expect(isFinite(f32(-0.0)));32 expect(isFinite(@as(f32, -0.0)));
33 expect(isFinite(f64(0.0)));33 expect(isFinite(@as(f64, 0.0)));
34 expect(isFinite(f64(-0.0)));34 expect(isFinite(@as(f64, -0.0)));
35 expect(!isFinite(math.inf(f16)));35 expect(!isFinite(math.inf(f16)));
36 expect(!isFinite(-math.inf(f16)));36 expect(!isFinite(-math.inf(f16)));
37 expect(!isFinite(math.inf(f32)));37 expect(!isFinite(math.inf(f32)));
lib/std/math/isinf.zig+24-24
...@@ -74,14 +74,14 @@ pub fn isNegativeInf(x: var) bool {...@@ -74,14 +74,14 @@ pub fn isNegativeInf(x: var) bool {
74}74}
7575
76test "math.isInf" {76test "math.isInf" {
77 expect(!isInf(f16(0.0)));77 expect(!isInf(@as(f16, 0.0)));
78 expect(!isInf(f16(-0.0)));78 expect(!isInf(@as(f16, -0.0)));
79 expect(!isInf(f32(0.0)));79 expect(!isInf(@as(f32, 0.0)));
80 expect(!isInf(f32(-0.0)));80 expect(!isInf(@as(f32, -0.0)));
81 expect(!isInf(f64(0.0)));81 expect(!isInf(@as(f64, 0.0)));
82 expect(!isInf(f64(-0.0)));82 expect(!isInf(@as(f64, -0.0)));
83 expect(!isInf(f128(0.0)));83 expect(!isInf(@as(f128, 0.0)));
84 expect(!isInf(f128(-0.0)));84 expect(!isInf(@as(f128, -0.0)));
85 expect(isInf(math.inf(f16)));85 expect(isInf(math.inf(f16)));
86 expect(isInf(-math.inf(f16)));86 expect(isInf(-math.inf(f16)));
87 expect(isInf(math.inf(f32)));87 expect(isInf(math.inf(f32)));
...@@ -93,14 +93,14 @@ test "math.isInf" {...@@ -93,14 +93,14 @@ test "math.isInf" {
93}93}
9494
95test "math.isPositiveInf" {95test "math.isPositiveInf" {
96 expect(!isPositiveInf(f16(0.0)));96 expect(!isPositiveInf(@as(f16, 0.0)));
97 expect(!isPositiveInf(f16(-0.0)));97 expect(!isPositiveInf(@as(f16, -0.0)));
98 expect(!isPositiveInf(f32(0.0)));98 expect(!isPositiveInf(@as(f32, 0.0)));
99 expect(!isPositiveInf(f32(-0.0)));99 expect(!isPositiveInf(@as(f32, -0.0)));
100 expect(!isPositiveInf(f64(0.0)));100 expect(!isPositiveInf(@as(f64, 0.0)));
101 expect(!isPositiveInf(f64(-0.0)));101 expect(!isPositiveInf(@as(f64, -0.0)));
102 expect(!isPositiveInf(f128(0.0)));102 expect(!isPositiveInf(@as(f128, 0.0)));
103 expect(!isPositiveInf(f128(-0.0)));103 expect(!isPositiveInf(@as(f128, -0.0)));
104 expect(isPositiveInf(math.inf(f16)));104 expect(isPositiveInf(math.inf(f16)));
105 expect(!isPositiveInf(-math.inf(f16)));105 expect(!isPositiveInf(-math.inf(f16)));
106 expect(isPositiveInf(math.inf(f32)));106 expect(isPositiveInf(math.inf(f32)));
...@@ -112,14 +112,14 @@ test "math.isPositiveInf" {...@@ -112,14 +112,14 @@ test "math.isPositiveInf" {
112}112}
113113
114test "math.isNegativeInf" {114test "math.isNegativeInf" {
115 expect(!isNegativeInf(f16(0.0)));115 expect(!isNegativeInf(@as(f16, 0.0)));
116 expect(!isNegativeInf(f16(-0.0)));116 expect(!isNegativeInf(@as(f16, -0.0)));
117 expect(!isNegativeInf(f32(0.0)));117 expect(!isNegativeInf(@as(f32, 0.0)));
118 expect(!isNegativeInf(f32(-0.0)));118 expect(!isNegativeInf(@as(f32, -0.0)));
119 expect(!isNegativeInf(f64(0.0)));119 expect(!isNegativeInf(@as(f64, 0.0)));
120 expect(!isNegativeInf(f64(-0.0)));120 expect(!isNegativeInf(@as(f64, -0.0)));
121 expect(!isNegativeInf(f128(0.0)));121 expect(!isNegativeInf(@as(f128, 0.0)));
122 expect(!isNegativeInf(f128(-0.0)));122 expect(!isNegativeInf(@as(f128, -0.0)));
123 expect(!isNegativeInf(math.inf(f16)));123 expect(!isNegativeInf(math.inf(f16)));
124 expect(isNegativeInf(-math.inf(f16)));124 expect(isNegativeInf(-math.inf(f16)));
125 expect(!isNegativeInf(math.inf(f32)));125 expect(!isNegativeInf(math.inf(f32)));
lib/std/math/isnan.zig+4-4
...@@ -20,8 +20,8 @@ test "math.isNan" {...@@ -20,8 +20,8 @@ test "math.isNan" {
20 expect(isNan(math.nan(f32)));20 expect(isNan(math.nan(f32)));
21 expect(isNan(math.nan(f64)));21 expect(isNan(math.nan(f64)));
22 expect(isNan(math.nan(f128)));22 expect(isNan(math.nan(f128)));
23 expect(!isNan(f16(1.0)));23 expect(!isNan(@as(f16, 1.0)));
24 expect(!isNan(f32(1.0)));24 expect(!isNan(@as(f32, 1.0)));
25 expect(!isNan(f64(1.0)));25 expect(!isNan(@as(f64, 1.0)));
26 expect(!isNan(f128(1.0)));26 expect(!isNan(@as(f128, 1.0)));
27}27}
lib/std/math/isnormal.zig+6-6
...@@ -29,10 +29,10 @@ test "math.isNormal" {...@@ -29,10 +29,10 @@ test "math.isNormal" {
29 expect(!isNormal(math.nan(f16)));29 expect(!isNormal(math.nan(f16)));
30 expect(!isNormal(math.nan(f32)));30 expect(!isNormal(math.nan(f32)));
31 expect(!isNormal(math.nan(f64)));31 expect(!isNormal(math.nan(f64)));
32 expect(!isNormal(f16(0)));32 expect(!isNormal(@as(f16, 0)));
33 expect(!isNormal(f32(0)));33 expect(!isNormal(@as(f32, 0)));
34 expect(!isNormal(f64(0)));34 expect(!isNormal(@as(f64, 0)));
35 expect(isNormal(f16(1.0)));35 expect(isNormal(@as(f16, 1.0)));
36 expect(isNormal(f32(1.0)));36 expect(isNormal(@as(f32, 1.0)));
37 expect(isNormal(f64(1.0)));37 expect(isNormal(@as(f64, 1.0)));
38}38}
lib/std/math/ln.zig+5-5
...@@ -31,10 +31,10 @@ pub fn ln(x: var) @typeOf(x) {...@@ -31,10 +31,10 @@ pub fn ln(x: var) @typeOf(x) {
31 };31 };
32 },32 },
33 TypeId.ComptimeInt => {33 TypeId.ComptimeInt => {
34 return @typeOf(1)(math.floor(ln_64(f64(x))));34 return @typeOf(1)(math.floor(ln_64(@as(f64, x))));
35 },35 },
36 TypeId.Int => {36 TypeId.Int => {
37 return T(math.floor(ln_64(f64(x))));37 return @as(T, math.floor(ln_64(@as(f64, x))));
38 },38 },
39 else => @compileError("ln not implemented for " ++ @typeName(T)),39 else => @compileError("ln not implemented for " ++ @typeName(T)),
40 }40 }
...@@ -132,7 +132,7 @@ pub fn ln_64(x_: f64) f64 {...@@ -132,7 +132,7 @@ pub fn ln_64(x_: f64) f64 {
132 hx += 0x3FF00000 - 0x3FE6A09E;132 hx += 0x3FF00000 - 0x3FE6A09E;
133 k += @intCast(i32, hx >> 20) - 0x3FF;133 k += @intCast(i32, hx >> 20) - 0x3FF;
134 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;134 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
135 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);135 ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
136 x = @bitCast(f64, ix);136 x = @bitCast(f64, ix);
137137
138 const f = x - 1.0;138 const f = x - 1.0;
...@@ -149,8 +149,8 @@ pub fn ln_64(x_: f64) f64 {...@@ -149,8 +149,8 @@ pub fn ln_64(x_: f64) f64 {
149}149}
150150
151test "math.ln" {151test "math.ln" {
152 expect(ln(f32(0.2)) == ln_32(0.2));152 expect(ln(@as(f32, 0.2)) == ln_32(0.2));
153 expect(ln(f64(0.2)) == ln_64(0.2));153 expect(ln(@as(f64, 0.2)) == ln_64(0.2));
154}154}
155155
156test "math.ln32" {156test "math.ln32" {
lib/std/math/log.zig+7-7
...@@ -23,10 +23,10 @@ pub fn log(comptime T: type, base: T, x: T) T {...@@ -23,10 +23,10 @@ pub fn log(comptime T: type, base: T, x: T) T {
23 const float_base = math.lossyCast(f64, base);23 const float_base = math.lossyCast(f64, base);
24 switch (@typeId(T)) {24 switch (@typeId(T)) {
25 TypeId.ComptimeFloat => {25 TypeId.ComptimeFloat => {
26 return @typeOf(1.0)(math.ln(f64(x)) / math.ln(float_base));26 return @typeOf(1.0)(math.ln(@as(f64, x)) / math.ln(float_base));
27 },27 },
28 TypeId.ComptimeInt => {28 TypeId.ComptimeInt => {
29 return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(float_base)));29 return @typeOf(1)(math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));
30 },30 },
31 builtin.TypeId.Int => {31 builtin.TypeId.Int => {
32 // TODO implement integer log without using float math32 // TODO implement integer log without using float math
...@@ -35,7 +35,7 @@ pub fn log(comptime T: type, base: T, x: T) T {...@@ -35,7 +35,7 @@ pub fn log(comptime T: type, base: T, x: T) T {
3535
36 builtin.TypeId.Float => {36 builtin.TypeId.Float => {
37 switch (T) {37 switch (T) {
38 f32 => return @floatCast(f32, math.ln(f64(x)) / math.ln(float_base)),38 f32 => return @floatCast(f32, math.ln(@as(f64, x)) / math.ln(float_base)),
39 f64 => return math.ln(x) / math.ln(float_base),39 f64 => return math.ln(x) / math.ln(float_base),
40 else => @compileError("log not implemented for " ++ @typeName(T)),40 else => @compileError("log not implemented for " ++ @typeName(T)),
41 }41 }
...@@ -64,9 +64,9 @@ test "math.log float" {...@@ -64,9 +64,9 @@ test "math.log float" {
64}64}
6565
66test "math.log float_special" {66test "math.log float_special" {
67 expect(log(f32, 2, 0.2301974) == math.log2(f32(0.2301974)));67 expect(log(f32, 2, 0.2301974) == math.log2(@as(f32, 0.2301974)));
68 expect(log(f32, 10, 0.2301974) == math.log10(f32(0.2301974)));68 expect(log(f32, 10, 0.2301974) == math.log10(@as(f32, 0.2301974)));
6969
70 expect(log(f64, 2, 213.23019799993) == math.log2(f64(213.23019799993)));70 expect(log(f64, 2, 213.23019799993) == math.log2(@as(f64, 213.23019799993)));
71 expect(log(f64, 10, 213.23019799993) == math.log10(f64(213.23019799993)));71 expect(log(f64, 10, 213.23019799993) == math.log10(@as(f64, 213.23019799993)));
72}72}
lib/std/math/log10.zig+5-5
...@@ -32,7 +32,7 @@ pub fn log10(x: var) @typeOf(x) {...@@ -32,7 +32,7 @@ pub fn log10(x: var) @typeOf(x) {
32 };32 };
33 },33 },
34 TypeId.ComptimeInt => {34 TypeId.ComptimeInt => {
35 return @typeOf(1)(math.floor(log10_64(f64(x))));35 return @typeOf(1)(math.floor(log10_64(@as(f64, x))));
36 },36 },
37 TypeId.Int => {37 TypeId.Int => {
38 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));38 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));
...@@ -143,7 +143,7 @@ pub fn log10_64(x_: f64) f64 {...@@ -143,7 +143,7 @@ pub fn log10_64(x_: f64) f64 {
143 hx += 0x3FF00000 - 0x3FE6A09E;143 hx += 0x3FF00000 - 0x3FE6A09E;
144 k += @intCast(i32, hx >> 20) - 0x3FF;144 k += @intCast(i32, hx >> 20) - 0x3FF;
145 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;145 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
146 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);146 ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
147 x = @bitCast(f64, ix);147 x = @bitCast(f64, ix);
148148
149 const f = x - 1.0;149 const f = x - 1.0;
...@@ -158,7 +158,7 @@ pub fn log10_64(x_: f64) f64 {...@@ -158,7 +158,7 @@ pub fn log10_64(x_: f64) f64 {
158 // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)158 // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
159 var hi = f - hfsq;159 var hi = f - hfsq;
160 var hii = @bitCast(u64, hi);160 var hii = @bitCast(u64, hi);
161 hii &= u64(maxInt(u64)) << 32;161 hii &= @as(u64, maxInt(u64)) << 32;
162 hi = @bitCast(f64, hii);162 hi = @bitCast(f64, hii);
163 const lo = f - hi - hfsq + s * (hfsq + R);163 const lo = f - hi - hfsq + s * (hfsq + R);
164164
...@@ -177,8 +177,8 @@ pub fn log10_64(x_: f64) f64 {...@@ -177,8 +177,8 @@ pub fn log10_64(x_: f64) f64 {
177}177}
178178
179test "math.log10" {179test "math.log10" {
180 testing.expect(log10(f32(0.2)) == log10_32(0.2));180 testing.expect(log10(@as(f32, 0.2)) == log10_32(0.2));
181 testing.expect(log10(f64(0.2)) == log10_64(0.2));181 testing.expect(log10(@as(f64, 0.2)) == log10_64(0.2));
182}182}
183183
184test "math.log10_32" {184test "math.log10_32" {
lib/std/math/log1p.zig+3-3
...@@ -166,7 +166,7 @@ fn log1p_64(x: f64) f64 {...@@ -166,7 +166,7 @@ fn log1p_64(x: f64) f64 {
166166
167 // u into [sqrt(2)/2, sqrt(2)]167 // u into [sqrt(2)/2, sqrt(2)]
168 iu = (iu & 0x000FFFFF) + 0x3FE6A09E;168 iu = (iu & 0x000FFFFF) + 0x3FE6A09E;
169 const iq = (u64(iu) << 32) | (hu & 0xFFFFFFFF);169 const iq = (@as(u64, iu) << 32) | (hu & 0xFFFFFFFF);
170 f = @bitCast(f64, iq) - 1;170 f = @bitCast(f64, iq) - 1;
171 }171 }
172172
...@@ -183,8 +183,8 @@ fn log1p_64(x: f64) f64 {...@@ -183,8 +183,8 @@ fn log1p_64(x: f64) f64 {
183}183}
184184
185test "math.log1p" {185test "math.log1p" {
186 expect(log1p(f32(0.0)) == log1p_32(0.0));186 expect(log1p(@as(f32, 0.0)) == log1p_32(0.0));
187 expect(log1p(f64(0.0)) == log1p_64(0.0));187 expect(log1p(@as(f64, 0.0)) == log1p_64(0.0));
188}188}
189189
190test "math.log1p_32" {190test "math.log1p_32" {
lib/std/math/log2.zig+4-4
...@@ -143,7 +143,7 @@ pub fn log2_64(x_: f64) f64 {...@@ -143,7 +143,7 @@ pub fn log2_64(x_: f64) f64 {
143 hx += 0x3FF00000 - 0x3FE6A09E;143 hx += 0x3FF00000 - 0x3FE6A09E;
144 k += @intCast(i32, hx >> 20) - 0x3FF;144 k += @intCast(i32, hx >> 20) - 0x3FF;
145 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;145 hx = (hx & 0x000FFFFF) + 0x3FE6A09E;
146 ix = (u64(hx) << 32) | (ix & 0xFFFFFFFF);146 ix = (@as(u64, hx) << 32) | (ix & 0xFFFFFFFF);
147 x = @bitCast(f64, ix);147 x = @bitCast(f64, ix);
148148
149 const f = x - 1.0;149 const f = x - 1.0;
...@@ -158,7 +158,7 @@ pub fn log2_64(x_: f64) f64 {...@@ -158,7 +158,7 @@ pub fn log2_64(x_: f64) f64 {
158 // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)158 // hi + lo = f - hfsq + s * (hfsq + R) ~ log(1 + f)
159 var hi = f - hfsq;159 var hi = f - hfsq;
160 var hii = @bitCast(u64, hi);160 var hii = @bitCast(u64, hi);
161 hii &= u64(maxInt(u64)) << 32;161 hii &= @as(u64, maxInt(u64)) << 32;
162 hi = @bitCast(f64, hii);162 hi = @bitCast(f64, hii);
163 const lo = f - hi - hfsq + s * (hfsq + R);163 const lo = f - hi - hfsq + s * (hfsq + R);
164164
...@@ -175,8 +175,8 @@ pub fn log2_64(x_: f64) f64 {...@@ -175,8 +175,8 @@ pub fn log2_64(x_: f64) f64 {
175}175}
176176
177test "math.log2" {177test "math.log2" {
178 expect(log2(f32(0.2)) == log2_32(0.2));178 expect(log2(@as(f32, 0.2)) == log2_32(0.2));
179 expect(log2(f64(0.2)) == log2_64(0.2));179 expect(log2(@as(f64, 0.2)) == log2_64(0.2));
180}180}
181181
182test "math.log2_32" {182test "math.log2_32" {
lib/std/math/modf.zig+4-4
...@@ -65,7 +65,7 @@ fn modf32(x: f32) modf32_result {...@@ -65,7 +65,7 @@ fn modf32(x: f32) modf32_result {
65 return result;65 return result;
66 }66 }
6767
68 const mask = u32(0x007FFFFF) >> @intCast(u5, e);68 const mask = @as(u32, 0x007FFFFF) >> @intCast(u5, e);
69 if (u & mask == 0) {69 if (u & mask == 0) {
70 result.ipart = x;70 result.ipart = x;
71 result.fpart = @bitCast(f32, us);71 result.fpart = @bitCast(f32, us);
...@@ -109,7 +109,7 @@ fn modf64(x: f64) modf64_result {...@@ -109,7 +109,7 @@ fn modf64(x: f64) modf64_result {
109 return result;109 return result;
110 }110 }
111111
112 const mask = u64(maxInt(u64) >> 12) >> @intCast(u6, e);112 const mask = @as(u64, maxInt(u64) >> 12) >> @intCast(u6, e);
113 if (u & mask == 0) {113 if (u & mask == 0) {
114 result.ipart = x;114 result.ipart = x;
115 result.fpart = @bitCast(f64, us);115 result.fpart = @bitCast(f64, us);
...@@ -123,12 +123,12 @@ fn modf64(x: f64) modf64_result {...@@ -123,12 +123,12 @@ fn modf64(x: f64) modf64_result {
123}123}
124124
125test "math.modf" {125test "math.modf" {
126 const a = modf(f32(1.0));126 const a = modf(@as(f32, 1.0));
127 const b = modf32(1.0);127 const b = modf32(1.0);
128 // NOTE: No struct comparison on generic return type function? non-named, makes sense, but still.128 // NOTE: No struct comparison on generic return type function? non-named, makes sense, but still.
129 expect(a.ipart == b.ipart and a.fpart == b.fpart);129 expect(a.ipart == b.ipart and a.fpart == b.fpart);
130130
131 const c = modf(f64(1.0));131 const c = modf(@as(f64, 1.0));
132 const d = modf64(1.0);132 const d = modf64(1.0);
133 expect(a.ipart == b.ipart and a.fpart == b.fpart);133 expect(a.ipart == b.ipart and a.fpart == b.fpart);
134}134}
lib/std/math/round.zig+2-2
...@@ -91,8 +91,8 @@ fn round64(x_: f64) f64 {...@@ -91,8 +91,8 @@ fn round64(x_: f64) f64 {
91}91}
9292
93test "math.round" {93test "math.round" {
94 expect(round(f32(1.3)) == round32(1.3));94 expect(round(@as(f32, 1.3)) == round32(1.3));
95 expect(round(f64(1.3)) == round64(1.3));95 expect(round(@as(f64, 1.3)) == round64(1.3));
96}96}
9797
98test "math.round32" {98test "math.round32" {
lib/std/math/scalbn.zig+2-2
...@@ -79,8 +79,8 @@ fn scalbn64(x: f64, n_: i32) f64 {...@@ -79,8 +79,8 @@ fn scalbn64(x: f64, n_: i32) f64 {
79}79}
8080
81test "math.scalbn" {81test "math.scalbn" {
82 expect(scalbn(f32(1.5), 4) == scalbn32(1.5, 4));82 expect(scalbn(@as(f32, 1.5), 4) == scalbn32(1.5, 4));
83 expect(scalbn(f64(1.5), 4) == scalbn64(1.5, 4));83 expect(scalbn(@as(f64, 1.5), 4) == scalbn64(1.5, 4));
84}84}
8585
86test "math.scalbn32" {86test "math.scalbn32" {
lib/std/math/signbit.zig+3-3
...@@ -29,9 +29,9 @@ fn signbit64(x: f64) bool {...@@ -29,9 +29,9 @@ fn signbit64(x: f64) bool {
29}29}
3030
31test "math.signbit" {31test "math.signbit" {
32 expect(signbit(f16(4.0)) == signbit16(4.0));32 expect(signbit(@as(f16, 4.0)) == signbit16(4.0));
33 expect(signbit(f32(4.0)) == signbit32(4.0));33 expect(signbit(@as(f32, 4.0)) == signbit32(4.0));
34 expect(signbit(f64(4.0)) == signbit64(4.0));34 expect(signbit(@as(f64, 4.0)) == signbit64(4.0));
35}35}
3636
37test "math.signbit16" {37test "math.signbit16" {
lib/std/math/sin.zig+3-3
...@@ -88,9 +88,9 @@ test "math.sin" {...@@ -88,9 +88,9 @@ test "math.sin" {
88 // TODO https://github.com/ziglang/zig/issues/328988 // TODO https://github.com/ziglang/zig/issues/3289
89 return error.SkipZigTest;89 return error.SkipZigTest;
90 }90 }
91 expect(sin(f32(0.0)) == sin_(f32, 0.0));91 expect(sin(@as(f32, 0.0)) == sin_(f32, 0.0));
92 expect(sin(f64(0.0)) == sin_(f64, 0.0));92 expect(sin(@as(f64, 0.0)) == sin_(f64, 0.0));
93 expect(comptime (math.sin(f64(2))) == math.sin(f64(2)));93 expect(comptime (math.sin(@as(f64, 2))) == math.sin(@as(f64, 2)));
94}94}
9595
96test "math.sin32" {96test "math.sin32" {
lib/std/math/sinh.zig+2-2
...@@ -93,8 +93,8 @@ fn sinh64(x: f64) f64 {...@@ -93,8 +93,8 @@ fn sinh64(x: f64) f64 {
93}93}
9494
95test "math.sinh" {95test "math.sinh" {
96 expect(sinh(f32(1.5)) == sinh32(1.5));96 expect(sinh(@as(f32, 1.5)) == sinh32(1.5));
97 expect(sinh(f64(1.5)) == sinh64(1.5));97 expect(sinh(@as(f64, 1.5)) == sinh64(1.5));
98}98}
9999
100test "math.sinh32" {100test "math.sinh32" {
lib/std/math/sqrt.zig+5-5
...@@ -15,7 +15,7 @@ const maxInt = std.math.maxInt;...@@ -15,7 +15,7 @@ const maxInt = std.math.maxInt;
15pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {15pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
16 const T = @typeOf(x);16 const T = @typeOf(x);
17 switch (@typeId(T)) {17 switch (@typeId(T)) {
18 TypeId.ComptimeFloat => return T(@sqrt(f64, x)), // TODO upgrade to f12818 TypeId.ComptimeFloat => return @as(T, @sqrt(f64, x)), // TODO upgrade to f128
19 TypeId.Float => return @sqrt(T, x),19 TypeId.Float => return @sqrt(T, x),
20 TypeId.ComptimeInt => comptime {20 TypeId.ComptimeInt => comptime {
21 if (x > maxInt(u128)) {21 if (x > maxInt(u128)) {
...@@ -24,7 +24,7 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ...@@ -24,7 +24,7 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ
24 if (x < 0) {24 if (x < 0) {
25 @compileError("sqrt on negative number");25 @compileError("sqrt on negative number");
26 }26 }
27 return T(sqrt_int(u128, x));27 return @as(T, sqrt_int(u128, x));
28 },28 },
29 TypeId.Int => return sqrt_int(T, x),29 TypeId.Int => return sqrt_int(T, x),
30 else => @compileError("sqrt not implemented for " ++ @typeName(T)),30 else => @compileError("sqrt not implemented for " ++ @typeName(T)),
...@@ -32,9 +32,9 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ...@@ -32,9 +32,9 @@ pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typ
32}32}
3333
34test "math.sqrt" {34test "math.sqrt" {
35 expect(sqrt(f16(0.0)) == @sqrt(f16, 0.0));35 expect(sqrt(@as(f16, 0.0)) == @sqrt(f16, 0.0));
36 expect(sqrt(f32(0.0)) == @sqrt(f32, 0.0));36 expect(sqrt(@as(f32, 0.0)) == @sqrt(f32, 0.0));
37 expect(sqrt(f64(0.0)) == @sqrt(f64, 0.0));37 expect(sqrt(@as(f64, 0.0)) == @sqrt(f64, 0.0));
38}38}
3939
40test "math.sqrt16" {40test "math.sqrt16" {
lib/std/math/tan.zig+2-2
...@@ -75,8 +75,8 @@ fn tan_(comptime T: type, x_: T) T {...@@ -75,8 +75,8 @@ fn tan_(comptime T: type, x_: T) T {
75}75}
7676
77test "math.tan" {77test "math.tan" {
78 expect(tan(f32(0.0)) == tan_(f32, 0.0));78 expect(tan(@as(f32, 0.0)) == tan_(f32, 0.0));
79 expect(tan(f64(0.0)) == tan_(f64, 0.0));79 expect(tan(@as(f64, 0.0)) == tan_(f64, 0.0));
80}80}
8181
82test "math.tan32" {82test "math.tan32" {
lib/std/math/tanh.zig+2-2
...@@ -119,8 +119,8 @@ fn tanh64(x: f64) f64 {...@@ -119,8 +119,8 @@ fn tanh64(x: f64) f64 {
119}119}
120120
121test "math.tanh" {121test "math.tanh" {
122 expect(tanh(f32(1.5)) == tanh32(1.5));122 expect(tanh(@as(f32, 1.5)) == tanh32(1.5));
123 expect(tanh(f64(1.5)) == tanh64(1.5));123 expect(tanh(@as(f64, 1.5)) == tanh64(1.5));
124}124}
125125
126test "math.tanh32" {126test "math.tanh32" {
lib/std/math/trunc.zig+4-4
...@@ -36,7 +36,7 @@ fn trunc32(x: f32) f32 {...@@ -36,7 +36,7 @@ fn trunc32(x: f32) f32 {
36 e = 1;36 e = 1;
37 }37 }
3838
39 m = u32(maxInt(u32)) >> @intCast(u5, e);39 m = @as(u32, maxInt(u32)) >> @intCast(u5, e);
40 if (u & m == 0) {40 if (u & m == 0) {
41 return x;41 return x;
42 } else {42 } else {
...@@ -57,7 +57,7 @@ fn trunc64(x: f64) f64 {...@@ -57,7 +57,7 @@ fn trunc64(x: f64) f64 {
57 e = 1;57 e = 1;
58 }58 }
5959
60 m = u64(maxInt(u64)) >> @intCast(u6, e);60 m = @as(u64, maxInt(u64)) >> @intCast(u6, e);
61 if (u & m == 0) {61 if (u & m == 0) {
62 return x;62 return x;
63 } else {63 } else {
...@@ -67,8 +67,8 @@ fn trunc64(x: f64) f64 {...@@ -67,8 +67,8 @@ fn trunc64(x: f64) f64 {
67}67}
6868
69test "math.trunc" {69test "math.trunc" {
70 expect(trunc(f32(1.3)) == trunc32(1.3));70 expect(trunc(@as(f32, 1.3)) == trunc32(1.3));
71 expect(trunc(f64(1.3)) == trunc64(1.3));71 expect(trunc(@as(f64, 1.3)) == trunc64(1.3));
72}72}
7373
74test "math.trunc32" {74test "math.trunc32" {
lib/std/mem.zig+13-13
...@@ -118,11 +118,11 @@ pub const Allocator = struct {...@@ -118,11 +118,11 @@ pub const Allocator = struct {
118 } else @alignOf(T);118 } else @alignOf(T);
119119
120 if (n == 0) {120 if (n == 0) {
121 return ([*]align(a) T)(undefined)[0..0];121 return @as([*]align(a) T, undefined)[0..0];
122 }122 }
123123
124 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;124 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
125 const byte_slice = try self.reallocFn(self, ([*]u8)(undefined)[0..0], undefined, byte_count, a);125 const byte_slice = try self.reallocFn(self, &[0]u8{}, undefined, byte_count, a);
126 assert(byte_slice.len == byte_count);126 assert(byte_slice.len == byte_count);
127 @memset(byte_slice.ptr, undefined, byte_slice.len);127 @memset(byte_slice.ptr, undefined, byte_slice.len);
128 if (alignment == null) {128 if (alignment == null) {
...@@ -170,7 +170,7 @@ pub const Allocator = struct {...@@ -170,7 +170,7 @@ pub const Allocator = struct {
170 }170 }
171 if (new_n == 0) {171 if (new_n == 0) {
172 self.free(old_mem);172 self.free(old_mem);
173 return ([*]align(new_alignment) T)(undefined)[0..0];173 return @as([*]align(new_alignment) T, undefined)[0..0];
174 }174 }
175175
176 const old_byte_slice = @sliceToBytes(old_mem);176 const old_byte_slice = @sliceToBytes(old_mem);
...@@ -523,7 +523,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin....@@ -523,7 +523,7 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin.
523 builtin.Endian.Little => {523 builtin.Endian.Little => {
524 const ShiftType = math.Log2Int(ReturnType);524 const ShiftType = math.Log2Int(ReturnType);
525 for (bytes) |b, index| {525 for (bytes) |b, index| {
526 result = result | (ReturnType(b) << @intCast(ShiftType, index * 8));526 result = result | (@as(ReturnType, b) << @intCast(ShiftType, index * 8));
527 }527 }
528 },528 },
529 }529 }
...@@ -976,7 +976,7 @@ pub const SplitIterator = struct {...@@ -976,7 +976,7 @@ pub const SplitIterator = struct {
976/// Naively combines a series of slices with a separator.976/// Naively combines a series of slices with a separator.
977/// Allocates memory for the result, which must be freed by the caller.977/// Allocates memory for the result, which must be freed by the caller.
978pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {978pub fn join(allocator: *Allocator, separator: []const u8, slices: []const []const u8) ![]u8 {
979 if (slices.len == 0) return (([*]u8)(undefined))[0..0];979 if (slices.len == 0) return &[0]u8{};
980980
981 const total_len = blk: {981 const total_len = blk: {
982 var sum: usize = separator.len * (slices.len - 1);982 var sum: usize = separator.len * (slices.len - 1);
...@@ -1011,7 +1011,7 @@ test "mem.join" {...@@ -1011,7 +1011,7 @@ test "mem.join" {
10111011
1012/// Copies each T from slices into a new slice that exactly holds all the elements.1012/// Copies each T from slices into a new slice that exactly holds all the elements.
1013pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T) ![]T {1013pub fn concat(allocator: *Allocator, comptime T: type, slices: []const []const T) ![]T {
1014 if (slices.len == 0) return (([*]T)(undefined))[0..0];1014 if (slices.len == 0) return &[0]T{};
10151015
1016 const total_len = blk: {1016 const total_len = blk: {
1017 var sum: usize = 0;1017 var sum: usize = 0;
...@@ -1332,7 +1332,7 @@ fn AsBytesReturnType(comptime P: type) type {...@@ -1332,7 +1332,7 @@ fn AsBytesReturnType(comptime P: type) type {
1332 if (comptime !trait.isSingleItemPtr(P))1332 if (comptime !trait.isSingleItemPtr(P))
1333 @compileError("expected single item " ++ "pointer, passed " ++ @typeName(P));1333 @compileError("expected single item " ++ "pointer, passed " ++ @typeName(P));
13341334
1335 const size = usize(@sizeOf(meta.Child(P)));1335 const size = @as(usize, @sizeOf(meta.Child(P)));
1336 const alignment = comptime meta.alignment(P);1336 const alignment = comptime meta.alignment(P);
13371337
1338 if (alignment == 0) {1338 if (alignment == 0) {
...@@ -1353,7 +1353,7 @@ pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) {...@@ -1353,7 +1353,7 @@ pub fn asBytes(ptr: var) AsBytesReturnType(@typeOf(ptr)) {
1353}1353}
13541354
1355test "asBytes" {1355test "asBytes" {
1356 const deadbeef = u32(0xDEADBEEF);1356 const deadbeef = @as(u32, 0xDEADBEEF);
1357 const deadbeef_bytes = switch (builtin.endian) {1357 const deadbeef_bytes = switch (builtin.endian) {
1358 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",1358 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
1359 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",1359 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
...@@ -1361,7 +1361,7 @@ test "asBytes" {...@@ -1361,7 +1361,7 @@ test "asBytes" {
13611361
1362 testing.expect(eql(u8, asBytes(&deadbeef), deadbeef_bytes));1362 testing.expect(eql(u8, asBytes(&deadbeef), deadbeef_bytes));
13631363
1364 var codeface = u32(0xC0DEFACE);1364 var codeface = @as(u32, 0xC0DEFACE);
1365 for (asBytes(&codeface).*) |*b|1365 for (asBytes(&codeface).*) |*b|
1366 b.* = 0;1366 b.* = 0;
1367 testing.expect(codeface == 0);1367 testing.expect(codeface == 0);
...@@ -1392,7 +1392,7 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {...@@ -1392,7 +1392,7 @@ pub fn toBytes(value: var) [@sizeOf(@typeOf(value))]u8 {
1392}1392}
13931393
1394test "toBytes" {1394test "toBytes" {
1395 var my_bytes = toBytes(u32(0x12345678));1395 var my_bytes = toBytes(@as(u32, 0x12345678));
1396 switch (builtin.endian) {1396 switch (builtin.endian) {
1397 builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")),1397 builtin.Endian.Big => testing.expect(eql(u8, my_bytes, "\x12\x34\x56\x78")),
1398 builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")),1398 builtin.Endian.Little => testing.expect(eql(u8, my_bytes, "\x78\x56\x34\x12")),
...@@ -1406,7 +1406,7 @@ test "toBytes" {...@@ -1406,7 +1406,7 @@ test "toBytes" {
1406}1406}
14071407
1408fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {1408fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
1409 const size = usize(@sizeOf(T));1409 const size = @as(usize, @sizeOf(T));
14101410
1411 if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) {1411 if (comptime !trait.is(builtin.TypeId.Pointer)(B) or meta.Child(B) != [size]u8) {
1412 @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));1412 @compileError("expected *[N]u8 " ++ ", passed " ++ @typeName(B));
...@@ -1424,7 +1424,7 @@ pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typ...@@ -1424,7 +1424,7 @@ pub fn bytesAsValue(comptime T: type, bytes: var) BytesAsValueReturnType(T, @typ
1424}1424}
14251425
1426test "bytesAsValue" {1426test "bytesAsValue" {
1427 const deadbeef = u32(0xDEADBEEF);1427 const deadbeef = @as(u32, 0xDEADBEEF);
1428 const deadbeef_bytes = switch (builtin.endian) {1428 const deadbeef_bytes = switch (builtin.endian) {
1429 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",1429 builtin.Endian.Big => "\xDE\xAD\xBE\xEF",
1430 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",1430 builtin.Endian.Little => "\xEF\xBE\xAD\xDE",
...@@ -1472,7 +1472,7 @@ test "bytesToValue" {...@@ -1472,7 +1472,7 @@ test "bytesToValue" {
1472 };1472 };
14731473
1474 const deadbeef = bytesToValue(u32, deadbeef_bytes);1474 const deadbeef = bytesToValue(u32, deadbeef_bytes);
1475 testing.expect(deadbeef == u32(0xDEADBEEF));1475 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
1476}1476}
14771477
1478fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {1478fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
lib/std/meta.zig+2-2
...@@ -341,7 +341,7 @@ test "std.meta.TagType" {...@@ -341,7 +341,7 @@ test "std.meta.TagType" {
341///Returns the active tag of a tagged union341///Returns the active tag of a tagged union
342pub fn activeTag(u: var) @TagType(@typeOf(u)) {342pub fn activeTag(u: var) @TagType(@typeOf(u)) {
343 const T = @typeOf(u);343 const T = @typeOf(u);
344 return @TagType(T)(u);344 return @as(@TagType(T), u);
345}345}
346346
347test "std.meta.activeTag" {347test "std.meta.activeTag" {
...@@ -505,7 +505,7 @@ test "std.meta.eql" {...@@ -505,7 +505,7 @@ test "std.meta.eql" {
505 const EU = struct {505 const EU = struct {
506 fn tst(err: bool) !u8 {506 fn tst(err: bool) !u8 {
507 if (err) return error.Error;507 if (err) return error.Error;
508 return u8(5);508 return @as(u8, 5);
509 }509 }
510 };510 };
511511
lib/std/meta/trait.zig+2-2
...@@ -327,8 +327,8 @@ pub fn isConstPtr(comptime T: type) bool {...@@ -327,8 +327,8 @@ pub fn isConstPtr(comptime T: type) bool {
327}327}
328328
329test "std.meta.trait.isConstPtr" {329test "std.meta.trait.isConstPtr" {
330 var t = u8(0);330 var t = @as(u8, 0);
331 const c = u8(0);331 const c = @as(u8, 0);
332 testing.expect(isConstPtr(*const @typeOf(t)));332 testing.expect(isConstPtr(*const @typeOf(t)));
333 testing.expect(isConstPtr(@typeOf(&c)));333 testing.expect(isConstPtr(@typeOf(&c)));
334 testing.expect(!isConstPtr(*@typeOf(t)));334 testing.expect(!isConstPtr(*@typeOf(t)));
lib/std/mutex.zig+64-69
...@@ -1,19 +1,13 @@...@@ -1,19 +1,13 @@
1const std = @import("std.zig");1const std = @import("std.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const AtomicOrder = builtin.AtomicOrder;
4const AtomicRmwOp = builtin.AtomicRmwOp;
5const testing = std.testing;3const testing = std.testing;
6const SpinLock = std.SpinLock;4const SpinLock = std.SpinLock;
7const linux = std.os.linux;5const ThreadParker = std.ThreadParker;
8const windows = std.os.windows;
96
10/// Lock may be held only once. If the same thread7/// Lock may be held only once. If the same thread
11/// tries to acquire the same mutex twice, it deadlocks.8/// tries to acquire the same mutex twice, it deadlocks.
12/// This type must be initialized at runtime, and then deinitialized when no9/// This type supports static initialization and is based off of Golang 1.13 runtime.lock_futex:
13/// longer needed, to free resources.10/// https://github.com/golang/go/blob/master/src/runtime/lock_futex.go
14/// If you need static initialization, use std.StaticallyInitializedMutex.
15/// The Linux implementation is based on mutex3 from
16/// https://www.akkadia.org/drepper/futex.pdf
17/// When an application is built in single threaded release mode, all the functions are11/// When an application is built in single threaded release mode, all the functions are
18/// no-ops. In single threaded debug mode, there is deadlock detection.12/// no-ops. In single threaded debug mode, there is deadlock detection.
19pub const Mutex = if (builtin.single_threaded)13pub const Mutex = if (builtin.single_threaded)
...@@ -43,84 +37,85 @@ pub const Mutex = if (builtin.single_threaded)...@@ -43,84 +37,85 @@ pub const Mutex = if (builtin.single_threaded)
43 return Held{ .mutex = self };37 return Held{ .mutex = self };
44 }38 }
45 }39 }
46else switch (builtin.os) {40else
47 builtin.Os.linux => struct {41 struct {
48 /// 0: unlocked42 state: State, // TODO: make this an enum
49 /// 1: locked, no waiters43 parker: ThreadParker,
50 /// 2: locked, one or more waiters
51 lock: i32,
52
53 pub const Held = struct {
54 mutex: *Mutex,
5544
56 pub fn release(self: Held) void {45 const State = enum(u32) {
57 const c = @atomicRmw(i32, &self.mutex.lock, AtomicRmwOp.Sub, 1, AtomicOrder.Release);46 Unlocked,
58 if (c != 1) {47 Sleeping,
59 _ = @atomicRmw(i32, &self.mutex.lock, AtomicRmwOp.Xchg, 0, AtomicOrder.Release);48 Locked,
60 const rc = linux.futex_wake(&self.mutex.lock, linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, 1);
61 switch (linux.getErrno(rc)) {
62 0 => {},
63 linux.EINVAL => unreachable,
64 else => unreachable,
65 }
66 }
67 }
68 };49 };
6950
51 /// number of iterations to spin yielding the cpu
52 const SPIN_CPU = 4;
53
54 /// number of iterations to perform in the cpu yield loop
55 const SPIN_CPU_COUNT = 30;
56
57 /// number of iterations to spin yielding the thread
58 const SPIN_THREAD = 1;
59
70 pub fn init() Mutex {60 pub fn init() Mutex {
71 return Mutex{ .lock = 0 };61 return Mutex{
62 .state = .Unlocked,
63 .parker = ThreadParker.init(),
64 };
72 }65 }
7366
74 pub fn deinit(self: *Mutex) void {}67 pub fn deinit(self: *Mutex) void {
7568 self.parker.deinit();
76 pub fn acquire(self: *Mutex) Held {
77 var c = @cmpxchgWeak(i32, &self.lock, 0, 1, AtomicOrder.Acquire, AtomicOrder.Monotonic) orelse
78 return Held{ .mutex = self };
79 if (c != 2)
80 c = @atomicRmw(i32, &self.lock, AtomicRmwOp.Xchg, 2, AtomicOrder.Acquire);
81 while (c != 0) {
82 const rc = linux.futex_wait(&self.lock, linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, 2, null);
83 switch (linux.getErrno(rc)) {
84 0, linux.EINTR, linux.EAGAIN => {},
85 linux.EINVAL => unreachable,
86 else => unreachable,
87 }
88 c = @atomicRmw(i32, &self.lock, AtomicRmwOp.Xchg, 2, AtomicOrder.Acquire);
89 }
90 return Held{ .mutex = self };
91 }69 }
92 },
93 // TODO once https://github.com/ziglang/zig/issues/287 (copy elision) is solved, we can make a
94 // better implementation of this. The problem is we need the init() function to have access to
95 // the address of the CRITICAL_SECTION, and then have it not move.
96 builtin.Os.windows => std.StaticallyInitializedMutex,
97 else => struct {
98 /// TODO better implementation than spin lock.
99 /// When changing this, one must also change the corresponding
100 /// std.StaticallyInitializedMutex code, since it aliases this type,
101 /// under the assumption that it works both statically and at runtime.
102 lock: SpinLock,
10370
104 pub const Held = struct {71 pub const Held = struct {
105 mutex: *Mutex,72 mutex: *Mutex,
10673
107 pub fn release(self: Held) void {74 pub fn release(self: Held) void {
108 SpinLock.Held.release(SpinLock.Held{ .spinlock = &self.mutex.lock });75 switch (@atomicRmw(State, &self.mutex.state, .Xchg, .Unlocked, .Release)) {
76 .Locked => {},
77 .Sleeping => self.mutex.parker.unpark(@ptrCast(*const u32, &self.mutex.state)),
78 .Unlocked => unreachable, // unlocking an unlocked mutex
79 else => unreachable, // should never be anything else
80 }
109 }81 }
110 };82 };
11183
112 pub fn init() Mutex {84 pub fn acquire(self: *Mutex) Held {
113 return Mutex{ .lock = SpinLock.init() };85 // Try and speculatively grab the lock.
114 }86 // If it fails, the state is either Locked or Sleeping
87 // depending on if theres a thread stuck sleeping below.
88 var state = @atomicRmw(State, &self.state, .Xchg, .Locked, .Acquire);
89 if (state == .Unlocked)
90 return Held{ .mutex = self };
11591
116 pub fn deinit(self: *Mutex) void {}92 while (true) {
93 // try and acquire the lock using cpu spinning on failure
94 var spin: usize = 0;
95 while (spin < SPIN_CPU) : (spin += 1) {
96 var value = @atomicLoad(State, &self.state, .Monotonic);
97 while (value == .Unlocked)
98 value = @cmpxchgWeak(State, &self.state, .Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
99 SpinLock.yield(SPIN_CPU_COUNT);
100 }
117101
118 pub fn acquire(self: *Mutex) Held {102 // try and acquire the lock using thread rescheduling on failure
119 _ = self.lock.acquire();103 spin = 0;
120 return Held{ .mutex = self };104 while (spin < SPIN_THREAD) : (spin += 1) {
105 var value = @atomicLoad(State, &self.state, .Monotonic);
106 while (value == .Unlocked)
107 value = @cmpxchgWeak(State, &self.state, .Unlocked, state, .Acquire, .Monotonic) orelse return Held{ .mutex = self };
108 std.os.sched_yield() catch std.time.sleep(1);
109 }
110
111 // failed to acquire the lock, go to sleep until woken up by `Held.release()`
112 if (@atomicRmw(State, &self.state, .Xchg, .Sleeping, .Acquire) == .Unlocked)
113 return Held{ .mutex = self };
114 state = .Sleeping;
115 self.parker.park(@ptrCast(*const u32, &self.state), @enumToInt(State.Sleeping));
116 }
121 }117 }
122 },118 };
123};
124119
125const TestContext = struct {120const TestContext = struct {
126 mutex: *Mutex,121 mutex: *Mutex,
lib/std/net.zig+114-72
...@@ -10,15 +10,18 @@ test "" {...@@ -10,15 +10,18 @@ test "" {
10 _ = @import("net/test.zig");10 _ = @import("net/test.zig");
11}11}
1212
13pub const IpAddress = extern union {13const has_unix_sockets = @hasDecl(os, "sockaddr_un");
14
15pub const Address = extern union {
14 any: os.sockaddr,16 any: os.sockaddr,
15 in: os.sockaddr_in,17 in: os.sockaddr_in,
16 in6: os.sockaddr_in6,18 in6: os.sockaddr_in6,
19 un: if (has_unix_sockets) os.sockaddr_un else void,
1720
18 // TODO this crashed the compiler21 // TODO this crashed the compiler
19 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);22 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
2023
21 pub fn parse(name: []const u8, port: u16) !IpAddress {24 pub fn parseIp(name: []const u8, port: u16) !Address {
22 if (parseIp4(name, port)) |ip4| return ip4 else |err| switch (err) {25 if (parseIp4(name, port)) |ip4| return ip4 else |err| switch (err) {
23 error.Overflow,26 error.Overflow,
24 error.InvalidEnd,27 error.InvalidEnd,
...@@ -39,17 +42,17 @@ pub const IpAddress = extern union {...@@ -39,17 +42,17 @@ pub const IpAddress = extern union {
39 return error.InvalidIPAddressFormat;42 return error.InvalidIPAddressFormat;
40 }43 }
4144
42 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !IpAddress {45 pub fn parseExpectingFamily(name: []const u8, family: os.sa_family_t, port: u16) !Address {
43 switch (family) {46 switch (family) {
44 os.AF_INET => return parseIp4(name, port),47 os.AF_INET => return parseIp4(name, port),
45 os.AF_INET6 => return parseIp6(name, port),48 os.AF_INET6 => return parseIp6(name, port),
46 os.AF_UNSPEC => return parse(name, port),49 os.AF_UNSPEC => return parseIp(name, port),
47 else => unreachable,50 else => unreachable,
48 }51 }
49 }52 }
5053
51 pub fn parseIp6(buf: []const u8, port: u16) !IpAddress {54 pub fn parseIp6(buf: []const u8, port: u16) !Address {
52 var result = IpAddress{55 var result = Address{
53 .in6 = os.sockaddr_in6{56 .in6 = os.sockaddr_in6{
54 .scope_id = 0,57 .scope_id = 0,
55 .port = mem.nativeToBig(u16, port),58 .port = mem.nativeToBig(u16, port),
...@@ -117,7 +120,7 @@ pub const IpAddress = extern union {...@@ -117,7 +120,7 @@ pub const IpAddress = extern union {
117 ip_slice[10] = 0xff;120 ip_slice[10] = 0xff;
118 ip_slice[11] = 0xff;121 ip_slice[11] = 0xff;
119122
120 const ptr = @sliceToBytes((*const [1]u32)(&addr)[0..]);123 const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]);
121124
122 ip_slice[12] = ptr[0];125 ip_slice[12] = ptr[0];
123 ip_slice[13] = ptr[1];126 ip_slice[13] = ptr[1];
...@@ -154,14 +157,14 @@ pub const IpAddress = extern union {...@@ -154,14 +157,14 @@ pub const IpAddress = extern union {
154 }157 }
155 }158 }
156159
157 pub fn parseIp4(buf: []const u8, port: u16) !IpAddress {160 pub fn parseIp4(buf: []const u8, port: u16) !Address {
158 var result = IpAddress{161 var result = Address{
159 .in = os.sockaddr_in{162 .in = os.sockaddr_in{
160 .port = mem.nativeToBig(u16, port),163 .port = mem.nativeToBig(u16, port),
161 .addr = undefined,164 .addr = undefined,
162 },165 },
163 };166 };
164 const out_ptr = @sliceToBytes((*[1]u32)(&result.in.addr)[0..]);167 const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]);
165168
166 var x: u8 = 0;169 var x: u8 = 0;
167 var index: u8 = 0;170 var index: u8 = 0;
...@@ -194,8 +197,8 @@ pub const IpAddress = extern union {...@@ -194,8 +197,8 @@ pub const IpAddress = extern union {
194 return error.Incomplete;197 return error.Incomplete;
195 }198 }
196199
197 pub fn initIp4(addr: [4]u8, port: u16) IpAddress {200 pub fn initIp4(addr: [4]u8, port: u16) Address {
198 return IpAddress{201 return Address{
199 .in = os.sockaddr_in{202 .in = os.sockaddr_in{
200 .port = mem.nativeToBig(u16, port),203 .port = mem.nativeToBig(u16, port),
201 .addr = @ptrCast(*align(1) const u32, &addr).*,204 .addr = @ptrCast(*align(1) const u32, &addr).*,
...@@ -203,8 +206,8 @@ pub const IpAddress = extern union {...@@ -203,8 +206,8 @@ pub const IpAddress = extern union {
203 };206 };
204 }207 }
205208
206 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) IpAddress {209 pub fn initIp6(addr: [16]u8, port: u16, flowinfo: u32, scope_id: u32) Address {
207 return IpAddress{210 return Address{
208 .in6 = os.sockaddr_in6{211 .in6 = os.sockaddr_in6{
209 .addr = addr,212 .addr = addr,
210 .port = mem.nativeToBig(u16, port),213 .port = mem.nativeToBig(u16, port),
...@@ -214,8 +217,24 @@ pub const IpAddress = extern union {...@@ -214,8 +217,24 @@ pub const IpAddress = extern union {
214 };217 };
215 }218 }
216219
220 pub fn initUnix(path: []const u8) !Address {
221 var sock_addr = os.sockaddr_un{
222 .family = os.AF_UNIX,
223 .path = undefined,
224 };
225
226 // this enables us to have the proper length of the socket in getOsSockLen
227 mem.set(u8, &sock_addr.path, 0);
228
229 if (path.len > sock_addr.path.len) return error.NameTooLong;
230 mem.copy(u8, &sock_addr.path, path);
231
232 return Address{ .un = sock_addr };
233 }
234
217 /// Returns the port in native endian.235 /// Returns the port in native endian.
218 pub fn getPort(self: IpAddress) u16 {236 /// Asserts that the address is ip4 or ip6.
237 pub fn getPort(self: Address) u16 {
219 const big_endian_port = switch (self.any.family) {238 const big_endian_port = switch (self.any.family) {
220 os.AF_INET => self.in.port,239 os.AF_INET => self.in.port,
221 os.AF_INET6 => self.in6.port,240 os.AF_INET6 => self.in6.port,
...@@ -225,7 +244,8 @@ pub const IpAddress = extern union {...@@ -225,7 +244,8 @@ pub const IpAddress = extern union {
225 }244 }
226245
227 /// `port` is native-endian.246 /// `port` is native-endian.
228 pub fn setPort(self: *IpAddress, port: u16) void {247 /// Asserts that the address is ip4 or ip6.
248 pub fn setPort(self: *Address, port: u16) void {
229 const ptr = switch (self.any.family) {249 const ptr = switch (self.any.family) {
230 os.AF_INET => &self.in.port,250 os.AF_INET => &self.in.port,
231 os.AF_INET6 => &self.in6.port,251 os.AF_INET6 => &self.in6.port,
...@@ -237,16 +257,16 @@ pub const IpAddress = extern union {...@@ -237,16 +257,16 @@ pub const IpAddress = extern union {
237 /// Asserts that `addr` is an IP address.257 /// Asserts that `addr` is an IP address.
238 /// This function will read past the end of the pointer, with a size depending258 /// This function will read past the end of the pointer, with a size depending
239 /// on the address family.259 /// on the address family.
240 pub fn initPosix(addr: *align(4) const os.sockaddr) IpAddress {260 pub fn initPosix(addr: *align(4) const os.sockaddr) Address {
241 switch (addr.family) {261 switch (addr.family) {
242 os.AF_INET => return IpAddress{ .in = @ptrCast(*const os.sockaddr_in, addr).* },262 os.AF_INET => return Address{ .in = @ptrCast(*const os.sockaddr_in, addr).* },
243 os.AF_INET6 => return IpAddress{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },263 os.AF_INET6 => return Address{ .in6 = @ptrCast(*const os.sockaddr_in6, addr).* },
244 else => unreachable,264 else => unreachable,
245 }265 }
246 }266 }
247267
248 pub fn format(268 pub fn format(
249 self: IpAddress,269 self: Address,
250 comptime fmt: []const u8,270 comptime fmt: []const u8,
251 options: std.fmt.FormatOptions,271 options: std.fmt.FormatOptions,
252 context: var,272 context: var,
...@@ -271,7 +291,7 @@ pub const IpAddress = extern union {...@@ -271,7 +291,7 @@ pub const IpAddress = extern union {
271 },291 },
272 os.AF_INET6 => {292 os.AF_INET6 => {
273 const port = mem.bigToNative(u16, self.in6.port);293 const port = mem.bigToNative(u16, self.in6.port);
274 if (mem.eql(u8, self.in6.addr[0..12], [_]u8{0,0,0,0,0,0,0,0,0,0,0xff,0xff})) {294 if (mem.eql(u8, self.in6.addr[0..12], [_]u8{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff })) {
275 try std.fmt.format(295 try std.fmt.format(
276 context,296 context,
277 Errors,297 Errors,
...@@ -314,20 +334,35 @@ pub const IpAddress = extern union {...@@ -314,20 +334,35 @@ pub const IpAddress = extern union {
314 }334 }
315 try std.fmt.format(context, Errors, output, "]:{}", port);335 try std.fmt.format(context, Errors, output, "]:{}", port);
316 },336 },
337 os.AF_UNIX => {
338 if (!has_unix_sockets) {
339 unreachable;
340 }
341
342 try std.fmt.format(context, Errors, output, "{}", self.un.path);
343 },
317 else => unreachable,344 else => unreachable,
318 }345 }
319 }346 }
320347
321 pub fn eql(a: IpAddress, b: IpAddress) bool {348 pub fn eql(a: Address, b: Address) bool {
322 const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];349 const a_bytes = @ptrCast([*]const u8, &a.any)[0..a.getOsSockLen()];
323 const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];350 const b_bytes = @ptrCast([*]const u8, &b.any)[0..b.getOsSockLen()];
324 return mem.eql(u8, a_bytes, b_bytes);351 return mem.eql(u8, a_bytes, b_bytes);
325 }352 }
326353
327 fn getOsSockLen(self: IpAddress) os.socklen_t {354 fn getOsSockLen(self: Address) os.socklen_t {
328 switch (self.any.family) {355 switch (self.any.family) {
329 os.AF_INET => return @sizeOf(os.sockaddr_in),356 os.AF_INET => return @sizeOf(os.sockaddr_in),
330 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),357 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
358 os.AF_UNIX => {
359 if (!has_unix_sockets) {
360 unreachable;
361 }
362
363 const path_len = std.mem.len(u8, &self.un.path);
364 return @intCast(os.socklen_t, @sizeOf(os.sockaddr_un) - self.un.path.len + path_len);
365 },
331 else => unreachable,366 else => unreachable,
332 }367 }
333 }368 }
...@@ -342,23 +377,20 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {...@@ -342,23 +377,20 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
342 );377 );
343 errdefer os.close(sockfd);378 errdefer os.close(sockfd);
344379
345 var sock_addr = os.sockaddr_un{380 var addr = try std.net.Address.initUnix(path);
346 .family = os.AF_UNIX,
347 .path = undefined,
348 };
349
350 if (path.len > sock_addr.path.len) return error.NameTooLong;
351 mem.copy(u8, &sock_addr.path, path);
352381
353 const size = @intCast(u32, @sizeOf(os.sockaddr_un) - sock_addr.path.len + path.len);382 try os.connect(
354 try os.connect(sockfd, &sock_addr, size);383 sockfd,
384 &addr.any,
385 addr.getOsSockLen(),
386 );
355387
356 return fs.File.openHandle(sockfd);388 return fs.File.openHandle(sockfd);
357}389}
358390
359pub const AddressList = struct {391pub const AddressList = struct {
360 arena: std.heap.ArenaAllocator,392 arena: std.heap.ArenaAllocator,
361 addrs: []IpAddress,393 addrs: []Address,
362 canon_name: ?[]u8,394 canon_name: ?[]u8,
363395
364 fn deinit(self: *AddressList) void {396 fn deinit(self: *AddressList) void {
...@@ -381,7 +413,7 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)...@@ -381,7 +413,7 @@ pub fn tcpConnectToHost(allocator: *mem.Allocator, name: []const u8, port: u16)
381 return tcpConnectToAddress(addrs[0], port);413 return tcpConnectToAddress(addrs[0], port);
382}414}
383415
384pub fn tcpConnectToAddress(address: IpAddress) !fs.File {416pub fn tcpConnectToAddress(address: Address) !fs.File {
385 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;417 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
386 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;418 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
387 const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);419 const sockfd = try os.socket(address.any.family, sock_flags, os.IPPROTO_TCP);
...@@ -456,13 +488,13 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -456,13 +488,13 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
456 }488 }
457 break :blk count;489 break :blk count;
458 };490 };
459 result.addrs = try arena.alloc(IpAddress, addr_count);491 result.addrs = try arena.alloc(Address, addr_count);
460492
461 var it: ?*os.addrinfo = res;493 var it: ?*os.addrinfo = res;
462 var i: usize = 0;494 var i: usize = 0;
463 while (it) |info| : (it = info.next) {495 while (it) |info| : (it = info.next) {
464 const addr = info.addr orelse continue;496 const addr = info.addr orelse continue;
465 result.addrs[i] = IpAddress.initPosix(@alignCast(4, addr));497 result.addrs[i] = Address.initPosix(@alignCast(4, addr));
466498
467 if (info.canonname) |n| {499 if (info.canonname) |n| {
468 if (result.canon_name == null) {500 if (result.canon_name == null) {
...@@ -485,7 +517,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -485,7 +517,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
485517
486 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);518 try linuxLookupName(&lookup_addrs, &canon, name, family, flags, port);
487519
488 result.addrs = try arena.alloc(IpAddress, lookup_addrs.len);520 result.addrs = try arena.alloc(Address, lookup_addrs.len);
489 if (!canon.isNull()) {521 if (!canon.isNull()) {
490 result.canon_name = canon.toOwnedSlice();522 result.canon_name = canon.toOwnedSlice();
491 }523 }
...@@ -501,7 +533,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*...@@ -501,7 +533,7 @@ pub fn getAddressList(allocator: *mem.Allocator, name: []const u8, port: u16) !*
501}533}
502534
503const LookupAddr = struct {535const LookupAddr = struct {
504 addr: IpAddress,536 addr: Address,
505 sortkey: i32 = 0,537 sortkey: i32 = 0,
506};538};
507539
...@@ -524,7 +556,7 @@ fn linuxLookupName(...@@ -524,7 +556,7 @@ fn linuxLookupName(
524 if (opt_name) |name| {556 if (opt_name) |name| {
525 // reject empty name and check len so it fits into temp bufs557 // reject empty name and check len so it fits into temp bufs
526 try canon.replaceContents(name);558 try canon.replaceContents(name);
527 if (IpAddress.parseExpectingFamily(name, family, port)) |addr| {559 if (Address.parseExpectingFamily(name, family, port)) |addr| {
528 try addrs.append(LookupAddr{ .addr = addr });560 try addrs.append(LookupAddr{ .addr = addr });
529 } else |name_err| if ((flags & std.c.AI_NUMERICHOST) != 0) {561 } else |name_err| if ((flags & std.c.AI_NUMERICHOST) != 0) {
530 return name_err;562 return name_err;
...@@ -611,7 +643,7 @@ fn linuxLookupName(...@@ -611,7 +643,7 @@ fn linuxLookupName(
611 // TODO sa6.addr[12..16] should return *[4]u8, making this cast unnecessary.643 // TODO sa6.addr[12..16] should return *[4]u8, making this cast unnecessary.
612 mem.writeIntNative(u32, @ptrCast(*[4]u8, &sa6.addr[12]), sa4.addr);644 mem.writeIntNative(u32, @ptrCast(*[4]u8, &sa6.addr[12]), sa4.addr);
613 }645 }
614 if (dscope == i32(scopeOf(sa6.addr))) key |= DAS_MATCHINGSCOPE;646 if (dscope == @as(i32, scopeOf(sa6.addr))) key |= DAS_MATCHINGSCOPE;
615 if (dlabel == labelOf(sa6.addr)) key |= DAS_MATCHINGLABEL;647 if (dlabel == labelOf(sa6.addr)) key |= DAS_MATCHINGLABEL;
616 prefixlen = prefixMatch(sa6.addr, da6.addr);648 prefixlen = prefixMatch(sa6.addr, da6.addr);
617 } else |_| {}649 } else |_| {}
...@@ -710,7 +742,7 @@ fn prefixMatch(s: [16]u8, d: [16]u8) u8 {...@@ -710,7 +742,7 @@ fn prefixMatch(s: [16]u8, d: [16]u8) u8 {
710 // address. However the definition of the source prefix length is742 // address. However the definition of the source prefix length is
711 // not clear and thus this limiting is not yet implemented.743 // not clear and thus this limiting is not yet implemented.
712 var i: u8 = 0;744 var i: u8 = 0;
713 while (i < 128 and ((s[i / 8] ^ d[i / 8]) & (u8(128) >> @intCast(u3, i % 8))) == 0) : (i += 1) {}745 while (i < 128 and ((s[i / 8] ^ d[i / 8]) & (@as(u8, 128) >> @intCast(u3, i % 8))) == 0) : (i += 1) {}
714 return i;746 return i;
715}747}
716748
...@@ -751,23 +783,23 @@ fn linuxLookupNameFromNull(...@@ -751,23 +783,23 @@ fn linuxLookupNameFromNull(
751 if ((flags & std.c.AI_PASSIVE) != 0) {783 if ((flags & std.c.AI_PASSIVE) != 0) {
752 if (family != os.AF_INET6) {784 if (family != os.AF_INET6) {
753 (try addrs.addOne()).* = LookupAddr{785 (try addrs.addOne()).* = LookupAddr{
754 .addr = IpAddress.initIp4([1]u8{0} ** 4, port),786 .addr = Address.initIp4([1]u8{0} ** 4, port),
755 };787 };
756 }788 }
757 if (family != os.AF_INET) {789 if (family != os.AF_INET) {
758 (try addrs.addOne()).* = LookupAddr{790 (try addrs.addOne()).* = LookupAddr{
759 .addr = IpAddress.initIp6([1]u8{0} ** 16, port, 0, 0),791 .addr = Address.initIp6([1]u8{0} ** 16, port, 0, 0),
760 };792 };
761 }793 }
762 } else {794 } else {
763 if (family != os.AF_INET6) {795 if (family != os.AF_INET6) {
764 (try addrs.addOne()).* = LookupAddr{796 (try addrs.addOne()).* = LookupAddr{
765 .addr = IpAddress.initIp4([4]u8{ 127, 0, 0, 1 }, port),797 .addr = Address.initIp4([4]u8{ 127, 0, 0, 1 }, port),
766 };798 };
767 }799 }
768 if (family != os.AF_INET) {800 if (family != os.AF_INET) {
769 (try addrs.addOne()).* = LookupAddr{801 (try addrs.addOne()).* = LookupAddr{
770 .addr = IpAddress.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),802 .addr = Address.initIp6(([1]u8{0} ** 15) ++ [1]u8{1}, port, 0, 0),
771 };803 };
772 }804 }
773 }805 }
...@@ -812,7 +844,7 @@ fn linuxLookupNameFromHosts(...@@ -812,7 +844,7 @@ fn linuxLookupNameFromHosts(
812 }844 }
813 } else continue;845 } else continue;
814846
815 const addr = IpAddress.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {847 const addr = Address.parseExpectingFamily(ip_text, family, port) catch |err| switch (err) {
816 error.Overflow,848 error.Overflow,
817 error.InvalidEnd,849 error.InvalidEnd,
818 error.InvalidCharacter,850 error.InvalidCharacter,
...@@ -1033,7 +1065,7 @@ fn linuxLookupNameFromNumericUnspec(...@@ -1033,7 +1065,7 @@ fn linuxLookupNameFromNumericUnspec(
1033 name: []const u8,1065 name: []const u8,
1034 port: u16,1066 port: u16,
1035) !void {1067) !void {
1036 const addr = try IpAddress.parse(name, port);1068 const addr = try Address.parseIp(name, port);
1037 (try addrs.addOne()).* = LookupAddr{ .addr = addr };1069 (try addrs.addOne()).* = LookupAddr{ .addr = addr };
1038}1070}
10391071
...@@ -1049,7 +1081,7 @@ fn resMSendRc(...@@ -1049,7 +1081,7 @@ fn resMSendRc(
1049 var sl: os.socklen_t = @sizeOf(os.sockaddr_in);1081 var sl: os.socklen_t = @sizeOf(os.sockaddr_in);
1050 var family: os.sa_family_t = os.AF_INET;1082 var family: os.sa_family_t = os.AF_INET;
10511083
1052 var ns_list = std.ArrayList(IpAddress).init(rc.ns.allocator);1084 var ns_list = std.ArrayList(Address).init(rc.ns.allocator);
1053 defer ns_list.deinit();1085 defer ns_list.deinit();
10541086
1055 try ns_list.resize(rc.ns.len);1087 try ns_list.resize(rc.ns.len);
...@@ -1065,8 +1097,8 @@ fn resMSendRc(...@@ -1065,8 +1097,8 @@ fn resMSendRc(
1065 }1097 }
10661098
1067 // Get local address and open/bind a socket1099 // Get local address and open/bind a socket
1068 var sa: IpAddress = undefined;1100 var sa: Address = undefined;
1069 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(IpAddress));1101 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1070 sa.any.family = family;1102 sa.any.family = family;
1071 const flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK;1103 const flags = os.SOCK_DGRAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK;
1072 const fd = os.socket(family, flags, 0) catch |err| switch (err) {1104 const fd = os.socket(family, flags, 0) catch |err| switch (err) {
...@@ -1133,7 +1165,7 @@ fn resMSendRc(...@@ -1133,7 +1165,7 @@ fn resMSendRc(
1133 }1165 }
11341166
1135 // Wait for a response, or until time to retry1167 // Wait for a response, or until time to retry
1136 const clamped_timeout = std.math.min(u31(std.math.maxInt(u31)), t1 + retry_interval - t2);1168 const clamped_timeout = std.math.min(@as(u31, std.math.maxInt(u31)), t1 + retry_interval - t2);
1137 const nevents = os.poll(&pfd, clamped_timeout) catch 0;1169 const nevents = os.poll(&pfd, clamped_timeout) catch 0;
1138 if (nevents == 0) continue;1170 if (nevents == 0) continue;
11391171
...@@ -1194,23 +1226,23 @@ fn dnsParse(...@@ -1194,23 +1226,23 @@ fn dnsParse(
1194 if (r.len < 12) return error.InvalidDnsPacket;1226 if (r.len < 12) return error.InvalidDnsPacket;
1195 if ((r[3] & 15) != 0) return;1227 if ((r[3] & 15) != 0) return;
1196 var p = r.ptr + 12;1228 var p = r.ptr + 12;
1197 var qdcount = r[4] * usize(256) + r[5];1229 var qdcount = r[4] * @as(usize, 256) + r[5];
1198 var ancount = r[6] * usize(256) + r[7];1230 var ancount = r[6] * @as(usize, 256) + r[7];
1199 if (qdcount + ancount > 64) return error.InvalidDnsPacket;1231 if (qdcount + ancount > 64) return error.InvalidDnsPacket;
1200 while (qdcount != 0) {1232 while (qdcount != 0) {
1201 qdcount -= 1;1233 qdcount -= 1;
1202 while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;1234 while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;
1203 if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)1235 if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)
1204 return error.InvalidDnsPacket;1236 return error.InvalidDnsPacket;
1205 p += usize(5) + @boolToInt(p[0] != 0);1237 p += @as(usize, 5) + @boolToInt(p[0] != 0);
1206 }1238 }
1207 while (ancount != 0) {1239 while (ancount != 0) {
1208 ancount -= 1;1240 ancount -= 1;
1209 while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;1241 while (@ptrToInt(p) - @ptrToInt(r.ptr) < r.len and p[0] -% 1 < 127) p += 1;
1210 if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)1242 if (p[0] > 193 or (p[0] == 193 and p[1] > 254) or @ptrToInt(p) > @ptrToInt(r.ptr) + r.len - 6)
1211 return error.InvalidDnsPacket;1243 return error.InvalidDnsPacket;
1212 p += usize(1) + @boolToInt(p[0] != 0);1244 p += @as(usize, 1) + @boolToInt(p[0] != 0);
1213 const len = p[8] * usize(256) + p[9];1245 const len = p[8] * @as(usize, 256) + p[9];
1214 if (@ptrToInt(p) + len > @ptrToInt(r.ptr) + r.len) return error.InvalidDnsPacket;1246 if (@ptrToInt(p) + len > @ptrToInt(r.ptr) + r.len) return error.InvalidDnsPacket;
1215 try callback(ctx, p[1], p[10 .. 10 + len], r);1247 try callback(ctx, p[1], p[10 .. 10 + len], r);
1216 p += 10 + len;1248 p += 10 + len;
...@@ -1224,7 +1256,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)...@@ -1224,7 +1256,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
1224 const new_addr = try ctx.addrs.addOne();1256 const new_addr = try ctx.addrs.addOne();
1225 new_addr.* = LookupAddr{1257 new_addr.* = LookupAddr{
1226 // TODO slice [0..4] to make this *[4]u8 without @ptrCast1258 // TODO slice [0..4] to make this *[4]u8 without @ptrCast
1227 .addr = IpAddress.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),1259 .addr = Address.initIp4(@ptrCast(*const [4]u8, data.ptr).*, ctx.port),
1228 };1260 };
1229 },1261 },
1230 os.RR_AAAA => {1262 os.RR_AAAA => {
...@@ -1232,7 +1264,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)...@@ -1232,7 +1264,7 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
1232 const new_addr = try ctx.addrs.addOne();1264 const new_addr = try ctx.addrs.addOne();
1233 new_addr.* = LookupAddr{1265 new_addr.* = LookupAddr{
1234 // TODO slice [0..16] to make this *[16]u8 without @ptrCast1266 // TODO slice [0..16] to make this *[16]u8 without @ptrCast
1235 .addr = IpAddress.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),1267 .addr = Address.initIp6(@ptrCast(*const [16]u8, data.ptr).*, ctx.port, 0, 0),
1236 };1268 };
1237 },1269 },
1238 os.RR_CNAME => {1270 os.RR_CNAME => {
...@@ -1248,12 +1280,12 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)...@@ -1248,12 +1280,12 @@ fn dnsParseCallback(ctx: dpc_ctx, rr: u8, data: []const u8, packet: []const u8)
1248 }1280 }
1249}1281}
12501282
1251pub const TcpServer = struct {1283pub const StreamServer = struct {
1252 /// Copied from `Options` on `init`.1284 /// Copied from `Options` on `init`.
1253 kernel_backlog: u32,1285 kernel_backlog: u32,
12541286
1255 /// `undefined` until `listen` returns successfully.1287 /// `undefined` until `listen` returns successfully.
1256 listen_address: IpAddress,1288 listen_address: Address,
12571289
1258 sockfd: ?os.fd_t,1290 sockfd: ?os.fd_t,
12591291
...@@ -1266,24 +1298,26 @@ pub const TcpServer = struct {...@@ -1266,24 +1298,26 @@ pub const TcpServer = struct {
12661298
1267 /// After this call succeeds, resources have been acquired and must1299 /// After this call succeeds, resources have been acquired and must
1268 /// be released with `deinit`.1300 /// be released with `deinit`.
1269 pub fn init(options: Options) TcpServer {1301 pub fn init(options: Options) StreamServer {
1270 return TcpServer{1302 return StreamServer{
1271 .sockfd = null,1303 .sockfd = null,
1272 .kernel_backlog = options.kernel_backlog,1304 .kernel_backlog = options.kernel_backlog,
1273 .listen_address = undefined,1305 .listen_address = undefined,
1274 };1306 };
1275 }1307 }
12761308
1277 /// Release all resources. The `TcpServer` memory becomes `undefined`.1309 /// Release all resources. The `StreamServer` memory becomes `undefined`.
1278 pub fn deinit(self: *TcpServer) void {1310 pub fn deinit(self: *StreamServer) void {
1279 self.close();1311 self.close();
1280 self.* = undefined;1312 self.* = undefined;
1281 }1313 }
12821314
1283 pub fn listen(self: *TcpServer, address: IpAddress) !void {1315 pub fn listen(self: *StreamServer, address: Address) !void {
1284 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;1316 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
1285 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;1317 const sock_flags = os.SOCK_STREAM | os.SOCK_CLOEXEC | nonblock;
1286 const sockfd = try os.socket(os.AF_INET, sock_flags, os.IPPROTO_TCP);1318 const proto = if (address.any.family == os.AF_UNIX) @as(u32, 0) else os.IPPROTO_TCP;
1319
1320 const sockfd = try os.socket(address.any.family, sock_flags, proto);
1287 self.sockfd = sockfd;1321 self.sockfd = sockfd;
1288 errdefer {1322 errdefer {
1289 os.close(sockfd);1323 os.close(sockfd);
...@@ -1299,7 +1333,7 @@ pub const TcpServer = struct {...@@ -1299,7 +1333,7 @@ pub const TcpServer = struct {
1299 /// Stop listening. It is still necessary to call `deinit` after stopping listening.1333 /// Stop listening. It is still necessary to call `deinit` after stopping listening.
1300 /// Calling `deinit` will automatically call `close`. It is safe to call `close` when1334 /// Calling `deinit` will automatically call `close`. It is safe to call `close` when
1301 /// not listening.1335 /// not listening.
1302 pub fn close(self: *TcpServer) void {1336 pub fn close(self: *StreamServer) void {
1303 if (self.sockfd) |fd| {1337 if (self.sockfd) |fd| {
1304 os.close(fd);1338 os.close(fd);
1305 self.sockfd = null;1339 self.sockfd = null;
...@@ -1326,14 +1360,22 @@ pub const TcpServer = struct {...@@ -1326,14 +1360,22 @@ pub const TcpServer = struct {
1326 BlockedByFirewall,1360 BlockedByFirewall,
1327 } || os.UnexpectedError;1361 } || os.UnexpectedError;
13281362
1329 /// If this function succeeds, the returned `fs.File` is a caller-managed resource.1363 pub const Connection = struct {
1330 pub fn accept(self: *TcpServer) AcceptError!fs.File {1364 file: fs.File,
1365 address: Address
1366 };
1367
1368 /// If this function succeeds, the returned `Connection` is a caller-managed resource.
1369 pub fn accept(self: *StreamServer) AcceptError!Connection {
1331 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;1370 const nonblock = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
1332 const accept_flags = nonblock | os.SOCK_CLOEXEC;1371 const accept_flags = nonblock | os.SOCK_CLOEXEC;
1333 var accepted_addr: IpAddress = undefined;1372 var accepted_addr: Address = undefined;
1334 var adr_len: os.socklen_t = @sizeOf(IpAddress);1373 var adr_len: os.socklen_t = @sizeOf(Address);
1335 if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {1374 if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {
1336 return fs.File.openHandle(fd);1375 return Connection{
1376 .file = fs.File.openHandle(fd),
1377 .address = accepted_addr,
1378 };
1337 } else |err| switch (err) {1379 } else |err| switch (err) {
1338 // We only give SOCK_NONBLOCK when I/O mode is async, in which case this error1380 // We only give SOCK_NONBLOCK when I/O mode is async, in which case this error
1339 // is handled by os.accept4.1381 // is handled by os.accept4.
lib/std/net/test.zig+19-19
...@@ -28,17 +28,17 @@ test "parse and render IPv6 addresses" {...@@ -28,17 +28,17 @@ test "parse and render IPv6 addresses" {
28 "::ffff:123.5.123.5",28 "::ffff:123.5.123.5",
29 };29 };
30 for (ips) |ip, i| {30 for (ips) |ip, i| {
31 var addr = net.IpAddress.parseIp6(ip, 0) catch unreachable;31 var addr = net.Address.parseIp6(ip, 0) catch unreachable;
32 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;32 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
33 std.testing.expect(std.mem.eql(u8, printed[i], newIp[1 .. newIp.len - 3]));33 std.testing.expect(std.mem.eql(u8, printed[i], newIp[1 .. newIp.len - 3]));
34 }34 }
3535
36 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6(":::", 0));36 testing.expectError(error.InvalidCharacter, net.Address.parseIp6(":::", 0));
37 testing.expectError(error.Overflow, net.IpAddress.parseIp6("FF001::FB", 0));37 testing.expectError(error.Overflow, net.Address.parseIp6("FF001::FB", 0));
38 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp6("FF01::Fb:zig", 0));38 testing.expectError(error.InvalidCharacter, net.Address.parseIp6("FF01::Fb:zig", 0));
39 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));39 testing.expectError(error.InvalidEnd, net.Address.parseIp6("FF01:0:0:0:0:0:0:FB:", 0));
40 testing.expectError(error.Incomplete, net.IpAddress.parseIp6("FF01:", 0));40 testing.expectError(error.Incomplete, net.Address.parseIp6("FF01:", 0));
41 testing.expectError(error.InvalidIpv4Mapping, net.IpAddress.parseIp6("::123.123.123.123", 0));41 testing.expectError(error.InvalidIpv4Mapping, net.Address.parseIp6("::123.123.123.123", 0));
42}42}
4343
44test "parse and render IPv4 addresses" {44test "parse and render IPv4 addresses" {
...@@ -50,16 +50,16 @@ test "parse and render IPv4 addresses" {...@@ -50,16 +50,16 @@ test "parse and render IPv4 addresses" {
50 "123.255.0.91",50 "123.255.0.91",
51 "127.0.0.1",51 "127.0.0.1",
52 }) |ip| {52 }) |ip| {
53 var addr = net.IpAddress.parseIp4(ip, 0) catch unreachable;53 var addr = net.Address.parseIp4(ip, 0) catch unreachable;
54 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;54 var newIp = std.fmt.bufPrint(buffer[0..], "{}", addr) catch unreachable;
55 std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));55 std.testing.expect(std.mem.eql(u8, ip, newIp[0 .. newIp.len - 2]));
56 }56 }
5757
58 testing.expectError(error.Overflow, net.IpAddress.parseIp4("256.0.0.1", 0));58 testing.expectError(error.Overflow, net.Address.parseIp4("256.0.0.1", 0));
59 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("x.0.0.1", 0));59 testing.expectError(error.InvalidCharacter, net.Address.parseIp4("x.0.0.1", 0));
60 testing.expectError(error.InvalidEnd, net.IpAddress.parseIp4("127.0.0.1.1", 0));60 testing.expectError(error.InvalidEnd, net.Address.parseIp4("127.0.0.1.1", 0));
61 testing.expectError(error.Incomplete, net.IpAddress.parseIp4("127.0.0.", 0));61 testing.expectError(error.Incomplete, net.Address.parseIp4("127.0.0.", 0));
62 testing.expectError(error.InvalidCharacter, net.IpAddress.parseIp4("100..0.1", 0));62 testing.expectError(error.InvalidCharacter, net.Address.parseIp4("100..0.1", 0));
63}63}
6464
65test "resolve DNS" {65test "resolve DNS" {
...@@ -91,9 +91,9 @@ test "listen on a port, send bytes, receive bytes" {...@@ -91,9 +91,9 @@ test "listen on a port, send bytes, receive bytes" {
91 }91 }
9292
93 // TODO doing this at comptime crashed the compiler93 // TODO doing this at comptime crashed the compiler
94 const localhost = net.IpAddress.parse("127.0.0.1", 0);94 const localhost = net.Address.parseIp("127.0.0.1", 0);
9595
96 var server = net.TcpServer.init(net.TcpServer.Options{});96 var server = net.StreamServer.init(net.StreamServer.Options{});
97 defer server.deinit();97 defer server.deinit();
98 try server.listen(localhost);98 try server.listen(localhost);
9999
...@@ -104,7 +104,7 @@ test "listen on a port, send bytes, receive bytes" {...@@ -104,7 +104,7 @@ test "listen on a port, send bytes, receive bytes" {
104 try await client_frame;104 try await client_frame;
105}105}
106106
107fn testClient(addr: net.IpAddress) anyerror!void {107fn testClient(addr: net.Address) anyerror!void {
108 const socket_file = try net.tcpConnectToAddress(addr);108 const socket_file = try net.tcpConnectToAddress(addr);
109 defer socket_file.close();109 defer socket_file.close();
110110
...@@ -114,9 +114,9 @@ fn testClient(addr: net.IpAddress) anyerror!void {...@@ -114,9 +114,9 @@ fn testClient(addr: net.IpAddress) anyerror!void {
114 testing.expect(mem.eql(u8, msg, "hello from server\n"));114 testing.expect(mem.eql(u8, msg, "hello from server\n"));
115}115}
116116
117fn testServer(server: *net.TcpServer) anyerror!void {117fn testServer(server: *net.StreamServer) anyerror!void {
118 var client_file = try server.accept();118 var client = try server.accept();
119119
120 const stream = &client_file.outStream().stream;120 const stream = &client.file.outStream().stream;
121 try stream.print("hello from server\n");121 try stream.print("hello from server\n");
122}122}
lib/std/os.zig+26-7
...@@ -472,7 +472,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {...@@ -472,7 +472,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
472472
473 var index: usize = 0;473 var index: usize = 0;
474 while (index < bytes.len) {474 while (index < bytes.len) {
475 const amt_to_write = math.min(bytes.len - index, usize(max_bytes_len));475 const amt_to_write = math.min(bytes.len - index, @as(usize, max_bytes_len));
476 const rc = system.write(fd, bytes.ptr + index, amt_to_write);476 const rc = system.write(fd, bytes.ptr + index, amt_to_write);
477 switch (errno(rc)) {477 switch (errno(rc)) {
478 0 => {478 0 => {
...@@ -1126,9 +1126,9 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro...@@ -1126,9 +1126,9 @@ pub fn unlinkatW(dirfd: fd_t, sub_path_w: [*]const u16, flags: u32) UnlinkatErro
11261126
1127 const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;1127 const want_rmdir_behavior = (flags & AT_REMOVEDIR) != 0;
1128 const create_options_flags = if (want_rmdir_behavior)1128 const create_options_flags = if (want_rmdir_behavior)
1129 w.ULONG(w.FILE_DELETE_ON_CLOSE)1129 @as(w.ULONG, w.FILE_DELETE_ON_CLOSE)
1130 else1130 else
1131 w.ULONG(w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);1131 @as(w.ULONG, w.FILE_DELETE_ON_CLOSE | w.FILE_NON_DIRECTORY_FILE);
11321132
1133 const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2);1133 const path_len_bytes = @intCast(u16, mem.toSliceConst(u16, sub_path_w).len * 2);
1134 var nt_name = w.UNICODE_STRING{1134 var nt_name = w.UNICODE_STRING{
...@@ -1526,7 +1526,7 @@ pub fn isatty(handle: fd_t) bool {...@@ -1526,7 +1526,7 @@ pub fn isatty(handle: fd_t) bool {
1526 }1526 }
1527 if (builtin.os == .linux) {1527 if (builtin.os == .linux) {
1528 var wsz: linux.winsize = undefined;1528 var wsz: linux.winsize = undefined;
1529 return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, isize(handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;1529 return linux.syscall3(linux.SYS_ioctl, @bitCast(usize, @as(isize, handle)), linux.TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
1530 }1530 }
1531 unreachable;1531 unreachable;
1532}1532}
...@@ -1547,7 +1547,7 @@ pub fn isCygwinPty(handle: fd_t) bool {...@@ -1547,7 +1547,7 @@ pub fn isCygwinPty(handle: fd_t) bool {
1547 }1547 }
15481548
1549 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);1549 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
1550 const name_bytes = name_info_bytes[size .. size + usize(name_info.FileNameLength)];1550 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];
1551 const name_wide = @bytesToSlice(u16, name_bytes);1551 const name_wide = @bytesToSlice(u16, name_bytes);
1552 return mem.indexOf(u16, name_wide, [_]u16{ 'm', 's', 'y', 's', '-' }) != null or1552 return mem.indexOf(u16, name_wide, [_]u16{ 'm', 's', 'y', 's', '-' }) != null or
1553 mem.indexOf(u16, name_wide, [_]u16{ '-', 'p', 't', 'y' }) != null;1553 mem.indexOf(u16, name_wide, [_]u16{ '-', 'p', 't', 'y' }) != null;
...@@ -2897,7 +2897,7 @@ pub fn res_mkquery(...@@ -2897,7 +2897,7 @@ pub fn res_mkquery(
2897 // Construct query template - ID will be filled later2897 // Construct query template - ID will be filled later
2898 var q: [280]u8 = undefined;2898 var q: [280]u8 = undefined;
2899 @memset(&q, 0, n);2899 @memset(&q, 0, n);
2900 q[2] = u8(op) * 8 + 1;2900 q[2] = @as(u8, op) * 8 + 1;
2901 q[5] = 1;2901 q[5] = 1;
2902 mem.copy(u8, q[13..], name);2902 mem.copy(u8, q[13..], name);
2903 var i: usize = 13;2903 var i: usize = 13;
...@@ -3143,7 +3143,7 @@ pub fn dn_expand(...@@ -3143,7 +3143,7 @@ pub fn dn_expand(
3143 // loop invariants: p<end, dest<dend3143 // loop invariants: p<end, dest<dend
3144 if ((p[0] & 0xc0) != 0) {3144 if ((p[0] & 0xc0) != 0) {
3145 if (p + 1 == end) return error.InvalidDnsPacket;3145 if (p + 1 == end) return error.InvalidDnsPacket;
3146 var j = ((p[0] & usize(0x3f)) << 8) | p[1];3146 var j = ((p[0] & @as(usize, 0x3f)) << 8) | p[1];
3147 if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 2 - @ptrToInt(comp_dn.ptr);3147 if (len == std.math.maxInt(usize)) len = @ptrToInt(p) + 2 - @ptrToInt(comp_dn.ptr);
3148 if (j >= msg.len) return error.InvalidDnsPacket;3148 if (j >= msg.len) return error.InvalidDnsPacket;
3149 p = msg.ptr + j;3149 p = msg.ptr + j;
...@@ -3171,3 +3171,22 @@ pub fn dn_expand(...@@ -3171,3 +3171,22 @@ pub fn dn_expand(
3171 }3171 }
3172 return error.InvalidDnsPacket;3172 return error.InvalidDnsPacket;
3173}3173}
3174
3175pub const SchedYieldError = error{
3176 /// The system is not configured to allow yielding
3177 SystemCannotYield,
3178};
3179
3180pub fn sched_yield() SchedYieldError!void {
3181 if (builtin.os == .windows) {
3182 // The return value has to do with how many other threads there are; it is not
3183 // an error condition on Windows.
3184 _ = windows.kernel32.SwitchToThread();
3185 return;
3186 }
3187 switch (errno(system.sched_yield())) {
3188 0 => return,
3189 ENOSYS => return error.SystemCannotYield,
3190 else => return error.SystemCannotYield,
3191 }
3192}
lib/std/os/bits.zig-3
...@@ -14,9 +14,6 @@ pub usingnamespace switch (builtin.os) {...@@ -14,9 +14,6 @@ pub usingnamespace switch (builtin.os) {
14 else => struct {},14 else => struct {},
15};15};
1616
17pub const pthread_t = *@OpaqueType();
18pub const FILE = @OpaqueType();
19
20pub const iovec = extern struct {17pub const iovec = extern struct {
21 iov_base: [*]u8,18 iov_base: [*]u8,
22 iov_len: usize,19 iov_len: usize,
lib/std/os/bits/darwin.zig-6
...@@ -133,11 +133,6 @@ pub const dirent = extern struct {...@@ -133,11 +133,6 @@ pub const dirent = extern struct {
133 }133 }
134};134};
135135
136pub const pthread_attr_t = extern struct {
137 __sig: c_long,
138 __opaque: [56]u8,
139};
140
141/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.136/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
142pub const Kevent = extern struct {137pub const Kevent = extern struct {
143 ident: usize,138 ident: usize,
...@@ -272,7 +267,6 @@ pub const SA_USERTRAMP = 0x0100;...@@ -272,7 +267,6 @@ pub const SA_USERTRAMP = 0x0100;
272/// signal handler with SA_SIGINFO args with 64bit regs information267/// signal handler with SA_SIGINFO args with 64bit regs information
273pub const SA_64REGSET = 0x0200;268pub const SA_64REGSET = 0x0200;
274269
275pub const O_LARGEFILE = 0x0000;
276pub const O_PATH = 0x0000;270pub const O_PATH = 0x0000;
277271
278pub const F_OK = 0;272pub const F_OK = 0;
lib/std/os/bits/dragonfly.zig+4-10
...@@ -241,7 +241,6 @@ pub const KERN_MAXID = 37;...@@ -241,7 +241,6 @@ pub const KERN_MAXID = 37;
241241
242pub const HOST_NAME_MAX = 255;242pub const HOST_NAME_MAX = 255;
243243
244pub const O_LARGEFILE = 0; // faked support
245pub const O_RDONLY = 0;244pub const O_RDONLY = 0;
246pub const O_NDELAY = O_NONBLOCK;245pub const O_NDELAY = O_NONBLOCK;
247pub const O_WRONLY = 1;246pub const O_WRONLY = 1;
...@@ -315,7 +314,7 @@ pub const dirent = extern struct {...@@ -315,7 +314,7 @@ pub const dirent = extern struct {
315 d_name: [256]u8,314 d_name: [256]u8,
316315
317 pub fn reclen(self: dirent) u16 {316 pub fn reclen(self: dirent) u16 {
318 return (@byteOffsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~u16(7);317 return (@byteOffsetOf(dirent, "d_name") + self.d_namlen + 1 + 7) & ~@as(u16, 7);
319 }318 }
320};319};
321320
...@@ -360,11 +359,6 @@ pub const Kevent = extern struct {...@@ -360,11 +359,6 @@ pub const Kevent = extern struct {
360 udata: usize,359 udata: usize,
361};360};
362361
363pub const pthread_attr_t = extern struct { // copied from freebsd
364 __size: [56]u8,
365 __align: c_long,
366};
367
368pub const EVFILT_FS = -10;362pub const EVFILT_FS = -10;
369pub const EVFILT_USER = -9;363pub const EVFILT_USER = -9;
370pub const EVFILT_EXCEPT = -8;364pub const EVFILT_EXCEPT = -8;
...@@ -515,13 +509,13 @@ pub const sigset_t = extern struct {...@@ -515,13 +509,13 @@ pub const sigset_t = extern struct {
515pub const sig_atomic_t = c_int;509pub const sig_atomic_t = c_int;
516pub const Sigaction = extern struct {510pub const Sigaction = extern struct {
517 __sigaction_u: extern union {511 __sigaction_u: extern union {
518 __sa_handler: ?extern fn(c_int) void,512 __sa_handler: ?extern fn (c_int) void,
519 __sa_sigaction: ?extern fn(c_int, [*c]siginfo_t, ?*c_void) void,513 __sa_sigaction: ?extern fn (c_int, [*c]siginfo_t, ?*c_void) void,
520 },514 },
521 sa_flags: c_int,515 sa_flags: c_int,
522 sa_mask: sigset_t,516 sa_mask: sigset_t,
523};517};
524pub const sig_t = [*c]extern fn(c_int) void;518pub const sig_t = [*c]extern fn (c_int) void;
525519
526pub const sigvec = extern struct {520pub const sigvec = extern struct {
527 sv_handler: [*c]__sighandler_t,521 sv_handler: [*c]__sighandler_t,
lib/std/os/bits/freebsd.zig-6
...@@ -15,11 +15,6 @@ pub const Kevent = extern struct {...@@ -15,11 +15,6 @@ pub const Kevent = extern struct {
15 // TODO ext15 // TODO ext
16};16};
1717
18pub const pthread_attr_t = extern struct {
19 __size: [56]u8,
20 __align: c_long,
21};
22
23pub const dl_phdr_info = extern struct {18pub const dl_phdr_info = extern struct {
24 dlpi_addr: usize,19 dlpi_addr: usize,
25 dlpi_name: ?[*]const u8,20 dlpi_name: ?[*]const u8,
...@@ -305,7 +300,6 @@ pub const O_CLOEXEC = 0x00100000;...@@ -305,7 +300,6 @@ pub const O_CLOEXEC = 0x00100000;
305300
306pub const O_ASYNC = 0x0040;301pub const O_ASYNC = 0x0040;
307pub const O_DIRECT = 0x00010000;302pub const O_DIRECT = 0x00010000;
308pub const O_LARGEFILE = 0;
309pub const O_NOATIME = 0o1000000;303pub const O_NOATIME = 0o1000000;
310pub const O_PATH = 0o10000000;304pub const O_PATH = 0o10000000;
311pub const O_TMPFILE = 0o20200000;305pub const O_TMPFILE = 0o20200000;
lib/std/os/bits/linux.zig+5-10
...@@ -559,10 +559,10 @@ pub const EPOLLMSG = 0x400;...@@ -559,10 +559,10 @@ pub const EPOLLMSG = 0x400;
559pub const EPOLLERR = 0x008;559pub const EPOLLERR = 0x008;
560pub const EPOLLHUP = 0x010;560pub const EPOLLHUP = 0x010;
561pub const EPOLLRDHUP = 0x2000;561pub const EPOLLRDHUP = 0x2000;
562pub const EPOLLEXCLUSIVE = (u32(1) << 28);562pub const EPOLLEXCLUSIVE = (@as(u32, 1) << 28);
563pub const EPOLLWAKEUP = (u32(1) << 29);563pub const EPOLLWAKEUP = (@as(u32, 1) << 29);
564pub const EPOLLONESHOT = (u32(1) << 30);564pub const EPOLLONESHOT = (@as(u32, 1) << 30);
565pub const EPOLLET = (u32(1) << 31);565pub const EPOLLET = (@as(u32, 1) << 31);
566566
567pub const CLOCK_REALTIME = 0;567pub const CLOCK_REALTIME = 0;
568pub const CLOCK_MONOTONIC = 1;568pub const CLOCK_MONOTONIC = 1;
...@@ -950,7 +950,7 @@ pub fn cap_valid(u8: x) bool {...@@ -950,7 +950,7 @@ pub fn cap_valid(u8: x) bool {
950}950}
951951
952pub fn CAP_TO_MASK(cap: u8) u32 {952pub fn CAP_TO_MASK(cap: u8) u32 {
953 return u32(1) << u5(cap & 31);953 return @as(u32, 1) << u5(cap & 31);
954}954}
955955
956pub fn CAP_TO_INDEX(cap: u8) u8 {956pub fn CAP_TO_INDEX(cap: u8) u8 {
...@@ -1000,11 +1000,6 @@ pub const dl_phdr_info = extern struct {...@@ -1000,11 +1000,6 @@ pub const dl_phdr_info = extern struct {
1000 dlpi_phnum: u16,1000 dlpi_phnum: u16,
1001};1001};
10021002
1003pub const pthread_attr_t = extern struct {
1004 __size: [56]u8,
1005 __align: c_long,
1006};
1007
1008pub const CPU_SETSIZE = 128;1003pub const CPU_SETSIZE = 128;
1009pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;1004pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
1010pub const cpu_count_t = @IntType(false, std.math.log2(CPU_SETSIZE * 8));1005pub const cpu_count_t = @IntType(false, std.math.log2(CPU_SETSIZE * 8));
lib/std/os/bits/netbsd.zig-7
...@@ -14,12 +14,6 @@ pub const Kevent = extern struct {...@@ -14,12 +14,6 @@ pub const Kevent = extern struct {
14 udata: usize,14 udata: usize,
15};15};
1616
17pub const pthread_attr_t = extern struct {
18 pta_magic: u32,
19 pta_flags: c_int,
20 pta_private: *c_void,
21};
22
23pub const dl_phdr_info = extern struct {17pub const dl_phdr_info = extern struct {
24 dlpi_addr: usize,18 dlpi_addr: usize,
25 dlpi_name: ?[*]const u8,19 dlpi_name: ?[*]const u8,
...@@ -298,7 +292,6 @@ pub const O_CLOEXEC = 0x00400000;...@@ -298,7 +292,6 @@ pub const O_CLOEXEC = 0x00400000;
298292
299pub const O_ASYNC = 0x0040;293pub const O_ASYNC = 0x0040;
300pub const O_DIRECT = 0x00080000;294pub const O_DIRECT = 0x00080000;
301pub const O_LARGEFILE = 0;
302pub const O_NOATIME = 0;295pub const O_NOATIME = 0;
303pub const O_PATH = 0;296pub const O_PATH = 0;
304pub const O_TMPFILE = 0;297pub const O_TMPFILE = 0;
lib/std/os/bits/windows.zig+19
...@@ -186,6 +186,11 @@ pub const sockaddr_in6 = extern struct {...@@ -186,6 +186,11 @@ pub const sockaddr_in6 = extern struct {
186pub const in6_addr = [16]u8;186pub const in6_addr = [16]u8;
187pub const in_addr = u32;187pub const in_addr = u32;
188188
189pub const sockaddr_un = extern struct {
190 family: sa_family_t = AF_UNIX,
191 path: [108]u8,
192};
193
189pub const AF_UNSPEC = 0;194pub const AF_UNSPEC = 0;
190pub const AF_UNIX = 1;195pub const AF_UNIX = 1;
191pub const AF_INET = 2;196pub const AF_INET = 2;
...@@ -221,3 +226,17 @@ pub const AF_TCNMESSAGE = 30;...@@ -221,3 +226,17 @@ pub const AF_TCNMESSAGE = 30;
221pub const AF_ICLFXBM = 31;226pub const AF_ICLFXBM = 31;
222pub const AF_BTH = 32;227pub const AF_BTH = 32;
223pub const AF_MAX = 33;228pub const AF_MAX = 33;
229
230pub const SOCK_STREAM = 1;
231pub const SOCK_DGRAM = 2;
232pub const SOCK_RAW = 3;
233pub const SOCK_RDM = 4;
234pub const SOCK_SEQPACKET = 5;
235
236pub const IPPROTO_ICMP = 1;
237pub const IPPROTO_IGMP = 2;
238pub const BTHPROTO_RFCOMM = 3;
239pub const IPPROTO_TCP = 6;
240pub const IPPROTO_UDP = 17;
241pub const IPPROTO_ICMPV6 = 58;
242pub const IPPROTO_RM = 113;
lib/std/os/linux.zig+99-95
...@@ -46,22 +46,22 @@ pub fn getErrno(r: usize) u12 {...@@ -46,22 +46,22 @@ pub fn getErrno(r: usize) u12 {
4646
47pub fn dup2(old: i32, new: i32) usize {47pub fn dup2(old: i32, new: i32) usize {
48 if (@hasDecl(@This(), "SYS_dup2")) {48 if (@hasDecl(@This(), "SYS_dup2")) {
49 return syscall2(SYS_dup2, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)));49 return syscall2(SYS_dup2, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)));
50 } else {50 } else {
51 if (old == new) {51 if (old == new) {
52 if (std.debug.runtime_safety) {52 if (std.debug.runtime_safety) {
53 const rc = syscall2(SYS_fcntl, @bitCast(usize, isize(old)), F_GETFD);53 const rc = syscall2(SYS_fcntl, @bitCast(usize, @as(isize, old)), F_GETFD);
54 if (@bitCast(isize, rc) < 0) return rc;54 if (@bitCast(isize, rc) < 0) return rc;
55 }55 }
56 return @intCast(usize, old);56 return @intCast(usize, old);
57 } else {57 } else {
58 return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), 0);58 return syscall3(SYS_dup3, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)), 0);
59 }59 }
60 }60 }
61}61}
6262
63pub fn dup3(old: i32, new: i32, flags: u32) usize {63pub fn dup3(old: i32, new: i32, flags: u32) usize {
64 return syscall3(SYS_dup3, @bitCast(usize, isize(old)), @bitCast(usize, isize(new)), flags);64 return syscall3(SYS_dup3, @bitCast(usize, @as(isize, old)), @bitCast(usize, @as(isize, new)), flags);
65}65}
6666
67// TODO https://github.com/ziglang/zig/issues/26567// TODO https://github.com/ziglang/zig/issues/265
...@@ -102,7 +102,7 @@ pub fn futimens(fd: i32, times: *const [2]timespec) usize {...@@ -102,7 +102,7 @@ pub fn futimens(fd: i32, times: *const [2]timespec) usize {
102102
103// TODO https://github.com/ziglang/zig/issues/265103// TODO https://github.com/ziglang/zig/issues/265
104pub fn utimensat(dirfd: i32, path: ?[*]const u8, times: *const [2]timespec, flags: u32) usize {104pub fn utimensat(dirfd: i32, path: ?[*]const u8, times: *const [2]timespec, flags: u32) usize {
105 return syscall4(SYS_utimensat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(times), flags);105 return syscall4(SYS_utimensat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(times), flags);
106}106}
107107
108pub fn futex_wait(uaddr: *const i32, futex_op: u32, val: i32, timeout: ?*timespec) usize {108pub fn futex_wait(uaddr: *const i32, futex_op: u32, val: i32, timeout: ?*timespec) usize {
...@@ -120,7 +120,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {...@@ -120,7 +120,7 @@ pub fn getcwd(buf: [*]u8, size: usize) usize {
120pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {120pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {
121 return syscall3(121 return syscall3(
122 SYS_getdents,122 SYS_getdents,
123 @bitCast(usize, isize(fd)),123 @bitCast(usize, @as(isize, fd)),
124 @ptrToInt(dirp),124 @ptrToInt(dirp),
125 std.math.min(len, maxInt(c_int)),125 std.math.min(len, maxInt(c_int)),
126 );126 );
...@@ -129,7 +129,7 @@ pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {...@@ -129,7 +129,7 @@ pub fn getdents(fd: i32, dirp: [*]u8, len: usize) usize {
129pub fn getdents64(fd: i32, dirp: [*]u8, len: usize) usize {129pub fn getdents64(fd: i32, dirp: [*]u8, len: usize) usize {
130 return syscall3(130 return syscall3(
131 SYS_getdents64,131 SYS_getdents64,
132 @bitCast(usize, isize(fd)),132 @bitCast(usize, @as(isize, fd)),
133 @ptrToInt(dirp),133 @ptrToInt(dirp),
134 std.math.min(len, maxInt(c_int)),134 std.math.min(len, maxInt(c_int)),
135 );135 );
...@@ -140,11 +140,11 @@ pub fn inotify_init1(flags: u32) usize {...@@ -140,11 +140,11 @@ pub fn inotify_init1(flags: u32) usize {
140}140}
141141
142pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize {142pub fn inotify_add_watch(fd: i32, pathname: [*]const u8, mask: u32) usize {
143 return syscall3(SYS_inotify_add_watch, @bitCast(usize, isize(fd)), @ptrToInt(pathname), mask);143 return syscall3(SYS_inotify_add_watch, @bitCast(usize, @as(isize, fd)), @ptrToInt(pathname), mask);
144}144}
145145
146pub fn inotify_rm_watch(fd: i32, wd: i32) usize {146pub fn inotify_rm_watch(fd: i32, wd: i32) usize {
147 return syscall2(SYS_inotify_rm_watch, @bitCast(usize, isize(fd)), @bitCast(usize, isize(wd)));147 return syscall2(SYS_inotify_rm_watch, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, wd)));
148}148}
149149
150// TODO https://github.com/ziglang/zig/issues/265150// TODO https://github.com/ziglang/zig/issues/265
...@@ -152,13 +152,13 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz...@@ -152,13 +152,13 @@ pub fn readlink(noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usiz
152 if (@hasDecl(@This(), "SYS_readlink")) {152 if (@hasDecl(@This(), "SYS_readlink")) {
153 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);153 return syscall3(SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
154 } else {154 } else {
155 return syscall4(SYS_readlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);155 return syscall4(SYS_readlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
156 }156 }
157}157}
158158
159// TODO https://github.com/ziglang/zig/issues/265159// TODO https://github.com/ziglang/zig/issues/265
160pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {160pub fn readlinkat(dirfd: i32, noalias path: [*]const u8, noalias buf_ptr: [*]u8, buf_len: usize) usize {
161 return syscall4(SYS_readlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);161 return syscall4(SYS_readlinkat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
162}162}
163163
164// TODO https://github.com/ziglang/zig/issues/265164// TODO https://github.com/ziglang/zig/issues/265
...@@ -166,13 +166,13 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {...@@ -166,13 +166,13 @@ pub fn mkdir(path: [*]const u8, mode: u32) usize {
166 if (@hasDecl(@This(), "SYS_mkdir")) {166 if (@hasDecl(@This(), "SYS_mkdir")) {
167 return syscall2(SYS_mkdir, @ptrToInt(path), mode);167 return syscall2(SYS_mkdir, @ptrToInt(path), mode);
168 } else {168 } else {
169 return syscall3(SYS_mkdirat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode);169 return syscall3(SYS_mkdirat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode);
170 }170 }
171}171}
172172
173// TODO https://github.com/ziglang/zig/issues/265173// TODO https://github.com/ziglang/zig/issues/265
174pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize {174pub fn mkdirat(dirfd: i32, path: [*]const u8, mode: u32) usize {
175 return syscall3(SYS_mkdirat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode);175 return syscall3(SYS_mkdirat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), mode);
176}176}
177177
178// TODO https://github.com/ziglang/zig/issues/265178// TODO https://github.com/ziglang/zig/issues/265
...@@ -194,7 +194,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -194,7 +194,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
194 if (@hasDecl(@This(), "SYS_mmap2")) {194 if (@hasDecl(@This(), "SYS_mmap2")) {
195 // Make sure the offset is also specified in multiples of page size195 // Make sure the offset is also specified in multiples of page size
196 if ((offset & (MMAP2_UNIT - 1)) != 0)196 if ((offset & (MMAP2_UNIT - 1)) != 0)
197 return @bitCast(usize, isize(-EINVAL));197 return @bitCast(usize, @as(isize, -EINVAL));
198198
199 return syscall6(199 return syscall6(
200 SYS_mmap2,200 SYS_mmap2,
...@@ -202,7 +202,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -202,7 +202,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
202 length,202 length,
203 prot,203 prot,
204 flags,204 flags,
205 @bitCast(usize, isize(fd)),205 @bitCast(usize, @as(isize, fd)),
206 @truncate(usize, offset / MMAP2_UNIT),206 @truncate(usize, offset / MMAP2_UNIT),
207 );207 );
208 } else {208 } else {
...@@ -212,7 +212,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of...@@ -212,7 +212,7 @@ pub fn mmap(address: ?[*]u8, length: usize, prot: usize, flags: u32, fd: i32, of
212 length,212 length,
213 prot,213 prot,
214 flags,214 flags,
215 @bitCast(usize, isize(fd)),215 @bitCast(usize, @as(isize, fd)),
216 offset,216 offset,
217 );217 );
218 }218 }
...@@ -249,13 +249,13 @@ pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {...@@ -249,13 +249,13 @@ pub fn poll(fds: [*]pollfd, n: nfds_t, timeout: i32) usize {
249}249}
250250
251pub fn read(fd: i32, buf: [*]u8, count: usize) usize {251pub fn read(fd: i32, buf: [*]u8, count: usize) usize {
252 return syscall3(SYS_read, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);252 return syscall3(SYS_read, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
253}253}
254254
255pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {255pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
256 return syscall5(256 return syscall5(
257 SYS_preadv,257 SYS_preadv,
258 @bitCast(usize, isize(fd)),258 @bitCast(usize, @as(isize, fd)),
259 @ptrToInt(iov),259 @ptrToInt(iov),
260 count,260 count,
261 @truncate(usize, offset),261 @truncate(usize, offset),
...@@ -266,7 +266,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {...@@ -266,7 +266,7 @@ pub fn preadv(fd: i32, iov: [*]const iovec, count: usize, offset: u64) usize {
266pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {266pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: kernel_rwf) usize {
267 return syscall6(267 return syscall6(
268 SYS_preadv2,268 SYS_preadv2,
269 @bitCast(usize, isize(fd)),269 @bitCast(usize, @as(isize, fd)),
270 @ptrToInt(iov),270 @ptrToInt(iov),
271 count,271 count,
272 @truncate(usize, offset),272 @truncate(usize, offset),
...@@ -276,17 +276,17 @@ pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: k...@@ -276,17 +276,17 @@ pub fn preadv2(fd: i32, iov: [*]const iovec, count: usize, offset: u64, flags: k
276}276}
277277
278pub fn readv(fd: i32, iov: [*]const iovec, count: usize) usize {278pub fn readv(fd: i32, iov: [*]const iovec, count: usize) usize {
279 return syscall3(SYS_readv, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);279 return syscall3(SYS_readv, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
280}280}
281281
282pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {282pub fn writev(fd: i32, iov: [*]const iovec_const, count: usize) usize {
283 return syscall3(SYS_writev, @bitCast(usize, isize(fd)), @ptrToInt(iov), count);283 return syscall3(SYS_writev, @bitCast(usize, @as(isize, fd)), @ptrToInt(iov), count);
284}284}
285285
286pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {286pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) usize {
287 return syscall5(287 return syscall5(
288 SYS_pwritev,288 SYS_pwritev,
289 @bitCast(usize, isize(fd)),289 @bitCast(usize, @as(isize, fd)),
290 @ptrToInt(iov),290 @ptrToInt(iov),
291 count,291 count,
292 @truncate(usize, offset),292 @truncate(usize, offset),
...@@ -297,7 +297,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us...@@ -297,7 +297,7 @@ pub fn pwritev(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64) us
297pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {297pub fn pwritev2(fd: i32, iov: [*]const iovec_const, count: usize, offset: u64, flags: kernel_rwf) usize {
298 return syscall6(298 return syscall6(
299 SYS_pwritev2,299 SYS_pwritev2,
300 @bitCast(usize, isize(fd)),300 @bitCast(usize, @as(isize, fd)),
301 @ptrToInt(iov),301 @ptrToInt(iov),
302 count,302 count,
303 @truncate(usize, offset),303 @truncate(usize, offset),
...@@ -311,7 +311,7 @@ pub fn rmdir(path: [*]const u8) usize {...@@ -311,7 +311,7 @@ pub fn rmdir(path: [*]const u8) usize {
311 if (@hasDecl(@This(), "SYS_rmdir")) {311 if (@hasDecl(@This(), "SYS_rmdir")) {
312 return syscall1(SYS_rmdir, @ptrToInt(path));312 return syscall1(SYS_rmdir, @ptrToInt(path));
313 } else {313 } else {
314 return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);314 return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), AT_REMOVEDIR);
315 }315 }
316}316}
317317
...@@ -320,18 +320,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {...@@ -320,18 +320,18 @@ pub fn symlink(existing: [*]const u8, new: [*]const u8) usize {
320 if (@hasDecl(@This(), "SYS_symlink")) {320 if (@hasDecl(@This(), "SYS_symlink")) {
321 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));321 return syscall2(SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
322 } else {322 } else {
323 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));323 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));
324 }324 }
325}325}
326326
327// TODO https://github.com/ziglang/zig/issues/265327// TODO https://github.com/ziglang/zig/issues/265
328pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize {328pub fn symlinkat(existing: [*]const u8, newfd: i32, newpath: [*]const u8) usize {
329 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, isize(newfd)), @ptrToInt(newpath));329 return syscall3(SYS_symlinkat, @ptrToInt(existing), @bitCast(usize, @as(isize, newfd)), @ptrToInt(newpath));
330}330}
331331
332// TODO https://github.com/ziglang/zig/issues/265332// TODO https://github.com/ziglang/zig/issues/265
333pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {333pub fn pread(fd: i32, buf: [*]u8, count: usize, offset: usize) usize {
334 return syscall4(SYS_pread, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);334 return syscall4(SYS_pread, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset);
335}335}
336336
337// TODO https://github.com/ziglang/zig/issues/265337// TODO https://github.com/ziglang/zig/issues/265
...@@ -339,13 +339,13 @@ pub fn access(path: [*]const u8, mode: u32) usize {...@@ -339,13 +339,13 @@ pub fn access(path: [*]const u8, mode: u32) usize {
339 if (@hasDecl(@This(), "SYS_access")) {339 if (@hasDecl(@This(), "SYS_access")) {
340 return syscall2(SYS_access, @ptrToInt(path), mode);340 return syscall2(SYS_access, @ptrToInt(path), mode);
341 } else {341 } else {
342 return syscall4(SYS_faccessat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), mode, 0);342 return syscall4(SYS_faccessat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), mode, 0);
343 }343 }
344}344}
345345
346// TODO https://github.com/ziglang/zig/issues/265346// TODO https://github.com/ziglang/zig/issues/265
347pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize {347pub fn faccessat(dirfd: i32, path: [*]const u8, mode: u32, flags: u32) usize {
348 return syscall4(SYS_faccessat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), mode, flags);348 return syscall4(SYS_faccessat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), mode, flags);
349}349}
350350
351pub fn pipe(fd: *[2]i32) usize {351pub fn pipe(fd: *[2]i32) usize {
...@@ -363,11 +363,11 @@ pub fn pipe2(fd: *[2]i32, flags: u32) usize {...@@ -363,11 +363,11 @@ pub fn pipe2(fd: *[2]i32, flags: u32) usize {
363}363}
364364
365pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {365pub fn write(fd: i32, buf: [*]const u8, count: usize) usize {
366 return syscall3(SYS_write, @bitCast(usize, isize(fd)), @ptrToInt(buf), count);366 return syscall3(SYS_write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
367}367}
368368
369pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {369pub fn pwrite(fd: i32, buf: [*]const u8, count: usize, offset: usize) usize {
370 return syscall4(SYS_pwrite, @bitCast(usize, isize(fd)), @ptrToInt(buf), count, offset);370 return syscall4(SYS_pwrite, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count, offset);
371}371}
372372
373// TODO https://github.com/ziglang/zig/issues/265373// TODO https://github.com/ziglang/zig/issues/265
...@@ -375,9 +375,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {...@@ -375,9 +375,9 @@ pub fn rename(old: [*]const u8, new: [*]const u8) usize {
375 if (@hasDecl(@This(), "SYS_rename")) {375 if (@hasDecl(@This(), "SYS_rename")) {
376 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));376 return syscall2(SYS_rename, @ptrToInt(old), @ptrToInt(new));
377 } else if (@hasDecl(@This(), "SYS_renameat")) {377 } else if (@hasDecl(@This(), "SYS_renameat")) {
378 return syscall4(SYS_renameat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new));378 return syscall4(SYS_renameat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new));
379 } else {379 } else {
380 return syscall5(SYS_renameat2, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(old), @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(new), 0);380 return syscall5(SYS_renameat2, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(old), @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(new), 0);
381 }381 }
382}382}
383383
...@@ -385,17 +385,17 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const...@@ -385,17 +385,17 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
385 if (@hasDecl(@This(), "SYS_renameat")) {385 if (@hasDecl(@This(), "SYS_renameat")) {
386 return syscall4(386 return syscall4(
387 SYS_renameat,387 SYS_renameat,
388 @bitCast(usize, isize(oldfd)),388 @bitCast(usize, @as(isize, oldfd)),
389 @ptrToInt(old),389 @ptrToInt(old),
390 @bitCast(usize, isize(newfd)),390 @bitCast(usize, @as(isize, newfd)),
391 @ptrToInt(new),391 @ptrToInt(new),
392 );392 );
393 } else {393 } else {
394 return syscall5(394 return syscall5(
395 SYS_renameat2,395 SYS_renameat2,
396 @bitCast(usize, isize(oldfd)),396 @bitCast(usize, @as(isize, oldfd)),
397 @ptrToInt(old),397 @ptrToInt(old),
398 @bitCast(usize, isize(newfd)),398 @bitCast(usize, @as(isize, newfd)),
399 @ptrToInt(new),399 @ptrToInt(new),
400 0,400 0,
401 );401 );
...@@ -406,9 +406,9 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const...@@ -406,9 +406,9 @@ pub fn renameat(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const
406pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize {406pub fn renameat2(oldfd: i32, oldpath: [*]const u8, newfd: i32, newpath: [*]const u8, flags: u32) usize {
407 return syscall5(407 return syscall5(
408 SYS_renameat2,408 SYS_renameat2,
409 @bitCast(usize, isize(oldfd)),409 @bitCast(usize, @as(isize, oldfd)),
410 @ptrToInt(oldpath),410 @ptrToInt(oldpath),
411 @bitCast(usize, isize(newfd)),411 @bitCast(usize, @as(isize, newfd)),
412 @ptrToInt(newpath),412 @ptrToInt(newpath),
413 flags,413 flags,
414 );414 );
...@@ -421,7 +421,7 @@ pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {...@@ -421,7 +421,7 @@ pub fn open(path: [*]const u8, flags: u32, perm: usize) usize {
421 } else {421 } else {
422 return syscall4(422 return syscall4(
423 SYS_openat,423 SYS_openat,
424 @bitCast(usize, isize(AT_FDCWD)),424 @bitCast(usize, @as(isize, AT_FDCWD)),
425 @ptrToInt(path),425 @ptrToInt(path),
426 flags,426 flags,
427 perm,427 perm,
...@@ -437,7 +437,7 @@ pub fn create(path: [*]const u8, perm: usize) usize {...@@ -437,7 +437,7 @@ pub fn create(path: [*]const u8, perm: usize) usize {
437// TODO https://github.com/ziglang/zig/issues/265437// TODO https://github.com/ziglang/zig/issues/265
438pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize {438pub fn openat(dirfd: i32, path: [*]const u8, flags: u32, mode: usize) usize {
439 // dirfd could be negative, for example AT_FDCWD is -100439 // dirfd could be negative, for example AT_FDCWD is -100
440 return syscall4(SYS_openat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags, mode);440 return syscall4(SYS_openat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags, mode);
441}441}
442442
443/// See also `clone` (from the arch-specific include)443/// See also `clone` (from the arch-specific include)
...@@ -451,14 +451,14 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize {...@@ -451,14 +451,14 @@ pub fn clone2(flags: u32, child_stack_ptr: usize) usize {
451}451}
452452
453pub fn close(fd: i32) usize {453pub fn close(fd: i32) usize {
454 return syscall1(SYS_close, @bitCast(usize, isize(fd)));454 return syscall1(SYS_close, @bitCast(usize, @as(isize, fd)));
455}455}
456456
457/// Can only be called on 32 bit systems. For 64 bit see `lseek`.457/// Can only be called on 32 bit systems. For 64 bit see `lseek`.
458pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {458pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
459 return syscall5(459 return syscall5(
460 SYS__llseek,460 SYS__llseek,
461 @bitCast(usize, isize(fd)),461 @bitCast(usize, @as(isize, fd)),
462 @truncate(usize, offset >> 32),462 @truncate(usize, offset >> 32),
463 @truncate(usize, offset),463 @truncate(usize, offset),
464 @ptrToInt(result),464 @ptrToInt(result),
...@@ -468,16 +468,16 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {...@@ -468,16 +468,16 @@ pub fn llseek(fd: i32, offset: u64, result: ?*u64, whence: usize) usize {
468468
469/// Can only be called on 64 bit systems. For 32 bit see `llseek`.469/// Can only be called on 64 bit systems. For 32 bit see `llseek`.
470pub fn lseek(fd: i32, offset: i64, whence: usize) usize {470pub fn lseek(fd: i32, offset: i64, whence: usize) usize {
471 return syscall3(SYS_lseek, @bitCast(usize, isize(fd)), @bitCast(usize, offset), whence);471 return syscall3(SYS_lseek, @bitCast(usize, @as(isize, fd)), @bitCast(usize, offset), whence);
472}472}
473473
474pub fn exit(status: i32) noreturn {474pub fn exit(status: i32) noreturn {
475 _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));475 _ = syscall1(SYS_exit, @bitCast(usize, @as(isize, status)));
476 unreachable;476 unreachable;
477}477}
478478
479pub fn exit_group(status: i32) noreturn {479pub fn exit_group(status: i32) noreturn {
480 _ = syscall1(SYS_exit_group, @bitCast(usize, isize(status)));480 _ = syscall1(SYS_exit_group, @bitCast(usize, @as(isize, status)));
481 unreachable;481 unreachable;
482}482}
483483
...@@ -486,7 +486,7 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {...@@ -486,7 +486,7 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
486}486}
487487
488pub fn kill(pid: i32, sig: i32) usize {488pub fn kill(pid: i32, sig: i32) usize {
489 return syscall2(SYS_kill, @bitCast(usize, isize(pid)), @bitCast(usize, isize(sig)));489 return syscall2(SYS_kill, @bitCast(usize, @as(isize, pid)), @bitCast(usize, @as(isize, sig)));
490}490}
491491
492// TODO https://github.com/ziglang/zig/issues/265492// TODO https://github.com/ziglang/zig/issues/265
...@@ -494,17 +494,17 @@ pub fn unlink(path: [*]const u8) usize {...@@ -494,17 +494,17 @@ pub fn unlink(path: [*]const u8) usize {
494 if (@hasDecl(@This(), "SYS_unlink")) {494 if (@hasDecl(@This(), "SYS_unlink")) {
495 return syscall1(SYS_unlink, @ptrToInt(path));495 return syscall1(SYS_unlink, @ptrToInt(path));
496 } else {496 } else {
497 return syscall3(SYS_unlinkat, @bitCast(usize, isize(AT_FDCWD)), @ptrToInt(path), 0);497 return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, AT_FDCWD)), @ptrToInt(path), 0);
498 }498 }
499}499}
500500
501// TODO https://github.com/ziglang/zig/issues/265501// TODO https://github.com/ziglang/zig/issues/265
502pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {502pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
503 return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);503 return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags);
504}504}
505505
506pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {506pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {
507 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0);507 return syscall4(SYS_wait4, @bitCast(usize, @as(isize, pid)), @ptrToInt(status), flags, 0);
508}508}
509509
510var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);510var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
...@@ -519,33 +519,33 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {...@@ -519,33 +519,33 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
519 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);519 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
520 const rc = f(clk_id, tp);520 const rc = f(clk_id, tp);
521 switch (rc) {521 switch (rc) {
522 0, @bitCast(usize, isize(-EINVAL)) => return rc,522 0, @bitCast(usize, @as(isize, -EINVAL)) => return rc,
523 else => {},523 else => {},
524 }524 }
525 }525 }
526 }526 }
527 return syscall2(SYS_clock_gettime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));527 return syscall2(SYS_clock_gettime, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
528}528}
529529
530extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {530extern fn init_vdso_clock_gettime(clk: i32, ts: *timespec) usize {
531 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));531 const ptr = @intToPtr(?*const c_void, vdso.lookup(VDSO_CGT_VER, VDSO_CGT_SYM));
532 // Note that we may not have a VDSO at all, update the stub address anyway532 // Note that we may not have a VDSO at all, update the stub address anyway
533 // so that clock_gettime will fall back on the good old (and slow) syscall533 // so that clock_gettime will fall back on the good old (and slow) syscall
534 _ = @cmpxchgStrong(?*const c_void, &vdso_clock_gettime, &init_vdso_clock_gettime, ptr, .Monotonic, .Monotonic);534 @atomicStore(?*const c_void, &vdso_clock_gettime, ptr, .Monotonic);
535 // Call into the VDSO if available535 // Call into the VDSO if available
536 if (ptr) |fn_ptr| {536 if (ptr) |fn_ptr| {
537 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);537 const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr);
538 return f(clk, ts);538 return f(clk, ts);
539 }539 }
540 return @bitCast(usize, isize(-ENOSYS));540 return @bitCast(usize, @as(isize, -ENOSYS));
541}541}
542542
543pub fn clock_getres(clk_id: i32, tp: *timespec) usize {543pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
544 return syscall2(SYS_clock_getres, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));544 return syscall2(SYS_clock_getres, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
545}545}
546546
547pub fn clock_settime(clk_id: i32, tp: *const timespec) usize {547pub fn clock_settime(clk_id: i32, tp: *const timespec) usize {
548 return syscall2(SYS_clock_settime, @bitCast(usize, isize(clk_id)), @ptrToInt(tp));548 return syscall2(SYS_clock_settime, @bitCast(usize, @as(isize, clk_id)), @ptrToInt(tp));
549}549}
550550
551pub fn gettimeofday(tv: *timeval, tz: *timezone) usize {551pub fn gettimeofday(tv: *timeval, tz: *timezone) usize {
...@@ -594,33 +594,33 @@ pub fn setregid(rgid: u32, egid: u32) usize {...@@ -594,33 +594,33 @@ pub fn setregid(rgid: u32, egid: u32) usize {
594594
595pub fn getuid() u32 {595pub fn getuid() u32 {
596 if (@hasDecl(@This(), "SYS_getuid32")) {596 if (@hasDecl(@This(), "SYS_getuid32")) {
597 return u32(syscall0(SYS_getuid32));597 return @as(u32, syscall0(SYS_getuid32));
598 } else {598 } else {
599 return u32(syscall0(SYS_getuid));599 return @as(u32, syscall0(SYS_getuid));
600 }600 }
601}601}
602602
603pub fn getgid() u32 {603pub fn getgid() u32 {
604 if (@hasDecl(@This(), "SYS_getgid32")) {604 if (@hasDecl(@This(), "SYS_getgid32")) {
605 return u32(syscall0(SYS_getgid32));605 return @as(u32, syscall0(SYS_getgid32));
606 } else {606 } else {
607 return u32(syscall0(SYS_getgid));607 return @as(u32, syscall0(SYS_getgid));
608 }608 }
609}609}
610610
611pub fn geteuid() u32 {611pub fn geteuid() u32 {
612 if (@hasDecl(@This(), "SYS_geteuid32")) {612 if (@hasDecl(@This(), "SYS_geteuid32")) {
613 return u32(syscall0(SYS_geteuid32));613 return @as(u32, syscall0(SYS_geteuid32));
614 } else {614 } else {
615 return u32(syscall0(SYS_geteuid));615 return @as(u32, syscall0(SYS_geteuid));
616 }616 }
617}617}
618618
619pub fn getegid() u32 {619pub fn getegid() u32 {
620 if (@hasDecl(@This(), "SYS_getegid32")) {620 if (@hasDecl(@This(), "SYS_getegid32")) {
621 return u32(syscall0(SYS_getegid32));621 return @as(u32, syscall0(SYS_getegid32));
622 } else {622 } else {
623 return u32(syscall0(SYS_getegid));623 return @as(u32, syscall0(SYS_getegid));
624 }624 }
625}625}
626626
...@@ -743,11 +743,11 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {...@@ -743,11 +743,11 @@ pub fn sigismember(set: *const sigset_t, sig: u6) bool {
743}743}
744744
745pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {745pub fn getsockname(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
746 return syscall3(SYS_getsockname, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));746 return syscall3(SYS_getsockname, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
747}747}
748748
749pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {749pub fn getpeername(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
750 return syscall3(SYS_getpeername, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len));750 return syscall3(SYS_getpeername, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len));
751}751}
752752
753pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {753pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
...@@ -755,15 +755,15 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {...@@ -755,15 +755,15 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) usize {
755}755}
756756
757pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {757pub fn setsockopt(fd: i32, level: u32, optname: u32, optval: [*]const u8, optlen: socklen_t) usize {
758 return syscall5(SYS_setsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));758 return syscall5(SYS_setsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @intCast(usize, optlen));
759}759}
760760
761pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {761pub fn getsockopt(fd: i32, level: u32, optname: u32, noalias optval: [*]u8, noalias optlen: *socklen_t) usize {
762 return syscall5(SYS_getsockopt, @bitCast(usize, isize(fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));762 return syscall5(SYS_getsockopt, @bitCast(usize, @as(isize, fd)), level, optname, @ptrToInt(optval), @ptrToInt(optlen));
763}763}
764764
765pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {765pub fn sendmsg(fd: i32, msg: *msghdr_const, flags: u32) usize {
766 return syscall3(SYS_sendmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);766 return syscall3(SYS_sendmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
767}767}
768768
769pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize {769pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize {
...@@ -781,7 +781,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize...@@ -781,7 +781,7 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
781 // batch-send all messages up to the current message781 // batch-send all messages up to the current message
782 if (next_unsent < i) {782 if (next_unsent < i) {
783 const batch_size = i - next_unsent;783 const batch_size = i - next_unsent;
784 const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);784 const r = syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
785 if (getErrno(r) != 0) return next_unsent;785 if (getErrno(r) != 0) return next_unsent;
786 if (r < batch_size) return next_unsent + r;786 if (r < batch_size) return next_unsent + r;
787 }787 }
...@@ -797,41 +797,41 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize...@@ -797,41 +797,41 @@ pub fn sendmmsg(fd: i32, msgvec: [*]mmsghdr_const, vlen: u32, flags: u32) usize
797 }797 }
798 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG_EOR)798 if (next_unsent < kvlen or next_unsent == 0) { // want to make sure at least one syscall occurs (e.g. to trigger MSG_EOR)
799 const batch_size = kvlen - next_unsent;799 const batch_size = kvlen - next_unsent;
800 const r = syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);800 const r = syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(&msgvec[next_unsent]), batch_size, flags);
801 if (getErrno(r) != 0) return r;801 if (getErrno(r) != 0) return r;
802 return next_unsent + r;802 return next_unsent + r;
803 }803 }
804 return kvlen;804 return kvlen;
805 }805 }
806 return syscall4(SYS_sendmmsg, @bitCast(usize, isize(fd)), @ptrToInt(msgvec), vlen, flags);806 return syscall4(SYS_sendmmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msgvec), vlen, flags);
807}807}
808808
809pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {809pub fn connect(fd: i32, addr: *const c_void, len: socklen_t) usize {
810 return syscall3(SYS_connect, @bitCast(usize, isize(fd)), @ptrToInt(addr), len);810 return syscall3(SYS_connect, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), len);
811}811}
812812
813pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {813pub fn recvmsg(fd: i32, msg: *msghdr, flags: u32) usize {
814 return syscall3(SYS_recvmsg, @bitCast(usize, isize(fd)), @ptrToInt(msg), flags);814 return syscall3(SYS_recvmsg, @bitCast(usize, @as(isize, fd)), @ptrToInt(msg), flags);
815}815}
816816
817pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {817pub fn recvfrom(fd: i32, noalias buf: [*]u8, len: usize, flags: u32, noalias addr: ?*sockaddr, noalias alen: ?*socklen_t) usize {
818 return syscall6(SYS_recvfrom, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));818 return syscall6(SYS_recvfrom, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
819}819}
820820
821pub fn shutdown(fd: i32, how: i32) usize {821pub fn shutdown(fd: i32, how: i32) usize {
822 return syscall2(SYS_shutdown, @bitCast(usize, isize(fd)), @bitCast(usize, isize(how)));822 return syscall2(SYS_shutdown, @bitCast(usize, @as(isize, fd)), @bitCast(usize, @as(isize, how)));
823}823}
824824
825pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {825pub fn bind(fd: i32, addr: *const sockaddr, len: socklen_t) usize {
826 return syscall3(SYS_bind, @bitCast(usize, isize(fd)), @ptrToInt(addr), @intCast(usize, len));826 return syscall3(SYS_bind, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @intCast(usize, len));
827}827}
828828
829pub fn listen(fd: i32, backlog: u32) usize {829pub fn listen(fd: i32, backlog: u32) usize {
830 return syscall2(SYS_listen, @bitCast(usize, isize(fd)), backlog);830 return syscall2(SYS_listen, @bitCast(usize, @as(isize, fd)), backlog);
831}831}
832832
833pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {833pub fn sendto(fd: i32, buf: [*]const u8, len: usize, flags: u32, addr: ?*const sockaddr, alen: socklen_t) usize {
834 return syscall6(SYS_sendto, @bitCast(usize, isize(fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));834 return syscall6(SYS_sendto, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), len, flags, @ptrToInt(addr), @intCast(usize, alen));
835}835}
836836
837pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {837pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
...@@ -843,14 +843,14 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {...@@ -843,14 +843,14 @@ pub fn accept(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t) usize {
843}843}
844844
845pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {845pub fn accept4(fd: i32, noalias addr: *sockaddr, noalias len: *socklen_t, flags: u32) usize {
846 return syscall4(SYS_accept4, @bitCast(usize, isize(fd)), @ptrToInt(addr), @ptrToInt(len), flags);846 return syscall4(SYS_accept4, @bitCast(usize, @as(isize, fd)), @ptrToInt(addr), @ptrToInt(len), flags);
847}847}
848848
849pub fn fstat(fd: i32, stat_buf: *Stat) usize {849pub fn fstat(fd: i32, stat_buf: *Stat) usize {
850 if (@hasDecl(@This(), "SYS_fstat64")) {850 if (@hasDecl(@This(), "SYS_fstat64")) {
851 return syscall2(SYS_fstat64, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));851 return syscall2(SYS_fstat64, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));
852 } else {852 } else {
853 return syscall2(SYS_fstat, @bitCast(usize, isize(fd)), @ptrToInt(stat_buf));853 return syscall2(SYS_fstat, @bitCast(usize, @as(isize, fd)), @ptrToInt(stat_buf));
854 }854 }
855}855}
856856
...@@ -875,9 +875,9 @@ pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {...@@ -875,9 +875,9 @@ pub fn lstat(pathname: [*]const u8, statbuf: *Stat) usize {
875// TODO https://github.com/ziglang/zig/issues/265875// TODO https://github.com/ziglang/zig/issues/265
876pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize {876pub fn fstatat(dirfd: i32, path: [*]const u8, stat_buf: *Stat, flags: u32) usize {
877 if (@hasDecl(@This(), "SYS_fstatat64")) {877 if (@hasDecl(@This(), "SYS_fstatat64")) {
878 return syscall4(SYS_fstatat64, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);878 return syscall4(SYS_fstatat64, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
879 } else {879 } else {
880 return syscall4(SYS_fstatat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);880 return syscall4(SYS_fstatat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
881 }881 }
882}882}
883883
...@@ -885,14 +885,14 @@ pub fn statx(dirfd: i32, path: [*]const u8, flags: u32, mask: u32, statx_buf: *S...@@ -885,14 +885,14 @@ pub fn statx(dirfd: i32, path: [*]const u8, flags: u32, mask: u32, statx_buf: *S
885 if (@hasDecl(@This(), "SYS_statx")) {885 if (@hasDecl(@This(), "SYS_statx")) {
886 return syscall5(886 return syscall5(
887 SYS_statx,887 SYS_statx,
888 @bitCast(usize, isize(dirfd)),888 @bitCast(usize, @as(isize, dirfd)),
889 @ptrToInt(path),889 @ptrToInt(path),
890 flags,890 flags,
891 mask,891 mask,
892 @ptrToInt(statx_buf),892 @ptrToInt(statx_buf),
893 );893 );
894 }894 }
895 return @bitCast(usize, isize(-ENOSYS));895 return @bitCast(usize, @as(isize, -ENOSYS));
896}896}
897897
898// TODO https://github.com/ziglang/zig/issues/265898// TODO https://github.com/ziglang/zig/issues/265
...@@ -954,8 +954,12 @@ pub fn fremovexattr(fd: usize, name: [*]const u8) usize {...@@ -954,8 +954,12 @@ pub fn fremovexattr(fd: usize, name: [*]const u8) usize {
954 return syscall2(SYS_fremovexattr, fd, @ptrToInt(name));954 return syscall2(SYS_fremovexattr, fd, @ptrToInt(name));
955}955}
956956
957pub fn sched_yield() usize {
958 return syscall0(SYS_sched_yield);
959}
960
957pub fn sched_getaffinity(pid: i32, size: usize, set: *cpu_set_t) usize {961pub fn sched_getaffinity(pid: i32, size: usize, set: *cpu_set_t) usize {
958 const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, isize(pid)), size, @ptrToInt(set));962 const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set));
959 if (@bitCast(isize, rc) < 0) return rc;963 if (@bitCast(isize, rc) < 0) return rc;
960 if (rc < size) @memset(@ptrCast([*]u8, set) + rc, 0, size - rc);964 if (rc < size) @memset(@ptrCast([*]u8, set) + rc, 0, size - rc);
961 return 0;965 return 0;
...@@ -970,7 +974,7 @@ pub fn epoll_create1(flags: usize) usize {...@@ -970,7 +974,7 @@ pub fn epoll_create1(flags: usize) usize {
970}974}
971975
972pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: ?*epoll_event) usize {976pub fn epoll_ctl(epoll_fd: i32, op: u32, fd: i32, ev: ?*epoll_event) usize {
973 return syscall4(SYS_epoll_ctl, @bitCast(usize, isize(epoll_fd)), @intCast(usize, op), @bitCast(usize, isize(fd)), @ptrToInt(ev));977 return syscall4(SYS_epoll_ctl, @bitCast(usize, @as(isize, epoll_fd)), @intCast(usize, op), @bitCast(usize, @as(isize, fd)), @ptrToInt(ev));
974}978}
975979
976pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {980pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32) usize {
...@@ -980,10 +984,10 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout...@@ -980,10 +984,10 @@ pub fn epoll_wait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout
980pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {984pub fn epoll_pwait(epoll_fd: i32, events: [*]epoll_event, maxevents: u32, timeout: i32, sigmask: ?*sigset_t) usize {
981 return syscall6(985 return syscall6(
982 SYS_epoll_pwait,986 SYS_epoll_pwait,
983 @bitCast(usize, isize(epoll_fd)),987 @bitCast(usize, @as(isize, epoll_fd)),
984 @ptrToInt(events),988 @ptrToInt(events),
985 @intCast(usize, maxevents),989 @intCast(usize, maxevents),
986 @bitCast(usize, isize(timeout)),990 @bitCast(usize, @as(isize, timeout)),
987 @ptrToInt(sigmask),991 @ptrToInt(sigmask),
988 @sizeOf(sigset_t),992 @sizeOf(sigset_t),
989 );993 );
...@@ -994,7 +998,7 @@ pub fn eventfd(count: u32, flags: u32) usize {...@@ -994,7 +998,7 @@ pub fn eventfd(count: u32, flags: u32) usize {
994}998}
995999
996pub fn timerfd_create(clockid: i32, flags: u32) usize {1000pub fn timerfd_create(clockid: i32, flags: u32) usize {
997 return syscall2(SYS_timerfd_create, @bitCast(usize, isize(clockid)), flags);1001 return syscall2(SYS_timerfd_create, @bitCast(usize, @as(isize, clockid)), flags);
998}1002}
9991003
1000pub const itimerspec = extern struct {1004pub const itimerspec = extern struct {
...@@ -1003,11 +1007,11 @@ pub const itimerspec = extern struct {...@@ -1003,11 +1007,11 @@ pub const itimerspec = extern struct {
1003};1007};
10041008
1005pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {1009pub fn timerfd_gettime(fd: i32, curr_value: *itimerspec) usize {
1006 return syscall2(SYS_timerfd_gettime, @bitCast(usize, isize(fd)), @ptrToInt(curr_value));1010 return syscall2(SYS_timerfd_gettime, @bitCast(usize, @as(isize, fd)), @ptrToInt(curr_value));
1007}1011}
10081012
1009pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {1013pub fn timerfd_settime(fd: i32, flags: u32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
1010 return syscall4(SYS_timerfd_settime, @bitCast(usize, isize(fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value));1014 return syscall4(SYS_timerfd_settime, @bitCast(usize, @as(isize, fd)), flags, @ptrToInt(new_value), @ptrToInt(old_value));
1011}1015}
10121016
1013pub fn unshare(flags: usize) usize {1017pub fn unshare(flags: usize) usize {
...@@ -1092,11 +1096,11 @@ pub fn io_uring_setup(entries: u32, p: *io_uring_params) usize {...@@ -1092,11 +1096,11 @@ pub fn io_uring_setup(entries: u32, p: *io_uring_params) usize {
1092}1096}
10931097
1094pub fn io_uring_enter(fd: i32, to_submit: u32, min_complete: u32, flags: u32, sig: ?*sigset_t) usize {1098pub fn io_uring_enter(fd: i32, to_submit: u32, min_complete: u32, flags: u32, sig: ?*sigset_t) usize {
1095 return syscall6(SYS_io_uring_enter, @bitCast(usize, isize(fd)), to_submit, min_complete, flags, @ptrToInt(sig), NSIG / 8);1099 return syscall6(SYS_io_uring_enter, @bitCast(usize, @as(isize, fd)), to_submit, min_complete, flags, @ptrToInt(sig), NSIG / 8);
1096}1100}
10971101
1098pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32) usize {1102pub fn io_uring_register(fd: i32, opcode: u32, arg: ?*const c_void, nr_args: u32) usize {
1099 return syscall4(SYS_io_uring_register, @bitCast(usize, isize(fd)), opcode, @ptrToInt(arg), nr_args);1103 return syscall4(SYS_io_uring_register, @bitCast(usize, @as(isize, fd)), opcode, @ptrToInt(arg), nr_args);
1100}1104}
11011105
1102test "" {1106test "" {
lib/std/os/linux/arm-eabi.zig+2-2
...@@ -100,7 +100,7 @@ pub extern fn getThreadPointer() usize {...@@ -100,7 +100,7 @@ pub extern fn getThreadPointer() usize {
100pub nakedcc fn restore() void {100pub nakedcc fn restore() void {
101 return asm volatile ("svc #0"101 return asm volatile ("svc #0"
102 :102 :
103 : [number] "{r7}" (usize(SYS_sigreturn))103 : [number] "{r7}" (@as(usize, SYS_sigreturn))
104 : "memory"104 : "memory"
105 );105 );
106}106}
...@@ -108,7 +108,7 @@ pub nakedcc fn restore() void {...@@ -108,7 +108,7 @@ pub nakedcc fn restore() void {
108pub nakedcc fn restore_rt() void {108pub nakedcc fn restore_rt() void {
109 return asm volatile ("svc #0"109 return asm volatile ("svc #0"
110 :110 :
111 : [number] "{r7}" (usize(SYS_rt_sigreturn))111 : [number] "{r7}" (@as(usize, SYS_rt_sigreturn))
112 : "memory"112 : "memory"
113 );113 );
114}114}
lib/std/os/linux/arm64.zig+1-1
...@@ -93,7 +93,7 @@ pub const restore = restore_rt;...@@ -93,7 +93,7 @@ pub const restore = restore_rt;
93pub nakedcc fn restore_rt() void {93pub nakedcc fn restore_rt() void {
94 return asm volatile ("svc #0"94 return asm volatile ("svc #0"
95 :95 :
96 : [number] "{x8}" (usize(SYS_rt_sigreturn))96 : [number] "{x8}" (@as(usize, SYS_rt_sigreturn))
97 : "memory", "cc"97 : "memory", "cc"
98 );98 );
99}99}
lib/std/os/linux/mipsel.zig+3-3
...@@ -26,7 +26,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {...@@ -26,7 +26,7 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
26 \\ sw $3, 4($4)26 \\ sw $3, 4($4)
27 \\ 2:27 \\ 2:
28 : [ret] "={$2}" (-> usize)28 : [ret] "={$2}" (-> usize)
29 : [number] "{$2}" (usize(SYS_pipe))29 : [number] "{$2}" (@as(usize, SYS_pipe))
30 : "memory", "cc", "$7"30 : "memory", "cc", "$7"
31 );31 );
32}32}
...@@ -147,7 +147,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a...@@ -147,7 +147,7 @@ pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, a
147pub nakedcc fn restore() void {147pub nakedcc fn restore() void {
148 return asm volatile ("syscall"148 return asm volatile ("syscall"
149 :149 :
150 : [number] "{$2}" (usize(SYS_sigreturn))150 : [number] "{$2}" (@as(usize, SYS_sigreturn))
151 : "memory", "cc", "$7"151 : "memory", "cc", "$7"
152 );152 );
153}153}
...@@ -155,7 +155,7 @@ pub nakedcc fn restore() void {...@@ -155,7 +155,7 @@ pub nakedcc fn restore() void {
155pub nakedcc fn restore_rt() void {155pub nakedcc fn restore_rt() void {
156 return asm volatile ("syscall"156 return asm volatile ("syscall"
157 :157 :
158 : [number] "{$2}" (usize(SYS_rt_sigreturn))158 : [number] "{$2}" (@as(usize, SYS_rt_sigreturn))
159 : "memory", "cc", "$7"159 : "memory", "cc", "$7"
160 );160 );
161}161}
lib/std/os/linux/riscv64.zig+1-1
...@@ -92,7 +92,7 @@ pub const restore = restore_rt;...@@ -92,7 +92,7 @@ pub const restore = restore_rt;
92pub nakedcc fn restore_rt() void {92pub nakedcc fn restore_rt() void {
93 return asm volatile ("ecall"93 return asm volatile ("ecall"
94 :94 :
95 : [number] "{x17}" (usize(SYS_rt_sigreturn))95 : [number] "{x17}" (@as(usize, SYS_rt_sigreturn))
96 : "memory"96 : "memory"
97 );97 );
98}98}
lib/std/os/linux/test.zig+3-3
...@@ -72,7 +72,7 @@ test "statx" {...@@ -72,7 +72,7 @@ test "statx" {
72 expect(stat_buf.mode == statx_buf.mode);72 expect(stat_buf.mode == statx_buf.mode);
73 expect(@bitCast(u32, stat_buf.uid) == statx_buf.uid);73 expect(@bitCast(u32, stat_buf.uid) == statx_buf.uid);
74 expect(@bitCast(u32, stat_buf.gid) == statx_buf.gid);74 expect(@bitCast(u32, stat_buf.gid) == statx_buf.gid);
75 expect(@bitCast(u64, i64(stat_buf.size)) == statx_buf.size);75 expect(@bitCast(u64, @as(i64, stat_buf.size)) == statx_buf.size);
76 expect(@bitCast(u64, i64(stat_buf.blksize)) == statx_buf.blksize);76 expect(@bitCast(u64, @as(i64, stat_buf.blksize)) == statx_buf.blksize);
77 expect(@bitCast(u64, i64(stat_buf.blocks)) == statx_buf.blocks);77 expect(@bitCast(u64, @as(i64, stat_buf.blocks)) == statx_buf.blocks);
78}78}
lib/std/os/linux/vdso.zig+2-2
...@@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {...@@ -62,8 +62,8 @@ pub fn lookup(vername: []const u8, name: []const u8) usize {
6262
63 var i: usize = 0;63 var i: usize = 0;
64 while (i < hashtab[1]) : (i += 1) {64 while (i < hashtab[1]) : (i += 1) {
65 if (0 == (u32(1) << @intCast(u5, syms[i].st_info & 0xf) & OK_TYPES)) continue;65 if (0 == (@as(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;66 if (0 == (@as(u32, 1) << @intCast(u5, syms[i].st_info >> 4) & OK_BINDS)) continue;
67 if (0 == syms[i].st_shndx) continue;67 if (0 == syms[i].st_shndx) continue;
68 if (!mem.eql(u8, name, mem.toSliceConst(u8, strings + syms[i].st_name))) continue;68 if (!mem.eql(u8, name, mem.toSliceConst(u8, strings + syms[i].st_name))) continue;
69 if (maybe_versym) |versym| {69 if (maybe_versym) |versym| {
lib/std/os/linux/x86_64.zig+1-1
...@@ -93,7 +93,7 @@ pub const restore = restore_rt;...@@ -93,7 +93,7 @@ pub const restore = restore_rt;
93pub nakedcc fn restore_rt() void {93pub nakedcc fn restore_rt() void {
94 return asm volatile ("syscall"94 return asm volatile ("syscall"
95 :95 :
96 : [number] "{rax}" (usize(SYS_rt_sigreturn))96 : [number] "{rax}" (@as(usize, SYS_rt_sigreturn))
97 : "rcx", "r11", "memory"97 : "rcx", "r11", "memory"
98 );98 );
99}99}
lib/std/os/test.zig+1-1
...@@ -172,7 +172,7 @@ export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {...@@ -172,7 +172,7 @@ export fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) i32 {
172172
173 var counter = data.?;173 var counter = data.?;
174 // Count how many libraries are loaded174 // Count how many libraries are loaded
175 counter.* += usize(1);175 counter.* += @as(usize, 1);
176176
177 // The image should contain at least a PT_LOAD segment177 // The image should contain at least a PT_LOAD segment
178 if (info.dlpi_phnum < 1) return -1;178 if (info.dlpi_phnum < 1) return -1;
lib/std/os/uefi/protocols.zig+44
...@@ -1,3 +1,7 @@...@@ -1,3 +1,7 @@
1pub const LoadedImageProtocol = @import("protocols/loaded_image_protocol.zig").LoadedImageProtocol;
2
3pub const DevicePathProtocol = @import("protocols/device_path_protocol.zig").DevicePathProtocol;
4
1pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;5pub const InputKey = @import("protocols/simple_text_input_ex_protocol.zig").InputKey;
2pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;6pub const KeyData = @import("protocols/simple_text_input_ex_protocol.zig").KeyData;
3pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;7pub const KeyState = @import("protocols/simple_text_input_ex_protocol.zig").KeyState;
...@@ -29,6 +33,46 @@ pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").Edi...@@ -29,6 +33,46 @@ pub const EdidActiveProtocol = @import("protocols/edid_active_protocol.zig").Edi
29pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;33pub const EdidOverrideProtocol = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocol;
30pub const EdidOverrideProtocolAttributes = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocolAttributes;34pub const EdidOverrideProtocolAttributes = @import("protocols/edid_override_protocol.zig").EdidOverrideProtocolAttributes;
3135
36pub const SimpleNetworkProtocol = @import("protocols/simple_network_protocol.zig").SimpleNetworkProtocol;
37pub const MacAddress = @import("protocols/simple_network_protocol.zig").MacAddress;
38pub const SimpleNetworkMode = @import("protocols/simple_network_protocol.zig").SimpleNetworkMode;
39pub const SimpleNetworkReceiveFilter = @import("protocols/simple_network_protocol.zig").SimpleNetworkReceiveFilter;
40pub const SimpleNetworkState = @import("protocols/simple_network_protocol.zig").SimpleNetworkState;
41pub const NetworkStatistics = @import("protocols/simple_network_protocol.zig").NetworkStatistics;
42pub const SimpleNetworkInterruptStatus = @import("protocols/simple_network_protocol.zig").SimpleNetworkInterruptStatus;
43
44pub const ManagedNetworkServiceBindingProtocol = @import("protocols/managed_network_service_binding_protocol.zig").ManagedNetworkServiceBindingProtocol;
45pub const ManagedNetworkProtocol = @import("protocols/managed_network_protocol.zig").ManagedNetworkProtocol;
46pub const ManagedNetworkConfigData = @import("protocols/managed_network_protocol.zig").ManagedNetworkConfigData;
47pub const ManagedNetworkCompletionToken = @import("protocols/managed_network_protocol.zig").ManagedNetworkCompletionToken;
48pub const ManagedNetworkReceiveData = @import("protocols/managed_network_protocol.zig").ManagedNetworkReceiveData;
49pub const ManagedNetworkTransmitData = @import("protocols/managed_network_protocol.zig").ManagedNetworkTransmitData;
50pub const ManagedNetworkFragmentData = @import("protocols/managed_network_protocol.zig").ManagedNetworkFragmentData;
51
52pub const Ip6ServiceBindingProtocol = @import("protocols/ip6_service_binding_protocol.zig").Ip6ServiceBindingProtocol;
53pub const Ip6Protocol = @import("protocols/ip6_protocol.zig").Ip6Protocol;
54pub const Ip6ModeData = @import("protocols/ip6_protocol.zig").Ip6ModeData;
55pub const Ip6ConfigData = @import("protocols/ip6_protocol.zig").Ip6ConfigData;
56pub const Ip6Address = @import("protocols/ip6_protocol.zig").Ip6Address;
57pub const Ip6AddressInfo = @import("protocols/ip6_protocol.zig").Ip6AddressInfo;
58pub const Ip6RouteTable = @import("protocols/ip6_protocol.zig").Ip6RouteTable;
59pub const Ip6NeighborState = @import("protocols/ip6_protocol.zig").Ip6NeighborState;
60pub const Ip6NeighborCache = @import("protocols/ip6_protocol.zig").Ip6NeighborCache;
61pub const Ip6IcmpType = @import("protocols/ip6_protocol.zig").Ip6IcmpType;
62pub const Ip6CompletionToken = @import("protocols/ip6_protocol.zig").Ip6CompletionToken;
63
64pub const Ip6ConfigProtocol = @import("protocols/ip6_config_protocol.zig").Ip6ConfigProtocol;
65pub const Ip6ConfigDataType = @import("protocols/ip6_config_protocol.zig").Ip6ConfigDataType;
66
67pub const Udp6ServiceBindingProtocol = @import("protocols/udp6_service_binding_protocol.zig").Udp6ServiceBindingProtocol;
68pub const Udp6Protocol = @import("protocols/udp6_protocol.zig").Udp6Protocol;
69pub const Udp6ConfigData = @import("protocols/udp6_protocol.zig").Udp6ConfigData;
70pub const Udp6CompletionToken = @import("protocols/udp6_protocol.zig").Udp6CompletionToken;
71pub const Udp6ReceiveData = @import("protocols/udp6_protocol.zig").Udp6ReceiveData;
72pub const Udp6TransmitData = @import("protocols/udp6_protocol.zig").Udp6TransmitData;
73pub const Udp6SessionData = @import("protocols/udp6_protocol.zig").Udp6SessionData;
74pub const Udp6FragmentData = @import("protocols/udp6_protocol.zig").Udp6FragmentData;
75
32pub const hii = @import("protocols/hii.zig");76pub const hii = @import("protocols/hii.zig");
33pub const HIIDatabaseProtocol = @import("protocols/hii_database_protocol.zig").HIIDatabaseProtocol;77pub const HIIDatabaseProtocol = @import("protocols/hii_database_protocol.zig").HIIDatabaseProtocol;
34pub const HIIPopupProtocol = @import("protocols/hii_popup_protocol.zig").HIIPopupProtocol;78pub const HIIPopupProtocol = @import("protocols/hii_popup_protocol.zig").HIIPopupProtocol;
lib/std/os/uefi/protocols/device_path_protocol.zig created+17
...@@ -0,0 +1,17 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3
4pub const DevicePathProtocol = extern struct {
5 type: u8,
6 subtype: u8,
7 length: u16,
8
9 pub const guid align(8) = Guid{
10 .time_low = 0x09576e91,
11 .time_mid = 0x6d3f,
12 .time_high_and_version = 0x11d2,
13 .clock_seq_high_and_reserved = 0x8e,
14 .clock_seq_low = 0x39,
15 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
16 };
17};
lib/std/os/uefi/protocols/ip6_config_protocol.zig created+45
...@@ -0,0 +1,45 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Event = uefi.Event;
4
5pub const Ip6ConfigProtocol = extern struct {
6 _set_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) usize,
7 _get_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) usize,
8 _register_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) usize,
9 _unregister_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) usize,
10
11 pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) usize {
12 return self._set_data(self, data_type, data_size, data);
13 }
14
15 pub fn getData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: *usize, data: ?*const c_void) usize {
16 return self._get_data(self, data_type, data_size, data);
17 }
18
19 pub fn registerDataNotify(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, event: Event) usize {
20 return self._register_data_notify(self, data_type, event);
21 }
22
23 pub fn unregisterDataNotify(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, event: Event) usize {
24 return self._unregister_data_notify(self, data_type, event);
25 }
26
27 pub const guid align(8) = Guid{
28 .time_low = 0x937fe521,
29 .time_mid = 0x95ae,
30 .time_high_and_version = 0x4d1a,
31 .clock_seq_high_and_reserved = 0x89,
32 .clock_seq_low = 0x29,
33 .node = [_]u8{ 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a },
34 };
35};
36
37pub const Ip6ConfigDataType = extern enum(u32) {
38 InterfaceInfo,
39 AltInterfaceId,
40 Policy,
41 DupAddrDetectTransmits,
42 ManualAddress,
43 Gateway,
44 DnsServer,
45};
lib/std/os/uefi/protocols/ip6_protocol.zig created+143
...@@ -0,0 +1,143 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Event = uefi.Event;
4const MacAddress = uefi.protocols.MacAddress;
5const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
6const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
7
8pub const Ip6Protocol = extern struct {
9 _get_mode_data: extern fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
10 _configure: extern fn (*const Ip6Protocol, ?*const Ip6ConfigData) usize,
11 _groups: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address) usize,
12 _routes: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) usize,
13 _neighbors: extern fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) usize,
14 _transmit: extern fn (*const Ip6Protocol, *Ip6CompletionToken) usize,
15 _receive: extern fn (*const Ip6Protocol, *Ip6CompletionToken) usize,
16 _cancel: extern fn (*const Ip6Protocol, ?*Ip6CompletionToken) usize,
17 _poll: extern fn (*const Ip6Protocol) usize,
18
19 /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
20 pub fn getModeData(self: *const Ip6Protocol, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
21 return self._get_mode_data(self, ip6_mode_data, mnp_config_data, snp_mode_data);
22 }
23
24 /// Assign IPv6 address and other configuration parameter to this EFI IPv6 Protocol driver instance.
25 pub fn configure(self: *const Ip6Protocol, ip6_config_data: ?*const Ip6ConfigData) usize {
26 return self._configure(self, ip6_config_data);
27 }
28
29 /// Joins and leaves multicast groups.
30 pub fn groups(self: *const Ip6Protocol, join_flag: bool, group_address: ?*const Ip6Address) usize {
31 return self._groups(self, join_flag, group_address);
32 }
33
34 /// Adds and deletes routing table entries.
35 pub fn routes(self: *const Ip6Protocol, delete_route: bool, destination: ?*const Ip6Address, prefix_length: u8, gateway_address: ?*const Ip6Address) usize {
36 return self._routes(self, delete_route, destination, prefix_length, gateway_address);
37 }
38
39 /// Add or delete Neighbor cache entries.
40 pub fn neighbors(self: *const Ip6Protocol, delete_flag: bool, target_ip6_address: *const Ip6Address, target_link_address: ?*const MacAddress, timeout: u32, override: bool) usize {
41 return self._neighbors(self, delete_flag, target_ip6_address, target_link_address, timeout, override);
42 }
43
44 /// Places outgoing data packets into the transmit queue.
45 pub fn transmit(self: *const Ip6Protocol, token: *Ip6CompletionToken) usize {
46 return self._transmit(self, token);
47 }
48
49 /// Places a receiving request into the receiving queue.
50 pub fn receive(self: *const Ip6Protocol, token: *Ip6CompletionToken) usize {
51 return self._receive(self, token);
52 }
53
54 /// Abort an asynchronous transmits or receive request.
55 pub fn cancel(self: *const Ip6Protocol, token: ?*Ip6CompletionToken) usize {
56 return self._cancel(self, token);
57 }
58
59 /// Polls for incoming data packets and processes outgoing data packets.
60 pub fn poll(self: *const Ip6Protocol) usize {
61 return self._poll(self);
62 }
63
64 pub const guid align(8) = Guid{
65 .time_low = 0x2c8759d5,
66 .time_mid = 0x5c2d,
67 .time_high_and_version = 0x66ef,
68 .clock_seq_high_and_reserved = 0x92,
69 .clock_seq_low = 0x5f,
70 .node = [_]u8{ 0xb6, 0x6c, 0x10, 0x19, 0x57, 0xe2 },
71 };
72};
73
74pub const Ip6ModeData = extern struct {
75 is_started: bool,
76 max_packet_size: u32,
77 config_data: Ip6ConfigData,
78 is_configured: bool,
79 address_count: u32,
80 address_list: [*]Ip6AddressInfo,
81 group_count: u32,
82 group_table: [*]Ip6Address,
83 route_count: u32,
84 route_table: [*]Ip6RouteTable,
85 neighbor_count: u32,
86 neighbor_cache: [*]Ip6NeighborCache,
87 prefix_count: u32,
88 prefix_table: [*]Ip6AddressInfo,
89 icmp_type_count: u32,
90 icmp_type_list: [*]Ip6IcmpType,
91};
92
93pub const Ip6ConfigData = extern struct {
94 default_protocol: u8,
95 accept_any_protocol: bool,
96 accept_icmp_errors: bool,
97 accept_promiscuous: bool,
98 destination_address: Ip6Address,
99 station_address: Ip6Address,
100 traffic_class: u8,
101 hop_limit: u8,
102 flow_label: u32,
103 receive_timeout: u32,
104 transmit_timeout: u32,
105};
106
107pub const Ip6Address = [16]u8;
108
109pub const Ip6AddressInfo = extern struct {
110 address: Ip6Address,
111 prefix_length: u8,
112};
113
114pub const Ip6RouteTable = extern struct {
115 gateway: Ip6Address,
116 destination: Ip6Address,
117 prefix_length: u8,
118};
119
120pub const Ip6NeighborState = extern enum(u32) {
121 Incomplete,
122 Reachable,
123 Stale,
124 Delay,
125 Probe,
126};
127
128pub const Ip6NeighborCache = extern struct {
129 neighbor: Ip6Address,
130 link_address: MacAddress,
131 state: Ip6NeighborState,
132};
133
134pub const Ip6IcmpType = extern struct {
135 type: u8,
136 code: u8,
137};
138
139pub const Ip6CompletionToken = extern struct {
140 event: Event,
141 status: usize,
142 packet: *c_void, // union TODO
143};
lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig created+25
...@@ -0,0 +1,25 @@
1const uefi = @import("std").os.uefi;
2const Handle = uefi.Handle;
3const Guid = uefi.Guid;
4
5pub const Ip6ServiceBindingProtocol = extern struct {
6 _create_child: extern fn (*const Ip6ServiceBindingProtocol, *?Handle) usize,
7 _destroy_child: extern fn (*const Ip6ServiceBindingProtocol, Handle) usize,
8
9 pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) usize {
10 return self._create_child(self, handle);
11 }
12
13 pub fn destroyChild(self: *const Ip6ServiceBindingProtocol, handle: Handle) usize {
14 return self._destroy_child(self, handle);
15 }
16
17 pub const guid align(8) = Guid{
18 .time_low = 0xec835dd3,
19 .time_mid = 0xfe0f,
20 .time_high_and_version = 0x617b,
21 .clock_seq_high_and_reserved = 0xa6,
22 .clock_seq_low = 0x21,
23 .node = [_]u8{ 0xb3, 0x50, 0xc3, 0xe1, 0x33, 0x88 },
24 };
25};
lib/std/os/uefi/protocols/loaded_image_protocol.zig created+36
...@@ -0,0 +1,36 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Handle = uefi.Handle;
4const SystemTable = uefi.tables.SystemTable;
5const MemoryType = uefi.tables.MemoryType;
6const DevicePathProtocol = uefi.protocols.DevicePathProtocol;
7
8pub const LoadedImageProtocol = extern struct {
9 revision: u32,
10 parent_handle: Handle,
11 system_table: *SystemTable,
12 device_handle: ?Handle,
13 file_path: *DevicePathProtocol,
14 reserved: *c_void,
15 load_options_size: u32,
16 load_options: *c_void,
17 image_base: [*]u8,
18 image_size: u64,
19 image_code_type: MemoryType,
20 image_data_type: MemoryType,
21 _unload: extern fn (*const LoadedImageProtocol, Handle) usize,
22
23 /// Unloads an image from memory.
24 pub fn unload(self: *const LoadedImageProtocol, handle: Handle) usize {
25 return self._unload(self, handle);
26 }
27
28 pub const guid align(8) = Guid{
29 .time_low = 0x5b1b31a1,
30 .time_mid = 0x9562,
31 .time_high_and_version = 0x11d2,
32 .clock_seq_high_and_reserved = 0x8e,
33 .clock_seq_low = 0x3f,
34 .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
35 };
36};
lib/std/os/uefi/protocols/managed_network_protocol.zig created+126
...@@ -0,0 +1,126 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Event = uefi.Event;
4const Time = uefi.Time;
5const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
6const MacAddress = uefi.protocols.MacAddress;
7
8pub const ManagedNetworkProtocol = extern struct {
9 _get_mode_data: extern fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
10 _configure: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) usize,
11 _mcast_ip_to_mac: extern fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) usize,
12 _groups: extern fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) usize,
13 _transmit: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) usize,
14 _receive: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) usize,
15 _cancel: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) usize,
16 _poll: extern fn (*const ManagedNetworkProtocol) usize,
17
18 /// Returns the operational parameters for the current MNP child driver.
19 /// May also support returning the underlying SNP driver mode data.
20 pub fn getModeData(self: *const ManagedNetworkProtocol, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
21 return self._get_mode_data(self, mnp_config_data, snp_mode_data);
22 }
23
24 /// Sets or clears the operational parameters for the MNP child driver.
25 pub fn configure(self: *const ManagedNetworkProtocol, mnp_config_data: ?*const ManagedNetworkConfigData) usize {
26 return self._configure(self, mnp_config_data);
27 }
28
29 /// Translates an IP multicast address to a hardware (MAC) multicast address.
30 /// This function may be unsupported in some MNP implementations.
31 pub fn mcastIpToMac(self: *const ManagedNetworkProtocol, ipv6flag: bool, ipaddress: *const c_void, mac_address: *MacAddress) usize {
32 return self._mcast_ip_to_mac(self, ipv6flag, ipaddress);
33 }
34
35 /// Enables and disables receive filters for multicast address.
36 /// This function may be unsupported in some MNP implementations.
37 pub fn groups(self: *const ManagedNetworkProtocol, join_flag: bool, mac_address: ?*const MacAddress) usiz {
38 return self._groups(self, join_flag, mac_address);
39 }
40
41 /// Places asynchronous outgoing data packets into the transmit queue.
42 pub fn transmit(self: *const ManagedNetworkProtocol, token: *const ManagedNetworkCompletionToken) usize {
43 return self._transmit(self, token);
44 }
45
46 /// Places an asynchronous receiving request into the receiving queue.
47 pub fn receive(self: *const ManagedNetworkProtocol, token: *const ManagedNetworkCompletionToken) usize {
48 return self._receive(self, token);
49 }
50
51 /// Aborts an asynchronous transmit or receive request.
52 pub fn cancel(self: *const ManagedNetworkProtocol, token: ?*const ManagedNetworkCompletionToken) usize {
53 return self._cancel(self, token);
54 }
55
56 /// Polls for incoming data packets and processes outgoing data packets.
57 pub fn poll(self: *const ManagedNetworkProtocol) usize {
58 return self._poll(self);
59 }
60
61 pub const guid align(8) = Guid{
62 .time_low = 0x7ab33a91,
63 .time_mid = 0xace5,
64 .time_high_and_version = 0x4326,
65 .clock_seq_high_and_reserved = 0xb5,
66 .clock_seq_low = 0x72,
67 .node = [_]u8{ 0xe7, 0xee, 0x33, 0xd3, 0x9f, 0x16 },
68 };
69};
70
71pub const ManagedNetworkConfigData = extern struct {
72 received_queue_timeout_value: u32,
73 transmit_queue_timeout_value: u32,
74 protocol_type_filter: u16,
75 enable_unicast_receive: bool,
76 enable_multicast_receive: bool,
77 enable_broadcast_receive: bool,
78 enable_promiscuous_receive: bool,
79 flush_queues_on_reset: bool,
80 enable_receive_timestamps: bool,
81 disable_background_polling: bool,
82};
83
84pub const ManagedNetworkCompletionToken = extern struct {
85 event: Event,
86 status: usize,
87 packet: extern union {
88 RxData: *ManagedNetworkReceiveData,
89 TxData: *ManagedNetworkTransmitData,
90 },
91};
92
93pub const ManagedNetworkReceiveData = extern struct {
94 timestamp: Time,
95 recycle_event: Event,
96 packet_length: u32,
97 header_length: u32,
98 address_length: u32,
99 data_length: u32,
100 broadcast_flag: bool,
101 multicast_flag: bool,
102 promiscuous_flag: bool,
103 protocol_type: u16,
104 destination_address: [*]u8,
105 source_address: [*]u8,
106 media_header: [*]u8,
107 packet_data: [*]u8,
108};
109
110pub const ManagedNetworkTransmitData = extern struct {
111 destination_address: ?*MacAddress,
112 source_address: ?*MacAddress,
113 protocol_type: u16,
114 data_length: u32,
115 header_length: u16,
116 fragment_count: u16,
117
118 pub fn getFragments(self: *ManagedNetworkTransmitData) []ManagedNetworkFragmentData {
119 return @ptrCast([*]ManagedNetworkFragmentData, @ptrCast([*]u8, self) + @sizeOf(ManagedNetworkTransmitData))[0..self.fragment_count];
120 }
121};
122
123pub const ManagedNetworkFragmentData = extern struct {
124 fragment_length: u32,
125 fragment_buffer: [*]u8,
126};
lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig created+25
...@@ -0,0 +1,25 @@
1const uefi = @import("std").os.uefi;
2const Handle = uefi.Handle;
3const Guid = uefi.Guid;
4
5pub const ManagedNetworkServiceBindingProtocol = extern struct {
6 _create_child: extern fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) usize,
7 _destroy_child: extern fn (*const ManagedNetworkServiceBindingProtocol, Handle) usize,
8
9 pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) usize {
10 return self._create_child(self, handle);
11 }
12
13 pub fn destroyChild(self: *const ManagedNetworkServiceBindingProtocol, handle: Handle) usize {
14 return self._destroy_child(self, handle);
15 }
16
17 pub const guid align(8) = Guid{
18 .time_low = 0xf36ff770,
19 .time_mid = 0xa7e1,
20 .time_high_and_version = 0x42cf,
21 .clock_seq_high_and_reserved = 0x9e,
22 .clock_seq_low = 0xd2,
23 .node = [_]u8{ 0x56, 0xf0, 0xf2, 0x71, 0xf4, 0x4c },
24 };
25};
lib/std/os/uefi/protocols/simple_network_protocol.zig created+172
...@@ -0,0 +1,172 @@
1const uefi = @import("std").os.uefi;
2const Event = uefi.Event;
3const Guid = uefi.Guid;
4
5pub const SimpleNetworkProtocol = extern struct {
6 revision: u64,
7 _start: extern fn (*const SimpleNetworkProtocol) usize,
8 _stop: extern fn (*const SimpleNetworkProtocol) usize,
9 _initialize: extern fn (*const SimpleNetworkProtocol, usize, usize) usize,
10 _reset: extern fn (*const SimpleNetworkProtocol, bool) usize,
11 _shutdown: extern fn (*const SimpleNetworkProtocol) usize,
12 _receive_filters: extern fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) usize,
13 _station_address: extern fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) usize,
14 _statistics: extern fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) usize,
15 _mcast_ip_to_mac: extern fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) usize,
16 _nvdata: extern fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) usize,
17 _get_status: extern fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) usize,
18 _transmit: extern fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) usize,
19 _receive: extern fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) usize,
20 wait_for_packet: Event,
21 mode: *SimpleNetworkMode,
22
23 /// Changes the state of a network interface from "stopped" to "started".
24 pub fn start(self: *const SimpleNetworkProtocol) usize {
25 return self._start(self);
26 }
27
28 /// Changes the state of a network interface from "started" to "stopped".
29 pub fn stop(self: *const SimpleNetworkProtocol) usize {
30 return self._stop(self);
31 }
32
33 /// Resets a network adapter and allocates the transmit and receive buffers required by the network interface.
34 pub fn initialize(self: *const SimpleNetworkProtocol, extra_rx_buffer_size: usize, extra_tx_buffer_size: usize) usize {
35 return self._initialize(self, extra_rx_buffer_size, extra_tx_buffer_size);
36 }
37
38 /// Resets a network adapter and reinitializes it with the parameters that were provided in the previous call to initialize().
39 pub fn reset(self: *const SimpleNetworkProtocol, extended_verification: bool) usize {
40 return self._reset(self, extended_verification);
41 }
42
43 /// Resets a network adapter and leaves it in a state that is safe for another driver to initialize.
44 pub fn shutdown(self: *const SimpleNetworkProtocol) usize {
45 return self._shutdown(self);
46 }
47
48 /// Manages the multicast receive filters of a network interface.
49 pub fn receiveFilters(self: *const SimpleNetworkProtocol, enable: SimpleNetworkReceiveFilter, disable: SimpleNetworkReceiveFilter, reset_mcast_filter: bool, mcast_filter_cnt: usize, mcast_filter: ?[*]const MacAddress) usize {
50 return self._receive_filters(self, enable, disable, reset_mcast_filter, mcast_filter_cnt, mcast_filter);
51 }
52
53 /// Modifies or resets the current station address, if supported.
54 pub fn stationAddress(self: *const SimpleNetworkProtocol, reset: bool, new: ?*const MacAddress) usize {
55 return self._station_address(self, reset, new);
56 }
57
58 /// Resets or collects the statistics on a network interface.
59 pub fn statistics(self: *const SimpleNetworkProtocol, reset_: bool, statistics_size: ?*usize, statistics_table: ?*NetworkStatistics) usize {
60 return self._statistics(self, reset_, statistics_size, statistics_table);
61 }
62
63 /// Converts a multicast IP address to a multicast HW MAC address.
64 pub fn mcastIpToMac(self: *const SimpleNetworkProtocol, ipv6: bool, ip: *const c_void, mac: *MacAddress) usize {
65 return self._mcast_ip_to_mac(self, ipv6, ip, mac);
66 }
67
68 /// Performs read and write operations on the NVRAM device attached to a network interface.
69 pub fn nvdata(self: *const SimpleNetworkProtocol, read_write: bool, offset: usize, buffer_size: usize, buffer: [*]u8) usize {
70 return self._nvdata(self, read_write, offset, buffer_size, buffer);
71 }
72
73 /// Reads the current interrupt status and recycled transmit buffer status from a network interface.
74 pub fn getStatus(self: *const SimpleNetworkProtocol, interrupt_status: *SimpleNetworkInterruptStatus, tx_buf: ?*?[*]u8) usize {
75 return self._get_status(self, interrupt_status, tx_buf);
76 }
77
78 /// Places a packet in the transmit queue of a network interface.
79 pub fn transmit(self: *const SimpleNetworkProtocol, header_size: usize, buffer_size: usize, buffer: [*]const u8, src_addr: ?*const MacAddress, dest_addr: ?*const MacAddress, protocol: ?*const u16) usize {
80 return self._transmit(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol);
81 }
82
83 /// Receives a packet from a network interface.
84 pub fn receive(self: *const SimpleNetworkProtocol, header_size: ?*usize, buffer_size: *usize, buffer: [*]u8, src_addr: ?*MacAddress, dest_addr: ?*MacAddress, protocol: ?*u16) usize {
85 return self._receive(self, header_size, buffer_size, buffer, src_addr, dest_addr, protocol);
86 }
87
88 pub const guid align(8) = Guid{
89 .time_low = 0xa19832b9,
90 .time_mid = 0xac25,
91 .time_high_and_version = 0x11d3,
92 .clock_seq_high_and_reserved = 0x9a,
93 .clock_seq_low = 0x2d,
94 .node = [_]u8{ 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d },
95 };
96};
97
98pub const MacAddress = [32]u8;
99
100pub const SimpleNetworkMode = extern struct {
101 state: SimpleNetworkState,
102 hw_address_size: u32,
103 media_header_size: u32,
104 max_packet_size: u32,
105 nvram_size: u32,
106 nvram_access_size: u32,
107 receive_filter_mask: SimpleNetworkReceiveFilter,
108 receive_filter_setting: SimpleNetworkReceiveFilter,
109 max_mcast_filter_count: u32,
110 mcast_filter_count: u32,
111 mcast_filter: [16]MacAddress,
112 current_address: MacAddress,
113 broadcast_address: MacAddress,
114 permanent_address: MacAddress,
115 if_type: u8,
116 mac_address_changeable: bool,
117 multiple_tx_supported: bool,
118 media_present_supported: bool,
119 media_present: bool,
120};
121
122pub const SimpleNetworkReceiveFilter = packed struct {
123 receive_unicast: bool,
124 receive_multicast: bool,
125 receive_broadcast: bool,
126 receive_promiscuous: bool,
127 receive_promiscuous_multicast: bool,
128 _pad: u27 = undefined,
129};
130
131pub const SimpleNetworkState = extern enum(u32) {
132 Stopped,
133 Started,
134 Initialized,
135};
136
137pub const NetworkStatistics = extern struct {
138 rx_total_frames: u64,
139 rx_good_frames: u64,
140 rx_undersize_frames: u64,
141 rx_oversize_frames: u64,
142 rx_dropped_frames: u64,
143 rx_unicast_frames: u64,
144 rx_broadcast_frames: u64,
145 rx_multicast_frames: u64,
146 rx_crc_error_frames: u64,
147 rx_total_bytes: u64,
148 tx_total_frames: u64,
149 tx_good_frames: u64,
150 tx_undersize_frames: u64,
151 tx_oversize_frames: u64,
152 tx_dropped_frames: u64,
153 tx_unicast_frames: u64,
154 tx_broadcast_frames: u64,
155 tx_multicast_frames: u64,
156 tx_crc_error_frames: u64,
157 tx_total_bytes: u64,
158 collisions: u64,
159 unsupported_protocol: u64,
160 rx_duplicated_frames: u64,
161 rx_decryptError_frames: u64,
162 tx_error_frames: u64,
163 tx_retry_frames: u64,
164};
165
166pub const SimpleNetworkInterruptStatus = packed struct {
167 receive_interrupt: bool,
168 transmit_interrupt: bool,
169 command_interrupt: bool,
170 software_interrupt: bool,
171 _pad: u28,
172};
lib/std/os/uefi/protocols/udp6_protocol.zig created+112
...@@ -0,0 +1,112 @@
1const uefi = @import("std").os.uefi;
2const Guid = uefi.Guid;
3const Event = uefi.Event;
4const Time = uefi.Time;
5const Ip6ModeData = uefi.protocols.Ip6ModeData;
6const Ip6Address = uefi.protocols.Ip6Address;
7const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
8const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
9
10pub const Udp6Protocol = extern struct {
11 _get_mode_data: extern fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) usize,
12 _configure: extern fn (*const Udp6Protocol, ?*const Udp6ConfigData) usize,
13 _groups: extern fn (*const Udp6Protocol, bool, ?*const Ip6Address) usize,
14 _transmit: extern fn (*const Udp6Protocol, *Udp6CompletionToken) usize,
15 _receive: extern fn (*const Udp6Protocol, *Udp6CompletionToken) usize,
16 _cancel: extern fn (*const Udp6Protocol, ?*Udp6CompletionToken) usize,
17 _poll: extern fn (*const Udp6Protocol) usize,
18
19 pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) usize {
20 return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data);
21 }
22
23 pub fn configure(self: *const Udp6Protocol, udp6_config_data: ?*const Udp6ConfigData) usize {
24 return self._configure(self, udp6_config_data);
25 }
26
27 pub fn groups(self: *const Udp6Protocol, join_flag: bool, multicast_address: ?*const Ip6Address) usize {
28 return self._groups(self, join_flag, multicast_address);
29 }
30
31 pub fn transmit(self: *const Udp6Protocol, token: *Udp6CompletionToken) usize {
32 return self._transmit(self, token);
33 }
34
35 pub fn receive(self: *const Udp6Protocol, token: *Udp6CompletionToken) usize {
36 return self._receive(self, token);
37 }
38
39 pub fn cancel(self: *const Udp6Protocol, token: ?*Udp6CompletionToken) usize {
40 return self._cancel(self, token);
41 }
42
43 pub fn poll(self: *const Udp6Protocol) usize {
44 return self._poll(self);
45 }
46
47 pub const guid align(8) = uefi.Guid{
48 .time_low = 0x4f948815,
49 .time_mid = 0xb4b9,
50 .time_high_and_version = 0x43cb,
51 .clock_seq_high_and_reserved = 0x8a,
52 .clock_seq_low = 0x33,
53 .node = [_]u8{ 0x90, 0xe0, 0x60, 0xb3, 0x49, 0x55 },
54 };
55};
56
57pub const Udp6ConfigData = extern struct {
58 accept_promiscuous: bool,
59 accept_any_port: bool,
60 allow_duplicate_port: bool,
61 traffic_class: u8,
62 hop_limit: u8,
63 receive_timeout: u32,
64 transmit_timeout: u32,
65 station_address: Ip6Address,
66 station_port: u16,
67 remote_address: Ip6Address,
68 remote_port: u16,
69};
70
71pub const Udp6CompletionToken = extern struct {
72 event: Event,
73 status: usize,
74 packet: extern union {
75 RxData: *Udp6ReceiveData,
76 TxData: *Udp6TransmitData,
77 },
78};
79
80pub const Udp6ReceiveData = extern struct {
81 timestamp: Time,
82 recycle_signal: Event,
83 udp6_session: Udp6SessionData,
84 data_length: u32,
85 fragment_count: u32,
86
87 pub fn getFragments(self: *Udp6ReceiveData) []Udp6FragmentData {
88 return @ptrCast([*]Udp6FragmentData, @ptrCast([*]u8, self) + @sizeOf(Udp6ReceiveData))[0..self.fragment_count];
89 }
90};
91
92pub const Udp6TransmitData = extern struct {
93 udp6_session_data: ?*Udp6SessionData,
94 data_length: u32,
95 fragment_count: u32,
96
97 pub fn getFragments(self: *Udp6TransmitData) []Udp6FragmentData {
98 return @ptrCast([*]Udp6FragmentData, @ptrCast([*]u8, self) + @sizeOf(Udp6TransmitData))[0..self.fragment_count];
99 }
100};
101
102pub const Udp6SessionData = extern struct {
103 source_address: Ip6Address,
104 source_port: u16,
105 destination_address: Ip6Address,
106 destination_port: u16,
107};
108
109pub const Udp6FragmentData = extern struct {
110 fragment_length: u32,
111 fragment_buffer: [*]u8,
112};
lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig created+25
...@@ -0,0 +1,25 @@
1const uefi = @import("std").os.uefi;
2const Handle = uefi.Handle;
3const Guid = uefi.Guid;
4
5pub const Udp6ServiceBindingProtocol = extern struct {
6 _create_child: extern fn (*const Udp6ServiceBindingProtocol, *?Handle) usize,
7 _destroy_child: extern fn (*const Udp6ServiceBindingProtocol, Handle) usize,
8
9 pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) usize {
10 return self._create_child(self, handle);
11 }
12
13 pub fn destroyChild(self: *const Udp6ServiceBindingProtocol, handle: Handle) usize {
14 return self._destroy_child(self, handle);
15 }
16
17 pub const guid align(8) = Guid{
18 .time_low = 0x66ed4721,
19 .time_mid = 0x3c98,
20 .time_high_and_version = 0x4d3e,
21 .clock_seq_high_and_reserved = 0x81,
22 .clock_seq_low = 0xe3,
23 .node = [_]u8{ 0xd0, 0x3d, 0xd3, 0x9a, 0x72, 0x54 },
24 };
25};
lib/std/os/uefi/tables.zig+3
...@@ -1,8 +1,11 @@...@@ -1,8 +1,11 @@
1pub const BootServices = @import("tables/boot_services.zig").BootServices;1pub const BootServices = @import("tables/boot_services.zig").BootServices;
2pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;2pub const ConfigurationTable = @import("tables/configuration_table.zig").ConfigurationTable;
3pub const global_variable align(8) = @import("tables/runtime_services.zig").global_variable;3pub const global_variable align(8) = @import("tables/runtime_services.zig").global_variable;
4pub const LocateSearchType = @import("tables/boot_services.zig").LocateSearchType;
4pub const MemoryDescriptor = @import("tables/boot_services.zig").MemoryDescriptor;5pub const MemoryDescriptor = @import("tables/boot_services.zig").MemoryDescriptor;
5pub const MemoryType = @import("tables/boot_services.zig").MemoryType;6pub const MemoryType = @import("tables/boot_services.zig").MemoryType;
7pub const OpenProtocolAttributes = @import("tables/boot_services.zig").OpenProtocolAttributes;
8pub const ProtocolInformationEntry = @import("tables/boot_services.zig").ProtocolInformationEntry;
6pub const ResetType = @import("tables/runtime_services.zig").ResetType;9pub const ResetType = @import("tables/runtime_services.zig").ResetType;
7pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;10pub const RuntimeServices = @import("tables/runtime_services.zig").RuntimeServices;
8pub const SystemTable = @import("tables/system_table.zig").SystemTable;11pub const SystemTable = @import("tables/system_table.zig").SystemTable;
lib/std/os/uefi/tables/boot_services.zig+75-11
...@@ -3,6 +3,7 @@ const Event = uefi.Event;...@@ -3,6 +3,7 @@ const Event = uefi.Event;
3const Guid = uefi.Guid;3const Guid = uefi.Guid;
4const Handle = uefi.Handle;4const Handle = uefi.Handle;
5const TableHeader = uefi.tables.TableHeader;5const TableHeader = uefi.tables.TableHeader;
6const DevicePathProtocol = uefi.protocols.DevicePathProtocol;
67
7/// Boot services are services provided by the system's firmware until the operating system takes8/// Boot services are services provided by the system's firmware until the operating system takes
8/// over control over the hardware by calling exitBootServices.9/// over control over the hardware by calling exitBootServices.
...@@ -17,56 +18,96 @@ const TableHeader = uefi.tables.TableHeader;...@@ -17,56 +18,96 @@ const TableHeader = uefi.tables.TableHeader;
17/// As the boot_services table may grow with new UEFI versions, it is important to check hdr.header_size.18/// As the boot_services table may grow with new UEFI versions, it is important to check hdr.header_size.
18pub const BootServices = extern struct {19pub const BootServices = extern struct {
19 hdr: TableHeader,20 hdr: TableHeader,
21
20 raiseTpl: usize, // TODO22 raiseTpl: usize, // TODO
21 restoreTpl: usize, // TODO23 restoreTpl: usize, // TODO
22 allocatePages: usize, // TODO24 allocatePages: usize, // TODO
23 freePages: usize, // TODO25 freePages: usize, // TODO
26
24 /// Returns the current memory map.27 /// Returns the current memory map.
25 getMemoryMap: extern fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) usize,28 getMemoryMap: extern fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) usize,
29
26 /// Allocates pool memory.30 /// Allocates pool memory.
27 allocatePool: extern fn (MemoryType, usize, *align(8) [*]u8) usize,31 allocatePool: extern fn (MemoryType, usize, *align(8) [*]u8) usize,
28 freePool: usize, // TODO32
33 /// Returns pool memory to the system.
34 freePool: extern fn ([*]align(8) u8) usize,
35
29 /// Creates an event.36 /// Creates an event.
30 createEvent: extern fn (u32, usize, ?extern fn (Event, ?*const c_void) void, ?*const c_void, *Event) usize,37 createEvent: extern fn (u32, usize, ?extern fn (Event, ?*c_void) void, ?*const c_void, *Event) usize,
38
31 /// Sets the type of timer and the trigger time for a timer event.39 /// Sets the type of timer and the trigger time for a timer event.
32 setTimer: extern fn (Event, TimerDelay, u64) usize,40 setTimer: extern fn (Event, TimerDelay, u64) usize,
41
33 /// Stops execution until an event is signaled.42 /// Stops execution until an event is signaled.
34 waitForEvent: extern fn (usize, [*]const Event, *usize) usize,43 waitForEvent: extern fn (usize, [*]const Event, *usize) usize,
44
35 /// Signals an event.45 /// Signals an event.
36 signalEvent: extern fn (Event) usize,46 signalEvent: extern fn (Event) usize,
47
37 /// Closes an event.48 /// Closes an event.
38 closeEvent: extern fn (Event) usize,49 closeEvent: extern fn (Event) usize,
39 checkEvent: usize, // TODO50
51 /// Checks whether an event is in the signaled state.
52 checkEvent: extern fn (Event) usize,
53
40 installProtocolInterface: usize, // TODO54 installProtocolInterface: usize, // TODO
41 reinstallProtocolInterface: usize, // TODO55 reinstallProtocolInterface: usize, // TODO
42 uninstallProtocolInterface: usize, // TODO56 uninstallProtocolInterface: usize, // TODO
43 handleProtocol: usize, // TODO57
58 /// Queries a handle to determine if it supports a specified protocol.
59 handleProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void) usize,
60
44 reserved: *c_void,61 reserved: *c_void,
62
45 registerProtocolNotify: usize, // TODO63 registerProtocolNotify: usize, // TODO
46 locateHandle: usize, // TODO64 locateHandle: usize, // TODO
47 locateDevicePath: usize, // TODO65 locateDevicePath: usize, // TODO
48 installConfigurationTable: usize, // TODO66 installConfigurationTable: usize, // TODO
49 imageLoad: usize, // TODO67
50 imageStart: usize, // TODO68 /// Loads an EFI image into memory.
69 loadImage: extern fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) usize,
70
71 /// Transfers control to a loaded image's entry point.
72 startImage: extern fn (Handle, ?*usize, ?*[*]u16) usize,
73
51 /// Terminates a loaded EFI image and returns control to boot services.74 /// Terminates a loaded EFI image and returns control to boot services.
52 exit: extern fn (Handle, usize, usize, ?*const c_void) usize,75 exit: extern fn (Handle, usize, usize, ?*const c_void) usize,
53 imageUnload: usize, // TODO76
77 /// Unloads an image.
78 unloadImage: extern fn (Handle) usize,
79
54 /// Terminates all boot services.80 /// Terminates all boot services.
55 exitBootServices: extern fn (Handle, usize) usize,81 exitBootServices: extern fn (Handle, usize) usize,
82
56 getNextMonotonicCount: usize, // TODO83 getNextMonotonicCount: usize, // TODO
84
57 /// Induces a fine-grained stall.85 /// Induces a fine-grained stall.
58 stall: extern fn (usize) usize,86 stall: extern fn (usize) usize,
87
59 /// Sets the system's watchdog timer.88 /// Sets the system's watchdog timer.
60 setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) usize,89 setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) usize,
90
61 connectController: usize, // TODO91 connectController: usize, // TODO
62 disconnectController: usize, // TODO92 disconnectController: usize, // TODO
63 openProtocol: usize, // TODO93
64 closeProtocol: usize, // TODO94 /// Queries a handle to determine if it supports a specified protocol.
65 openProtocolInformation: usize, // TODO95 openProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) usize,
96
97 /// Closes a protocol on a handle that was opened using openProtocol().
98 closeProtocol: extern fn (Handle, *align(8) const Guid, Handle, ?Handle) usize,
99
100 /// Retrieves the list of agents that currently have a protocol interface opened.
101 openProtocolInformation: extern fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) usize,
102
66 protocolsPerHandle: usize, // TODO103 protocolsPerHandle: usize, // TODO
67 locateHandleBuffer: usize, // TODO104
105 /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.
106 locateHandleBuffer: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) usize,
107
68 /// Returns the first protocol instance that matches the given protocol.108 /// Returns the first protocol instance that matches the given protocol.
69 locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) usize,109 locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) usize,
110
70 installMultipleProtocolInterfaces: usize, // TODO111 installMultipleProtocolInterfaces: usize, // TODO
71 uninstallMultipleProtocolInterfaces: usize, // TODO112 uninstallMultipleProtocolInterfaces: usize, // TODO
72 calculateCrc32: usize, // TODO113 calculateCrc32: usize, // TODO
...@@ -138,3 +179,26 @@ pub const MemoryDescriptor = extern struct {...@@ -138,3 +179,26 @@ pub const MemoryDescriptor = extern struct {
138 memory_runtime: bool,179 memory_runtime: bool,
139 },180 },
140};181};
182
183pub const LocateSearchType = extern enum(u32) {
184 AllHandles,
185 ByRegisterNotify,
186 ByProtocol,
187};
188
189pub const OpenProtocolAttributes = packed struct {
190 by_handle_protocol: bool,
191 get_protocol: bool,
192 test_protocol: bool,
193 by_child_controller: bool,
194 by_driver: bool,
195 exclusive: bool,
196 _pad: u26,
197};
198
199pub const ProtocolInformationEntry = extern struct {
200 agent_handle: ?Handle,
201 controller_handle: ?Handle,
202 attributes: OpenProtocolAttributes,
203 open_count: u32,
204};
lib/std/os/uefi/tables/runtime_services.zig+8
...@@ -14,22 +14,30 @@ const TimeCapabilities = uefi.TimeCapabilities;...@@ -14,22 +14,30 @@ const TimeCapabilities = uefi.TimeCapabilities;
14/// Some functions may not be called while other functions are running.14/// Some functions may not be called while other functions are running.
15pub const RuntimeServices = extern struct {15pub const RuntimeServices = extern struct {
16 hdr: TableHeader,16 hdr: TableHeader,
17
17 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.18 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.
18 getTime: extern fn (*uefi.Time, ?*TimeCapabilities) usize,19 getTime: extern fn (*uefi.Time, ?*TimeCapabilities) usize,
20
19 setTime: usize, // TODO21 setTime: usize, // TODO
20 getWakeupTime: usize, // TODO22 getWakeupTime: usize, // TODO
21 setWakeupTime: usize, // TODO23 setWakeupTime: usize, // TODO
22 setVirtualAddressMap: usize, // TODO24 setVirtualAddressMap: usize, // TODO
23 convertPointer: usize, // TODO25 convertPointer: usize, // TODO
26
24 /// Returns the value of a variable.27 /// Returns the value of a variable.
25 getVariable: extern fn ([*]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) usize,28 getVariable: extern fn ([*]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) usize,
29
26 /// Enumerates the current variable names.30 /// Enumerates the current variable names.
27 getNextVariableName: extern fn (*usize, [*]u16, *align(8) Guid) usize,31 getNextVariableName: extern fn (*usize, [*]u16, *align(8) Guid) usize,
32
28 /// Sets the value of a variable.33 /// Sets the value of a variable.
29 setVariable: extern fn ([*]const u16, *align(8) const Guid, u32, usize, *c_void) usize,34 setVariable: extern fn ([*]const u16, *align(8) const Guid, u32, usize, *c_void) usize,
35
30 getNextHighMonotonicCount: usize, // TODO36 getNextHighMonotonicCount: usize, // TODO
37
31 /// Resets the entire platform.38 /// Resets the entire platform.
32 resetSystem: extern fn (ResetType, usize, usize, ?*const c_void) noreturn,39 resetSystem: extern fn (ResetType, usize, usize, ?*const c_void) noreturn,
40
33 updateCapsule: usize, // TODO41 updateCapsule: usize, // TODO
34 queryCapsuleCapabilities: usize, // TODO42 queryCapsuleCapabilities: usize, // TODO
35 queryVariableInfo: usize, // TODO43 queryVariableInfo: usize, // TODO
lib/std/os/uefi/tables/system_table.zig+1
...@@ -17,6 +17,7 @@ const TableHeader = uefi.tables.TableHeader;...@@ -17,6 +17,7 @@ const TableHeader = uefi.tables.TableHeader;
17/// hdr.crc32 must be recomputed.17/// hdr.crc32 must be recomputed.
18pub const SystemTable = extern struct {18pub const SystemTable = extern struct {
19 hdr: TableHeader,19 hdr: TableHeader,
20
20 /// A null-terminated string that identifies the vendor that produces the system firmware of the platform.21 /// A null-terminated string that identifies the vendor that produces the system firmware of the platform.
21 firmware_vendor: [*]u16,22 firmware_vendor: [*]u16,
22 firmware_revision: u32,23 firmware_revision: u32,
lib/std/os/windows.zig+129-3
...@@ -16,6 +16,7 @@ pub const kernel32 = @import("windows/kernel32.zig");...@@ -16,6 +16,7 @@ pub const kernel32 = @import("windows/kernel32.zig");
16pub const ntdll = @import("windows/ntdll.zig");16pub const ntdll = @import("windows/ntdll.zig");
17pub const ole32 = @import("windows/ole32.zig");17pub const ole32 = @import("windows/ole32.zig");
18pub const shell32 = @import("windows/shell32.zig");18pub const shell32 = @import("windows/shell32.zig");
19pub const ws2_32 = @import("windows/ws2_32.zig");
1920
20pub usingnamespace @import("windows/bits.zig");21pub usingnamespace @import("windows/bits.zig");
2122
...@@ -96,6 +97,42 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C...@@ -96,6 +97,42 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C
96 }97 }
97}98}
9899
100pub fn DeviceIoControl(
101 h: HANDLE,
102 ioControlCode: DWORD,
103 in: ?[]const u8,
104 out: ?[]u8,
105 overlapped: ?*OVERLAPPED,
106) !DWORD {
107 var bytes: DWORD = undefined;
108 if (kernel32.DeviceIoControl(
109 h,
110 ioControlCode,
111 if (in) |i| i.ptr else null,
112 if (in) |i| @intCast(u32, i.len) else 0,
113 if (out) |o| o.ptr else null,
114 if (out) |o| @intCast(u32, o.len) else 0,
115 &bytes,
116 overlapped,
117 ) == 0) {
118 switch (kernel32.GetLastError()) {
119 else => |err| return unexpectedError(err),
120 }
121 }
122 return bytes;
123}
124
125pub fn GetOverlappedResult(h: HANDLE, overlapped: *OVERLAPPED, wait: bool) !DWORD {
126 var bytes: DWORD = undefined;
127 if (kernel32.GetOverlappedResult(h, overlapped, &bytes, wait) == 0) {
128 switch (kernel32.GetLastError()) {
129 ERROR_IO_INCOMPLETE => if (!wait) return error.WouldBlock else unreachable,
130 else => |err| return unexpectedError(err),
131 }
132 }
133 return bytes;
134}
135
99pub const SetHandleInformationError = error{Unexpected};136pub const SetHandleInformationError = error{Unexpected};
100137
101pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void {138pub fn SetHandleInformation(h: HANDLE, mask: DWORD, flags: DWORD) SetHandleInformationError!void {
...@@ -262,7 +299,7 @@ pub const ReadFileError = error{Unexpected};...@@ -262,7 +299,7 @@ pub const ReadFileError = error{Unexpected};
262pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize {299pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize {
263 var index: usize = 0;300 var index: usize = 0;
264 while (index < buffer.len) {301 while (index < buffer.len) {
265 const want_read_count = @intCast(DWORD, math.min(DWORD(maxInt(DWORD)), buffer.len - index));302 const want_read_count = @intCast(DWORD, math.min(@as(DWORD, maxInt(DWORD)), buffer.len - index));
266 var amt_read: DWORD = undefined;303 var amt_read: DWORD = undefined;
267 if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) {304 if (kernel32.ReadFile(in_hFile, buffer.ptr + index, want_read_count, &amt_read, null) == 0) {
268 switch (kernel32.GetLastError()) {305 switch (kernel32.GetLastError()) {
...@@ -571,6 +608,74 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD...@@ -571,6 +608,74 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD
571 return rc;608 return rc;
572}609}
573610
611pub fn WSAStartup(majorVersion: u8, minorVersion: u8) !ws2_32.WSADATA {
612 var wsadata: ws2_32.WSADATA = undefined;
613 return switch (ws2_32.WSAStartup((@as(WORD, minorVersion) << 8) | majorVersion, &wsadata)) {
614 0 => wsadata,
615 else => |err| unexpectedWSAError(err),
616 };
617}
618
619pub fn WSACleanup() !void {
620 return switch (ws2_32.WSACleanup()) {
621 0 => {},
622 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
623 else => |err| return unexpectedWSAError(err),
624 },
625 else => unreachable,
626 };
627}
628
629pub fn WSASocketW(
630 af: i32,
631 socket_type: i32,
632 protocol: i32,
633 protocolInfo: ?*ws2_32.WSAPROTOCOL_INFOW,
634 g: ws2_32.GROUP,
635 dwFlags: DWORD,
636) !ws2_32.SOCKET {
637 const rc = ws2_32.WSASocketW(af, socket_type, protocol, protocolInfo, g, dwFlags);
638 if (rc == ws2_32.INVALID_SOCKET) {
639 switch (ws2_32.WSAGetLastError()) {
640 ws2_32.WSAEAFNOSUPPORT => return error.AddressFamilyNotSupported,
641 ws2_32.WSAEMFILE => return error.ProcessFdQuotaExceeded,
642 ws2_32.WSAENOBUFS => return error.SystemResources,
643 ws2_32.WSAEPROTONOSUPPORT => return error.ProtocolNotSupported,
644 else => |err| return unexpectedWSAError(err),
645 }
646 }
647 return rc;
648}
649
650pub fn WSAIoctl(
651 s: ws2_32.SOCKET,
652 dwIoControlCode: DWORD,
653 inBuffer: ?[]const u8,
654 outBuffer: []u8,
655 overlapped: ?*ws2_32.WSAOVERLAPPED,
656 completionRoutine: ?*ws2_32.WSAOVERLAPPED_COMPLETION_ROUTINE,
657) !DWORD {
658 var bytes: DWORD = undefined;
659 switch (ws2_32.WSAIoctl(
660 s,
661 dwIoControlCode,
662 if (inBuffer) |i| i.ptr else null,
663 if (inBuffer) |i| @intCast(DWORD, i.len) else 0,
664 outBuffer.ptr,
665 @intCast(DWORD, outBuffer.len),
666 &bytes,
667 overlapped,
668 completionRoutine,
669 )) {
670 0 => {},
671 ws2_32.SOCKET_ERROR => switch (ws2_32.WSAGetLastError()) {
672 else => |err| return unexpectedWSAError(err),
673 },
674 else => unreachable,
675 }
676 return bytes;
677}
678
574const GetModuleFileNameError = error{Unexpected};679const GetModuleFileNameError = error{Unexpected};
575680
576pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 {681pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 {
...@@ -801,7 +906,7 @@ pub fn toSysTime(ns: i64) i64 {...@@ -801,7 +906,7 @@ pub fn toSysTime(ns: i64) i64 {
801}906}
802907
803pub fn fileTimeToNanoSeconds(ft: FILETIME) i64 {908pub fn fileTimeToNanoSeconds(ft: FILETIME) i64 {
804 const hns = @bitCast(i64, (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime);909 const hns = @bitCast(i64, (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime);
805 return fromSysTime(hns);910 return fromSysTime(hns);
806}911}
807912
...@@ -822,6 +927,24 @@ pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE + 1]u16 {...@@ -822,6 +927,24 @@ pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE + 1]u16 {
822 return sliceToPrefixedSuffixedFileW(s, [_]u16{0});927 return sliceToPrefixedSuffixedFileW(s, [_]u16{0});
823}928}
824929
930/// Assumes an absolute path.
931pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE + 1]u16 {
932 // TODO https://github.com/ziglang/zig/issues/2765
933 var result: [PATH_MAX_WIDE + 1]u16 = undefined;
934
935 const start_index = if (mem.startsWith(u16, s, [_]u16{'\\', '?'})) 0 else blk: {
936 const prefix = [_]u16{ '\\', '?', '?', '\\' };
937 mem.copy(u16, result[0..], prefix);
938 break :blk prefix.len;
939 };
940 const end_index = start_index + s.len;
941 if (end_index + 1 > result.len) return error.NameTooLong;
942 mem.copy(u16, result[start_index..], s);
943 result[end_index] = 0;
944 return result;
945
946}
947
825pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len]u16 {948pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len]u16 {
826 // TODO https://github.com/ziglang/zig/issues/2765949 // TODO https://github.com/ziglang/zig/issues/2765
827 var result: [PATH_MAX_WIDE + suffix.len]u16 = undefined;950 var result: [PATH_MAX_WIDE + suffix.len]u16 = undefined;
...@@ -843,7 +966,6 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)...@@ -843,7 +966,6 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
843 break :blk prefix.len;966 break :blk prefix.len;
844 };967 };
845 const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);968 const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);
846 assert(end_index <= result.len);
847 if (end_index + suffix.len > result.len) return error.NameTooLong;969 if (end_index + suffix.len > result.len) return error.NameTooLong;
848 mem.copy(u16, result[end_index..], suffix);970 mem.copy(u16, result[end_index..], suffix);
849 return result;971 return result;
...@@ -868,6 +990,10 @@ pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {...@@ -868,6 +990,10 @@ pub fn unexpectedError(err: DWORD) std.os.UnexpectedError {
868 return error.Unexpected;990 return error.Unexpected;
869}991}
870992
993pub fn unexpectedWSAError(err: c_int) std.os.UnexpectedError {
994 return unexpectedError(@intCast(DWORD, err));
995}
996
871/// Call this when you made a windows NtDll call997/// Call this when you made a windows NtDll call
872/// and you get an unexpected status.998/// and you get an unexpected status.
873pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {999pub fn unexpectedStatus(status: NTSTATUS) std.os.UnexpectedError {
lib/std/os/windows/bits.zig+119-12
...@@ -67,9 +67,116 @@ pub const va_list = *@OpaqueType();...@@ -67,9 +67,116 @@ pub const va_list = *@OpaqueType();
67pub const TRUE = 1;67pub const TRUE = 1;
68pub const FALSE = 0;68pub const FALSE = 0;
6969
70pub const DEVICE_TYPE = ULONG;
71pub const FILE_DEVICE_BEEP: DEVICE_TYPE = 0x0001;
72pub const FILE_DEVICE_CD_ROM: DEVICE_TYPE = 0x0002;
73pub const FILE_DEVICE_CD_ROM_FILE_SYSTEM: DEVICE_TYPE = 0x0003;
74pub const FILE_DEVICE_CONTROLLER: DEVICE_TYPE = 0x0004;
75pub const FILE_DEVICE_DATALINK: DEVICE_TYPE = 0x0005;
76pub const FILE_DEVICE_DFS: DEVICE_TYPE = 0x0006;
77pub const FILE_DEVICE_DISK: DEVICE_TYPE = 0x0007;
78pub const FILE_DEVICE_DISK_FILE_SYSTEM: DEVICE_TYPE = 0x0008;
79pub const FILE_DEVICE_FILE_SYSTEM: DEVICE_TYPE = 0x0009;
80pub const FILE_DEVICE_INPORT_PORT: DEVICE_TYPE = 0x000a;
81pub const FILE_DEVICE_KEYBOARD: DEVICE_TYPE = 0x000b;
82pub const FILE_DEVICE_MAILSLOT: DEVICE_TYPE = 0x000c;
83pub const FILE_DEVICE_MIDI_IN: DEVICE_TYPE = 0x000d;
84pub const FILE_DEVICE_MIDI_OUT: DEVICE_TYPE = 0x000e;
85pub const FILE_DEVICE_MOUSE: DEVICE_TYPE = 0x000f;
86pub const FILE_DEVICE_MULTI_UNC_PROVIDER: DEVICE_TYPE = 0x0010;
87pub const FILE_DEVICE_NAMED_PIPE: DEVICE_TYPE = 0x0011;
88pub const FILE_DEVICE_NETWORK: DEVICE_TYPE = 0x0012;
89pub const FILE_DEVICE_NETWORK_BROWSER: DEVICE_TYPE = 0x0013;
90pub const FILE_DEVICE_NETWORK_FILE_SYSTEM: DEVICE_TYPE = 0x0014;
91pub const FILE_DEVICE_NULL: DEVICE_TYPE = 0x0015;
92pub const FILE_DEVICE_PARALLEL_PORT: DEVICE_TYPE = 0x0016;
93pub const FILE_DEVICE_PHYSICAL_NETCARD: DEVICE_TYPE = 0x0017;
94pub const FILE_DEVICE_PRINTER: DEVICE_TYPE = 0x0018;
95pub const FILE_DEVICE_SCANNER: DEVICE_TYPE = 0x0019;
96pub const FILE_DEVICE_SERIAL_MOUSE_PORT: DEVICE_TYPE = 0x001a;
97pub const FILE_DEVICE_SERIAL_PORT: DEVICE_TYPE = 0x001b;
98pub const FILE_DEVICE_SCREEN: DEVICE_TYPE = 0x001c;
99pub const FILE_DEVICE_SOUND: DEVICE_TYPE = 0x001d;
100pub const FILE_DEVICE_STREAMS: DEVICE_TYPE = 0x001e;
101pub const FILE_DEVICE_TAPE: DEVICE_TYPE = 0x001f;
102pub const FILE_DEVICE_TAPE_FILE_SYSTEM: DEVICE_TYPE = 0x0020;
103pub const FILE_DEVICE_TRANSPORT: DEVICE_TYPE = 0x0021;
104pub const FILE_DEVICE_UNKNOWN: DEVICE_TYPE = 0x0022;
105pub const FILE_DEVICE_VIDEO: DEVICE_TYPE = 0x0023;
106pub const FILE_DEVICE_VIRTUAL_DISK: DEVICE_TYPE = 0x0024;
107pub const FILE_DEVICE_WAVE_IN: DEVICE_TYPE = 0x0025;
108pub const FILE_DEVICE_WAVE_OUT: DEVICE_TYPE = 0x0026;
109pub const FILE_DEVICE_8042_PORT: DEVICE_TYPE = 0x0027;
110pub const FILE_DEVICE_NETWORK_REDIRECTOR: DEVICE_TYPE = 0x0028;
111pub const FILE_DEVICE_BATTERY: DEVICE_TYPE = 0x0029;
112pub const FILE_DEVICE_BUS_EXTENDER: DEVICE_TYPE = 0x002a;
113pub const FILE_DEVICE_MODEM: DEVICE_TYPE = 0x002b;
114pub const FILE_DEVICE_VDM: DEVICE_TYPE = 0x002c;
115pub const FILE_DEVICE_MASS_STORAGE: DEVICE_TYPE = 0x002d;
116pub const FILE_DEVICE_SMB: DEVICE_TYPE = 0x002e;
117pub const FILE_DEVICE_KS: DEVICE_TYPE = 0x002f;
118pub const FILE_DEVICE_CHANGER: DEVICE_TYPE = 0x0030;
119pub const FILE_DEVICE_SMARTCARD: DEVICE_TYPE = 0x0031;
120pub const FILE_DEVICE_ACPI: DEVICE_TYPE = 0x0032;
121pub const FILE_DEVICE_DVD: DEVICE_TYPE = 0x0033;
122pub const FILE_DEVICE_FULLSCREEN_VIDEO: DEVICE_TYPE = 0x0034;
123pub const FILE_DEVICE_DFS_FILE_SYSTEM: DEVICE_TYPE = 0x0035;
124pub const FILE_DEVICE_DFS_VOLUME: DEVICE_TYPE = 0x0036;
125pub const FILE_DEVICE_SERENUM: DEVICE_TYPE = 0x0037;
126pub const FILE_DEVICE_TERMSRV: DEVICE_TYPE = 0x0038;
127pub const FILE_DEVICE_KSEC: DEVICE_TYPE = 0x0039;
128pub const FILE_DEVICE_FIPS: DEVICE_TYPE = 0x003a;
129pub const FILE_DEVICE_INFINIBAND: DEVICE_TYPE = 0x003b;
130// TODO: missing values?
131pub const FILE_DEVICE_VMBUS: DEVICE_TYPE = 0x003e;
132pub const FILE_DEVICE_CRYPT_PROVIDER: DEVICE_TYPE = 0x003f;
133pub const FILE_DEVICE_WPD: DEVICE_TYPE = 0x0040;
134pub const FILE_DEVICE_BLUETOOTH: DEVICE_TYPE = 0x0041;
135pub const FILE_DEVICE_MT_COMPOSITE: DEVICE_TYPE = 0x0042;
136pub const FILE_DEVICE_MT_TRANSPORT: DEVICE_TYPE = 0x0043;
137pub const FILE_DEVICE_BIOMETRIC: DEVICE_TYPE = 0x0044;
138pub const FILE_DEVICE_PMI: DEVICE_TYPE = 0x0045;
139pub const FILE_DEVICE_EHSTOR: DEVICE_TYPE = 0x0046;
140pub const FILE_DEVICE_DEVAPI: DEVICE_TYPE = 0x0047;
141pub const FILE_DEVICE_GPIO: DEVICE_TYPE = 0x0048;
142pub const FILE_DEVICE_USBEX: DEVICE_TYPE = 0x0049;
143pub const FILE_DEVICE_CONSOLE: DEVICE_TYPE = 0x0050;
144pub const FILE_DEVICE_NFP: DEVICE_TYPE = 0x0051;
145pub const FILE_DEVICE_SYSENV: DEVICE_TYPE = 0x0052;
146pub const FILE_DEVICE_VIRTUAL_BLOCK: DEVICE_TYPE = 0x0053;
147pub const FILE_DEVICE_POINT_OF_SERVICE: DEVICE_TYPE = 0x0054;
148pub const FILE_DEVICE_STORAGE_REPLICATION: DEVICE_TYPE = 0x0055;
149pub const FILE_DEVICE_TRUST_ENV: DEVICE_TYPE = 0x0056;
150pub const FILE_DEVICE_UCM: DEVICE_TYPE = 0x0057;
151pub const FILE_DEVICE_UCMTCPCI: DEVICE_TYPE = 0x0058;
152pub const FILE_DEVICE_PERSISTENT_MEMORY: DEVICE_TYPE = 0x0059;
153pub const FILE_DEVICE_NVDIMM: DEVICE_TYPE = 0x005a;
154pub const FILE_DEVICE_HOLOGRAPHIC: DEVICE_TYPE = 0x005b;
155pub const FILE_DEVICE_SDFXHCI: DEVICE_TYPE = 0x005c;
156
157/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/buffer-descriptions-for-i-o-control-codes
158pub const TransferType = enum(u2) {
159 METHOD_BUFFERED = 0,
160 METHOD_IN_DIRECT = 1,
161 METHOD_OUT_DIRECT = 2,
162 METHOD_NEITHER = 3,
163};
164
165pub const FILE_ANY_ACCESS = 0;
166pub const FILE_READ_ACCESS = 1;
167pub const FILE_WRITE_ACCESS = 2;
168
169/// https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-i-o-control-codes
170pub fn CTL_CODE(deviceType: u16, function: u12, method: TransferType, access: u2) DWORD {
171 return (@as(DWORD, deviceType) << 16) |
172 (@as(DWORD, access) << 14) |
173 (@as(DWORD, function) << 2) |
174 @enumToInt(method);
175}
176
70pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));177pub const INVALID_HANDLE_VALUE = @intToPtr(HANDLE, maxInt(usize));
71178
72pub const INVALID_FILE_ATTRIBUTES = DWORD(maxInt(DWORD));179pub const INVALID_FILE_ATTRIBUTES = @as(DWORD, maxInt(DWORD));
73180
74pub const FILE_ALL_INFORMATION = extern struct {181pub const FILE_ALL_INFORMATION = extern struct {
75 BasicInformation: FILE_BASIC_INFORMATION,182 BasicInformation: FILE_BASIC_INFORMATION,
...@@ -571,16 +678,16 @@ pub const KF_FLAG_SIMPLE_IDLIST = 256;...@@ -571,16 +678,16 @@ pub const KF_FLAG_SIMPLE_IDLIST = 256;
571pub const KF_FLAG_ALIAS_ONLY = -2147483648;678pub const KF_FLAG_ALIAS_ONLY = -2147483648;
572679
573pub const S_OK = 0;680pub const S_OK = 0;
574pub const E_NOTIMPL = @bitCast(c_long, c_ulong(0x80004001));681pub const E_NOTIMPL = @bitCast(c_long, @as(c_ulong, 0x80004001));
575pub const E_NOINTERFACE = @bitCast(c_long, c_ulong(0x80004002));682pub const E_NOINTERFACE = @bitCast(c_long, @as(c_ulong, 0x80004002));
576pub const E_POINTER = @bitCast(c_long, c_ulong(0x80004003));683pub const E_POINTER = @bitCast(c_long, @as(c_ulong, 0x80004003));
577pub const E_ABORT = @bitCast(c_long, c_ulong(0x80004004));684pub const E_ABORT = @bitCast(c_long, @as(c_ulong, 0x80004004));
578pub const E_FAIL = @bitCast(c_long, c_ulong(0x80004005));685pub const E_FAIL = @bitCast(c_long, @as(c_ulong, 0x80004005));
579pub const E_UNEXPECTED = @bitCast(c_long, c_ulong(0x8000FFFF));686pub const E_UNEXPECTED = @bitCast(c_long, @as(c_ulong, 0x8000FFFF));
580pub const E_ACCESSDENIED = @bitCast(c_long, c_ulong(0x80070005));687pub const E_ACCESSDENIED = @bitCast(c_long, @as(c_ulong, 0x80070005));
581pub const E_HANDLE = @bitCast(c_long, c_ulong(0x80070006));688pub const E_HANDLE = @bitCast(c_long, @as(c_ulong, 0x80070006));
582pub const E_OUTOFMEMORY = @bitCast(c_long, c_ulong(0x8007000E));689pub const E_OUTOFMEMORY = @bitCast(c_long, @as(c_ulong, 0x8007000E));
583pub const E_INVALIDARG = @bitCast(c_long, c_ulong(0x80070057));690pub const E_INVALIDARG = @bitCast(c_long, @as(c_ulong, 0x80070057));
584691
585pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;692pub const FILE_FLAG_BACKUP_SEMANTICS = 0x02000000;
586pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;693pub const FILE_FLAG_DELETE_ON_CLOSE = 0x04000000;
...@@ -873,4 +980,4 @@ pub const CURDIR = extern struct {...@@ -873,4 +980,4 @@ pub const CURDIR = extern struct {
873 Handle: HANDLE,980 Handle: HANDLE,
874};981};
875982
876pub const DUPLICATE_SAME_ACCESS = 2;
\ No newline at end of file
983pub const DUPLICATE_SAME_ACCESS = 2;
lib/std/os/windows/kernel32.zig+13
...@@ -45,6 +45,17 @@ pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, Ex...@@ -45,6 +45,17 @@ pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, Ex
4545
46pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;46pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;
4747
48pub extern "kernel32" stdcallcc fn DeviceIoControl(
49 h: HANDLE,
50 dwIoControlCode: DWORD,
51 lpInBuffer: ?*const c_void,
52 nInBufferSize: DWORD,
53 lpOutBuffer: ?LPVOID,
54 nOutBufferSize: DWORD,
55 lpBytesReturned: LPDWORD,
56 lpOverlapped: ?*OVERLAPPED,
57) BOOL;
58
48pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL;59pub extern "kernel32" stdcallcc fn DeleteFileW(lpFileName: [*]const u16) BOOL;
4960
50pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL;61pub extern "kernel32" stdcallcc fn DuplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: *HANDLE, dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwOptions: DWORD) BOOL;
...@@ -184,6 +195,8 @@ pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask:...@@ -184,6 +195,8 @@ pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask:
184195
185pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;196pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
186197
198pub extern "kernel32" stdcallcc fn SwitchToThread() BOOL;
199
187pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;200pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
188201
189pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD;202pub extern "kernel32" stdcallcc fn TlsAlloc() DWORD;
lib/std/os/windows/ntdll.zig+30
...@@ -21,6 +21,18 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(...@@ -21,6 +21,18 @@ pub extern "NtDll" stdcallcc fn NtCreateFile(
21 EaBuffer: ?*c_void,21 EaBuffer: ?*c_void,
22 EaLength: ULONG,22 EaLength: ULONG,
23) NTSTATUS;23) NTSTATUS;
24pub extern "NtDll" stdcallcc fn NtDeviceIoControlFile(
25 FileHandle: HANDLE,
26 Event: ?HANDLE,
27 ApcRoutine: ?*IO_APC_ROUTINE,
28 ApcContext: usize,
29 IoStatusBlock: *IO_STATUS_BLOCK,
30 IoControlCode: ULONG,
31 InputBuffer: ?*const c_void,
32 InputBufferLength: ULONG,
33 OutputBuffer: ?PVOID,
34 OutputBufferLength: ULONG,
35) NTSTATUS;
24pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS;36pub extern "NtDll" stdcallcc fn NtClose(Handle: HANDLE) NTSTATUS;
25pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U(37pub extern "NtDll" stdcallcc fn RtlDosPathNameToNtPathName_U(
26 DosPathName: [*]const u16,38 DosPathName: [*]const u16,
...@@ -43,3 +55,21 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(...@@ -43,3 +55,21 @@ pub extern "NtDll" stdcallcc fn NtQueryDirectoryFile(
43 FileName: ?*UNICODE_STRING,55 FileName: ?*UNICODE_STRING,
44 RestartScan: BOOLEAN,56 RestartScan: BOOLEAN,
45) NTSTATUS;57) NTSTATUS;
58pub extern "NtDll" stdcallcc fn NtCreateKeyedEvent(
59 KeyedEventHandle: *HANDLE,
60 DesiredAccess: ACCESS_MASK,
61 ObjectAttributes: ?PVOID,
62 Flags: ULONG,
63) NTSTATUS;
64pub extern "NtDll" stdcallcc fn NtReleaseKeyedEvent(
65 EventHandle: HANDLE,
66 Key: *const c_void,
67 Alertable: BOOLEAN,
68 Timeout: ?*LARGE_INTEGER,
69) NTSTATUS;
70pub extern "NtDll" stdcallcc fn NtWaitForKeyedEvent(
71 EventHandle: HANDLE,
72 Key: *const c_void,
73 Alertable: BOOLEAN,
74 Timeout: ?*LARGE_INTEGER,
75) NTSTATUS;
lib/std/os/windows/status.zig+1652-2
...@@ -1,13 +1,1663 @@...@@ -1,13 +1,1663 @@
1/// The operation completed successfully.1/// The operation completed successfully.
2pub const SUCCESS = 0x00000000;2pub const SUCCESS = 0x00000000;
33
4/// The data was too large to fit into the specified buffer.4pub const WAIT_0 = 0x00000000;
5pub const WAIT_1 = 0x00000001;
6pub const WAIT_2 = 0x00000002;
7pub const WAIT_3 = 0x00000003;
8pub const WAIT_63 = 0x0000003F;
9pub const ABANDONED = 0x00000080;
10pub const ABANDONED_WAIT_0 = 0x00000080;
11pub const ABANDONED_WAIT_63 = 0x000000BF;
12pub const USER_APC = 0x000000C0;
13pub const ALERTED = 0x00000101;
14pub const TIMEOUT = 0x00000102;
15pub const PENDING = 0x00000103;
16pub const REPARSE = 0x00000104;
17pub const MORE_ENTRIES = 0x00000105;
18pub const NOT_ALL_ASSIGNED = 0x00000106;
19pub const SOME_NOT_MAPPED = 0x00000107;
20pub const OPLOCK_BREAK_IN_PROGRESS = 0x00000108;
21pub const VOLUME_MOUNTED = 0x00000109;
22pub const RXACT_COMMITTED = 0x0000010A;
23pub const NOTIFY_CLEANUP = 0x0000010B;
24pub const NOTIFY_ENUM_DIR = 0x0000010C;
25pub const NO_QUOTAS_FOR_ACCOUNT = 0x0000010D;
26pub const PRIMARY_TRANSPORT_CONNECT_FAILED = 0x0000010E;
27pub const PAGE_FAULT_TRANSITION = 0x00000110;
28pub const PAGE_FAULT_DEMAND_ZERO = 0x00000111;
29pub const PAGE_FAULT_COPY_ON_WRITE = 0x00000112;
30pub const PAGE_FAULT_GUARD_PAGE = 0x00000113;
31pub const PAGE_FAULT_PAGING_FILE = 0x00000114;
32pub const CACHE_PAGE_LOCKED = 0x00000115;
33pub const CRASH_DUMP = 0x00000116;
34pub const BUFFER_ALL_ZEROS = 0x00000117;
35pub const REPARSE_OBJECT = 0x00000118;
36pub const RESOURCE_REQUIREMENTS_CHANGED = 0x00000119;
37pub const TRANSLATION_COMPLETE = 0x00000120;
38pub const DS_MEMBERSHIP_EVALUATED_LOCALLY = 0x00000121;
39pub const NOTHING_TO_TERMINATE = 0x00000122;
40pub const PROCESS_NOT_IN_JOB = 0x00000123;
41pub const PROCESS_IN_JOB = 0x00000124;
42pub const VOLSNAP_HIBERNATE_READY = 0x00000125;
43pub const FSFILTER_OP_COMPLETED_SUCCESSFULLY = 0x00000126;
44pub const INTERRUPT_VECTOR_ALREADY_CONNECTED = 0x00000127;
45pub const INTERRUPT_STILL_CONNECTED = 0x00000128;
46pub const PROCESS_CLONED = 0x00000129;
47pub const FILE_LOCKED_WITH_ONLY_READERS = 0x0000012A;
48pub const FILE_LOCKED_WITH_WRITERS = 0x0000012B;
49pub const RESOURCEMANAGER_READ_ONLY = 0x00000202;
50pub const WAIT_FOR_OPLOCK = 0x00000367;
51pub const FLT_IO_COMPLETE = 0x001C0001;
52pub const FILE_NOT_AVAILABLE = 0xC0000467;
53pub const OBJECT_NAME_EXISTS = 0x40000000;
54pub const THREAD_WAS_SUSPENDED = 0x40000001;
55pub const WORKING_SET_LIMIT_RANGE = 0x40000002;
56pub const IMAGE_NOT_AT_BASE = 0x40000003;
57pub const RXACT_STATE_CREATED = 0x40000004;
58pub const SEGMENT_NOTIFICATION = 0x40000005;
59pub const LOCAL_USER_SESSION_KEY = 0x40000006;
60pub const BAD_CURRENT_DIRECTORY = 0x40000007;
61pub const SERIAL_MORE_WRITES = 0x40000008;
62pub const REGISTRY_RECOVERED = 0x40000009;
63pub const FT_READ_RECOVERY_FROM_BACKUP = 0x4000000A;
64pub const FT_WRITE_RECOVERY = 0x4000000B;
65pub const SERIAL_COUNTER_TIMEOUT = 0x4000000C;
66pub const NULL_LM_PASSWORD = 0x4000000D;
67pub const IMAGE_MACHINE_TYPE_MISMATCH = 0x4000000E;
68pub const RECEIVE_PARTIAL = 0x4000000F;
69pub const RECEIVE_EXPEDITED = 0x40000010;
70pub const RECEIVE_PARTIAL_EXPEDITED = 0x40000011;
71pub const EVENT_DONE = 0x40000012;
72pub const EVENT_PENDING = 0x40000013;
73pub const CHECKING_FILE_SYSTEM = 0x40000014;
74pub const FATAL_APP_EXIT = 0x40000015;
75pub const PREDEFINED_HANDLE = 0x40000016;
76pub const WAS_UNLOCKED = 0x40000017;
77pub const SERVICE_NOTIFICATION = 0x40000018;
78pub const WAS_LOCKED = 0x40000019;
79pub const LOG_HARD_ERROR = 0x4000001A;
80pub const ALREADY_WIN32 = 0x4000001B;
81pub const WX86_UNSIMULATE = 0x4000001C;
82pub const WX86_CONTINUE = 0x4000001D;
83pub const WX86_SINGLE_STEP = 0x4000001E;
84pub const WX86_BREAKPOINT = 0x4000001F;
85pub const WX86_EXCEPTION_CONTINUE = 0x40000020;
86pub const WX86_EXCEPTION_LASTCHANCE = 0x40000021;
87pub const WX86_EXCEPTION_CHAIN = 0x40000022;
88pub const IMAGE_MACHINE_TYPE_MISMATCH_EXE = 0x40000023;
89pub const NO_YIELD_PERFORMED = 0x40000024;
90pub const TIMER_RESUME_IGNORED = 0x40000025;
91pub const ARBITRATION_UNHANDLED = 0x40000026;
92pub const CARDBUS_NOT_SUPPORTED = 0x40000027;
93pub const WX86_CREATEWX86TIB = 0x40000028;
94pub const MP_PROCESSOR_MISMATCH = 0x40000029;
95pub const HIBERNATED = 0x4000002A;
96pub const RESUME_HIBERNATION = 0x4000002B;
97pub const FIRMWARE_UPDATED = 0x4000002C;
98pub const DRIVERS_LEAKING_LOCKED_PAGES = 0x4000002D;
99pub const MESSAGE_RETRIEVED = 0x4000002E;
100pub const SYSTEM_POWERSTATE_TRANSITION = 0x4000002F;
101pub const ALPC_CHECK_COMPLETION_LIST = 0x40000030;
102pub const SYSTEM_POWERSTATE_COMPLEX_TRANSITION = 0x40000031;
103pub const ACCESS_AUDIT_BY_POLICY = 0x40000032;
104pub const ABANDON_HIBERFILE = 0x40000033;
105pub const BIZRULES_NOT_ENABLED = 0x40000034;
106pub const WAKE_SYSTEM = 0x40000294;
107pub const DS_SHUTTING_DOWN = 0x40000370;
108pub const CTX_CDM_CONNECT = 0x400A0004;
109pub const CTX_CDM_DISCONNECT = 0x400A0005;
110pub const SXS_RELEASE_ACTIVATION_CONTEXT = 0x4015000D;
111pub const RECOVERY_NOT_NEEDED = 0x40190034;
112pub const RM_ALREADY_STARTED = 0x40190035;
113pub const LOG_NO_RESTART = 0x401A000C;
114pub const VIDEO_DRIVER_DEBUG_REPORT_REQUEST = 0x401B00EC;
115pub const GRAPHICS_PARTIAL_DATA_POPULATED = 0x401E000A;
116pub const GRAPHICS_DRIVER_MISMATCH = 0x401E0117;
117pub const GRAPHICS_MODE_NOT_PINNED = 0x401E0307;
118pub const GRAPHICS_NO_PREFERRED_MODE = 0x401E031E;
119pub const GRAPHICS_DATASET_IS_EMPTY = 0x401E034B;
120pub const GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET = 0x401E034C;
121pub const GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED = 0x401E0351;
122pub const GRAPHICS_UNKNOWN_CHILD_STATUS = 0x401E042F;
123pub const GRAPHICS_LEADLINK_START_DEFERRED = 0x401E0437;
124pub const GRAPHICS_POLLING_TOO_FREQUENTLY = 0x401E0439;
125pub const GRAPHICS_START_DEFERRED = 0x401E043A;
126pub const NDIS_INDICATION_REQUIRED = 0x40230001;
127pub const GUARD_PAGE_VIOLATION = 0x80000001;
128pub const DATATYPE_MISALIGNMENT = 0x80000002;
129pub const BREAKPOINT = 0x80000003;
130pub const SINGLE_STEP = 0x80000004;
5pub const BUFFER_OVERFLOW = 0x80000005;131pub const BUFFER_OVERFLOW = 0x80000005;
6132pub const NO_MORE_FILES = 0x80000006;
133pub const WAKE_SYSTEM_DEBUGGER = 0x80000007;
134pub const HANDLES_CLOSED = 0x8000000A;
135pub const NO_INHERITANCE = 0x8000000B;
136pub const GUID_SUBSTITUTION_MADE = 0x8000000C;
137pub const PARTIAL_COPY = 0x8000000D;
138pub const DEVICE_PAPER_EMPTY = 0x8000000E;
139pub const DEVICE_POWERED_OFF = 0x8000000F;
140pub const DEVICE_OFF_LINE = 0x80000010;
141pub const DEVICE_BUSY = 0x80000011;
142pub const NO_MORE_EAS = 0x80000012;
143pub const INVALID_EA_NAME = 0x80000013;
144pub const EA_LIST_INCONSISTENT = 0x80000014;
145pub const INVALID_EA_FLAG = 0x80000015;
146pub const VERIFY_REQUIRED = 0x80000016;
147pub const EXTRANEOUS_INFORMATION = 0x80000017;
148pub const RXACT_COMMIT_NECESSARY = 0x80000018;
149pub const NO_MORE_ENTRIES = 0x8000001A;
150pub const FILEMARK_DETECTED = 0x8000001B;
151pub const MEDIA_CHANGED = 0x8000001C;
152pub const BUS_RESET = 0x8000001D;
153pub const END_OF_MEDIA = 0x8000001E;
154pub const BEGINNING_OF_MEDIA = 0x8000001F;
155pub const MEDIA_CHECK = 0x80000020;
156pub const SETMARK_DETECTED = 0x80000021;
157pub const NO_DATA_DETECTED = 0x80000022;
158pub const REDIRECTOR_HAS_OPEN_HANDLES = 0x80000023;
159pub const SERVER_HAS_OPEN_HANDLES = 0x80000024;
160pub const ALREADY_DISCONNECTED = 0x80000025;
161pub const LONGJUMP = 0x80000026;
162pub const CLEANER_CARTRIDGE_INSTALLED = 0x80000027;
163pub const PLUGPLAY_QUERY_VETOED = 0x80000028;
164pub const UNWIND_CONSOLIDATE = 0x80000029;
165pub const REGISTRY_HIVE_RECOVERED = 0x8000002A;
166pub const DLL_MIGHT_BE_INSECURE = 0x8000002B;
167pub const DLL_MIGHT_BE_INCOMPATIBLE = 0x8000002C;
168pub const STOPPED_ON_SYMLINK = 0x8000002D;
169pub const DEVICE_REQUIRES_CLEANING = 0x80000288;
170pub const DEVICE_DOOR_OPEN = 0x80000289;
171pub const DATA_LOST_REPAIR = 0x80000803;
172pub const CLUSTER_NODE_ALREADY_UP = 0x80130001;
173pub const CLUSTER_NODE_ALREADY_DOWN = 0x80130002;
174pub const CLUSTER_NETWORK_ALREADY_ONLINE = 0x80130003;
175pub const CLUSTER_NETWORK_ALREADY_OFFLINE = 0x80130004;
176pub const CLUSTER_NODE_ALREADY_MEMBER = 0x80130005;
177pub const COULD_NOT_RESIZE_LOG = 0x80190009;
178pub const NO_TXF_METADATA = 0x80190029;
179pub const CANT_RECOVER_WITH_HANDLE_OPEN = 0x80190031;
180pub const TXF_METADATA_ALREADY_PRESENT = 0x80190041;
181pub const TRANSACTION_SCOPE_CALLBACKS_NOT_SET = 0x80190042;
182pub const VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED = 0x801B00EB;
183pub const FLT_BUFFER_TOO_SMALL = 0x801C0001;
184pub const FVE_PARTIAL_METADATA = 0x80210001;
185pub const FVE_TRANSIENT_STATE = 0x80210002;
186pub const UNSUCCESSFUL = 0xC0000001;
187pub const NOT_IMPLEMENTED = 0xC0000002;
188pub const INVALID_INFO_CLASS = 0xC0000003;
189pub const INFO_LENGTH_MISMATCH = 0xC0000004;
190pub const ACCESS_VIOLATION = 0xC0000005;
191pub const IN_PAGE_ERROR = 0xC0000006;
192pub const PAGEFILE_QUOTA = 0xC0000007;
193pub const INVALID_HANDLE = 0xC0000008;
194pub const BAD_INITIAL_STACK = 0xC0000009;
195pub const BAD_INITIAL_PC = 0xC000000A;
196pub const INVALID_CID = 0xC000000B;
197pub const TIMER_NOT_CANCELED = 0xC000000C;
7pub const INVALID_PARAMETER = 0xC000000D;198pub const INVALID_PARAMETER = 0xC000000D;
199pub const NO_SUCH_DEVICE = 0xC000000E;
200pub const NO_SUCH_FILE = 0xC000000F;
201pub const INVALID_DEVICE_REQUEST = 0xC0000010;
202pub const END_OF_FILE = 0xC0000011;
203pub const WRONG_VOLUME = 0xC0000012;
204pub const NO_MEDIA_IN_DEVICE = 0xC0000013;
205pub const UNRECOGNIZED_MEDIA = 0xC0000014;
206pub const NONEXISTENT_SECTOR = 0xC0000015;
207pub const MORE_PROCESSING_REQUIRED = 0xC0000016;
208pub const NO_MEMORY = 0xC0000017;
209pub const CONFLICTING_ADDRESSES = 0xC0000018;
210pub const NOT_MAPPED_VIEW = 0xC0000019;
211pub const UNABLE_TO_FREE_VM = 0xC000001A;
212pub const UNABLE_TO_DELETE_SECTION = 0xC000001B;
213pub const INVALID_SYSTEM_SERVICE = 0xC000001C;
214pub const ILLEGAL_INSTRUCTION = 0xC000001D;
215pub const INVALID_LOCK_SEQUENCE = 0xC000001E;
216pub const INVALID_VIEW_SIZE = 0xC000001F;
217pub const INVALID_FILE_FOR_SECTION = 0xC0000020;
218pub const ALREADY_COMMITTED = 0xC0000021;
8pub const ACCESS_DENIED = 0xC0000022;219pub const ACCESS_DENIED = 0xC0000022;
220pub const BUFFER_TOO_SMALL = 0xC0000023;
221pub const OBJECT_TYPE_MISMATCH = 0xC0000024;
222pub const NONCONTINUABLE_EXCEPTION = 0xC0000025;
223pub const INVALID_DISPOSITION = 0xC0000026;
224pub const UNWIND = 0xC0000027;
225pub const BAD_STACK = 0xC0000028;
226pub const INVALID_UNWIND_TARGET = 0xC0000029;
227pub const NOT_LOCKED = 0xC000002A;
228pub const PARITY_ERROR = 0xC000002B;
229pub const UNABLE_TO_DECOMMIT_VM = 0xC000002C;
230pub const NOT_COMMITTED = 0xC000002D;
231pub const INVALID_PORT_ATTRIBUTES = 0xC000002E;
232pub const PORT_MESSAGE_TOO_LONG = 0xC000002F;
233pub const INVALID_PARAMETER_MIX = 0xC0000030;
234pub const INVALID_QUOTA_LOWER = 0xC0000031;
235pub const DISK_CORRUPT_ERROR = 0xC0000032;
9pub const OBJECT_NAME_INVALID = 0xC0000033;236pub const OBJECT_NAME_INVALID = 0xC0000033;
10pub const OBJECT_NAME_NOT_FOUND = 0xC0000034;237pub const OBJECT_NAME_NOT_FOUND = 0xC0000034;
238pub const OBJECT_NAME_COLLISION = 0xC0000035;
239pub const PORT_DISCONNECTED = 0xC0000037;
240pub const DEVICE_ALREADY_ATTACHED = 0xC0000038;
241pub const OBJECT_PATH_INVALID = 0xC0000039;
11pub const OBJECT_PATH_NOT_FOUND = 0xC000003A;242pub const OBJECT_PATH_NOT_FOUND = 0xC000003A;
12pub const OBJECT_PATH_SYNTAX_BAD = 0xC000003B;243pub const OBJECT_PATH_SYNTAX_BAD = 0xC000003B;
244pub const DATA_OVERRUN = 0xC000003C;
245pub const DATA_LATE_ERROR = 0xC000003D;
246pub const DATA_ERROR = 0xC000003E;
247pub const CRC_ERROR = 0xC000003F;
248pub const SECTION_TOO_BIG = 0xC0000040;
249pub const PORT_CONNECTION_REFUSED = 0xC0000041;
250pub const INVALID_PORT_HANDLE = 0xC0000042;
251pub const SHARING_VIOLATION = 0xC0000043;
252pub const QUOTA_EXCEEDED = 0xC0000044;
253pub const INVALID_PAGE_PROTECTION = 0xC0000045;
254pub const MUTANT_NOT_OWNED = 0xC0000046;
255pub const SEMAPHORE_LIMIT_EXCEEDED = 0xC0000047;
256pub const PORT_ALREADY_SET = 0xC0000048;
257pub const SECTION_NOT_IMAGE = 0xC0000049;
258pub const SUSPEND_COUNT_EXCEEDED = 0xC000004A;
259pub const THREAD_IS_TERMINATING = 0xC000004B;
260pub const BAD_WORKING_SET_LIMIT = 0xC000004C;
261pub const INCOMPATIBLE_FILE_MAP = 0xC000004D;
262pub const SECTION_PROTECTION = 0xC000004E;
263pub const EAS_NOT_SUPPORTED = 0xC000004F;
264pub const EA_TOO_LARGE = 0xC0000050;
265pub const NONEXISTENT_EA_ENTRY = 0xC0000051;
266pub const NO_EAS_ON_FILE = 0xC0000052;
267pub const EA_CORRUPT_ERROR = 0xC0000053;
268pub const FILE_LOCK_CONFLICT = 0xC0000054;
269pub const LOCK_NOT_GRANTED = 0xC0000055;
270pub const DELETE_PENDING = 0xC0000056;
271pub const CTL_FILE_NOT_SUPPORTED = 0xC0000057;
272pub const UNKNOWN_REVISION = 0xC0000058;
273pub const REVISION_MISMATCH = 0xC0000059;
274pub const INVALID_OWNER = 0xC000005A;
275pub const INVALID_PRIMARY_GROUP = 0xC000005B;
276pub const NO_IMPERSONATION_TOKEN = 0xC000005C;
277pub const CANT_DISABLE_MANDATORY = 0xC000005D;
278pub const NO_LOGON_SERVERS = 0xC000005E;
279pub const NO_SUCH_LOGON_SESSION = 0xC000005F;
280pub const NO_SUCH_PRIVILEGE = 0xC0000060;
281pub const PRIVILEGE_NOT_HELD = 0xC0000061;
282pub const INVALID_ACCOUNT_NAME = 0xC0000062;
283pub const USER_EXISTS = 0xC0000063;
284pub const NO_SUCH_USER = 0xC0000064;
285pub const GROUP_EXISTS = 0xC0000065;
286pub const NO_SUCH_GROUP = 0xC0000066;
287pub const MEMBER_IN_GROUP = 0xC0000067;
288pub const MEMBER_NOT_IN_GROUP = 0xC0000068;
289pub const LAST_ADMIN = 0xC0000069;
290pub const WRONG_PASSWORD = 0xC000006A;
291pub const ILL_FORMED_PASSWORD = 0xC000006B;
292pub const PASSWORD_RESTRICTION = 0xC000006C;
293pub const LOGON_FAILURE = 0xC000006D;
294pub const ACCOUNT_RESTRICTION = 0xC000006E;
295pub const INVALID_LOGON_HOURS = 0xC000006F;
296pub const INVALID_WORKSTATION = 0xC0000070;
297pub const PASSWORD_EXPIRED = 0xC0000071;
298pub const ACCOUNT_DISABLED = 0xC0000072;
299pub const NONE_MAPPED = 0xC0000073;
300pub const TOO_MANY_LUIDS_REQUESTED = 0xC0000074;
301pub const LUIDS_EXHAUSTED = 0xC0000075;
302pub const INVALID_SUB_AUTHORITY = 0xC0000076;
303pub const INVALID_ACL = 0xC0000077;
304pub const INVALID_SID = 0xC0000078;
305pub const INVALID_SECURITY_DESCR = 0xC0000079;
306pub const PROCEDURE_NOT_FOUND = 0xC000007A;
307pub const INVALID_IMAGE_FORMAT = 0xC000007B;
308pub const NO_TOKEN = 0xC000007C;
309pub const BAD_INHERITANCE_ACL = 0xC000007D;
310pub const RANGE_NOT_LOCKED = 0xC000007E;
311pub const DISK_FULL = 0xC000007F;
312pub const SERVER_DISABLED = 0xC0000080;
313pub const SERVER_NOT_DISABLED = 0xC0000081;
314pub const TOO_MANY_GUIDS_REQUESTED = 0xC0000082;
315pub const GUIDS_EXHAUSTED = 0xC0000083;
316pub const INVALID_ID_AUTHORITY = 0xC0000084;
317pub const AGENTS_EXHAUSTED = 0xC0000085;
318pub const INVALID_VOLUME_LABEL = 0xC0000086;
319pub const SECTION_NOT_EXTENDED = 0xC0000087;
320pub const NOT_MAPPED_DATA = 0xC0000088;
321pub const RESOURCE_DATA_NOT_FOUND = 0xC0000089;
322pub const RESOURCE_TYPE_NOT_FOUND = 0xC000008A;
323pub const RESOURCE_NAME_NOT_FOUND = 0xC000008B;
324pub const ARRAY_BOUNDS_EXCEEDED = 0xC000008C;
325pub const FLOAT_DENORMAL_OPERAND = 0xC000008D;
326pub const FLOAT_DIVIDE_BY_ZERO = 0xC000008E;
327pub const FLOAT_INEXACT_RESULT = 0xC000008F;
328pub const FLOAT_INVALID_OPERATION = 0xC0000090;
329pub const FLOAT_OVERFLOW = 0xC0000091;
330pub const FLOAT_STACK_CHECK = 0xC0000092;
331pub const FLOAT_UNDERFLOW = 0xC0000093;
332pub const INTEGER_DIVIDE_BY_ZERO = 0xC0000094;
333pub const INTEGER_OVERFLOW = 0xC0000095;
334pub const PRIVILEGED_INSTRUCTION = 0xC0000096;
335pub const TOO_MANY_PAGING_FILES = 0xC0000097;
336pub const FILE_INVALID = 0xC0000098;
337pub const ALLOTTED_SPACE_EXCEEDED = 0xC0000099;
338pub const INSUFFICIENT_RESOURCES = 0xC000009A;
339pub const DFS_EXIT_PATH_FOUND = 0xC000009B;
340pub const DEVICE_DATA_ERROR = 0xC000009C;
341pub const DEVICE_NOT_CONNECTED = 0xC000009D;
342pub const FREE_VM_NOT_AT_BASE = 0xC000009F;
343pub const MEMORY_NOT_ALLOCATED = 0xC00000A0;
344pub const WORKING_SET_QUOTA = 0xC00000A1;
345pub const MEDIA_WRITE_PROTECTED = 0xC00000A2;
346pub const DEVICE_NOT_READY = 0xC00000A3;
347pub const INVALID_GROUP_ATTRIBUTES = 0xC00000A4;
348pub const BAD_IMPERSONATION_LEVEL = 0xC00000A5;
349pub const CANT_OPEN_ANONYMOUS = 0xC00000A6;
350pub const BAD_VALIDATION_CLASS = 0xC00000A7;
351pub const BAD_TOKEN_TYPE = 0xC00000A8;
352pub const BAD_MASTER_BOOT_RECORD = 0xC00000A9;
353pub const INSTRUCTION_MISALIGNMENT = 0xC00000AA;
354pub const INSTANCE_NOT_AVAILABLE = 0xC00000AB;
355pub const PIPE_NOT_AVAILABLE = 0xC00000AC;
356pub const INVALID_PIPE_STATE = 0xC00000AD;
357pub const PIPE_BUSY = 0xC00000AE;
358pub const ILLEGAL_FUNCTION = 0xC00000AF;
359pub const PIPE_DISCONNECTED = 0xC00000B0;
360pub const PIPE_CLOSING = 0xC00000B1;
361pub const PIPE_CONNECTED = 0xC00000B2;
362pub const PIPE_LISTENING = 0xC00000B3;
363pub const INVALID_READ_MODE = 0xC00000B4;
364pub const IO_TIMEOUT = 0xC00000B5;
365pub const FILE_FORCED_CLOSED = 0xC00000B6;
366pub const PROFILING_NOT_STARTED = 0xC00000B7;
367pub const PROFILING_NOT_STOPPED = 0xC00000B8;
368pub const COULD_NOT_INTERPRET = 0xC00000B9;
13pub const FILE_IS_A_DIRECTORY = 0xC00000BA;369pub const FILE_IS_A_DIRECTORY = 0xC00000BA;
370pub const NOT_SUPPORTED = 0xC00000BB;
371pub const REMOTE_NOT_LISTENING = 0xC00000BC;
372pub const DUPLICATE_NAME = 0xC00000BD;
373pub const BAD_NETWORK_PATH = 0xC00000BE;
374pub const NETWORK_BUSY = 0xC00000BF;
375pub const DEVICE_DOES_NOT_EXIST = 0xC00000C0;
376pub const TOO_MANY_COMMANDS = 0xC00000C1;
377pub const ADAPTER_HARDWARE_ERROR = 0xC00000C2;
378pub const INVALID_NETWORK_RESPONSE = 0xC00000C3;
379pub const UNEXPECTED_NETWORK_ERROR = 0xC00000C4;
380pub const BAD_REMOTE_ADAPTER = 0xC00000C5;
381pub const PRINT_QUEUE_FULL = 0xC00000C6;
382pub const NO_SPOOL_SPACE = 0xC00000C7;
383pub const PRINT_CANCELLED = 0xC00000C8;
384pub const NETWORK_NAME_DELETED = 0xC00000C9;
385pub const NETWORK_ACCESS_DENIED = 0xC00000CA;
386pub const BAD_DEVICE_TYPE = 0xC00000CB;
387pub const BAD_NETWORK_NAME = 0xC00000CC;
388pub const TOO_MANY_NAMES = 0xC00000CD;
389pub const TOO_MANY_SESSIONS = 0xC00000CE;
390pub const SHARING_PAUSED = 0xC00000CF;
391pub const REQUEST_NOT_ACCEPTED = 0xC00000D0;
392pub const REDIRECTOR_PAUSED = 0xC00000D1;
393pub const NET_WRITE_FAULT = 0xC00000D2;
394pub const PROFILING_AT_LIMIT = 0xC00000D3;
395pub const NOT_SAME_DEVICE = 0xC00000D4;
396pub const FILE_RENAMED = 0xC00000D5;
397pub const VIRTUAL_CIRCUIT_CLOSED = 0xC00000D6;
398pub const NO_SECURITY_ON_OBJECT = 0xC00000D7;
399pub const CANT_WAIT = 0xC00000D8;
400pub const PIPE_EMPTY = 0xC00000D9;
401pub const CANT_ACCESS_DOMAIN_INFO = 0xC00000DA;
402pub const CANT_TERMINATE_SELF = 0xC00000DB;
403pub const INVALID_SERVER_STATE = 0xC00000DC;
404pub const INVALID_DOMAIN_STATE = 0xC00000DD;
405pub const INVALID_DOMAIN_ROLE = 0xC00000DE;
406pub const NO_SUCH_DOMAIN = 0xC00000DF;
407pub const DOMAIN_EXISTS = 0xC00000E0;
408pub const DOMAIN_LIMIT_EXCEEDED = 0xC00000E1;
409pub const OPLOCK_NOT_GRANTED = 0xC00000E2;
410pub const INVALID_OPLOCK_PROTOCOL = 0xC00000E3;
411pub const INTERNAL_DB_CORRUPTION = 0xC00000E4;
412pub const INTERNAL_ERROR = 0xC00000E5;
413pub const GENERIC_NOT_MAPPED = 0xC00000E6;
414pub const BAD_DESCRIPTOR_FORMAT = 0xC00000E7;
415pub const INVALID_USER_BUFFER = 0xC00000E8;
416pub const UNEXPECTED_IO_ERROR = 0xC00000E9;
417pub const UNEXPECTED_MM_CREATE_ERR = 0xC00000EA;
418pub const UNEXPECTED_MM_MAP_ERROR = 0xC00000EB;
419pub const UNEXPECTED_MM_EXTEND_ERR = 0xC00000EC;
420pub const NOT_LOGON_PROCESS = 0xC00000ED;
421pub const LOGON_SESSION_EXISTS = 0xC00000EE;
422pub const INVALID_PARAMETER_1 = 0xC00000EF;
423pub const INVALID_PARAMETER_2 = 0xC00000F0;
424pub const INVALID_PARAMETER_3 = 0xC00000F1;
425pub const INVALID_PARAMETER_4 = 0xC00000F2;
426pub const INVALID_PARAMETER_5 = 0xC00000F3;
427pub const INVALID_PARAMETER_6 = 0xC00000F4;
428pub const INVALID_PARAMETER_7 = 0xC00000F5;
429pub const INVALID_PARAMETER_8 = 0xC00000F6;
430pub const INVALID_PARAMETER_9 = 0xC00000F7;
431pub const INVALID_PARAMETER_10 = 0xC00000F8;
432pub const INVALID_PARAMETER_11 = 0xC00000F9;
433pub const INVALID_PARAMETER_12 = 0xC00000FA;
434pub const REDIRECTOR_NOT_STARTED = 0xC00000FB;
435pub const REDIRECTOR_STARTED = 0xC00000FC;
436pub const STACK_OVERFLOW = 0xC00000FD;
437pub const NO_SUCH_PACKAGE = 0xC00000FE;
438pub const BAD_FUNCTION_TABLE = 0xC00000FF;
439pub const VARIABLE_NOT_FOUND = 0xC0000100;
440pub const DIRECTORY_NOT_EMPTY = 0xC0000101;
441pub const FILE_CORRUPT_ERROR = 0xC0000102;
442pub const NOT_A_DIRECTORY = 0xC0000103;
443pub const BAD_LOGON_SESSION_STATE = 0xC0000104;
444pub const LOGON_SESSION_COLLISION = 0xC0000105;
445pub const NAME_TOO_LONG = 0xC0000106;
446pub const FILES_OPEN = 0xC0000107;
447pub const CONNECTION_IN_USE = 0xC0000108;
448pub const MESSAGE_NOT_FOUND = 0xC0000109;
449pub const PROCESS_IS_TERMINATING = 0xC000010A;
450pub const INVALID_LOGON_TYPE = 0xC000010B;
451pub const NO_GUID_TRANSLATION = 0xC000010C;
452pub const CANNOT_IMPERSONATE = 0xC000010D;
453pub const IMAGE_ALREADY_LOADED = 0xC000010E;
454pub const NO_LDT = 0xC0000117;
455pub const INVALID_LDT_SIZE = 0xC0000118;
456pub const INVALID_LDT_OFFSET = 0xC0000119;
457pub const INVALID_LDT_DESCRIPTOR = 0xC000011A;
458pub const INVALID_IMAGE_NE_FORMAT = 0xC000011B;
459pub const RXACT_INVALID_STATE = 0xC000011C;
460pub const RXACT_COMMIT_FAILURE = 0xC000011D;
461pub const MAPPED_FILE_SIZE_ZERO = 0xC000011E;
462pub const TOO_MANY_OPENED_FILES = 0xC000011F;
463pub const CANCELLED = 0xC0000120;
464pub const CANNOT_DELETE = 0xC0000121;
465pub const INVALID_COMPUTER_NAME = 0xC0000122;
466pub const FILE_DELETED = 0xC0000123;
467pub const SPECIAL_ACCOUNT = 0xC0000124;
468pub const SPECIAL_GROUP = 0xC0000125;
469pub const SPECIAL_USER = 0xC0000126;
470pub const MEMBERS_PRIMARY_GROUP = 0xC0000127;
471pub const FILE_CLOSED = 0xC0000128;
472pub const TOO_MANY_THREADS = 0xC0000129;
473pub const THREAD_NOT_IN_PROCESS = 0xC000012A;
474pub const TOKEN_ALREADY_IN_USE = 0xC000012B;
475pub const PAGEFILE_QUOTA_EXCEEDED = 0xC000012C;
476pub const COMMITMENT_LIMIT = 0xC000012D;
477pub const INVALID_IMAGE_LE_FORMAT = 0xC000012E;
478pub const INVALID_IMAGE_NOT_MZ = 0xC000012F;
479pub const INVALID_IMAGE_PROTECT = 0xC0000130;
480pub const INVALID_IMAGE_WIN_16 = 0xC0000131;
481pub const LOGON_SERVER_CONFLICT = 0xC0000132;
482pub const TIME_DIFFERENCE_AT_DC = 0xC0000133;
483pub const SYNCHRONIZATION_REQUIRED = 0xC0000134;
484pub const DLL_NOT_FOUND = 0xC0000135;
485pub const OPEN_FAILED = 0xC0000136;
486pub const IO_PRIVILEGE_FAILED = 0xC0000137;
487pub const ORDINAL_NOT_FOUND = 0xC0000138;
488pub const ENTRYPOINT_NOT_FOUND = 0xC0000139;
489pub const CONTROL_C_EXIT = 0xC000013A;
490pub const LOCAL_DISCONNECT = 0xC000013B;
491pub const REMOTE_DISCONNECT = 0xC000013C;
492pub const REMOTE_RESOURCES = 0xC000013D;
493pub const LINK_FAILED = 0xC000013E;
494pub const LINK_TIMEOUT = 0xC000013F;
495pub const INVALID_CONNECTION = 0xC0000140;
496pub const INVALID_ADDRESS = 0xC0000141;
497pub const DLL_INIT_FAILED = 0xC0000142;
498pub const MISSING_SYSTEMFILE = 0xC0000143;
499pub const UNHANDLED_EXCEPTION = 0xC0000144;
500pub const APP_INIT_FAILURE = 0xC0000145;
501pub const PAGEFILE_CREATE_FAILED = 0xC0000146;
502pub const NO_PAGEFILE = 0xC0000147;
503pub const INVALID_LEVEL = 0xC0000148;
504pub const WRONG_PASSWORD_CORE = 0xC0000149;
505pub const ILLEGAL_FLOAT_CONTEXT = 0xC000014A;
506pub const PIPE_BROKEN = 0xC000014B;
507pub const REGISTRY_CORRUPT = 0xC000014C;
508pub const REGISTRY_IO_FAILED = 0xC000014D;
509pub const NO_EVENT_PAIR = 0xC000014E;
510pub const UNRECOGNIZED_VOLUME = 0xC000014F;
511pub const SERIAL_NO_DEVICE_INITED = 0xC0000150;
512pub const NO_SUCH_ALIAS = 0xC0000151;
513pub const MEMBER_NOT_IN_ALIAS = 0xC0000152;
514pub const MEMBER_IN_ALIAS = 0xC0000153;
515pub const ALIAS_EXISTS = 0xC0000154;
516pub const LOGON_NOT_GRANTED = 0xC0000155;
517pub const TOO_MANY_SECRETS = 0xC0000156;
518pub const SECRET_TOO_LONG = 0xC0000157;
519pub const INTERNAL_DB_ERROR = 0xC0000158;
520pub const FULLSCREEN_MODE = 0xC0000159;
521pub const TOO_MANY_CONTEXT_IDS = 0xC000015A;
522pub const LOGON_TYPE_NOT_GRANTED = 0xC000015B;
523pub const NOT_REGISTRY_FILE = 0xC000015C;
524pub const NT_CROSS_ENCRYPTION_REQUIRED = 0xC000015D;
525pub const DOMAIN_CTRLR_CONFIG_ERROR = 0xC000015E;
526pub const FT_MISSING_MEMBER = 0xC000015F;
527pub const ILL_FORMED_SERVICE_ENTRY = 0xC0000160;
528pub const ILLEGAL_CHARACTER = 0xC0000161;
529pub const UNMAPPABLE_CHARACTER = 0xC0000162;
530pub const UNDEFINED_CHARACTER = 0xC0000163;
531pub const FLOPPY_VOLUME = 0xC0000164;
532pub const FLOPPY_ID_MARK_NOT_FOUND = 0xC0000165;
533pub const FLOPPY_WRONG_CYLINDER = 0xC0000166;
534pub const FLOPPY_UNKNOWN_ERROR = 0xC0000167;
535pub const FLOPPY_BAD_REGISTERS = 0xC0000168;
536pub const DISK_RECALIBRATE_FAILED = 0xC0000169;
537pub const DISK_OPERATION_FAILED = 0xC000016A;
538pub const DISK_RESET_FAILED = 0xC000016B;
539pub const SHARED_IRQ_BUSY = 0xC000016C;
540pub const FT_ORPHANING = 0xC000016D;
541pub const BIOS_FAILED_TO_CONNECT_INTERRUPT = 0xC000016E;
542pub const PARTITION_FAILURE = 0xC0000172;
543pub const INVALID_BLOCK_LENGTH = 0xC0000173;
544pub const DEVICE_NOT_PARTITIONED = 0xC0000174;
545pub const UNABLE_TO_LOCK_MEDIA = 0xC0000175;
546pub const UNABLE_TO_UNLOAD_MEDIA = 0xC0000176;
547pub const EOM_OVERFLOW = 0xC0000177;
548pub const NO_MEDIA = 0xC0000178;
549pub const NO_SUCH_MEMBER = 0xC000017A;
550pub const INVALID_MEMBER = 0xC000017B;
551pub const KEY_DELETED = 0xC000017C;
552pub const NO_LOG_SPACE = 0xC000017D;
553pub const TOO_MANY_SIDS = 0xC000017E;
554pub const LM_CROSS_ENCRYPTION_REQUIRED = 0xC000017F;
555pub const KEY_HAS_CHILDREN = 0xC0000180;
556pub const CHILD_MUST_BE_VOLATILE = 0xC0000181;
557pub const DEVICE_CONFIGURATION_ERROR = 0xC0000182;
558pub const DRIVER_INTERNAL_ERROR = 0xC0000183;
559pub const INVALID_DEVICE_STATE = 0xC0000184;
560pub const IO_DEVICE_ERROR = 0xC0000185;
561pub const DEVICE_PROTOCOL_ERROR = 0xC0000186;
562pub const BACKUP_CONTROLLER = 0xC0000187;
563pub const LOG_FILE_FULL = 0xC0000188;
564pub const TOO_LATE = 0xC0000189;
565pub const NO_TRUST_LSA_SECRET = 0xC000018A;
566pub const NO_TRUST_SAM_ACCOUNT = 0xC000018B;
567pub const TRUSTED_DOMAIN_FAILURE = 0xC000018C;
568pub const TRUSTED_RELATIONSHIP_FAILURE = 0xC000018D;
569pub const EVENTLOG_FILE_CORRUPT = 0xC000018E;
570pub const EVENTLOG_CANT_START = 0xC000018F;
571pub const TRUST_FAILURE = 0xC0000190;
572pub const MUTANT_LIMIT_EXCEEDED = 0xC0000191;
573pub const NETLOGON_NOT_STARTED = 0xC0000192;
574pub const ACCOUNT_EXPIRED = 0xC0000193;
575pub const POSSIBLE_DEADLOCK = 0xC0000194;
576pub const NETWORK_CREDENTIAL_CONFLICT = 0xC0000195;
577pub const REMOTE_SESSION_LIMIT = 0xC0000196;
578pub const EVENTLOG_FILE_CHANGED = 0xC0000197;
579pub const NOLOGON_INTERDOMAIN_TRUST_ACCOUNT = 0xC0000198;
580pub const NOLOGON_WORKSTATION_TRUST_ACCOUNT = 0xC0000199;
581pub const NOLOGON_SERVER_TRUST_ACCOUNT = 0xC000019A;
582pub const DOMAIN_TRUST_INCONSISTENT = 0xC000019B;
583pub const FS_DRIVER_REQUIRED = 0xC000019C;
584pub const IMAGE_ALREADY_LOADED_AS_DLL = 0xC000019D;
585pub const INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING = 0xC000019E;
586pub const SHORT_NAMES_NOT_ENABLED_ON_VOLUME = 0xC000019F;
587pub const SECURITY_STREAM_IS_INCONSISTENT = 0xC00001A0;
588pub const INVALID_LOCK_RANGE = 0xC00001A1;
589pub const INVALID_ACE_CONDITION = 0xC00001A2;
590pub const IMAGE_SUBSYSTEM_NOT_PRESENT = 0xC00001A3;
591pub const NOTIFICATION_GUID_ALREADY_DEFINED = 0xC00001A4;
592pub const NETWORK_OPEN_RESTRICTION = 0xC0000201;
593pub const NO_USER_SESSION_KEY = 0xC0000202;
594pub const USER_SESSION_DELETED = 0xC0000203;
595pub const RESOURCE_LANG_NOT_FOUND = 0xC0000204;
596pub const INSUFF_SERVER_RESOURCES = 0xC0000205;
597pub const INVALID_BUFFER_SIZE = 0xC0000206;
598pub const INVALID_ADDRESS_COMPONENT = 0xC0000207;
599pub const INVALID_ADDRESS_WILDCARD = 0xC0000208;
600pub const TOO_MANY_ADDRESSES = 0xC0000209;
601pub const ADDRESS_ALREADY_EXISTS = 0xC000020A;
602pub const ADDRESS_CLOSED = 0xC000020B;
603pub const CONNECTION_DISCONNECTED = 0xC000020C;
604pub const CONNECTION_RESET = 0xC000020D;
605pub const TOO_MANY_NODES = 0xC000020E;
606pub const TRANSACTION_ABORTED = 0xC000020F;
607pub const TRANSACTION_TIMED_OUT = 0xC0000210;
608pub const TRANSACTION_NO_RELEASE = 0xC0000211;
609pub const TRANSACTION_NO_MATCH = 0xC0000212;
610pub const TRANSACTION_RESPONDED = 0xC0000213;
611pub const TRANSACTION_INVALID_ID = 0xC0000214;
612pub const TRANSACTION_INVALID_TYPE = 0xC0000215;
613pub const NOT_SERVER_SESSION = 0xC0000216;
614pub const NOT_CLIENT_SESSION = 0xC0000217;
615pub const CANNOT_LOAD_REGISTRY_FILE = 0xC0000218;
616pub const DEBUG_ATTACH_FAILED = 0xC0000219;
617pub const SYSTEM_PROCESS_TERMINATED = 0xC000021A;
618pub const DATA_NOT_ACCEPTED = 0xC000021B;
619pub const NO_BROWSER_SERVERS_FOUND = 0xC000021C;
620pub const VDM_HARD_ERROR = 0xC000021D;
621pub const DRIVER_CANCEL_TIMEOUT = 0xC000021E;
622pub const REPLY_MESSAGE_MISMATCH = 0xC000021F;
623pub const MAPPED_ALIGNMENT = 0xC0000220;
624pub const IMAGE_CHECKSUM_MISMATCH = 0xC0000221;
625pub const LOST_WRITEBEHIND_DATA = 0xC0000222;
626pub const CLIENT_SERVER_PARAMETERS_INVALID = 0xC0000223;
627pub const PASSWORD_MUST_CHANGE = 0xC0000224;
628pub const NOT_FOUND = 0xC0000225;
629pub const NOT_TINY_STREAM = 0xC0000226;
630pub const RECOVERY_FAILURE = 0xC0000227;
631pub const STACK_OVERFLOW_READ = 0xC0000228;
632pub const FAIL_CHECK = 0xC0000229;
633pub const DUPLICATE_OBJECTID = 0xC000022A;
634pub const OBJECTID_EXISTS = 0xC000022B;
635pub const CONVERT_TO_LARGE = 0xC000022C;
636pub const RETRY = 0xC000022D;
637pub const FOUND_OUT_OF_SCOPE = 0xC000022E;
638pub const ALLOCATE_BUCKET = 0xC000022F;
639pub const PROPSET_NOT_FOUND = 0xC0000230;
640pub const MARSHALL_OVERFLOW = 0xC0000231;
641pub const INVALID_VARIANT = 0xC0000232;
642pub const DOMAIN_CONTROLLER_NOT_FOUND = 0xC0000233;
643pub const ACCOUNT_LOCKED_OUT = 0xC0000234;
644pub const HANDLE_NOT_CLOSABLE = 0xC0000235;
645pub const CONNECTION_REFUSED = 0xC0000236;
646pub const GRACEFUL_DISCONNECT = 0xC0000237;
647pub const ADDRESS_ALREADY_ASSOCIATED = 0xC0000238;
648pub const ADDRESS_NOT_ASSOCIATED = 0xC0000239;
649pub const CONNECTION_INVALID = 0xC000023A;
650pub const CONNECTION_ACTIVE = 0xC000023B;
651pub const NETWORK_UNREACHABLE = 0xC000023C;
652pub const HOST_UNREACHABLE = 0xC000023D;
653pub const PROTOCOL_UNREACHABLE = 0xC000023E;
654pub const PORT_UNREACHABLE = 0xC000023F;
655pub const REQUEST_ABORTED = 0xC0000240;
656pub const CONNECTION_ABORTED = 0xC0000241;
657pub const BAD_COMPRESSION_BUFFER = 0xC0000242;
658pub const USER_MAPPED_FILE = 0xC0000243;
659pub const AUDIT_FAILED = 0xC0000244;
660pub const TIMER_RESOLUTION_NOT_SET = 0xC0000245;
661pub const CONNECTION_COUNT_LIMIT = 0xC0000246;
662pub const LOGIN_TIME_RESTRICTION = 0xC0000247;
663pub const LOGIN_WKSTA_RESTRICTION = 0xC0000248;
664pub const IMAGE_MP_UP_MISMATCH = 0xC0000249;
665pub const INSUFFICIENT_LOGON_INFO = 0xC0000250;
666pub const BAD_DLL_ENTRYPOINT = 0xC0000251;
667pub const BAD_SERVICE_ENTRYPOINT = 0xC0000252;
668pub const LPC_REPLY_LOST = 0xC0000253;
669pub const IP_ADDRESS_CONFLICT1 = 0xC0000254;
670pub const IP_ADDRESS_CONFLICT2 = 0xC0000255;
671pub const REGISTRY_QUOTA_LIMIT = 0xC0000256;
672pub const PATH_NOT_COVERED = 0xC0000257;
673pub const NO_CALLBACK_ACTIVE = 0xC0000258;
674pub const LICENSE_QUOTA_EXCEEDED = 0xC0000259;
675pub const PWD_TOO_SHORT = 0xC000025A;
676pub const PWD_TOO_RECENT = 0xC000025B;
677pub const PWD_HISTORY_CONFLICT = 0xC000025C;
678pub const PLUGPLAY_NO_DEVICE = 0xC000025E;
679pub const UNSUPPORTED_COMPRESSION = 0xC000025F;
680pub const INVALID_HW_PROFILE = 0xC0000260;
681pub const INVALID_PLUGPLAY_DEVICE_PATH = 0xC0000261;
682pub const DRIVER_ORDINAL_NOT_FOUND = 0xC0000262;
683pub const DRIVER_ENTRYPOINT_NOT_FOUND = 0xC0000263;
684pub const RESOURCE_NOT_OWNED = 0xC0000264;
685pub const TOO_MANY_LINKS = 0xC0000265;
686pub const QUOTA_LIST_INCONSISTENT = 0xC0000266;
687pub const FILE_IS_OFFLINE = 0xC0000267;
688pub const EVALUATION_EXPIRATION = 0xC0000268;
689pub const ILLEGAL_DLL_RELOCATION = 0xC0000269;
690pub const LICENSE_VIOLATION = 0xC000026A;
691pub const DLL_INIT_FAILED_LOGOFF = 0xC000026B;
692pub const DRIVER_UNABLE_TO_LOAD = 0xC000026C;
693pub const DFS_UNAVAILABLE = 0xC000026D;
694pub const VOLUME_DISMOUNTED = 0xC000026E;
695pub const WX86_INTERNAL_ERROR = 0xC000026F;
696pub const WX86_FLOAT_STACK_CHECK = 0xC0000270;
697pub const VALIDATE_CONTINUE = 0xC0000271;
698pub const NO_MATCH = 0xC0000272;
699pub const NO_MORE_MATCHES = 0xC0000273;
700pub const NOT_A_REPARSE_POINT = 0xC0000275;
701pub const IO_REPARSE_TAG_INVALID = 0xC0000276;
702pub const IO_REPARSE_TAG_MISMATCH = 0xC0000277;
703pub const IO_REPARSE_DATA_INVALID = 0xC0000278;
704pub const IO_REPARSE_TAG_NOT_HANDLED = 0xC0000279;
705pub const REPARSE_POINT_NOT_RESOLVED = 0xC0000280;
706pub const DIRECTORY_IS_A_REPARSE_POINT = 0xC0000281;
707pub const RANGE_LIST_CONFLICT = 0xC0000282;
708pub const SOURCE_ELEMENT_EMPTY = 0xC0000283;
709pub const DESTINATION_ELEMENT_FULL = 0xC0000284;
710pub const ILLEGAL_ELEMENT_ADDRESS = 0xC0000285;
711pub const MAGAZINE_NOT_PRESENT = 0xC0000286;
712pub const REINITIALIZATION_NEEDED = 0xC0000287;
713pub const ENCRYPTION_FAILED = 0xC000028A;
714pub const DECRYPTION_FAILED = 0xC000028B;
715pub const RANGE_NOT_FOUND = 0xC000028C;
716pub const NO_RECOVERY_POLICY = 0xC000028D;
717pub const NO_EFS = 0xC000028E;
718pub const WRONG_EFS = 0xC000028F;
719pub const NO_USER_KEYS = 0xC0000290;
720pub const FILE_NOT_ENCRYPTED = 0xC0000291;
721pub const NOT_EXPORT_FORMAT = 0xC0000292;
722pub const FILE_ENCRYPTED = 0xC0000293;
723pub const WMI_GUID_NOT_FOUND = 0xC0000295;
724pub const WMI_INSTANCE_NOT_FOUND = 0xC0000296;
725pub const WMI_ITEMID_NOT_FOUND = 0xC0000297;
726pub const WMI_TRY_AGAIN = 0xC0000298;
727pub const SHARED_POLICY = 0xC0000299;
728pub const POLICY_OBJECT_NOT_FOUND = 0xC000029A;
729pub const POLICY_ONLY_IN_DS = 0xC000029B;
730pub const VOLUME_NOT_UPGRADED = 0xC000029C;
731pub const REMOTE_STORAGE_NOT_ACTIVE = 0xC000029D;
732pub const REMOTE_STORAGE_MEDIA_ERROR = 0xC000029E;
733pub const NO_TRACKING_SERVICE = 0xC000029F;
734pub const SERVER_SID_MISMATCH = 0xC00002A0;
735pub const DS_NO_ATTRIBUTE_OR_VALUE = 0xC00002A1;
736pub const DS_INVALID_ATTRIBUTE_SYNTAX = 0xC00002A2;
737pub const DS_ATTRIBUTE_TYPE_UNDEFINED = 0xC00002A3;
738pub const DS_ATTRIBUTE_OR_VALUE_EXISTS = 0xC00002A4;
739pub const DS_BUSY = 0xC00002A5;
740pub const DS_UNAVAILABLE = 0xC00002A6;
741pub const DS_NO_RIDS_ALLOCATED = 0xC00002A7;
742pub const DS_NO_MORE_RIDS = 0xC00002A8;
743pub const DS_INCORRECT_ROLE_OWNER = 0xC00002A9;
744pub const DS_RIDMGR_INIT_ERROR = 0xC00002AA;
745pub const DS_OBJ_CLASS_VIOLATION = 0xC00002AB;
746pub const DS_CANT_ON_NON_LEAF = 0xC00002AC;
747pub const DS_CANT_ON_RDN = 0xC00002AD;
748pub const DS_CANT_MOD_OBJ_CLASS = 0xC00002AE;
749pub const DS_CROSS_DOM_MOVE_FAILED = 0xC00002AF;
750pub const DS_GC_NOT_AVAILABLE = 0xC00002B0;
751pub const DIRECTORY_SERVICE_REQUIRED = 0xC00002B1;
752pub const REPARSE_ATTRIBUTE_CONFLICT = 0xC00002B2;
753pub const CANT_ENABLE_DENY_ONLY = 0xC00002B3;
754pub const FLOAT_MULTIPLE_FAULTS = 0xC00002B4;
755pub const FLOAT_MULTIPLE_TRAPS = 0xC00002B5;
756pub const DEVICE_REMOVED = 0xC00002B6;
757pub const JOURNAL_DELETE_IN_PROGRESS = 0xC00002B7;
758pub const JOURNAL_NOT_ACTIVE = 0xC00002B8;
759pub const NOINTERFACE = 0xC00002B9;
760pub const DS_ADMIN_LIMIT_EXCEEDED = 0xC00002C1;
761pub const DRIVER_FAILED_SLEEP = 0xC00002C2;
762pub const MUTUAL_AUTHENTICATION_FAILED = 0xC00002C3;
763pub const CORRUPT_SYSTEM_FILE = 0xC00002C4;
764pub const DATATYPE_MISALIGNMENT_ERROR = 0xC00002C5;
765pub const WMI_READ_ONLY = 0xC00002C6;
766pub const WMI_SET_FAILURE = 0xC00002C7;
767pub const COMMITMENT_MINIMUM = 0xC00002C8;
768pub const REG_NAT_CONSUMPTION = 0xC00002C9;
769pub const TRANSPORT_FULL = 0xC00002CA;
770pub const DS_SAM_INIT_FAILURE = 0xC00002CB;
771pub const ONLY_IF_CONNECTED = 0xC00002CC;
772pub const DS_SENSITIVE_GROUP_VIOLATION = 0xC00002CD;
773pub const PNP_RESTART_ENUMERATION = 0xC00002CE;
774pub const JOURNAL_ENTRY_DELETED = 0xC00002CF;
775pub const DS_CANT_MOD_PRIMARYGROUPID = 0xC00002D0;
776pub const SYSTEM_IMAGE_BAD_SIGNATURE = 0xC00002D1;
777pub const PNP_REBOOT_REQUIRED = 0xC00002D2;
778pub const POWER_STATE_INVALID = 0xC00002D3;
779pub const DS_INVALID_GROUP_TYPE = 0xC00002D4;
780pub const DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN = 0xC00002D5;
781pub const DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN = 0xC00002D6;
782pub const DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D7;
783pub const DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER = 0xC00002D8;
784pub const DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER = 0xC00002D9;
785pub const DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER = 0xC00002DA;
786pub const DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER = 0xC00002DB;
787pub const DS_HAVE_PRIMARY_MEMBERS = 0xC00002DC;
788pub const WMI_NOT_SUPPORTED = 0xC00002DD;
789pub const INSUFFICIENT_POWER = 0xC00002DE;
790pub const SAM_NEED_BOOTKEY_PASSWORD = 0xC00002DF;
791pub const SAM_NEED_BOOTKEY_FLOPPY = 0xC00002E0;
792pub const DS_CANT_START = 0xC00002E1;
793pub const DS_INIT_FAILURE = 0xC00002E2;
794pub const SAM_INIT_FAILURE = 0xC00002E3;
795pub const DS_GC_REQUIRED = 0xC00002E4;
796pub const DS_LOCAL_MEMBER_OF_LOCAL_ONLY = 0xC00002E5;
797pub const DS_NO_FPO_IN_UNIVERSAL_GROUPS = 0xC00002E6;
798pub const DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED = 0xC00002E7;
799pub const CURRENT_DOMAIN_NOT_ALLOWED = 0xC00002E9;
800pub const CANNOT_MAKE = 0xC00002EA;
801pub const SYSTEM_SHUTDOWN = 0xC00002EB;
802pub const DS_INIT_FAILURE_CONSOLE = 0xC00002EC;
803pub const DS_SAM_INIT_FAILURE_CONSOLE = 0xC00002ED;
804pub const UNFINISHED_CONTEXT_DELETED = 0xC00002EE;
805pub const NO_TGT_REPLY = 0xC00002EF;
806pub const OBJECTID_NOT_FOUND = 0xC00002F0;
807pub const NO_IP_ADDRESSES = 0xC00002F1;
808pub const WRONG_CREDENTIAL_HANDLE = 0xC00002F2;
809pub const CRYPTO_SYSTEM_INVALID = 0xC00002F3;
810pub const MAX_REFERRALS_EXCEEDED = 0xC00002F4;
811pub const MUST_BE_KDC = 0xC00002F5;
812pub const STRONG_CRYPTO_NOT_SUPPORTED = 0xC00002F6;
813pub const TOO_MANY_PRINCIPALS = 0xC00002F7;
814pub const NO_PA_DATA = 0xC00002F8;
815pub const PKINIT_NAME_MISMATCH = 0xC00002F9;
816pub const SMARTCARD_LOGON_REQUIRED = 0xC00002FA;
817pub const KDC_INVALID_REQUEST = 0xC00002FB;
818pub const KDC_UNABLE_TO_REFER = 0xC00002FC;
819pub const KDC_UNKNOWN_ETYPE = 0xC00002FD;
820pub const SHUTDOWN_IN_PROGRESS = 0xC00002FE;
821pub const SERVER_SHUTDOWN_IN_PROGRESS = 0xC00002FF;
822pub const NOT_SUPPORTED_ON_SBS = 0xC0000300;
823pub const WMI_GUID_DISCONNECTED = 0xC0000301;
824pub const WMI_ALREADY_DISABLED = 0xC0000302;
825pub const WMI_ALREADY_ENABLED = 0xC0000303;
826pub const MFT_TOO_FRAGMENTED = 0xC0000304;
827pub const COPY_PROTECTION_FAILURE = 0xC0000305;
828pub const CSS_AUTHENTICATION_FAILURE = 0xC0000306;
829pub const CSS_KEY_NOT_PRESENT = 0xC0000307;
830pub const CSS_KEY_NOT_ESTABLISHED = 0xC0000308;
831pub const CSS_SCRAMBLED_SECTOR = 0xC0000309;
832pub const CSS_REGION_MISMATCH = 0xC000030A;
833pub const CSS_RESETS_EXHAUSTED = 0xC000030B;
834pub const PKINIT_FAILURE = 0xC0000320;
835pub const SMARTCARD_SUBSYSTEM_FAILURE = 0xC0000321;
836pub const NO_KERB_KEY = 0xC0000322;
837pub const HOST_DOWN = 0xC0000350;
838pub const UNSUPPORTED_PREAUTH = 0xC0000351;
839pub const EFS_ALG_BLOB_TOO_BIG = 0xC0000352;
840pub const PORT_NOT_SET = 0xC0000353;
841pub const DEBUGGER_INACTIVE = 0xC0000354;
842pub const DS_VERSION_CHECK_FAILURE = 0xC0000355;
843pub const AUDITING_DISABLED = 0xC0000356;
844pub const PRENT4_MACHINE_ACCOUNT = 0xC0000357;
845pub const DS_AG_CANT_HAVE_UNIVERSAL_MEMBER = 0xC0000358;
846pub const INVALID_IMAGE_WIN_32 = 0xC0000359;
847pub const INVALID_IMAGE_WIN_64 = 0xC000035A;
848pub const BAD_BINDINGS = 0xC000035B;
849pub const NETWORK_SESSION_EXPIRED = 0xC000035C;
850pub const APPHELP_BLOCK = 0xC000035D;
851pub const ALL_SIDS_FILTERED = 0xC000035E;
852pub const NOT_SAFE_MODE_DRIVER = 0xC000035F;
853pub const ACCESS_DISABLED_BY_POLICY_DEFAULT = 0xC0000361;
854pub const ACCESS_DISABLED_BY_POLICY_PATH = 0xC0000362;
855pub const ACCESS_DISABLED_BY_POLICY_PUBLISHER = 0xC0000363;
856pub const ACCESS_DISABLED_BY_POLICY_OTHER = 0xC0000364;
857pub const FAILED_DRIVER_ENTRY = 0xC0000365;
858pub const DEVICE_ENUMERATION_ERROR = 0xC0000366;
859pub const MOUNT_POINT_NOT_RESOLVED = 0xC0000368;
860pub const INVALID_DEVICE_OBJECT_PARAMETER = 0xC0000369;
861pub const MCA_OCCURED = 0xC000036A;
862pub const DRIVER_BLOCKED_CRITICAL = 0xC000036B;
863pub const DRIVER_BLOCKED = 0xC000036C;
864pub const DRIVER_DATABASE_ERROR = 0xC000036D;
865pub const SYSTEM_HIVE_TOO_LARGE = 0xC000036E;
866pub const INVALID_IMPORT_OF_NON_DLL = 0xC000036F;
867pub const NO_SECRETS = 0xC0000371;
868pub const ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY = 0xC0000372;
869pub const FAILED_STACK_SWITCH = 0xC0000373;
870pub const HEAP_CORRUPTION = 0xC0000374;
871pub const SMARTCARD_WRONG_PIN = 0xC0000380;
872pub const SMARTCARD_CARD_BLOCKED = 0xC0000381;
873pub const SMARTCARD_CARD_NOT_AUTHENTICATED = 0xC0000382;
874pub const SMARTCARD_NO_CARD = 0xC0000383;
875pub const SMARTCARD_NO_KEY_CONTAINER = 0xC0000384;
876pub const SMARTCARD_NO_CERTIFICATE = 0xC0000385;
877pub const SMARTCARD_NO_KEYSET = 0xC0000386;
878pub const SMARTCARD_IO_ERROR = 0xC0000387;
879pub const DOWNGRADE_DETECTED = 0xC0000388;
880pub const SMARTCARD_CERT_REVOKED = 0xC0000389;
881pub const ISSUING_CA_UNTRUSTED = 0xC000038A;
882pub const REVOCATION_OFFLINE_C = 0xC000038B;
883pub const PKINIT_CLIENT_FAILURE = 0xC000038C;
884pub const SMARTCARD_CERT_EXPIRED = 0xC000038D;
885pub const DRIVER_FAILED_PRIOR_UNLOAD = 0xC000038E;
886pub const SMARTCARD_SILENT_CONTEXT = 0xC000038F;
887pub const PER_USER_TRUST_QUOTA_EXCEEDED = 0xC0000401;
888pub const ALL_USER_TRUST_QUOTA_EXCEEDED = 0xC0000402;
889pub const USER_DELETE_TRUST_QUOTA_EXCEEDED = 0xC0000403;
890pub const DS_NAME_NOT_UNIQUE = 0xC0000404;
891pub const DS_DUPLICATE_ID_FOUND = 0xC0000405;
892pub const DS_GROUP_CONVERSION_ERROR = 0xC0000406;
893pub const VOLSNAP_PREPARE_HIBERNATE = 0xC0000407;
894pub const USER2USER_REQUIRED = 0xC0000408;
895pub const STACK_BUFFER_OVERRUN = 0xC0000409;
896pub const NO_S4U_PROT_SUPPORT = 0xC000040A;
897pub const CROSSREALM_DELEGATION_FAILURE = 0xC000040B;
898pub const REVOCATION_OFFLINE_KDC = 0xC000040C;
899pub const ISSUING_CA_UNTRUSTED_KDC = 0xC000040D;
900pub const KDC_CERT_EXPIRED = 0xC000040E;
901pub const KDC_CERT_REVOKED = 0xC000040F;
902pub const PARAMETER_QUOTA_EXCEEDED = 0xC0000410;
903pub const HIBERNATION_FAILURE = 0xC0000411;
904pub const DELAY_LOAD_FAILED = 0xC0000412;
905pub const AUTHENTICATION_FIREWALL_FAILED = 0xC0000413;
906pub const VDM_DISALLOWED = 0xC0000414;
907pub const HUNG_DISPLAY_DRIVER_THREAD = 0xC0000415;
908pub const INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE = 0xC0000416;
909pub const INVALID_CRUNTIME_PARAMETER = 0xC0000417;
910pub const NTLM_BLOCKED = 0xC0000418;
911pub const DS_SRC_SID_EXISTS_IN_FOREST = 0xC0000419;
912pub const DS_DOMAIN_NAME_EXISTS_IN_FOREST = 0xC000041A;
913pub const DS_FLAT_NAME_EXISTS_IN_FOREST = 0xC000041B;
914pub const INVALID_USER_PRINCIPAL_NAME = 0xC000041C;
915pub const ASSERTION_FAILURE = 0xC0000420;
916pub const VERIFIER_STOP = 0xC0000421;
917pub const CALLBACK_POP_STACK = 0xC0000423;
918pub const INCOMPATIBLE_DRIVER_BLOCKED = 0xC0000424;
919pub const HIVE_UNLOADED = 0xC0000425;
920pub const COMPRESSION_DISABLED = 0xC0000426;
921pub const FILE_SYSTEM_LIMITATION = 0xC0000427;
922pub const INVALID_IMAGE_HASH = 0xC0000428;
923pub const NOT_CAPABLE = 0xC0000429;
924pub const REQUEST_OUT_OF_SEQUENCE = 0xC000042A;
925pub const IMPLEMENTATION_LIMIT = 0xC000042B;
926pub const ELEVATION_REQUIRED = 0xC000042C;
927pub const NO_SECURITY_CONTEXT = 0xC000042D;
928pub const PKU2U_CERT_FAILURE = 0xC000042E;
929pub const BEYOND_VDL = 0xC0000432;
930pub const ENCOUNTERED_WRITE_IN_PROGRESS = 0xC0000433;
931pub const PTE_CHANGED = 0xC0000434;
932pub const PURGE_FAILED = 0xC0000435;
933pub const CRED_REQUIRES_CONFIRMATION = 0xC0000440;
934pub const CS_ENCRYPTION_INVALID_SERVER_RESPONSE = 0xC0000441;
935pub const CS_ENCRYPTION_UNSUPPORTED_SERVER = 0xC0000442;
936pub const CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE = 0xC0000443;
937pub const CS_ENCRYPTION_NEW_ENCRYPTED_FILE = 0xC0000444;
938pub const CS_ENCRYPTION_FILE_NOT_CSE = 0xC0000445;
939pub const INVALID_LABEL = 0xC0000446;
940pub const DRIVER_PROCESS_TERMINATED = 0xC0000450;
941pub const AMBIGUOUS_SYSTEM_DEVICE = 0xC0000451;
942pub const SYSTEM_DEVICE_NOT_FOUND = 0xC0000452;
943pub const RESTART_BOOT_APPLICATION = 0xC0000453;
944pub const INSUFFICIENT_NVRAM_RESOURCES = 0xC0000454;
945pub const INVALID_TASK_NAME = 0xC0000500;
946pub const INVALID_TASK_INDEX = 0xC0000501;
947pub const THREAD_ALREADY_IN_TASK = 0xC0000502;
948pub const CALLBACK_BYPASS = 0xC0000503;
949pub const FAIL_FAST_EXCEPTION = 0xC0000602;
950pub const IMAGE_CERT_REVOKED = 0xC0000603;
951pub const PORT_CLOSED = 0xC0000700;
952pub const MESSAGE_LOST = 0xC0000701;
953pub const INVALID_MESSAGE = 0xC0000702;
954pub const REQUEST_CANCELED = 0xC0000703;
955pub const RECURSIVE_DISPATCH = 0xC0000704;
956pub const LPC_RECEIVE_BUFFER_EXPECTED = 0xC0000705;
957pub const LPC_INVALID_CONNECTION_USAGE = 0xC0000706;
958pub const LPC_REQUESTS_NOT_ALLOWED = 0xC0000707;
959pub const RESOURCE_IN_USE = 0xC0000708;
960pub const HARDWARE_MEMORY_ERROR = 0xC0000709;
961pub const THREADPOOL_HANDLE_EXCEPTION = 0xC000070A;
962pub const THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED = 0xC000070B;
963pub const THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED = 0xC000070C;
964pub const THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED = 0xC000070D;
965pub const THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED = 0xC000070E;
966pub const THREADPOOL_RELEASED_DURING_OPERATION = 0xC000070F;
967pub const CALLBACK_RETURNED_WHILE_IMPERSONATING = 0xC0000710;
968pub const APC_RETURNED_WHILE_IMPERSONATING = 0xC0000711;
969pub const PROCESS_IS_PROTECTED = 0xC0000712;
970pub const MCA_EXCEPTION = 0xC0000713;
971pub const CERTIFICATE_MAPPING_NOT_UNIQUE = 0xC0000714;
972pub const SYMLINK_CLASS_DISABLED = 0xC0000715;
973pub const INVALID_IDN_NORMALIZATION = 0xC0000716;
974pub const NO_UNICODE_TRANSLATION = 0xC0000717;
975pub const ALREADY_REGISTERED = 0xC0000718;
976pub const CONTEXT_MISMATCH = 0xC0000719;
977pub const PORT_ALREADY_HAS_COMPLETION_LIST = 0xC000071A;
978pub const CALLBACK_RETURNED_THREAD_PRIORITY = 0xC000071B;
979pub const INVALID_THREAD = 0xC000071C;
980pub const CALLBACK_RETURNED_TRANSACTION = 0xC000071D;
981pub const CALLBACK_RETURNED_LDR_LOCK = 0xC000071E;
982pub const CALLBACK_RETURNED_LANG = 0xC000071F;
983pub const CALLBACK_RETURNED_PRI_BACK = 0xC0000720;
984pub const DISK_REPAIR_DISABLED = 0xC0000800;
985pub const DS_DOMAIN_RENAME_IN_PROGRESS = 0xC0000801;
986pub const DISK_QUOTA_EXCEEDED = 0xC0000802;
987pub const CONTENT_BLOCKED = 0xC0000804;
988pub const BAD_CLUSTERS = 0xC0000805;
989pub const VOLUME_DIRTY = 0xC0000806;
990pub const FILE_CHECKED_OUT = 0xC0000901;
991pub const CHECKOUT_REQUIRED = 0xC0000902;
992pub const BAD_FILE_TYPE = 0xC0000903;
993pub const FILE_TOO_LARGE = 0xC0000904;
994pub const FORMS_AUTH_REQUIRED = 0xC0000905;
995pub const VIRUS_INFECTED = 0xC0000906;
996pub const VIRUS_DELETED = 0xC0000907;
997pub const BAD_MCFG_TABLE = 0xC0000908;
998pub const CANNOT_BREAK_OPLOCK = 0xC0000909;
999pub const WOW_ASSERTION = 0xC0009898;
1000pub const INVALID_SIGNATURE = 0xC000A000;
1001pub const HMAC_NOT_SUPPORTED = 0xC000A001;
1002pub const IPSEC_QUEUE_OVERFLOW = 0xC000A010;
1003pub const ND_QUEUE_OVERFLOW = 0xC000A011;
1004pub const HOPLIMIT_EXCEEDED = 0xC000A012;
1005pub const PROTOCOL_NOT_SUPPORTED = 0xC000A013;
1006pub const LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED = 0xC000A080;
1007pub const LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR = 0xC000A081;
1008pub const LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR = 0xC000A082;
1009pub const XML_PARSE_ERROR = 0xC000A083;
1010pub const XMLDSIG_ERROR = 0xC000A084;
1011pub const WRONG_COMPARTMENT = 0xC000A085;
1012pub const AUTHIP_FAILURE = 0xC000A086;
1013pub const DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS = 0xC000A087;
1014pub const DS_OID_NOT_FOUND = 0xC000A088;
1015pub const HASH_NOT_SUPPORTED = 0xC000A100;
1016pub const HASH_NOT_PRESENT = 0xC000A101;
1017pub const PNP_BAD_MPS_TABLE = 0xC0040035;
1018pub const PNP_TRANSLATION_FAILED = 0xC0040036;
1019pub const PNP_IRQ_TRANSLATION_FAILED = 0xC0040037;
1020pub const PNP_INVALID_ID = 0xC0040038;
1021pub const IO_REISSUE_AS_CACHED = 0xC0040039;
1022pub const CTX_WINSTATION_NAME_INVALID = 0xC00A0001;
1023pub const CTX_INVALID_PD = 0xC00A0002;
1024pub const CTX_PD_NOT_FOUND = 0xC00A0003;
1025pub const CTX_CLOSE_PENDING = 0xC00A0006;
1026pub const CTX_NO_OUTBUF = 0xC00A0007;
1027pub const CTX_MODEM_INF_NOT_FOUND = 0xC00A0008;
1028pub const CTX_INVALID_MODEMNAME = 0xC00A0009;
1029pub const CTX_RESPONSE_ERROR = 0xC00A000A;
1030pub const CTX_MODEM_RESPONSE_TIMEOUT = 0xC00A000B;
1031pub const CTX_MODEM_RESPONSE_NO_CARRIER = 0xC00A000C;
1032pub const CTX_MODEM_RESPONSE_NO_DIALTONE = 0xC00A000D;
1033pub const CTX_MODEM_RESPONSE_BUSY = 0xC00A000E;
1034pub const CTX_MODEM_RESPONSE_VOICE = 0xC00A000F;
1035pub const CTX_TD_ERROR = 0xC00A0010;
1036pub const CTX_LICENSE_CLIENT_INVALID = 0xC00A0012;
1037pub const CTX_LICENSE_NOT_AVAILABLE = 0xC00A0013;
1038pub const CTX_LICENSE_EXPIRED = 0xC00A0014;
1039pub const CTX_WINSTATION_NOT_FOUND = 0xC00A0015;
1040pub const CTX_WINSTATION_NAME_COLLISION = 0xC00A0016;
1041pub const CTX_WINSTATION_BUSY = 0xC00A0017;
1042pub const CTX_BAD_VIDEO_MODE = 0xC00A0018;
1043pub const CTX_GRAPHICS_INVALID = 0xC00A0022;
1044pub const CTX_NOT_CONSOLE = 0xC00A0024;
1045pub const CTX_CLIENT_QUERY_TIMEOUT = 0xC00A0026;
1046pub const CTX_CONSOLE_DISCONNECT = 0xC00A0027;
1047pub const CTX_CONSOLE_CONNECT = 0xC00A0028;
1048pub const CTX_SHADOW_DENIED = 0xC00A002A;
1049pub const CTX_WINSTATION_ACCESS_DENIED = 0xC00A002B;
1050pub const CTX_INVALID_WD = 0xC00A002E;
1051pub const CTX_WD_NOT_FOUND = 0xC00A002F;
1052pub const CTX_SHADOW_INVALID = 0xC00A0030;
1053pub const CTX_SHADOW_DISABLED = 0xC00A0031;
1054pub const RDP_PROTOCOL_ERROR = 0xC00A0032;
1055pub const CTX_CLIENT_LICENSE_NOT_SET = 0xC00A0033;
1056pub const CTX_CLIENT_LICENSE_IN_USE = 0xC00A0034;
1057pub const CTX_SHADOW_ENDED_BY_MODE_CHANGE = 0xC00A0035;
1058pub const CTX_SHADOW_NOT_RUNNING = 0xC00A0036;
1059pub const CTX_LOGON_DISABLED = 0xC00A0037;
1060pub const CTX_SECURITY_LAYER_ERROR = 0xC00A0038;
1061pub const TS_INCOMPATIBLE_SESSIONS = 0xC00A0039;
1062pub const MUI_FILE_NOT_FOUND = 0xC00B0001;
1063pub const MUI_INVALID_FILE = 0xC00B0002;
1064pub const MUI_INVALID_RC_CONFIG = 0xC00B0003;
1065pub const MUI_INVALID_LOCALE_NAME = 0xC00B0004;
1066pub const MUI_INVALID_ULTIMATEFALLBACK_NAME = 0xC00B0005;
1067pub const MUI_FILE_NOT_LOADED = 0xC00B0006;
1068pub const RESOURCE_ENUM_USER_STOP = 0xC00B0007;
1069pub const CLUSTER_INVALID_NODE = 0xC0130001;
1070pub const CLUSTER_NODE_EXISTS = 0xC0130002;
1071pub const CLUSTER_JOIN_IN_PROGRESS = 0xC0130003;
1072pub const CLUSTER_NODE_NOT_FOUND = 0xC0130004;
1073pub const CLUSTER_LOCAL_NODE_NOT_FOUND = 0xC0130005;
1074pub const CLUSTER_NETWORK_EXISTS = 0xC0130006;
1075pub const CLUSTER_NETWORK_NOT_FOUND = 0xC0130007;
1076pub const CLUSTER_NETINTERFACE_EXISTS = 0xC0130008;
1077pub const CLUSTER_NETINTERFACE_NOT_FOUND = 0xC0130009;
1078pub const CLUSTER_INVALID_REQUEST = 0xC013000A;
1079pub const CLUSTER_INVALID_NETWORK_PROVIDER = 0xC013000B;
1080pub const CLUSTER_NODE_DOWN = 0xC013000C;
1081pub const CLUSTER_NODE_UNREACHABLE = 0xC013000D;
1082pub const CLUSTER_NODE_NOT_MEMBER = 0xC013000E;
1083pub const CLUSTER_JOIN_NOT_IN_PROGRESS = 0xC013000F;
1084pub const CLUSTER_INVALID_NETWORK = 0xC0130010;
1085pub const CLUSTER_NO_NET_ADAPTERS = 0xC0130011;
1086pub const CLUSTER_NODE_UP = 0xC0130012;
1087pub const CLUSTER_NODE_PAUSED = 0xC0130013;
1088pub const CLUSTER_NODE_NOT_PAUSED = 0xC0130014;
1089pub const CLUSTER_NO_SECURITY_CONTEXT = 0xC0130015;
1090pub const CLUSTER_NETWORK_NOT_INTERNAL = 0xC0130016;
1091pub const CLUSTER_POISONED = 0xC0130017;
1092pub const ACPI_INVALID_OPCODE = 0xC0140001;
1093pub const ACPI_STACK_OVERFLOW = 0xC0140002;
1094pub const ACPI_ASSERT_FAILED = 0xC0140003;
1095pub const ACPI_INVALID_INDEX = 0xC0140004;
1096pub const ACPI_INVALID_ARGUMENT = 0xC0140005;
1097pub const ACPI_FATAL = 0xC0140006;
1098pub const ACPI_INVALID_SUPERNAME = 0xC0140007;
1099pub const ACPI_INVALID_ARGTYPE = 0xC0140008;
1100pub const ACPI_INVALID_OBJTYPE = 0xC0140009;
1101pub const ACPI_INVALID_TARGETTYPE = 0xC014000A;
1102pub const ACPI_INCORRECT_ARGUMENT_COUNT = 0xC014000B;
1103pub const ACPI_ADDRESS_NOT_MAPPED = 0xC014000C;
1104pub const ACPI_INVALID_EVENTTYPE = 0xC014000D;
1105pub const ACPI_HANDLER_COLLISION = 0xC014000E;
1106pub const ACPI_INVALID_DATA = 0xC014000F;
1107pub const ACPI_INVALID_REGION = 0xC0140010;
1108pub const ACPI_INVALID_ACCESS_SIZE = 0xC0140011;
1109pub const ACPI_ACQUIRE_GLOBAL_LOCK = 0xC0140012;
1110pub const ACPI_ALREADY_INITIALIZED = 0xC0140013;
1111pub const ACPI_NOT_INITIALIZED = 0xC0140014;
1112pub const ACPI_INVALID_MUTEX_LEVEL = 0xC0140015;
1113pub const ACPI_MUTEX_NOT_OWNED = 0xC0140016;
1114pub const ACPI_MUTEX_NOT_OWNER = 0xC0140017;
1115pub const ACPI_RS_ACCESS = 0xC0140018;
1116pub const ACPI_INVALID_TABLE = 0xC0140019;
1117pub const ACPI_REG_HANDLER_FAILED = 0xC0140020;
1118pub const ACPI_POWER_REQUEST_FAILED = 0xC0140021;
1119pub const SXS_SECTION_NOT_FOUND = 0xC0150001;
1120pub const SXS_CANT_GEN_ACTCTX = 0xC0150002;
1121pub const SXS_INVALID_ACTCTXDATA_FORMAT = 0xC0150003;
1122pub const SXS_ASSEMBLY_NOT_FOUND = 0xC0150004;
1123pub const SXS_MANIFEST_FORMAT_ERROR = 0xC0150005;
1124pub const SXS_MANIFEST_PARSE_ERROR = 0xC0150006;
1125pub const SXS_ACTIVATION_CONTEXT_DISABLED = 0xC0150007;
1126pub const SXS_KEY_NOT_FOUND = 0xC0150008;
1127pub const SXS_VERSION_CONFLICT = 0xC0150009;
1128pub const SXS_WRONG_SECTION_TYPE = 0xC015000A;
1129pub const SXS_THREAD_QUERIES_DISABLED = 0xC015000B;
1130pub const SXS_ASSEMBLY_MISSING = 0xC015000C;
1131pub const SXS_PROCESS_DEFAULT_ALREADY_SET = 0xC015000E;
1132pub const SXS_EARLY_DEACTIVATION = 0xC015000F;
1133pub const SXS_INVALID_DEACTIVATION = 0xC0150010;
1134pub const SXS_MULTIPLE_DEACTIVATION = 0xC0150011;
1135pub const SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY = 0xC0150012;
1136pub const SXS_PROCESS_TERMINATION_REQUESTED = 0xC0150013;
1137pub const SXS_CORRUPT_ACTIVATION_STACK = 0xC0150014;
1138pub const SXS_CORRUPTION = 0xC0150015;
1139pub const SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE = 0xC0150016;
1140pub const SXS_INVALID_IDENTITY_ATTRIBUTE_NAME = 0xC0150017;
1141pub const SXS_IDENTITY_DUPLICATE_ATTRIBUTE = 0xC0150018;
1142pub const SXS_IDENTITY_PARSE_ERROR = 0xC0150019;
1143pub const SXS_COMPONENT_STORE_CORRUPT = 0xC015001A;
1144pub const SXS_FILE_HASH_MISMATCH = 0xC015001B;
1145pub const SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT = 0xC015001C;
1146pub const SXS_IDENTITIES_DIFFERENT = 0xC015001D;
1147pub const SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT = 0xC015001E;
1148pub const SXS_FILE_NOT_PART_OF_ASSEMBLY = 0xC015001F;
1149pub const ADVANCED_INSTALLER_FAILED = 0xC0150020;
1150pub const XML_ENCODING_MISMATCH = 0xC0150021;
1151pub const SXS_MANIFEST_TOO_BIG = 0xC0150022;
1152pub const SXS_SETTING_NOT_REGISTERED = 0xC0150023;
1153pub const SXS_TRANSACTION_CLOSURE_INCOMPLETE = 0xC0150024;
1154pub const SMI_PRIMITIVE_INSTALLER_FAILED = 0xC0150025;
1155pub const GENERIC_COMMAND_FAILED = 0xC0150026;
1156pub const SXS_FILE_HASH_MISSING = 0xC0150027;
1157pub const TRANSACTIONAL_CONFLICT = 0xC0190001;
1158pub const INVALID_TRANSACTION = 0xC0190002;
1159pub const TRANSACTION_NOT_ACTIVE = 0xC0190003;
1160pub const TM_INITIALIZATION_FAILED = 0xC0190004;
1161pub const RM_NOT_ACTIVE = 0xC0190005;
1162pub const RM_METADATA_CORRUPT = 0xC0190006;
1163pub const TRANSACTION_NOT_JOINED = 0xC0190007;
1164pub const DIRECTORY_NOT_RM = 0xC0190008;
1165pub const TRANSACTIONS_UNSUPPORTED_REMOTE = 0xC019000A;
1166pub const LOG_RESIZE_INVALID_SIZE = 0xC019000B;
1167pub const REMOTE_FILE_VERSION_MISMATCH = 0xC019000C;
1168pub const CRM_PROTOCOL_ALREADY_EXISTS = 0xC019000F;
1169pub const TRANSACTION_PROPAGATION_FAILED = 0xC0190010;
1170pub const CRM_PROTOCOL_NOT_FOUND = 0xC0190011;
1171pub const TRANSACTION_SUPERIOR_EXISTS = 0xC0190012;
1172pub const TRANSACTION_REQUEST_NOT_VALID = 0xC0190013;
1173pub const TRANSACTION_NOT_REQUESTED = 0xC0190014;
1174pub const TRANSACTION_ALREADY_ABORTED = 0xC0190015;
1175pub const TRANSACTION_ALREADY_COMMITTED = 0xC0190016;
1176pub const TRANSACTION_INVALID_MARSHALL_BUFFER = 0xC0190017;
1177pub const CURRENT_TRANSACTION_NOT_VALID = 0xC0190018;
1178pub const LOG_GROWTH_FAILED = 0xC0190019;
1179pub const OBJECT_NO_LONGER_EXISTS = 0xC0190021;
1180pub const STREAM_MINIVERSION_NOT_FOUND = 0xC0190022;
1181pub const STREAM_MINIVERSION_NOT_VALID = 0xC0190023;
1182pub const MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION = 0xC0190024;
1183pub const CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT = 0xC0190025;
1184pub const CANT_CREATE_MORE_STREAM_MINIVERSIONS = 0xC0190026;
1185pub const HANDLE_NO_LONGER_VALID = 0xC0190028;
1186pub const LOG_CORRUPTION_DETECTED = 0xC0190030;
1187pub const RM_DISCONNECTED = 0xC0190032;
1188pub const ENLISTMENT_NOT_SUPERIOR = 0xC0190033;
1189pub const FILE_IDENTITY_NOT_PERSISTENT = 0xC0190036;
1190pub const CANT_BREAK_TRANSACTIONAL_DEPENDENCY = 0xC0190037;
1191pub const CANT_CROSS_RM_BOUNDARY = 0xC0190038;
1192pub const TXF_DIR_NOT_EMPTY = 0xC0190039;
1193pub const INDOUBT_TRANSACTIONS_EXIST = 0xC019003A;
1194pub const TM_VOLATILE = 0xC019003B;
1195pub const ROLLBACK_TIMER_EXPIRED = 0xC019003C;
1196pub const TXF_ATTRIBUTE_CORRUPT = 0xC019003D;
1197pub const EFS_NOT_ALLOWED_IN_TRANSACTION = 0xC019003E;
1198pub const TRANSACTIONAL_OPEN_NOT_ALLOWED = 0xC019003F;
1199pub const TRANSACTED_MAPPING_UNSUPPORTED_REMOTE = 0xC0190040;
1200pub const TRANSACTION_REQUIRED_PROMOTION = 0xC0190043;
1201pub const CANNOT_EXECUTE_FILE_IN_TRANSACTION = 0xC0190044;
1202pub const TRANSACTIONS_NOT_FROZEN = 0xC0190045;
1203pub const TRANSACTION_FREEZE_IN_PROGRESS = 0xC0190046;
1204pub const NOT_SNAPSHOT_VOLUME = 0xC0190047;
1205pub const NO_SAVEPOINT_WITH_OPEN_FILES = 0xC0190048;
1206pub const SPARSE_NOT_ALLOWED_IN_TRANSACTION = 0xC0190049;
1207pub const TM_IDENTITY_MISMATCH = 0xC019004A;
1208pub const FLOATED_SECTION = 0xC019004B;
1209pub const CANNOT_ACCEPT_TRANSACTED_WORK = 0xC019004C;
1210pub const CANNOT_ABORT_TRANSACTIONS = 0xC019004D;
1211pub const TRANSACTION_NOT_FOUND = 0xC019004E;
1212pub const RESOURCEMANAGER_NOT_FOUND = 0xC019004F;
1213pub const ENLISTMENT_NOT_FOUND = 0xC0190050;
1214pub const TRANSACTIONMANAGER_NOT_FOUND = 0xC0190051;
1215pub const TRANSACTIONMANAGER_NOT_ONLINE = 0xC0190052;
1216pub const TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION = 0xC0190053;
1217pub const TRANSACTION_NOT_ROOT = 0xC0190054;
1218pub const TRANSACTION_OBJECT_EXPIRED = 0xC0190055;
1219pub const COMPRESSION_NOT_ALLOWED_IN_TRANSACTION = 0xC0190056;
1220pub const TRANSACTION_RESPONSE_NOT_ENLISTED = 0xC0190057;
1221pub const TRANSACTION_RECORD_TOO_LONG = 0xC0190058;
1222pub const NO_LINK_TRACKING_IN_TRANSACTION = 0xC0190059;
1223pub const OPERATION_NOT_SUPPORTED_IN_TRANSACTION = 0xC019005A;
1224pub const TRANSACTION_INTEGRITY_VIOLATED = 0xC019005B;
1225pub const EXPIRED_HANDLE = 0xC0190060;
1226pub const TRANSACTION_NOT_ENLISTED = 0xC0190061;
1227pub const LOG_SECTOR_INVALID = 0xC01A0001;
1228pub const LOG_SECTOR_PARITY_INVALID = 0xC01A0002;
1229pub const LOG_SECTOR_REMAPPED = 0xC01A0003;
1230pub const LOG_BLOCK_INCOMPLETE = 0xC01A0004;
1231pub const LOG_INVALID_RANGE = 0xC01A0005;
1232pub const LOG_BLOCKS_EXHAUSTED = 0xC01A0006;
1233pub const LOG_READ_CONTEXT_INVALID = 0xC01A0007;
1234pub const LOG_RESTART_INVALID = 0xC01A0008;
1235pub const LOG_BLOCK_VERSION = 0xC01A0009;
1236pub const LOG_BLOCK_INVALID = 0xC01A000A;
1237pub const LOG_READ_MODE_INVALID = 0xC01A000B;
1238pub const LOG_METADATA_CORRUPT = 0xC01A000D;
1239pub const LOG_METADATA_INVALID = 0xC01A000E;
1240pub const LOG_METADATA_INCONSISTENT = 0xC01A000F;
1241pub const LOG_RESERVATION_INVALID = 0xC01A0010;
1242pub const LOG_CANT_DELETE = 0xC01A0011;
1243pub const LOG_CONTAINER_LIMIT_EXCEEDED = 0xC01A0012;
1244pub const LOG_START_OF_LOG = 0xC01A0013;
1245pub const LOG_POLICY_ALREADY_INSTALLED = 0xC01A0014;
1246pub const LOG_POLICY_NOT_INSTALLED = 0xC01A0015;
1247pub const LOG_POLICY_INVALID = 0xC01A0016;
1248pub const LOG_POLICY_CONFLICT = 0xC01A0017;
1249pub const LOG_PINNED_ARCHIVE_TAIL = 0xC01A0018;
1250pub const LOG_RECORD_NONEXISTENT = 0xC01A0019;
1251pub const LOG_RECORDS_RESERVED_INVALID = 0xC01A001A;
1252pub const LOG_SPACE_RESERVED_INVALID = 0xC01A001B;
1253pub const LOG_TAIL_INVALID = 0xC01A001C;
1254pub const LOG_FULL = 0xC01A001D;
1255pub const LOG_MULTIPLEXED = 0xC01A001E;
1256pub const LOG_DEDICATED = 0xC01A001F;
1257pub const LOG_ARCHIVE_NOT_IN_PROGRESS = 0xC01A0020;
1258pub const LOG_ARCHIVE_IN_PROGRESS = 0xC01A0021;
1259pub const LOG_EPHEMERAL = 0xC01A0022;
1260pub const LOG_NOT_ENOUGH_CONTAINERS = 0xC01A0023;
1261pub const LOG_CLIENT_ALREADY_REGISTERED = 0xC01A0024;
1262pub const LOG_CLIENT_NOT_REGISTERED = 0xC01A0025;
1263pub const LOG_FULL_HANDLER_IN_PROGRESS = 0xC01A0026;
1264pub const LOG_CONTAINER_READ_FAILED = 0xC01A0027;
1265pub const LOG_CONTAINER_WRITE_FAILED = 0xC01A0028;
1266pub const LOG_CONTAINER_OPEN_FAILED = 0xC01A0029;
1267pub const LOG_CONTAINER_STATE_INVALID = 0xC01A002A;
1268pub const LOG_STATE_INVALID = 0xC01A002B;
1269pub const LOG_PINNED = 0xC01A002C;
1270pub const LOG_METADATA_FLUSH_FAILED = 0xC01A002D;
1271pub const LOG_INCONSISTENT_SECURITY = 0xC01A002E;
1272pub const LOG_APPENDED_FLUSH_FAILED = 0xC01A002F;
1273pub const LOG_PINNED_RESERVATION = 0xC01A0030;
1274pub const VIDEO_HUNG_DISPLAY_DRIVER_THREAD = 0xC01B00EA;
1275pub const FLT_NO_HANDLER_DEFINED = 0xC01C0001;
1276pub const FLT_CONTEXT_ALREADY_DEFINED = 0xC01C0002;
1277pub const FLT_INVALID_ASYNCHRONOUS_REQUEST = 0xC01C0003;
1278pub const FLT_DISALLOW_FAST_IO = 0xC01C0004;
1279pub const FLT_INVALID_NAME_REQUEST = 0xC01C0005;
1280pub const FLT_NOT_SAFE_TO_POST_OPERATION = 0xC01C0006;
1281pub const FLT_NOT_INITIALIZED = 0xC01C0007;
1282pub const FLT_FILTER_NOT_READY = 0xC01C0008;
1283pub const FLT_POST_OPERATION_CLEANUP = 0xC01C0009;
1284pub const FLT_INTERNAL_ERROR = 0xC01C000A;
1285pub const FLT_DELETING_OBJECT = 0xC01C000B;
1286pub const FLT_MUST_BE_NONPAGED_POOL = 0xC01C000C;
1287pub const FLT_DUPLICATE_ENTRY = 0xC01C000D;
1288pub const FLT_CBDQ_DISABLED = 0xC01C000E;
1289pub const FLT_DO_NOT_ATTACH = 0xC01C000F;
1290pub const FLT_DO_NOT_DETACH = 0xC01C0010;
1291pub const FLT_INSTANCE_ALTITUDE_COLLISION = 0xC01C0011;
1292pub const FLT_INSTANCE_NAME_COLLISION = 0xC01C0012;
1293pub const FLT_FILTER_NOT_FOUND = 0xC01C0013;
1294pub const FLT_VOLUME_NOT_FOUND = 0xC01C0014;
1295pub const FLT_INSTANCE_NOT_FOUND = 0xC01C0015;
1296pub const FLT_CONTEXT_ALLOCATION_NOT_FOUND = 0xC01C0016;
1297pub const FLT_INVALID_CONTEXT_REGISTRATION = 0xC01C0017;
1298pub const FLT_NAME_CACHE_MISS = 0xC01C0018;
1299pub const FLT_NO_DEVICE_OBJECT = 0xC01C0019;
1300pub const FLT_VOLUME_ALREADY_MOUNTED = 0xC01C001A;
1301pub const FLT_ALREADY_ENLISTED = 0xC01C001B;
1302pub const FLT_CONTEXT_ALREADY_LINKED = 0xC01C001C;
1303pub const FLT_NO_WAITER_FOR_REPLY = 0xC01C0020;
1304pub const MONITOR_NO_DESCRIPTOR = 0xC01D0001;
1305pub const MONITOR_UNKNOWN_DESCRIPTOR_FORMAT = 0xC01D0002;
1306pub const MONITOR_INVALID_DESCRIPTOR_CHECKSUM = 0xC01D0003;
1307pub const MONITOR_INVALID_STANDARD_TIMING_BLOCK = 0xC01D0004;
1308pub const MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED = 0xC01D0005;
1309pub const MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK = 0xC01D0006;
1310pub const MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK = 0xC01D0007;
1311pub const MONITOR_NO_MORE_DESCRIPTOR_DATA = 0xC01D0008;
1312pub const MONITOR_INVALID_DETAILED_TIMING_BLOCK = 0xC01D0009;
1313pub const MONITOR_INVALID_MANUFACTURE_DATE = 0xC01D000A;
1314pub const GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER = 0xC01E0000;
1315pub const GRAPHICS_INSUFFICIENT_DMA_BUFFER = 0xC01E0001;
1316pub const GRAPHICS_INVALID_DISPLAY_ADAPTER = 0xC01E0002;
1317pub const GRAPHICS_ADAPTER_WAS_RESET = 0xC01E0003;
1318pub const GRAPHICS_INVALID_DRIVER_MODEL = 0xC01E0004;
1319pub const GRAPHICS_PRESENT_MODE_CHANGED = 0xC01E0005;
1320pub const GRAPHICS_PRESENT_OCCLUDED = 0xC01E0006;
1321pub const GRAPHICS_PRESENT_DENIED = 0xC01E0007;
1322pub const GRAPHICS_CANNOTCOLORCONVERT = 0xC01E0008;
1323pub const GRAPHICS_PRESENT_REDIRECTION_DISABLED = 0xC01E000B;
1324pub const GRAPHICS_PRESENT_UNOCCLUDED = 0xC01E000C;
1325pub const GRAPHICS_NO_VIDEO_MEMORY = 0xC01E0100;
1326pub const GRAPHICS_CANT_LOCK_MEMORY = 0xC01E0101;
1327pub const GRAPHICS_ALLOCATION_BUSY = 0xC01E0102;
1328pub const GRAPHICS_TOO_MANY_REFERENCES = 0xC01E0103;
1329pub const GRAPHICS_TRY_AGAIN_LATER = 0xC01E0104;
1330pub const GRAPHICS_TRY_AGAIN_NOW = 0xC01E0105;
1331pub const GRAPHICS_ALLOCATION_INVALID = 0xC01E0106;
1332pub const GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE = 0xC01E0107;
1333pub const GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED = 0xC01E0108;
1334pub const GRAPHICS_CANT_EVICT_PINNED_ALLOCATION = 0xC01E0109;
1335pub const GRAPHICS_INVALID_ALLOCATION_USAGE = 0xC01E0110;
1336pub const GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION = 0xC01E0111;
1337pub const GRAPHICS_ALLOCATION_CLOSED = 0xC01E0112;
1338pub const GRAPHICS_INVALID_ALLOCATION_INSTANCE = 0xC01E0113;
1339pub const GRAPHICS_INVALID_ALLOCATION_HANDLE = 0xC01E0114;
1340pub const GRAPHICS_WRONG_ALLOCATION_DEVICE = 0xC01E0115;
1341pub const GRAPHICS_ALLOCATION_CONTENT_LOST = 0xC01E0116;
1342pub const GRAPHICS_GPU_EXCEPTION_ON_DEVICE = 0xC01E0200;
1343pub const GRAPHICS_INVALID_VIDPN_TOPOLOGY = 0xC01E0300;
1344pub const GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED = 0xC01E0301;
1345pub const GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED = 0xC01E0302;
1346pub const GRAPHICS_INVALID_VIDPN = 0xC01E0303;
1347pub const GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE = 0xC01E0304;
1348pub const GRAPHICS_INVALID_VIDEO_PRESENT_TARGET = 0xC01E0305;
1349pub const GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED = 0xC01E0306;
1350pub const GRAPHICS_INVALID_VIDPN_SOURCEMODESET = 0xC01E0308;
1351pub const GRAPHICS_INVALID_VIDPN_TARGETMODESET = 0xC01E0309;
1352pub const GRAPHICS_INVALID_FREQUENCY = 0xC01E030A;
1353pub const GRAPHICS_INVALID_ACTIVE_REGION = 0xC01E030B;
1354pub const GRAPHICS_INVALID_TOTAL_REGION = 0xC01E030C;
1355pub const GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE = 0xC01E0310;
1356pub const GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE = 0xC01E0311;
1357pub const GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET = 0xC01E0312;
1358pub const GRAPHICS_PATH_ALREADY_IN_TOPOLOGY = 0xC01E0313;
1359pub const GRAPHICS_MODE_ALREADY_IN_MODESET = 0xC01E0314;
1360pub const GRAPHICS_INVALID_VIDEOPRESENTSOURCESET = 0xC01E0315;
1361pub const GRAPHICS_INVALID_VIDEOPRESENTTARGETSET = 0xC01E0316;
1362pub const GRAPHICS_SOURCE_ALREADY_IN_SET = 0xC01E0317;
1363pub const GRAPHICS_TARGET_ALREADY_IN_SET = 0xC01E0318;
1364pub const GRAPHICS_INVALID_VIDPN_PRESENT_PATH = 0xC01E0319;
1365pub const GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY = 0xC01E031A;
1366pub const GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET = 0xC01E031B;
1367pub const GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE = 0xC01E031C;
1368pub const GRAPHICS_FREQUENCYRANGE_NOT_IN_SET = 0xC01E031D;
1369pub const GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET = 0xC01E031F;
1370pub const GRAPHICS_STALE_MODESET = 0xC01E0320;
1371pub const GRAPHICS_INVALID_MONITOR_SOURCEMODESET = 0xC01E0321;
1372pub const GRAPHICS_INVALID_MONITOR_SOURCE_MODE = 0xC01E0322;
1373pub const GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN = 0xC01E0323;
1374pub const GRAPHICS_MODE_ID_MUST_BE_UNIQUE = 0xC01E0324;
1375pub const GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION = 0xC01E0325;
1376pub const GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES = 0xC01E0326;
1377pub const GRAPHICS_PATH_NOT_IN_TOPOLOGY = 0xC01E0327;
1378pub const GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE = 0xC01E0328;
1379pub const GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET = 0xC01E0329;
1380pub const GRAPHICS_INVALID_MONITORDESCRIPTORSET = 0xC01E032A;
1381pub const GRAPHICS_INVALID_MONITORDESCRIPTOR = 0xC01E032B;
1382pub const GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET = 0xC01E032C;
1383pub const GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET = 0xC01E032D;
1384pub const GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE = 0xC01E032E;
1385pub const GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE = 0xC01E032F;
1386pub const GRAPHICS_RESOURCES_NOT_RELATED = 0xC01E0330;
1387pub const GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE = 0xC01E0331;
1388pub const GRAPHICS_TARGET_ID_MUST_BE_UNIQUE = 0xC01E0332;
1389pub const GRAPHICS_NO_AVAILABLE_VIDPN_TARGET = 0xC01E0333;
1390pub const GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER = 0xC01E0334;
1391pub const GRAPHICS_NO_VIDPNMGR = 0xC01E0335;
1392pub const GRAPHICS_NO_ACTIVE_VIDPN = 0xC01E0336;
1393pub const GRAPHICS_STALE_VIDPN_TOPOLOGY = 0xC01E0337;
1394pub const GRAPHICS_MONITOR_NOT_CONNECTED = 0xC01E0338;
1395pub const GRAPHICS_SOURCE_NOT_IN_TOPOLOGY = 0xC01E0339;
1396pub const GRAPHICS_INVALID_PRIMARYSURFACE_SIZE = 0xC01E033A;
1397pub const GRAPHICS_INVALID_VISIBLEREGION_SIZE = 0xC01E033B;
1398pub const GRAPHICS_INVALID_STRIDE = 0xC01E033C;
1399pub const GRAPHICS_INVALID_PIXELFORMAT = 0xC01E033D;
1400pub const GRAPHICS_INVALID_COLORBASIS = 0xC01E033E;
1401pub const GRAPHICS_INVALID_PIXELVALUEACCESSMODE = 0xC01E033F;
1402pub const GRAPHICS_TARGET_NOT_IN_TOPOLOGY = 0xC01E0340;
1403pub const GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT = 0xC01E0341;
1404pub const GRAPHICS_VIDPN_SOURCE_IN_USE = 0xC01E0342;
1405pub const GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN = 0xC01E0343;
1406pub const GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL = 0xC01E0344;
1407pub const GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION = 0xC01E0345;
1408pub const GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED = 0xC01E0346;
1409pub const GRAPHICS_INVALID_GAMMA_RAMP = 0xC01E0347;
1410pub const GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED = 0xC01E0348;
1411pub const GRAPHICS_MULTISAMPLING_NOT_SUPPORTED = 0xC01E0349;
1412pub const GRAPHICS_MODE_NOT_IN_MODESET = 0xC01E034A;
1413pub const GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON = 0xC01E034D;
1414pub const GRAPHICS_INVALID_PATH_CONTENT_TYPE = 0xC01E034E;
1415pub const GRAPHICS_INVALID_COPYPROTECTION_TYPE = 0xC01E034F;
1416pub const GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS = 0xC01E0350;
1417pub const GRAPHICS_INVALID_SCANLINE_ORDERING = 0xC01E0352;
1418pub const GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED = 0xC01E0353;
1419pub const GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS = 0xC01E0354;
1420pub const GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT = 0xC01E0355;
1421pub const GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM = 0xC01E0356;
1422pub const GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN = 0xC01E0357;
1423pub const GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT = 0xC01E0358;
1424pub const GRAPHICS_MAX_NUM_PATHS_REACHED = 0xC01E0359;
1425pub const GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION = 0xC01E035A;
1426pub const GRAPHICS_INVALID_CLIENT_TYPE = 0xC01E035B;
1427pub const GRAPHICS_CLIENTVIDPN_NOT_SET = 0xC01E035C;
1428pub const GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED = 0xC01E0400;
1429pub const GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED = 0xC01E0401;
1430pub const GRAPHICS_NOT_A_LINKED_ADAPTER = 0xC01E0430;
1431pub const GRAPHICS_LEADLINK_NOT_ENUMERATED = 0xC01E0431;
1432pub const GRAPHICS_CHAINLINKS_NOT_ENUMERATED = 0xC01E0432;
1433pub const GRAPHICS_ADAPTER_CHAIN_NOT_READY = 0xC01E0433;
1434pub const GRAPHICS_CHAINLINKS_NOT_STARTED = 0xC01E0434;
1435pub const GRAPHICS_CHAINLINKS_NOT_POWERED_ON = 0xC01E0435;
1436pub const GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE = 0xC01E0436;
1437pub const GRAPHICS_NOT_POST_DEVICE_DRIVER = 0xC01E0438;
1438pub const GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED = 0xC01E043B;
1439pub const GRAPHICS_OPM_NOT_SUPPORTED = 0xC01E0500;
1440pub const GRAPHICS_COPP_NOT_SUPPORTED = 0xC01E0501;
1441pub const GRAPHICS_UAB_NOT_SUPPORTED = 0xC01E0502;
1442pub const GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS = 0xC01E0503;
1443pub const GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL = 0xC01E0504;
1444pub const GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST = 0xC01E0505;
1445pub const GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME = 0xC01E0506;
1446pub const GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP = 0xC01E0507;
1447pub const GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED = 0xC01E0508;
1448pub const GRAPHICS_OPM_INVALID_POINTER = 0xC01E050A;
1449pub const GRAPHICS_OPM_INTERNAL_ERROR = 0xC01E050B;
1450pub const GRAPHICS_OPM_INVALID_HANDLE = 0xC01E050C;
1451pub const GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE = 0xC01E050D;
1452pub const GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH = 0xC01E050E;
1453pub const GRAPHICS_OPM_SPANNING_MODE_ENABLED = 0xC01E050F;
1454pub const GRAPHICS_OPM_THEATER_MODE_ENABLED = 0xC01E0510;
1455pub const GRAPHICS_PVP_HFS_FAILED = 0xC01E0511;
1456pub const GRAPHICS_OPM_INVALID_SRM = 0xC01E0512;
1457pub const GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP = 0xC01E0513;
1458pub const GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP = 0xC01E0514;
1459pub const GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA = 0xC01E0515;
1460pub const GRAPHICS_OPM_HDCP_SRM_NEVER_SET = 0xC01E0516;
1461pub const GRAPHICS_OPM_RESOLUTION_TOO_HIGH = 0xC01E0517;
1462pub const GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE = 0xC01E0518;
1463pub const GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS = 0xC01E051A;
1464pub const GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS = 0xC01E051B;
1465pub const GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS = 0xC01E051C;
1466pub const GRAPHICS_OPM_INVALID_INFORMATION_REQUEST = 0xC01E051D;
1467pub const GRAPHICS_OPM_DRIVER_INTERNAL_ERROR = 0xC01E051E;
1468pub const GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS = 0xC01E051F;
1469pub const GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED = 0xC01E0520;
1470pub const GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST = 0xC01E0521;
1471pub const GRAPHICS_I2C_NOT_SUPPORTED = 0xC01E0580;
1472pub const GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST = 0xC01E0581;
1473pub const GRAPHICS_I2C_ERROR_TRANSMITTING_DATA = 0xC01E0582;
1474pub const GRAPHICS_I2C_ERROR_RECEIVING_DATA = 0xC01E0583;
1475pub const GRAPHICS_DDCCI_VCP_NOT_SUPPORTED = 0xC01E0584;
1476pub const GRAPHICS_DDCCI_INVALID_DATA = 0xC01E0585;
1477pub const GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE = 0xC01E0586;
1478pub const GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING = 0xC01E0587;
1479pub const GRAPHICS_MCA_INTERNAL_ERROR = 0xC01E0588;
1480pub const GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND = 0xC01E0589;
1481pub const GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH = 0xC01E058A;
1482pub const GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM = 0xC01E058B;
1483pub const GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE = 0xC01E058C;
1484pub const GRAPHICS_MONITOR_NO_LONGER_EXISTS = 0xC01E058D;
1485pub const GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED = 0xC01E05E0;
1486pub const GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME = 0xC01E05E1;
1487pub const GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP = 0xC01E05E2;
1488pub const GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED = 0xC01E05E3;
1489pub const GRAPHICS_INVALID_POINTER = 0xC01E05E4;
1490pub const GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE = 0xC01E05E5;
1491pub const GRAPHICS_PARAMETER_ARRAY_TOO_SMALL = 0xC01E05E6;
1492pub const GRAPHICS_INTERNAL_ERROR = 0xC01E05E7;
1493pub const GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS = 0xC01E05E8;
1494pub const FVE_LOCKED_VOLUME = 0xC0210000;
1495pub const FVE_NOT_ENCRYPTED = 0xC0210001;
1496pub const FVE_BAD_INFORMATION = 0xC0210002;
1497pub const FVE_TOO_SMALL = 0xC0210003;
1498pub const FVE_FAILED_WRONG_FS = 0xC0210004;
1499pub const FVE_FAILED_BAD_FS = 0xC0210005;
1500pub const FVE_FS_NOT_EXTENDED = 0xC0210006;
1501pub const FVE_FS_MOUNTED = 0xC0210007;
1502pub const FVE_NO_LICENSE = 0xC0210008;
1503pub const FVE_ACTION_NOT_ALLOWED = 0xC0210009;
1504pub const FVE_BAD_DATA = 0xC021000A;
1505pub const FVE_VOLUME_NOT_BOUND = 0xC021000B;
1506pub const FVE_NOT_DATA_VOLUME = 0xC021000C;
1507pub const FVE_CONV_READ_ERROR = 0xC021000D;
1508pub const FVE_CONV_WRITE_ERROR = 0xC021000E;
1509pub const FVE_OVERLAPPED_UPDATE = 0xC021000F;
1510pub const FVE_FAILED_SECTOR_SIZE = 0xC0210010;
1511pub const FVE_FAILED_AUTHENTICATION = 0xC0210011;
1512pub const FVE_NOT_OS_VOLUME = 0xC0210012;
1513pub const FVE_KEYFILE_NOT_FOUND = 0xC0210013;
1514pub const FVE_KEYFILE_INVALID = 0xC0210014;
1515pub const FVE_KEYFILE_NO_VMK = 0xC0210015;
1516pub const FVE_TPM_DISABLED = 0xC0210016;
1517pub const FVE_TPM_SRK_AUTH_NOT_ZERO = 0xC0210017;
1518pub const FVE_TPM_INVALID_PCR = 0xC0210018;
1519pub const FVE_TPM_NO_VMK = 0xC0210019;
1520pub const FVE_PIN_INVALID = 0xC021001A;
1521pub const FVE_AUTH_INVALID_APPLICATION = 0xC021001B;
1522pub const FVE_AUTH_INVALID_CONFIG = 0xC021001C;
1523pub const FVE_DEBUGGER_ENABLED = 0xC021001D;
1524pub const FVE_DRY_RUN_FAILED = 0xC021001E;
1525pub const FVE_BAD_METADATA_POINTER = 0xC021001F;
1526pub const FVE_OLD_METADATA_COPY = 0xC0210020;
1527pub const FVE_REBOOT_REQUIRED = 0xC0210021;
1528pub const FVE_RAW_ACCESS = 0xC0210022;
1529pub const FVE_RAW_BLOCKED = 0xC0210023;
1530pub const FVE_NO_FEATURE_LICENSE = 0xC0210026;
1531pub const FVE_POLICY_USER_DISABLE_RDV_NOT_ALLOWED = 0xC0210027;
1532pub const FVE_CONV_RECOVERY_FAILED = 0xC0210028;
1533pub const FVE_VIRTUALIZED_SPACE_TOO_BIG = 0xC0210029;
1534pub const FVE_VOLUME_TOO_SMALL = 0xC0210030;
1535pub const FWP_CALLOUT_NOT_FOUND = 0xC0220001;
1536pub const FWP_CONDITION_NOT_FOUND = 0xC0220002;
1537pub const FWP_FILTER_NOT_FOUND = 0xC0220003;
1538pub const FWP_LAYER_NOT_FOUND = 0xC0220004;
1539pub const FWP_PROVIDER_NOT_FOUND = 0xC0220005;
1540pub const FWP_PROVIDER_CONTEXT_NOT_FOUND = 0xC0220006;
1541pub const FWP_SUBLAYER_NOT_FOUND = 0xC0220007;
1542pub const FWP_NOT_FOUND = 0xC0220008;
1543pub const FWP_ALREADY_EXISTS = 0xC0220009;
1544pub const FWP_IN_USE = 0xC022000A;
1545pub const FWP_DYNAMIC_SESSION_IN_PROGRESS = 0xC022000B;
1546pub const FWP_WRONG_SESSION = 0xC022000C;
1547pub const FWP_NO_TXN_IN_PROGRESS = 0xC022000D;
1548pub const FWP_TXN_IN_PROGRESS = 0xC022000E;
1549pub const FWP_TXN_ABORTED = 0xC022000F;
1550pub const FWP_SESSION_ABORTED = 0xC0220010;
1551pub const FWP_INCOMPATIBLE_TXN = 0xC0220011;
1552pub const FWP_TIMEOUT = 0xC0220012;
1553pub const FWP_NET_EVENTS_DISABLED = 0xC0220013;
1554pub const FWP_INCOMPATIBLE_LAYER = 0xC0220014;
1555pub const FWP_KM_CLIENTS_ONLY = 0xC0220015;
1556pub const FWP_LIFETIME_MISMATCH = 0xC0220016;
1557pub const FWP_BUILTIN_OBJECT = 0xC0220017;
1558pub const FWP_TOO_MANY_BOOTTIME_FILTERS = 0xC0220018;
1559pub const FWP_TOO_MANY_CALLOUTS = 0xC0220018;
1560pub const FWP_NOTIFICATION_DROPPED = 0xC0220019;
1561pub const FWP_TRAFFIC_MISMATCH = 0xC022001A;
1562pub const FWP_INCOMPATIBLE_SA_STATE = 0xC022001B;
1563pub const FWP_NULL_POINTER = 0xC022001C;
1564pub const FWP_INVALID_ENUMERATOR = 0xC022001D;
1565pub const FWP_INVALID_FLAGS = 0xC022001E;
1566pub const FWP_INVALID_NET_MASK = 0xC022001F;
1567pub const FWP_INVALID_RANGE = 0xC0220020;
1568pub const FWP_INVALID_INTERVAL = 0xC0220021;
1569pub const FWP_ZERO_LENGTH_ARRAY = 0xC0220022;
1570pub const FWP_NULL_DISPLAY_NAME = 0xC0220023;
1571pub const FWP_INVALID_ACTION_TYPE = 0xC0220024;
1572pub const FWP_INVALID_WEIGHT = 0xC0220025;
1573pub const FWP_MATCH_TYPE_MISMATCH = 0xC0220026;
1574pub const FWP_TYPE_MISMATCH = 0xC0220027;
1575pub const FWP_OUT_OF_BOUNDS = 0xC0220028;
1576pub const FWP_RESERVED = 0xC0220029;
1577pub const FWP_DUPLICATE_CONDITION = 0xC022002A;
1578pub const FWP_DUPLICATE_KEYMOD = 0xC022002B;
1579pub const FWP_ACTION_INCOMPATIBLE_WITH_LAYER = 0xC022002C;
1580pub const FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER = 0xC022002D;
1581pub const FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER = 0xC022002E;
1582pub const FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT = 0xC022002F;
1583pub const FWP_INCOMPATIBLE_AUTH_METHOD = 0xC0220030;
1584pub const FWP_INCOMPATIBLE_DH_GROUP = 0xC0220031;
1585pub const FWP_EM_NOT_SUPPORTED = 0xC0220032;
1586pub const FWP_NEVER_MATCH = 0xC0220033;
1587pub const FWP_PROVIDER_CONTEXT_MISMATCH = 0xC0220034;
1588pub const FWP_INVALID_PARAMETER = 0xC0220035;
1589pub const FWP_TOO_MANY_SUBLAYERS = 0xC0220036;
1590pub const FWP_CALLOUT_NOTIFICATION_FAILED = 0xC0220037;
1591pub const FWP_INCOMPATIBLE_AUTH_CONFIG = 0xC0220038;
1592pub const FWP_INCOMPATIBLE_CIPHER_CONFIG = 0xC0220039;
1593pub const FWP_DUPLICATE_AUTH_METHOD = 0xC022003C;
1594pub const FWP_TCPIP_NOT_READY = 0xC0220100;
1595pub const FWP_INJECT_HANDLE_CLOSING = 0xC0220101;
1596pub const FWP_INJECT_HANDLE_STALE = 0xC0220102;
1597pub const FWP_CANNOT_PEND = 0xC0220103;
1598pub const NDIS_CLOSING = 0xC0230002;
1599pub const NDIS_BAD_VERSION = 0xC0230004;
1600pub const NDIS_BAD_CHARACTERISTICS = 0xC0230005;
1601pub const NDIS_ADAPTER_NOT_FOUND = 0xC0230006;
1602pub const NDIS_OPEN_FAILED = 0xC0230007;
1603pub const NDIS_DEVICE_FAILED = 0xC0230008;
1604pub const NDIS_MULTICAST_FULL = 0xC0230009;
1605pub const NDIS_MULTICAST_EXISTS = 0xC023000A;
1606pub const NDIS_MULTICAST_NOT_FOUND = 0xC023000B;
1607pub const NDIS_REQUEST_ABORTED = 0xC023000C;
1608pub const NDIS_RESET_IN_PROGRESS = 0xC023000D;
1609pub const NDIS_INVALID_PACKET = 0xC023000F;
1610pub const NDIS_INVALID_DEVICE_REQUEST = 0xC0230010;
1611pub const NDIS_ADAPTER_NOT_READY = 0xC0230011;
1612pub const NDIS_INVALID_LENGTH = 0xC0230014;
1613pub const NDIS_INVALID_DATA = 0xC0230015;
1614pub const NDIS_BUFFER_TOO_SHORT = 0xC0230016;
1615pub const NDIS_INVALID_OID = 0xC0230017;
1616pub const NDIS_ADAPTER_REMOVED = 0xC0230018;
1617pub const NDIS_UNSUPPORTED_MEDIA = 0xC0230019;
1618pub const NDIS_GROUP_ADDRESS_IN_USE = 0xC023001A;
1619pub const NDIS_FILE_NOT_FOUND = 0xC023001B;
1620pub const NDIS_ERROR_READING_FILE = 0xC023001C;
1621pub const NDIS_ALREADY_MAPPED = 0xC023001D;
1622pub const NDIS_RESOURCE_CONFLICT = 0xC023001E;
1623pub const NDIS_MEDIA_DISCONNECTED = 0xC023001F;
1624pub const NDIS_INVALID_ADDRESS = 0xC0230022;
1625pub const NDIS_PAUSED = 0xC023002A;
1626pub const NDIS_INTERFACE_NOT_FOUND = 0xC023002B;
1627pub const NDIS_UNSUPPORTED_REVISION = 0xC023002C;
1628pub const NDIS_INVALID_PORT = 0xC023002D;
1629pub const NDIS_INVALID_PORT_STATE = 0xC023002E;
1630pub const NDIS_LOW_POWER_STATE = 0xC023002F;
1631pub const NDIS_NOT_SUPPORTED = 0xC02300BB;
1632pub const NDIS_OFFLOAD_POLICY = 0xC023100F;
1633pub const NDIS_OFFLOAD_CONNECTION_REJECTED = 0xC0231012;
1634pub const NDIS_OFFLOAD_PATH_REJECTED = 0xC0231013;
1635pub const NDIS_DOT11_AUTO_CONFIG_ENABLED = 0xC0232000;
1636pub const NDIS_DOT11_MEDIA_IN_USE = 0xC0232001;
1637pub const NDIS_DOT11_POWER_STATE_INVALID = 0xC0232002;
1638pub const NDIS_PM_WOL_PATTERN_LIST_FULL = 0xC0232003;
1639pub const NDIS_PM_PROTOCOL_OFFLOAD_LIST_FULL = 0xC0232004;
1640pub const IPSEC_BAD_SPI = 0xC0360001;
1641pub const IPSEC_SA_LIFETIME_EXPIRED = 0xC0360002;
1642pub const IPSEC_WRONG_SA = 0xC0360003;
1643pub const IPSEC_REPLAY_CHECK_FAILED = 0xC0360004;
1644pub const IPSEC_INVALID_PACKET = 0xC0360005;
1645pub const IPSEC_INTEGRITY_CHECK_FAILED = 0xC0360006;
1646pub const IPSEC_CLEAR_TEXT_DROP = 0xC0360007;
1647pub const IPSEC_AUTH_FIREWALL_DROP = 0xC0360008;
1648pub const IPSEC_THROTTLE_DROP = 0xC0360009;
1649pub const IPSEC_DOSP_BLOCK = 0xC0368000;
1650pub const IPSEC_DOSP_RECEIVED_MULTICAST = 0xC0368001;
1651pub const IPSEC_DOSP_INVALID_PACKET = 0xC0368002;
1652pub const IPSEC_DOSP_STATE_LOOKUP_FAILED = 0xC0368003;
1653pub const IPSEC_DOSP_MAX_ENTRIES = 0xC0368004;
1654pub const IPSEC_DOSP_KEYMOD_NOT_ALLOWED = 0xC0368005;
1655pub const IPSEC_DOSP_MAX_PER_IP_RATELIMIT_QUEUES = 0xC0368006;
1656pub const VOLMGR_MIRROR_NOT_SUPPORTED = 0xC038005B;
1657pub const VOLMGR_RAID5_NOT_SUPPORTED = 0xC038005C;
1658pub const VIRTDISK_PROVIDER_NOT_FOUND = 0xC03A0014;
1659pub const VIRTDISK_NOT_VIRTUAL_DISK = 0xC03A0015;
1660pub const VHD_PARENT_VHD_ACCESS_DENIED = 0xC03A0016;
1661pub const VHD_CHILD_PARENT_SIZE_MISMATCH = 0xC03A0017;
1662pub const VHD_DIFFERENCING_CHAIN_CYCLE_DETECTED = 0xC03A0018;
1663pub const VHD_DIFFERENCING_CHAIN_ERROR_IN_PARENT = 0xC03A0019;
lib/std/os/windows/ws2_32.zig created+257
...@@ -0,0 +1,257 @@
1usingnamespace @import("bits.zig");
2
3pub const SOCKET = *@OpaqueType();
4pub const INVALID_SOCKET = @intToPtr(SOCKET, ~@as(usize, 0));
5pub const SOCKET_ERROR = -1;
6
7pub const WSADESCRIPTION_LEN = 256;
8pub const WSASYS_STATUS_LEN = 128;
9
10pub const WSADATA = if (usize.bit_count == u64.bit_count)
11 extern struct {
12 wVersion: WORD,
13 wHighVersion: WORD,
14 iMaxSockets: u16,
15 iMaxUdpDg: u16,
16 lpVendorInfo: *u8,
17 szDescription: [WSADESCRIPTION_LEN + 1]u8,
18 szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
19 }
20else
21 extern struct {
22 wVersion: WORD,
23 wHighVersion: WORD,
24 szDescription: [WSADESCRIPTION_LEN + 1]u8,
25 szSystemStatus: [WSASYS_STATUS_LEN + 1]u8,
26 iMaxSockets: u16,
27 iMaxUdpDg: u16,
28 lpVendorInfo: *u8,
29 };
30
31pub const MAX_PROTOCOL_CHAIN = 7;
32
33pub const WSAPROTOCOLCHAIN = extern struct {
34 ChainLen: c_int,
35 ChainEntries: [MAX_PROTOCOL_CHAIN]DWORD,
36};
37
38pub const WSAPROTOCOL_LEN = 255;
39
40pub const WSAPROTOCOL_INFOA = extern struct {
41 dwServiceFlags1: DWORD,
42 dwServiceFlags2: DWORD,
43 dwServiceFlags3: DWORD,
44 dwServiceFlags4: DWORD,
45 dwProviderFlags: DWORD,
46 ProviderId: GUID,
47 dwCatalogEntryId: DWORD,
48 ProtocolChain: WSAPROTOCOLCHAIN,
49 iVersion: c_int,
50 iAddressFamily: c_int,
51 iMaxSockAddr: c_int,
52 iMinSockAddr: c_int,
53 iSocketType: c_int,
54 iProtocol: c_int,
55 iProtocolMaxOffset: c_int,
56 iNetworkByteOrder: c_int,
57 iSecurityScheme: c_int,
58 dwMessageSize: DWORD,
59 dwProviderReserved: DWORD,
60 szProtocol: [WSAPROTOCOL_LEN + 1]CHAR,
61};
62
63pub const WSAPROTOCOL_INFOW = extern struct {
64 dwServiceFlags1: DWORD,
65 dwServiceFlags2: DWORD,
66 dwServiceFlags3: DWORD,
67 dwServiceFlags4: DWORD,
68 dwProviderFlags: DWORD,
69 ProviderId: GUID,
70 dwCatalogEntryId: DWORD,
71 ProtocolChain: WSAPROTOCOLCHAIN,
72 iVersion: c_int,
73 iAddressFamily: c_int,
74 iMaxSockAddr: c_int,
75 iMinSockAddr: c_int,
76 iSocketType: c_int,
77 iProtocol: c_int,
78 iProtocolMaxOffset: c_int,
79 iNetworkByteOrder: c_int,
80 iSecurityScheme: c_int,
81 dwMessageSize: DWORD,
82 dwProviderReserved: DWORD,
83 szProtocol: [WSAPROTOCOL_LEN + 1]WCHAR,
84};
85
86pub const GROUP = u32;
87
88pub const SG_UNCONSTRAINED_GROUP = 0x1;
89pub const SG_CONSTRAINED_GROUP = 0x2;
90
91pub const WSA_FLAG_OVERLAPPED = 0x01;
92pub const WSA_FLAG_MULTIPOINT_C_ROOT = 0x02;
93pub const WSA_FLAG_MULTIPOINT_C_LEAF = 0x04;
94pub const WSA_FLAG_MULTIPOINT_D_ROOT = 0x08;
95pub const WSA_FLAG_MULTIPOINT_D_LEAF = 0x10;
96pub const WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40;
97pub const WSA_FLAG_NO_HANDLE_INHERIT = 0x80;
98
99pub const WSAEVENT = HANDLE;
100
101pub const WSAOVERLAPPED = extern struct {
102 Internal: DWORD,
103 InternalHigh: DWORD,
104 Offset: DWORD,
105 OffsetHigh: DWORD,
106 hEvent: ?WSAEVENT,
107};
108
109pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (
110 dwError: DWORD,
111 cbTransferred: DWORD,
112 lpOverlapped: *WSAOVERLAPPED,
113 dwFlags: DWORD
114) void;
115
116pub const WSA_INVALID_HANDLE = 6;
117pub const WSA_NOT_ENOUGH_MEMORY = 8;
118pub const WSA_INVALID_PARAMETER = 87;
119pub const WSA_OPERATION_ABORTED = 995;
120pub const WSA_IO_INCOMPLETE = 996;
121pub const WSA_IO_PENDING = 997;
122pub const WSAEINTR = 10004;
123pub const WSAEBADF = 10009;
124pub const WSAEACCES = 10013;
125pub const WSAEFAULT = 10014;
126pub const WSAEINVAL = 10022;
127pub const WSAEMFILE = 10024;
128pub const WSAEWOULDBLOCK = 10035;
129pub const WSAEINPROGRESS = 10036;
130pub const WSAEALREADY = 10037;
131pub const WSAENOTSOCK = 10038;
132pub const WSAEDESTADDRREQ = 10039;
133pub const WSAEMSGSIZE = 10040;
134pub const WSAEPROTOTYPE = 10041;
135pub const WSAENOPROTOOPT = 10042;
136pub const WSAEPROTONOSUPPORT = 10043;
137pub const WSAESOCKTNOSUPPORT = 10044;
138pub const WSAEOPNOTSUPP = 10045;
139pub const WSAEPFNOSUPPORT = 10046;
140pub const WSAEAFNOSUPPORT = 10047;
141pub const WSAEADDRINUSE = 10048;
142pub const WSAEADDRNOTAVAIL = 10049;
143pub const WSAENETDOWN = 10050;
144pub const WSAENETUNREACH = 10051;
145pub const WSAENETRESET = 10052;
146pub const WSAECONNABORTED = 10053;
147pub const WSAECONNRESET = 10054;
148pub const WSAENOBUFS = 10055;
149pub const WSAEISCONN = 10056;
150pub const WSAENOTCONN = 10057;
151pub const WSAESHUTDOWN = 10058;
152pub const WSAETOOMANYREFS = 10059;
153pub const WSAETIMEDOUT = 10060;
154pub const WSAECONNREFUSED = 10061;
155pub const WSAELOOP = 10062;
156pub const WSAENAMETOOLONG = 10063;
157pub const WSAEHOSTDOWN = 10064;
158pub const WSAEHOSTUNREACH = 10065;
159pub const WSAENOTEMPTY = 10066;
160pub const WSAEPROCLIM = 10067;
161pub const WSAEUSERS = 10068;
162pub const WSAEDQUOT = 10069;
163pub const WSAESTALE = 10070;
164pub const WSAEREMOTE = 10071;
165pub const WSASYSNOTREADY = 10091;
166pub const WSAVERNOTSUPPORTED = 10092;
167pub const WSANOTINITIALISED = 10093;
168pub const WSAEDISCON = 10101;
169pub const WSAENOMORE = 10102;
170pub const WSAECANCELLED = 10103;
171pub const WSAEINVALIDPROCTABLE = 10104;
172pub const WSAEINVALIDPROVIDER = 10105;
173pub const WSAEPROVIDERFAILEDINIT = 10106;
174pub const WSASYSCALLFAILURE = 10107;
175pub const WSASERVICE_NOT_FOUND = 10108;
176pub const WSATYPE_NOT_FOUND = 10109;
177pub const WSA_E_NO_MORE = 10110;
178pub const WSA_E_CANCELLED = 10111;
179pub const WSAEREFUSED = 10112;
180pub const WSAHOST_NOT_FOUND = 11001;
181pub const WSATRY_AGAIN = 11002;
182pub const WSANO_RECOVERY = 11003;
183pub const WSANO_DATA = 11004;
184pub const WSA_QOS_RECEIVERS = 11005;
185pub const WSA_QOS_SENDERS = 11006;
186pub const WSA_QOS_NO_SENDERS = 11007;
187pub const WSA_QOS_NO_RECEIVERS = 11008;
188pub const WSA_QOS_REQUEST_CONFIRMED = 11009;
189pub const WSA_QOS_ADMISSION_FAILURE = 11010;
190pub const WSA_QOS_POLICY_FAILURE = 11011;
191pub const WSA_QOS_BAD_STYLE = 11012;
192pub const WSA_QOS_BAD_OBJECT = 11013;
193pub const WSA_QOS_TRAFFIC_CTRL_ERROR = 11014;
194pub const WSA_QOS_GENERIC_ERROR = 11015;
195pub const WSA_QOS_ESERVICETYPE = 11016;
196pub const WSA_QOS_EFLOWSPEC = 11017;
197pub const WSA_QOS_EPROVSPECBUF = 11018;
198pub const WSA_QOS_EFILTERSTYLE = 11019;
199pub const WSA_QOS_EFILTERTYPE = 11020;
200pub const WSA_QOS_EFILTERCOUNT = 11021;
201pub const WSA_QOS_EOBJLENGTH = 11022;
202pub const WSA_QOS_EFLOWCOUNT = 11023;
203pub const WSA_QOS_EUNKOWNPSOBJ = 11024;
204pub const WSA_QOS_EPOLICYOBJ = 11025;
205pub const WSA_QOS_EFLOWDESC = 11026;
206pub const WSA_QOS_EPSFLOWSPEC = 11027;
207pub const WSA_QOS_EPSFILTERSPEC = 11028;
208pub const WSA_QOS_ESDMODEOBJ = 11029;
209pub const WSA_QOS_ESHAPERATEOBJ = 11030;
210pub const WSA_QOS_RESERVED_PETYPE = 11031;
211
212
213/// no parameters
214const IOC_VOID = 0x80000000;
215/// copy out parameters
216const IOC_OUT = 0x40000000;
217/// copy in parameters
218const IOC_IN = 0x80000000;
219
220/// The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.
221const IOC_WS2 = 0x08000000;
222
223pub const SIO_BASE_HANDLE = IOC_OUT | IOC_WS2 | 34;
224
225pub extern "ws2_32" stdcallcc fn WSAStartup(
226 wVersionRequired: WORD,
227 lpWSAData: *WSADATA,
228) c_int;
229pub extern "ws2_32" stdcallcc fn WSACleanup() c_int;
230pub extern "ws2_32" stdcallcc fn WSAGetLastError() c_int;
231pub extern "ws2_32" stdcallcc fn WSASocketA(
232 af: c_int,
233 type: c_int,
234 protocol: c_int,
235 lpProtocolInfo: ?*WSAPROTOCOL_INFOA,
236 g: GROUP,
237 dwFlags: DWORD,
238) SOCKET;
239pub extern "ws2_32" stdcallcc fn WSASocketW(
240 af: c_int,
241 type: c_int,
242 protocol: c_int,
243 lpProtocolInfo: ?*WSAPROTOCOL_INFOW,
244 g: GROUP,
245 dwFlags: DWORD,
246) SOCKET;
247pub extern "ws2_32" stdcallcc fn WSAIoctl(
248 s: SOCKET,
249 dwIoControlCode: DWORD,
250 lpvInBuffer: ?*const c_void,
251 cbInBuffer: DWORD,
252 lpvOutBuffer: ?LPVOID,
253 cbOutBuffer: DWORD,
254 lpcbBytesReturned: LPDWORD,
255 lpOverlapped: ?*WSAOVERLAPPED,
256 lpCompletionRoutine: ?*WSAOVERLAPPED_COMPLETION_ROUTINE,
257) c_int;
lib/std/os/zen.zig+2-2
...@@ -138,7 +138,7 @@ pub const Syscall = enum(usize) {...@@ -138,7 +138,7 @@ pub const Syscall = enum(usize) {
138////////////////////138////////////////////
139139
140pub fn exit(status: i32) noreturn {140pub fn exit(status: i32) noreturn {
141 _ = syscall1(Syscall.exit, @bitCast(usize, isize(status)));141 _ = syscall1(Syscall.exit, @bitCast(usize, @as(isize, status)));
142 unreachable;142 unreachable;
143}143}
144144
...@@ -167,7 +167,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {...@@ -167,7 +167,7 @@ pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
167}167}
168168
169pub fn createThread(function: fn () void) u16 {169pub fn createThread(function: fn () void) u16 {
170 return u16(syscall1(Syscall.createThread, @ptrToInt(function)));170 return @as(u16, syscall1(Syscall.createThread, @ptrToInt(function)));
171}171}
172172
173/////////////////////////173/////////////////////////
lib/std/packed_int_array.zig+18-18
...@@ -193,7 +193,7 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian,...@@ -193,7 +193,7 @@ pub fn PackedIntArrayEndian(comptime Int: type, comptime endian: builtin.Endian,
193 ///Initialize a packed array using an unpacked array193 ///Initialize a packed array using an unpacked array
194 /// or, more likely, an array literal.194 /// or, more likely, an array literal.
195 pub fn init(ints: [int_count]Int) Self {195 pub fn init(ints: [int_count]Int) Self {
196 var self = Self(undefined);196 var self = @as(Self, undefined);
197 for (ints) |int, i| self.set(i, int);197 for (ints) |int, i| self.set(i, int);
198 return self;198 return self;
199 }199 }
...@@ -328,11 +328,11 @@ test "PackedIntArray" {...@@ -328,11 +328,11 @@ test "PackedIntArray" {
328 const expected_bytes = ((bits * int_count) + 7) / 8;328 const expected_bytes = ((bits * int_count) + 7) / 8;
329 testing.expect(@sizeOf(PackedArray) == expected_bytes);329 testing.expect(@sizeOf(PackedArray) == expected_bytes);
330330
331 var data = PackedArray(undefined);331 var data = @as(PackedArray, undefined);
332332
333 //write values, counting up333 //write values, counting up
334 var i = usize(0);334 var i = @as(usize, 0);
335 var count = I(0);335 var count = @as(I, 0);
336 while (i < data.len()) : (i += 1) {336 while (i < data.len()) : (i += 1) {
337 data.set(i, count);337 data.set(i, count);
338 if (bits > 0) count +%= 1;338 if (bits > 0) count +%= 1;
...@@ -352,7 +352,7 @@ test "PackedIntArray" {...@@ -352,7 +352,7 @@ test "PackedIntArray" {
352test "PackedIntArray init" {352test "PackedIntArray init" {
353 const PackedArray = PackedIntArray(u3, 8);353 const PackedArray = PackedIntArray(u3, 8);
354 var packed_array = PackedArray.init([_]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });354 var packed_array = PackedArray.init([_]u3{ 0, 1, 2, 3, 4, 5, 6, 7 });
355 var i = usize(0);355 var i = @as(usize, 0);
356 while (i < packed_array.len()) : (i += 1) testing.expect(packed_array.get(i) == i);356 while (i < packed_array.len()) : (i += 1) testing.expect(packed_array.get(i) == i);
357}357}
358358
...@@ -375,8 +375,8 @@ test "PackedIntSlice" {...@@ -375,8 +375,8 @@ test "PackedIntSlice" {
375 var data = P.init(&buffer, int_count);375 var data = P.init(&buffer, int_count);
376376
377 //write values, counting up377 //write values, counting up
378 var i = usize(0);378 var i = @as(usize, 0);
379 var count = I(0);379 var count = @as(I, 0);
380 while (i < data.len()) : (i += 1) {380 while (i < data.len()) : (i += 1) {
381 data.set(i, count);381 data.set(i, count);
382 if (bits > 0) count +%= 1;382 if (bits > 0) count +%= 1;
...@@ -402,11 +402,11 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {...@@ -402,11 +402,11 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
402 const Int = @IntType(false, bits);402 const Int = @IntType(false, bits);
403403
404 const PackedArray = PackedIntArray(Int, int_count);404 const PackedArray = PackedIntArray(Int, int_count);
405 var packed_array = PackedArray(undefined);405 var packed_array = @as(PackedArray, undefined);
406406
407 const limit = (1 << bits);407 const limit = (1 << bits);
408408
409 var i = usize(0);409 var i = @as(usize, 0);
410 while (i < packed_array.len()) : (i += 1) {410 while (i < packed_array.len()) : (i += 1) {
411 packed_array.set(i, @intCast(Int, i % limit));411 packed_array.set(i, @intCast(Int, i % limit));
412 }412 }
...@@ -463,20 +463,20 @@ test "PackedIntSlice accumulating bit offsets" {...@@ -463,20 +463,20 @@ test "PackedIntSlice accumulating bit offsets" {
463 // anything463 // anything
464 {464 {
465 const PackedArray = PackedIntArray(u3, 16);465 const PackedArray = PackedIntArray(u3, 16);
466 var packed_array = PackedArray(undefined);466 var packed_array = @as(PackedArray, undefined);
467467
468 var packed_slice = packed_array.slice(0, packed_array.len());468 var packed_slice = packed_array.slice(0, packed_array.len());
469 var i = usize(0);469 var i = @as(usize, 0);
470 while (i < packed_array.len() - 1) : (i += 1) {470 while (i < packed_array.len() - 1) : (i += 1) {
471 packed_slice = packed_slice.slice(1, packed_slice.len());471 packed_slice = packed_slice.slice(1, packed_slice.len());
472 }472 }
473 }473 }
474 {474 {
475 const PackedArray = PackedIntArray(u11, 88);475 const PackedArray = PackedIntArray(u11, 88);
476 var packed_array = PackedArray(undefined);476 var packed_array = @as(PackedArray, undefined);
477477
478 var packed_slice = packed_array.slice(0, packed_array.len());478 var packed_slice = packed_array.slice(0, packed_array.len());
479 var i = usize(0);479 var i = @as(usize, 0);
480 while (i < packed_array.len() - 1) : (i += 1) {480 while (i < packed_array.len() - 1) : (i += 1) {
481 packed_slice = packed_slice.slice(1, packed_slice.len());481 packed_slice = packed_slice.slice(1, packed_slice.len());
482 }482 }
...@@ -493,7 +493,7 @@ test "PackedInt(Array/Slice) sliceCast" {...@@ -493,7 +493,7 @@ test "PackedInt(Array/Slice) sliceCast" {
493 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);493 var packed_slice_cast_9 = packed_array.slice(0, (packed_array.len() / 9) * 9).sliceCast(u9);
494 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);494 const packed_slice_cast_3 = packed_slice_cast_9.sliceCast(u3);
495495
496 var i = usize(0);496 var i = @as(usize, 0);
497 while (i < packed_slice_cast_2.len()) : (i += 1) {497 while (i < packed_slice_cast_2.len()) : (i += 1) {
498 const val = switch (builtin.endian) {498 const val = switch (builtin.endian) {
499 .Big => 0b01,499 .Big => 0b01,
...@@ -518,8 +518,8 @@ test "PackedInt(Array/Slice) sliceCast" {...@@ -518,8 +518,8 @@ test "PackedInt(Array/Slice) sliceCast" {
518 i = 0;518 i = 0;
519 while (i < packed_slice_cast_3.len()) : (i += 1) {519 while (i < packed_slice_cast_3.len()) : (i += 1) {
520 const val = switch (builtin.endian) {520 const val = switch (builtin.endian) {
521 .Big => if (i % 2 == 0) u3(0b111) else u3(0b000),521 .Big => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),
522 .Little => if (i % 2 == 0) u3(0b111) else u3(0b000),522 .Little => if (i % 2 == 0) @as(u3, 0b111) else @as(u3, 0b000),
523 };523 };
524 testing.expect(packed_slice_cast_3.get(i) == val);524 testing.expect(packed_slice_cast_3.get(i) == val);
525 }525 }
...@@ -541,7 +541,7 @@ test "PackedInt(Array/Slice)Endian" {...@@ -541,7 +541,7 @@ test "PackedInt(Array/Slice)Endian" {
541 testing.expect(packed_array_be.bytes[0] == 0b00000001);541 testing.expect(packed_array_be.bytes[0] == 0b00000001);
542 testing.expect(packed_array_be.bytes[1] == 0b00100011);542 testing.expect(packed_array_be.bytes[1] == 0b00100011);
543543
544 var i = usize(0);544 var i = @as(usize, 0);
545 while (i < packed_array_be.len()) : (i += 1) {545 while (i < packed_array_be.len()) : (i += 1) {
546 testing.expect(packed_array_be.get(i) == i);546 testing.expect(packed_array_be.get(i) == i);
547 }547 }
...@@ -579,7 +579,7 @@ test "PackedInt(Array/Slice)Endian" {...@@ -579,7 +579,7 @@ test "PackedInt(Array/Slice)Endian" {
579 testing.expect(packed_array_be.bytes[3] == 0b00000001);579 testing.expect(packed_array_be.bytes[3] == 0b00000001);
580 testing.expect(packed_array_be.bytes[4] == 0b00000000);580 testing.expect(packed_array_be.bytes[4] == 0b00000000);
581581
582 var i = usize(0);582 var i = @as(usize, 0);
583 while (i < packed_array_be.len()) : (i += 1) {583 while (i < packed_array_be.len()) : (i += 1) {
584 testing.expect(packed_array_be.get(i) == i);584 testing.expect(packed_array_be.get(i) == i);
585 }585 }
lib/std/parker.zig created+180
...@@ -0,0 +1,180 @@
1const std = @import("std.zig");
2const builtin = @import("builtin");
3const time = std.time;
4const testing = std.testing;
5const assert = std.debug.assert;
6const SpinLock = std.SpinLock;
7const linux = std.os.linux;
8const windows = std.os.windows;
9
10pub const ThreadParker = switch (builtin.os) {
11 .linux => if (builtin.link_libc) PosixParker else LinuxParker,
12 .windows => WindowsParker,
13 else => if (builtin.link_libc) PosixParker else SpinParker,
14};
15
16const SpinParker = struct {
17 pub fn init() SpinParker {
18 return SpinParker{};
19 }
20 pub fn deinit(self: *SpinParker) void {}
21
22 pub fn unpark(self: *SpinParker, ptr: *const u32) void {}
23
24 pub fn park(self: *SpinParker, ptr: *const u32, expected: u32) void {
25 var backoff = SpinLock.Backoff.init();
26 while (@atomicLoad(u32, ptr, .Acquire) == expected)
27 backoff.yield();
28 }
29};
30
31const LinuxParker = struct {
32 pub fn init() LinuxParker {
33 return LinuxParker{};
34 }
35 pub fn deinit(self: *LinuxParker) void {}
36
37 pub fn unpark(self: *LinuxParker, ptr: *const u32) void {
38 const rc = linux.futex_wake(@ptrCast(*const i32, ptr), linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG, 1);
39 assert(linux.getErrno(rc) == 0);
40 }
41
42 pub fn park(self: *LinuxParker, ptr: *const u32, expected: u32) void {
43 const value = @intCast(i32, expected);
44 while (@atomicLoad(u32, ptr, .Acquire) == expected) {
45 const rc = linux.futex_wait(@ptrCast(*const i32, ptr), linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG, value, null);
46 switch (linux.getErrno(rc)) {
47 0, linux.EAGAIN => return,
48 linux.EINTR => continue,
49 linux.EINVAL => unreachable,
50 else => continue,
51 }
52 }
53 }
54};
55
56const WindowsParker = struct {
57 waiters: u32,
58
59 pub fn init() WindowsParker {
60 return WindowsParker{ .waiters = 0 };
61 }
62 pub fn deinit(self: *WindowsParker) void {}
63
64 pub fn unpark(self: *WindowsParker, ptr: *const u32) void {
65 const key = @ptrCast(*const c_void, ptr);
66 const handle = getEventHandle() orelse return;
67
68 var waiting = @atomicLoad(u32, &self.waiters, .Monotonic);
69 while (waiting != 0) {
70 waiting = @cmpxchgWeak(u32, &self.waiters, waiting, waiting - 1, .Acquire, .Monotonic) orelse {
71 const rc = windows.ntdll.NtReleaseKeyedEvent(handle, key, windows.FALSE, null);
72 assert(rc == 0);
73 return;
74 };
75 }
76 }
77
78 pub fn park(self: *WindowsParker, ptr: *const u32, expected: u32) void {
79 var spin = SpinLock.Backoff.init();
80 const ev_handle = getEventHandle();
81 const key = @ptrCast(*const c_void, ptr);
82
83 while (@atomicLoad(u32, ptr, .Monotonic) == expected) {
84 if (ev_handle) |handle| {
85 _ = @atomicRmw(u32, &self.waiters, .Add, 1, .Release);
86 const rc = windows.ntdll.NtWaitForKeyedEvent(handle, key, windows.FALSE, null);
87 assert(rc == 0);
88 } else {
89 spin.yield();
90 }
91 }
92 }
93
94 var event_handle = std.lazyInit(windows.HANDLE);
95
96 fn getEventHandle() ?windows.HANDLE {
97 if (event_handle.get()) |handle_ptr|
98 return handle_ptr.*;
99 defer event_handle.resolve();
100
101 const access_mask = windows.GENERIC_READ | windows.GENERIC_WRITE;
102 if (windows.ntdll.NtCreateKeyedEvent(&event_handle.data, access_mask, null, 0) != 0)
103 return null;
104 return event_handle.data;
105 }
106};
107
108const PosixParker = struct {
109 cond: c.pthread_cond_t,
110 mutex: c.pthread_mutex_t,
111
112 const c = std.c;
113
114 pub fn init() PosixParker {
115 return PosixParker{
116 .cond = c.PTHREAD_COND_INITIALIZER,
117 .mutex = c.PTHREAD_MUTEX_INITIALIZER,
118 };
119 }
120
121 pub fn deinit(self: *PosixParker) void {
122 // On dragonfly, the destroy functions return EINVAL if they were initialized statically.
123 const retm = c.pthread_mutex_destroy(&self.mutex);
124 assert(retm == 0 or retm == (if (builtin.os == .dragonfly) os.EINVAL else 0));
125 const retc = c.pthread_cond_destroy(&self.cond);
126 assert(retc == 0 or retc == (if (builtin.os == .dragonfly) os.EINVAL else 0));
127 }
128
129 pub fn unpark(self: *PosixParker, ptr: *const u32) void {
130 assert(c.pthread_mutex_lock(&self.mutex) == 0);
131 defer assert(c.pthread_mutex_unlock(&self.mutex) == 0);
132 assert(c.pthread_cond_signal(&self.cond) == 0);
133 }
134
135 pub fn park(self: *PosixParker, ptr: *const u32, expected: u32) void {
136 assert(c.pthread_mutex_lock(&self.mutex) == 0);
137 defer assert(c.pthread_mutex_unlock(&self.mutex) == 0);
138 while (@atomicLoad(u32, ptr, .Acquire) == expected)
139 assert(c.pthread_cond_wait(&self.cond, &self.mutex) == 0);
140 }
141};
142
143test "std.ThreadParker" {
144 if (builtin.single_threaded)
145 return error.SkipZigTest;
146
147 const Context = struct {
148 parker: ThreadParker,
149 data: u32,
150
151 fn receiver(self: *@This()) void {
152 self.parker.park(&self.data, 0); // receives 1
153 assert(@atomicRmw(u32, &self.data, .Xchg, 2, .SeqCst) == 1); // sends 2
154 self.parker.unpark(&self.data); // wakes up waiters on 2
155 self.parker.park(&self.data, 2); // receives 3
156 assert(@atomicRmw(u32, &self.data, .Xchg, 4, .SeqCst) == 3); // sends 4
157 self.parker.unpark(&self.data); // wakes up waiters on 4
158 }
159
160 fn sender(self: *@This()) void {
161 assert(@atomicRmw(u32, &self.data, .Xchg, 1, .SeqCst) == 0); // sends 1
162 self.parker.unpark(&self.data); // wakes up waiters on 1
163 self.parker.park(&self.data, 1); // receives 2
164 assert(@atomicRmw(u32, &self.data, .Xchg, 3, .SeqCst) == 2); // sends 3
165 self.parker.unpark(&self.data); // wakes up waiters on 3
166 self.parker.park(&self.data, 3); // receives 4
167 }
168 };
169
170 var context = Context{
171 .parker = ThreadParker.init(),
172 .data = 0,
173 };
174 defer context.parker.deinit();
175
176 var receiver = try std.Thread.spawn(&context, Context.receiver);
177 defer receiver.wait();
178
179 context.sender();
180}
lib/std/pdb.zig+1-1
...@@ -532,7 +532,7 @@ const Msf = struct {...@@ -532,7 +532,7 @@ const Msf = struct {
532 const stream_sizes = try allocator.alloc(u32, stream_count);532 const stream_sizes = try allocator.alloc(u32, stream_count);
533 defer allocator.free(stream_sizes);533 defer allocator.free(stream_sizes);
534534
535 // Microsoft's implementation uses u32(-1) for inexistant streams.535 // Microsoft's implementation uses @as(u32, -1) for inexistant streams.
536 // These streams are not used, but still participate in the file536 // These streams are not used, but still participate in the file
537 // and must be taken into account when resolving stream indices.537 // and must be taken into account when resolving stream indices.
538 const Nil = 0xFFFFFFFF;538 const Nil = 0xFFFFFFFF;
lib/std/priority_queue.zig+30-30
...@@ -236,12 +236,12 @@ test "std.PriorityQueue: add and remove min heap" {...@@ -236,12 +236,12 @@ test "std.PriorityQueue: add and remove min heap" {
236 try queue.add(23);236 try queue.add(23);
237 try queue.add(25);237 try queue.add(25);
238 try queue.add(13);238 try queue.add(13);
239 expectEqual(u32(7), queue.remove());239 expectEqual(@as(u32, 7), queue.remove());
240 expectEqual(u32(12), queue.remove());240 expectEqual(@as(u32, 12), queue.remove());
241 expectEqual(u32(13), queue.remove());241 expectEqual(@as(u32, 13), queue.remove());
242 expectEqual(u32(23), queue.remove());242 expectEqual(@as(u32, 23), queue.remove());
243 expectEqual(u32(25), queue.remove());243 expectEqual(@as(u32, 25), queue.remove());
244 expectEqual(u32(54), queue.remove());244 expectEqual(@as(u32, 54), queue.remove());
245}245}
246246
247test "std.PriorityQueue: add and remove same min heap" {247test "std.PriorityQueue: add and remove same min heap" {
...@@ -254,12 +254,12 @@ test "std.PriorityQueue: add and remove same min heap" {...@@ -254,12 +254,12 @@ test "std.PriorityQueue: add and remove same min heap" {
254 try queue.add(2);254 try queue.add(2);
255 try queue.add(1);255 try queue.add(1);
256 try queue.add(1);256 try queue.add(1);
257 expectEqual(u32(1), queue.remove());257 expectEqual(@as(u32, 1), queue.remove());
258 expectEqual(u32(1), queue.remove());258 expectEqual(@as(u32, 1), queue.remove());
259 expectEqual(u32(1), queue.remove());259 expectEqual(@as(u32, 1), queue.remove());
260 expectEqual(u32(1), queue.remove());260 expectEqual(@as(u32, 1), queue.remove());
261 expectEqual(u32(2), queue.remove());261 expectEqual(@as(u32, 2), queue.remove());
262 expectEqual(u32(2), queue.remove());262 expectEqual(@as(u32, 2), queue.remove());
263}263}
264264
265test "std.PriorityQueue: removeOrNull on empty" {265test "std.PriorityQueue: removeOrNull on empty" {
...@@ -276,9 +276,9 @@ test "std.PriorityQueue: edge case 3 elements" {...@@ -276,9 +276,9 @@ test "std.PriorityQueue: edge case 3 elements" {
276 try queue.add(9);276 try queue.add(9);
277 try queue.add(3);277 try queue.add(3);
278 try queue.add(2);278 try queue.add(2);
279 expectEqual(u32(2), queue.remove());279 expectEqual(@as(u32, 2), queue.remove());
280 expectEqual(u32(3), queue.remove());280 expectEqual(@as(u32, 3), queue.remove());
281 expectEqual(u32(9), queue.remove());281 expectEqual(@as(u32, 9), queue.remove());
282}282}
283283
284test "std.PriorityQueue: peek" {284test "std.PriorityQueue: peek" {
...@@ -289,8 +289,8 @@ test "std.PriorityQueue: peek" {...@@ -289,8 +289,8 @@ test "std.PriorityQueue: peek" {
289 try queue.add(9);289 try queue.add(9);
290 try queue.add(3);290 try queue.add(3);
291 try queue.add(2);291 try queue.add(2);
292 expectEqual(u32(2), queue.peek().?);292 expectEqual(@as(u32, 2), queue.peek().?);
293 expectEqual(u32(2), queue.peek().?);293 expectEqual(@as(u32, 2), queue.peek().?);
294}294}
295295
296test "std.PriorityQueue: sift up with odd indices" {296test "std.PriorityQueue: sift up with odd indices" {
...@@ -341,12 +341,12 @@ test "std.PriorityQueue: add and remove max heap" {...@@ -341,12 +341,12 @@ test "std.PriorityQueue: add and remove max heap" {
341 try queue.add(23);341 try queue.add(23);
342 try queue.add(25);342 try queue.add(25);
343 try queue.add(13);343 try queue.add(13);
344 expectEqual(u32(54), queue.remove());344 expectEqual(@as(u32, 54), queue.remove());
345 expectEqual(u32(25), queue.remove());345 expectEqual(@as(u32, 25), queue.remove());
346 expectEqual(u32(23), queue.remove());346 expectEqual(@as(u32, 23), queue.remove());
347 expectEqual(u32(13), queue.remove());347 expectEqual(@as(u32, 13), queue.remove());
348 expectEqual(u32(12), queue.remove());348 expectEqual(@as(u32, 12), queue.remove());
349 expectEqual(u32(7), queue.remove());349 expectEqual(@as(u32, 7), queue.remove());
350}350}
351351
352test "std.PriorityQueue: add and remove same max heap" {352test "std.PriorityQueue: add and remove same max heap" {
...@@ -359,12 +359,12 @@ test "std.PriorityQueue: add and remove same max heap" {...@@ -359,12 +359,12 @@ test "std.PriorityQueue: add and remove same max heap" {
359 try queue.add(2);359 try queue.add(2);
360 try queue.add(1);360 try queue.add(1);
361 try queue.add(1);361 try queue.add(1);
362 expectEqual(u32(2), queue.remove());362 expectEqual(@as(u32, 2), queue.remove());
363 expectEqual(u32(2), queue.remove());363 expectEqual(@as(u32, 2), queue.remove());
364 expectEqual(u32(1), queue.remove());364 expectEqual(@as(u32, 1), queue.remove());
365 expectEqual(u32(1), queue.remove());365 expectEqual(@as(u32, 1), queue.remove());
366 expectEqual(u32(1), queue.remove());366 expectEqual(@as(u32, 1), queue.remove());
367 expectEqual(u32(1), queue.remove());367 expectEqual(@as(u32, 1), queue.remove());
368}368}
369369
370test "std.PriorityQueue: iterator" {370test "std.PriorityQueue: iterator" {
...@@ -386,5 +386,5 @@ test "std.PriorityQueue: iterator" {...@@ -386,5 +386,5 @@ test "std.PriorityQueue: iterator" {
386 _ = map.remove(e);386 _ = map.remove(e);
387 }387 }
388388
389 expectEqual(usize(0), map.count());389 expectEqual(@as(usize, 0), map.count());
390}390}
lib/std/progress.zig+2-5
...@@ -98,11 +98,8 @@ pub const Progress = struct {...@@ -98,11 +98,8 @@ pub const Progress = struct {
98 /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this98 /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
99 /// API to return Progress rather than accept it as a parameter.99 /// API to return Progress rather than accept it as a parameter.
100 pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node {100 pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node {
101 if (std.io.getStdErr()) |stderr| {101 const stderr = std.io.getStdErr();
102 self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null;102 self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null;
103 } else |_| {
104 self.terminal = null;
105 }
106 self.root = Node{103 self.root = Node{
107 .context = self,104 .context = self,
108 .parent = null,105 .parent = null,
lib/std/rand.zig+8-8
...@@ -93,13 +93,13 @@ pub const Random = struct {...@@ -93,13 +93,13 @@ pub const Random = struct {
93 // http://www.pcg-random.org/posts/bounded-rands.html93 // http://www.pcg-random.org/posts/bounded-rands.html
94 // "Lemire's (with an extra tweak from me)"94 // "Lemire's (with an extra tweak from me)"
95 var x: Small = r.int(Small);95 var x: Small = r.int(Small);
96 var m: Large = Large(x) * Large(less_than);96 var m: Large = @as(Large, x) * @as(Large, less_than);
97 var l: Small = @truncate(Small, m);97 var l: Small = @truncate(Small, m);
98 if (l < less_than) {98 if (l < less_than) {
99 // TODO: workaround for https://github.com/ziglang/zig/issues/177099 // TODO: workaround for https://github.com/ziglang/zig/issues/1770
100 // should be:100 // should be:
101 // var t: Small = -%less_than;101 // var t: Small = -%less_than;
102 var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), Small(less_than)));102 var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), @as(Small, less_than)));
103103
104 if (t >= less_than) {104 if (t >= less_than) {
105 t -= less_than;105 t -= less_than;
...@@ -109,7 +109,7 @@ pub const Random = struct {...@@ -109,7 +109,7 @@ pub const Random = struct {
109 }109 }
110 while (l < t) {110 while (l < t) {
111 x = r.int(Small);111 x = r.int(Small);
112 m = Large(x) * Large(less_than);112 m = @as(Large, x) * @as(Large, less_than);
113 l = @truncate(Small, m);113 l = @truncate(Small, m);
114 }114 }
115 }115 }
...@@ -286,7 +286,7 @@ pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {...@@ -286,7 +286,7 @@ pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
286 // adapted from:286 // adapted from:
287 // http://www.pcg-random.org/posts/bounded-rands.html287 // http://www.pcg-random.org/posts/bounded-rands.html
288 // "Integer Multiplication (Biased)"288 // "Integer Multiplication (Biased)"
289 var m: T2 = T2(random_int) * T2(less_than);289 var m: T2 = @as(T2, random_int) * @as(T2, less_than);
290 return @intCast(T, m >> T.bit_count);290 return @intCast(T, m >> T.bit_count);
291}291}
292292
...@@ -633,8 +633,8 @@ pub const Xoroshiro128 = struct {...@@ -633,8 +633,8 @@ pub const Xoroshiro128 = struct {
633 const r = s0 +% s1;633 const r = s0 +% s1;
634634
635 s1 ^= s0;635 s1 ^= s0;
636 self.s[0] = math.rotl(u64, s0, u8(55)) ^ s1 ^ (s1 << 14);636 self.s[0] = math.rotl(u64, s0, @as(u8, 55)) ^ s1 ^ (s1 << 14);
637 self.s[1] = math.rotl(u64, s1, u8(36));637 self.s[1] = math.rotl(u64, s1, @as(u8, 36));
638638
639 return r;639 return r;
640 }640 }
...@@ -652,7 +652,7 @@ pub const Xoroshiro128 = struct {...@@ -652,7 +652,7 @@ pub const Xoroshiro128 = struct {
652 inline for (table) |entry| {652 inline for (table) |entry| {
653 var b: usize = 0;653 var b: usize = 0;
654 while (b < 64) : (b += 1) {654 while (b < 64) : (b += 1) {
655 if ((entry & (u64(1) << @intCast(u6, b))) != 0) {655 if ((entry & (@as(u64, 1) << @intCast(u6, b))) != 0) {
656 s0 ^= self.s[0];656 s0 ^= self.s[0];
657 s1 ^= self.s[1];657 s1 ^= self.s[1];
658 }658 }
...@@ -1090,7 +1090,7 @@ fn testRange(r: *Random, start: i8, end: i8) void {...@@ -1090,7 +1090,7 @@ fn testRange(r: *Random, start: i8, end: i8) void {
1090 testRangeBias(r, start, end, false);1090 testRangeBias(r, start, end, false);
1091}1091}
1092fn testRangeBias(r: *Random, start: i8, end: i8, biased: bool) void {1092fn testRangeBias(r: *Random, start: i8, end: i8, biased: bool) void {
1093 const count = @intCast(usize, i32(end) - i32(start));1093 const count = @intCast(usize, @as(i32, end) - @as(i32, start));
1094 var values_buffer = [_]bool{false} ** 0x100;1094 var values_buffer = [_]bool{false} ** 0x100;
1095 const values = values_buffer[0..count];1095 const values = values_buffer[0..count];
1096 var i: usize = 0;1096 var i: usize = 0;
lib/std/rand/ziggurat.zig+1-1
...@@ -17,7 +17,7 @@ pub fn next_f64(random: *Random, comptime tables: ZigTable) f64 {...@@ -17,7 +17,7 @@ pub fn next_f64(random: *Random, comptime tables: ZigTable) f64 {
17 // We manually construct a float from parts as we can avoid an extra random lookup here by17 // We manually construct a float from parts as we can avoid an extra random lookup here by
18 // using the unused exponent for the lookup table entry.18 // using the unused exponent for the lookup table entry.
19 const bits = random.scalar(u64);19 const bits = random.scalar(u64);
20 const i = usize(bits & 0xff);20 const i = @as(usize, bits & 0xff);
2121
22 const u = blk: {22 const u = blk: {
23 if (tables.is_symmetric) {23 if (tables.is_symmetric) {
lib/std/segmented_list.zig+5-5
...@@ -162,7 +162,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -162,7 +162,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
162 /// Grows or shrinks capacity to match usage.162 /// Grows or shrinks capacity to match usage.
163 pub fn setCapacity(self: *Self, new_capacity: usize) !void {163 pub fn setCapacity(self: *Self, new_capacity: usize) !void {
164 if (prealloc_item_count != 0) {164 if (prealloc_item_count != 0) {
165 if (new_capacity <= usize(1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {165 if (new_capacity <= @as(usize, 1) << (prealloc_exp + @intCast(ShelfIndex, self.dynamic_segments.len))) {
166 return self.shrinkCapacity(new_capacity);166 return self.shrinkCapacity(new_capacity);
167 }167 }
168 }168 }
...@@ -231,9 +231,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -231,9 +231,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
231231
232 fn shelfSize(shelf_index: ShelfIndex) usize {232 fn shelfSize(shelf_index: ShelfIndex) usize {
233 if (prealloc_item_count == 0) {233 if (prealloc_item_count == 0) {
234 return usize(1) << shelf_index;234 return @as(usize, 1) << shelf_index;
235 }235 }
236 return usize(1) << (shelf_index + (prealloc_exp + 1));236 return @as(usize, 1) << (shelf_index + (prealloc_exp + 1));
237 }237 }
238238
239 fn shelfIndex(list_index: usize) ShelfIndex {239 fn shelfIndex(list_index: usize) ShelfIndex {
...@@ -245,9 +245,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type...@@ -245,9 +245,9 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
245245
246 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {246 fn boxIndex(list_index: usize, shelf_index: ShelfIndex) usize {
247 if (prealloc_item_count == 0) {247 if (prealloc_item_count == 0) {
248 return (list_index + 1) - (usize(1) << shelf_index);248 return (list_index + 1) - (@as(usize, 1) << shelf_index);
249 }249 }
250 return list_index + prealloc_item_count - (usize(1) << ((prealloc_exp + 1) + shelf_index));250 return list_index + prealloc_item_count - (@as(usize, 1) << ((prealloc_exp + 1) + shelf_index));
251 }251 }
252252
253 fn freeShelves(self: *Self, from_count: ShelfIndex, to_count: ShelfIndex) void {253 fn freeShelves(self: *Self, from_count: ShelfIndex, to_count: ShelfIndex) void {
lib/std/sort.zig+4-4
...@@ -813,7 +813,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s...@@ -813,7 +813,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
813// where have some idea as to how many unique values there are and where the next value might be813// where have some idea as to how many unique values there are and where the next value might be
814fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {814fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
815 if (range.length() == 0) return range.start;815 if (range.length() == 0) return range.start;
816 const skip = math.max(range.length() / unique, usize(1));816 const skip = math.max(range.length() / unique, @as(usize, 1));
817817
818 var index = range.start + skip;818 var index = range.start + skip;
819 while (lessThan(items[index - 1], value)) : (index += skip) {819 while (lessThan(items[index - 1], value)) : (index += skip) {
...@@ -827,7 +827,7 @@ fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessTh...@@ -827,7 +827,7 @@ fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessTh
827827
828fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {828fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
829 if (range.length() == 0) return range.start;829 if (range.length() == 0) return range.start;
830 const skip = math.max(range.length() / unique, usize(1));830 const skip = math.max(range.length() / unique, @as(usize, 1));
831831
832 var index = range.end - skip;832 var index = range.end - skip;
833 while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {833 while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {
...@@ -841,7 +841,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessT...@@ -841,7 +841,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessT
841841
842fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {842fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
843 if (range.length() == 0) return range.start;843 if (range.length() == 0) return range.start;
844 const skip = math.max(range.length() / unique, usize(1));844 const skip = math.max(range.length() / unique, @as(usize, 1));
845845
846 var index = range.start + skip;846 var index = range.start + skip;
847 while (!lessThan(value, items[index - 1])) : (index += skip) {847 while (!lessThan(value, items[index - 1])) : (index += skip) {
...@@ -855,7 +855,7 @@ fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessTha...@@ -855,7 +855,7 @@ fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessTha
855855
856fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {856fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
857 if (range.length() == 0) return range.start;857 if (range.length() == 0) return range.start;
858 const skip = math.max(range.length() / unique, usize(1));858 const skip = math.max(range.length() / unique, @as(usize, 1));
859859
860 var index = range.end - skip;860 var index = range.end - skip;
861 while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {861 while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {
lib/std/special/build_runner.zig+12-23
...@@ -43,19 +43,8 @@ pub fn main() !void {...@@ -43,19 +43,8 @@ pub fn main() !void {
4343
44 var targets = ArrayList([]const u8).init(allocator);44 var targets = ArrayList([]const u8).init(allocator);
4545
46 var stderr_file = io.getStdErr();46 const stderr_stream = &io.getStdErr().outStream().stream;
47 var stderr_file_stream: File.OutStream = undefined;47 const stdout_stream = &io.getStdOut().outStream().stream;
48 var stderr_stream = if (stderr_file) |f| x: {
49 stderr_file_stream = f.outStream();
50 break :x &stderr_file_stream.stream;
51 } else |err| err;
52
53 var stdout_file = io.getStdOut();
54 var stdout_file_stream: File.OutStream = undefined;
55 var stdout_stream = if (stdout_file) |f| x: {
56 stdout_file_stream = f.outStream();
57 break :x &stdout_file_stream.stream;
58 } else |err| err;
5948
60 while (arg_it.next(allocator)) |err_or_arg| {49 while (arg_it.next(allocator)) |err_or_arg| {
61 const arg = try unwrapArg(err_or_arg);50 const arg = try unwrapArg(err_or_arg);
...@@ -63,37 +52,37 @@ pub fn main() !void {...@@ -63,37 +52,37 @@ pub fn main() !void {
63 const option_contents = arg[2..];52 const option_contents = arg[2..];
64 if (option_contents.len == 0) {53 if (option_contents.len == 0) {
65 warn("Expected option name after '-D'\n\n");54 warn("Expected option name after '-D'\n\n");
66 return usageAndErr(builder, false, try stderr_stream);55 return usageAndErr(builder, false, stderr_stream);
67 }56 }
68 if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {57 if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
69 const option_name = option_contents[0..name_end];58 const option_name = option_contents[0..name_end];
70 const option_value = option_contents[name_end + 1 ..];59 const option_value = option_contents[name_end + 1 ..];
71 if (try builder.addUserInputOption(option_name, option_value))60 if (try builder.addUserInputOption(option_name, option_value))
72 return usageAndErr(builder, false, try stderr_stream);61 return usageAndErr(builder, false, stderr_stream);
73 } else {62 } else {
74 if (try builder.addUserInputFlag(option_contents))63 if (try builder.addUserInputFlag(option_contents))
75 return usageAndErr(builder, false, try stderr_stream);64 return usageAndErr(builder, false, stderr_stream);
76 }65 }
77 } else if (mem.startsWith(u8, arg, "-")) {66 } else if (mem.startsWith(u8, arg, "-")) {
78 if (mem.eql(u8, arg, "--verbose")) {67 if (mem.eql(u8, arg, "--verbose")) {
79 builder.verbose = true;68 builder.verbose = true;
80 } else if (mem.eql(u8, arg, "--help")) {69 } else if (mem.eql(u8, arg, "--help")) {
81 return usage(builder, false, try stdout_stream);70 return usage(builder, false, stdout_stream);
82 } else if (mem.eql(u8, arg, "--prefix")) {71 } else if (mem.eql(u8, arg, "--prefix")) {
83 builder.install_prefix = try unwrapArg(arg_it.next(allocator) orelse {72 builder.install_prefix = try unwrapArg(arg_it.next(allocator) orelse {
84 warn("Expected argument after --prefix\n\n");73 warn("Expected argument after --prefix\n\n");
85 return usageAndErr(builder, false, try stderr_stream);74 return usageAndErr(builder, false, stderr_stream);
86 });75 });
87 } else if (mem.eql(u8, arg, "--search-prefix")) {76 } else if (mem.eql(u8, arg, "--search-prefix")) {
88 const search_prefix = try unwrapArg(arg_it.next(allocator) orelse {77 const search_prefix = try unwrapArg(arg_it.next(allocator) orelse {
89 warn("Expected argument after --search-prefix\n\n");78 warn("Expected argument after --search-prefix\n\n");
90 return usageAndErr(builder, false, try stderr_stream);79 return usageAndErr(builder, false, stderr_stream);
91 });80 });
92 builder.addSearchPrefix(search_prefix);81 builder.addSearchPrefix(search_prefix);
93 } else if (mem.eql(u8, arg, "--override-lib-dir")) {82 } else if (mem.eql(u8, arg, "--override-lib-dir")) {
94 builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse {83 builder.override_lib_dir = try unwrapArg(arg_it.next(allocator) orelse {
95 warn("Expected argument after --override-lib-dir\n\n");84 warn("Expected argument after --override-lib-dir\n\n");
96 return usageAndErr(builder, false, try stderr_stream);85 return usageAndErr(builder, false, stderr_stream);
97 });86 });
98 } else if (mem.eql(u8, arg, "--verbose-tokenize")) {87 } else if (mem.eql(u8, arg, "--verbose-tokenize")) {
99 builder.verbose_tokenize = true;88 builder.verbose_tokenize = true;
...@@ -111,7 +100,7 @@ pub fn main() !void {...@@ -111,7 +100,7 @@ pub fn main() !void {
111 builder.verbose_cc = true;100 builder.verbose_cc = true;
112 } else {101 } else {
113 warn("Unrecognized argument: {}\n\n", arg);102 warn("Unrecognized argument: {}\n\n", arg);
114 return usageAndErr(builder, false, try stderr_stream);103 return usageAndErr(builder, false, stderr_stream);
115 }104 }
116 } else {105 } else {
117 try targets.append(arg);106 try targets.append(arg);
...@@ -122,12 +111,12 @@ pub fn main() !void {...@@ -122,12 +111,12 @@ pub fn main() !void {
122 try runBuild(builder);111 try runBuild(builder);
123112
124 if (builder.validateUserInputDidItFail())113 if (builder.validateUserInputDidItFail())
125 return usageAndErr(builder, true, try stderr_stream);114 return usageAndErr(builder, true, stderr_stream);
126115
127 builder.make(targets.toSliceConst()) catch |err| {116 builder.make(targets.toSliceConst()) catch |err| {
128 switch (err) {117 switch (err) {
129 error.InvalidStepName => {118 error.InvalidStepName => {
130 return usageAndErr(builder, true, try stderr_stream);119 return usageAndErr(builder, true, stderr_stream);
131 },120 },
132 error.UncleanExit => process.exit(1),121 error.UncleanExit => process.exit(1),
133 else => return err,122 else => return err,
lib/std/special/c.zig+3-3
...@@ -62,7 +62,7 @@ extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int {...@@ -62,7 +62,7 @@ extern fn strncmp(_l: [*]const u8, _r: [*]const u8, _n: usize) c_int {
62 r += 1;62 r += 1;
63 n -= 1;63 n -= 1;
64 }64 }
65 return c_int(l[0]) - c_int(r[0]);65 return @as(c_int, l[0]) - @as(c_int, r[0]);
66}66}
6767
68extern fn strerror(errnum: c_int) [*]const u8 {68extern fn strerror(errnum: c_int) [*]const u8 {
...@@ -540,7 +540,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {...@@ -540,7 +540,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) T {
540 // scale result up540 // scale result up
541 if (ex > 0) {541 if (ex > 0) {
542 ux -%= 1 << digits;542 ux -%= 1 << digits;
543 ux |= uint(@bitCast(u32, ex)) << digits;543 ux |= @as(uint, @bitCast(u32, ex)) << digits;
544 } else {544 } else {
545 ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));545 ux >>= @intCast(log2uint, @bitCast(u32, -ex + 1));
546 }546 }
...@@ -687,7 +687,7 @@ export fn sqrt(x: f64) f64 {...@@ -687,7 +687,7 @@ export fn sqrt(x: f64) f64 {
687687
688export fn sqrtf(x: f32) f32 {688export fn sqrtf(x: f32) f32 {
689 const tiny: f32 = 1.0e-30;689 const tiny: f32 = 1.0e-30;
690 const sign: i32 = @bitCast(i32, u32(0x80000000));690 const sign: i32 = @bitCast(i32, @as(u32, 0x80000000));
691 var ix: i32 = @bitCast(i32, x);691 var ix: i32 = @bitCast(i32, x);
692692
693 if ((ix & 0x7F800000) == 0x7F800000) {693 if ((ix & 0x7F800000) == 0x7F800000) {
lib/std/special/compiler_rt.zig+17-17
...@@ -672,7 +672,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {...@@ -672,7 +672,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
672 // special cases672 // special cases
673 if (d == 0) return 0; // ?!673 if (d == 0) return 0; // ?!
674 if (n == 0) return 0;674 if (n == 0) return 0;
675 var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n)));675 var sr = @bitCast(c_uint, @as(c_int, @clz(u32, d)) - @as(c_int, @clz(u32, n)));
676 // 0 <= sr <= n_uword_bits - 1 or sr large676 // 0 <= sr <= n_uword_bits - 1 or sr large
677 if (sr > n_uword_bits - 1) {677 if (sr > n_uword_bits - 1) {
678 // d > r678 // d > r
...@@ -1414,10 +1414,10 @@ test "test_divsi3" {...@@ -1414,10 +1414,10 @@ test "test_divsi3" {
1414 [_]i32{ -2, 1, -2 },1414 [_]i32{ -2, 1, -2 },
1415 [_]i32{ -2, -1, 2 },1415 [_]i32{ -2, -1, 2 },
14161416
1417 [_]i32{ @bitCast(i32, u32(0x80000000)), 1, @bitCast(i32, u32(0x80000000)) },1417 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 1, @bitCast(i32, @as(u32, 0x80000000)) },
1418 [_]i32{ @bitCast(i32, u32(0x80000000)), -1, @bitCast(i32, u32(0x80000000)) },1418 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -1, @bitCast(i32, @as(u32, 0x80000000)) },
1419 [_]i32{ @bitCast(i32, u32(0x80000000)), -2, 0x40000000 },1419 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), -2, 0x40000000 },
1420 [_]i32{ @bitCast(i32, u32(0x80000000)), 2, @bitCast(i32, u32(0xC0000000)) },1420 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 2, @bitCast(i32, @as(u32, 0xC0000000)) },
1421 };1421 };
14221422
1423 for (cases) |case| {1423 for (cases) |case| {
...@@ -1443,8 +1443,8 @@ test "test_divmodsi4" {...@@ -1443,8 +1443,8 @@ test "test_divmodsi4" {
1443 [_]i32{ 19, 5, 3, 4 },1443 [_]i32{ 19, 5, 3, 4 },
1444 [_]i32{ 19, -5, -3, 4 },1444 [_]i32{ 19, -5, -3, 4 },
14451445
1446 [_]i32{ @bitCast(i32, u32(0x80000000)), 8, @bitCast(i32, u32(0xf0000000)), 0 },1446 [_]i32{ @bitCast(i32, @as(u32, 0x80000000)), 8, @bitCast(i32, @as(u32, 0xf0000000)), 0 },
1447 [_]i32{ @bitCast(i32, u32(0x80000007)), 8, @bitCast(i32, u32(0xf0000001)), -1 },1447 [_]i32{ @bitCast(i32, @as(u32, 0x80000007)), 8, @bitCast(i32, @as(u32, 0xf0000001)), -1 },
1448 };1448 };
14491449
1450 for (cases) |case| {1450 for (cases) |case| {
...@@ -1467,10 +1467,10 @@ test "test_divdi3" {...@@ -1467,10 +1467,10 @@ test "test_divdi3" {
1467 [_]i64{ -2, 1, -2 },1467 [_]i64{ -2, 1, -2 },
1468 [_]i64{ -2, -1, 2 },1468 [_]i64{ -2, -1, 2 },
14691469
1470 [_]i64{ @bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)) },1470 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
1471 [_]i64{ @bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)) },1471 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)) },
1472 [_]i64{ @bitCast(i64, u64(0x8000000000000000)), -2, 0x4000000000000000 },1472 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0x4000000000000000 },
1473 [_]i64{ @bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0xC000000000000000)) },1473 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0xC000000000000000)) },
1474 };1474 };
14751475
1476 for (cases) |case| {1476 for (cases) |case| {
...@@ -1492,12 +1492,12 @@ test "test_moddi3" {...@@ -1492,12 +1492,12 @@ test "test_moddi3" {
1492 [_]i64{ -5, 3, -2 },1492 [_]i64{ -5, 3, -2 },
1493 [_]i64{ -5, -3, -2 },1493 [_]i64{ -5, -3, -2 },
14941494
1495 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 1, 0 },1495 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 1, 0 },
1496 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -1, 0 },1496 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -1, 0 },
1497 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 2, 0 },1497 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 2, 0 },
1498 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -2, 0 },1498 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -2, 0 },
1499 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), 3, -2 },1499 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), 3, -2 },
1500 [_]i64{ @bitCast(i64, @intCast(u64, 0x8000000000000000)), -3, -2 },1500 [_]i64{ @bitCast(i64, @as(u64, 0x8000000000000000)), -3, -2 },
1501 };1501 };
15021502
1503 for (cases) |case| {1503 for (cases) |case| {
lib/std/special/compiler_rt/addXf3.zig+13-13
...@@ -19,26 +19,26 @@ pub extern fn __addtf3(a: f128, b: f128) f128 {...@@ -19,26 +19,26 @@ pub extern fn __addtf3(a: f128, b: f128) f128 {
19}19}
2020
21pub extern fn __subsf3(a: f32, b: f32) f32 {21pub extern fn __subsf3(a: f32, b: f32) f32 {
22 const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (u32(1) << 31));22 const neg_b = @bitCast(f32, @bitCast(u32, b) ^ (@as(u32, 1) << 31));
23 return addXf3(f32, a, neg_b);23 return addXf3(f32, a, neg_b);
24}24}
2525
26pub extern fn __subdf3(a: f64, b: f64) f64 {26pub extern fn __subdf3(a: f64, b: f64) f64 {
27 const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (u64(1) << 63));27 const neg_b = @bitCast(f64, @bitCast(u64, b) ^ (@as(u64, 1) << 63));
28 return addXf3(f64, a, neg_b);28 return addXf3(f64, a, neg_b);
29}29}
3030
31pub extern fn __subtf3(a: f128, b: f128) f128 {31pub extern fn __subtf3(a: f128, b: f128) f128 {
32 const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (u128(1) << 127));32 const neg_b = @bitCast(f128, @bitCast(u128, b) ^ (@as(u128, 1) << 127));
33 return addXf3(f128, a, neg_b);33 return addXf3(f128, a, neg_b);
34}34}
3535
36// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215436// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
37fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {37fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
38 const Z = @IntType(false, T.bit_count);38 const Z = @IntType(false, T.bit_count);
39 const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));39 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
40 const significandBits = std.math.floatMantissaBits(T);40 const significandBits = std.math.floatMantissaBits(T);
41 const implicitBit = Z(1) << significandBits;41 const implicitBit = @as(Z, 1) << significandBits;
4242
43 const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);43 const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
44 significand.* <<= @intCast(S, shift);44 significand.* <<= @intCast(S, shift);
...@@ -48,17 +48,17 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {...@@ -48,17 +48,17 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
48// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215448// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
49fn addXf3(comptime T: type, a: T, b: T) T {49fn addXf3(comptime T: type, a: T, b: T) T {
50 const Z = @IntType(false, T.bit_count);50 const Z = @IntType(false, T.bit_count);
51 const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));51 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
5252
53 const typeWidth = T.bit_count;53 const typeWidth = T.bit_count;
54 const significandBits = std.math.floatMantissaBits(T);54 const significandBits = std.math.floatMantissaBits(T);
55 const exponentBits = std.math.floatExponentBits(T);55 const exponentBits = std.math.floatExponentBits(T);
5656
57 const signBit = (Z(1) << (significandBits + exponentBits));57 const signBit = (@as(Z, 1) << (significandBits + exponentBits));
58 const maxExponent = ((1 << exponentBits) - 1);58 const maxExponent = ((1 << exponentBits) - 1);
59 const exponentBias = (maxExponent >> 1);59 const exponentBias = (maxExponent >> 1);
6060
61 const implicitBit = (Z(1) << significandBits);61 const implicitBit = (@as(Z, 1) << significandBits);
62 const quietBit = implicitBit >> 1;62 const quietBit = implicitBit >> 1;
63 const significandMask = implicitBit - 1;63 const significandMask = implicitBit - 1;
6464
...@@ -78,8 +78,8 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -78,8 +78,8 @@ fn addXf3(comptime T: type, a: T, b: T) T {
78 const infRep = @bitCast(Z, std.math.inf(T));78 const infRep = @bitCast(Z, std.math.inf(T));
7979
80 // Detect if a or b is zero, infinity, or NaN.80 // Detect if a or b is zero, infinity, or NaN.
81 if (aAbs -% Z(1) >= infRep - Z(1) or81 if (aAbs -% @as(Z, 1) >= infRep - @as(Z, 1) or
82 bAbs -% Z(1) >= infRep - Z(1))82 bAbs -% @as(Z, 1) >= infRep - @as(Z, 1))
83 {83 {
84 // NaN + anything = qNaN84 // NaN + anything = qNaN
85 if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);85 if (aAbs > infRep) return @bitCast(T, @bitCast(Z, a) | quietBit);
...@@ -148,7 +148,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -148,7 +148,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
148 const @"align" = @intCast(Z, aExponent - bExponent);148 const @"align" = @intCast(Z, aExponent - bExponent);
149 if (@"align" != 0) {149 if (@"align" != 0) {
150 if (@"align" < typeWidth) {150 if (@"align" < typeWidth) {
151 const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) Z(1) else 0;151 const sticky = if (bSignificand << @intCast(S, typeWidth - @"align") != 0) @as(Z, 1) else 0;
152 bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;152 bSignificand = (bSignificand >> @truncate(S, @"align")) | sticky;
153 } else {153 } else {
154 bSignificand = 1; // sticky; b is known to be non-zero.154 bSignificand = 1; // sticky; b is known to be non-zero.
...@@ -157,7 +157,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -157,7 +157,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
157 if (subtraction) {157 if (subtraction) {
158 aSignificand -= bSignificand;158 aSignificand -= bSignificand;
159 // If a == -b, return +zero.159 // If a == -b, return +zero.
160 if (aSignificand == 0) return @bitCast(T, Z(0));160 if (aSignificand == 0) return @bitCast(T, @as(Z, 0));
161161
162 // If partial cancellation occured, we need to left-shift the result162 // If partial cancellation occured, we need to left-shift the result
163 // and adjust the exponent:163 // and adjust the exponent:
...@@ -185,7 +185,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -185,7 +185,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
185 // Result is denormal before rounding; the exponent is zero and we185 // Result is denormal before rounding; the exponent is zero and we
186 // need to shift the significand.186 // need to shift the significand.
187 const shift = @intCast(Z, 1 - aExponent);187 const shift = @intCast(Z, 1 - aExponent);
188 const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) Z(1) else 0;188 const sticky = if (aSignificand << @intCast(S, typeWidth - shift) != 0) @as(Z, 1) else 0;
189 aSignificand = aSignificand >> @intCast(S, shift | sticky);189 aSignificand = aSignificand >> @intCast(S, shift | sticky);
190 aExponent = 0;190 aExponent = 0;
191 }191 }
lib/std/special/compiler_rt/addXf3_test.zig+4-4
...@@ -3,8 +3,8 @@...@@ -3,8 +3,8 @@
3// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c3// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/addtf3_test.c
4// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/subtf3_test.c4// https://github.com/llvm/llvm-project/blob/02d85149a05cb1f6dc49f0ba7a2ceca53718ae17/compiler-rt/test/builtins/Unit/subtf3_test.c
55
6const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);6const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
7const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);7const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64);
88
9const __addtf3 = @import("addXf3.zig").__addtf3;9const __addtf3 = @import("addXf3.zig").__addtf3;
1010
...@@ -34,7 +34,7 @@ test "addtf3" {...@@ -34,7 +34,7 @@ test "addtf3" {
34 test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);34 test__addtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
3535
36 // NaN + any = NaN36 // NaN + any = NaN
37 test__addtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);37 test__addtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
3838
39 // inf + inf = inf39 // inf + inf = inf
40 test__addtf3(inf128, inf128, 0x7fff000000000000, 0x0);40 test__addtf3(inf128, inf128, 0x7fff000000000000, 0x0);
...@@ -75,7 +75,7 @@ test "subtf3" {...@@ -75,7 +75,7 @@ test "subtf3" {
75 test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);75 test__subtf3(qnan128, 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
7676
77 // NaN + any = NaN77 // NaN + any = NaN
78 test__subtf3(@bitCast(f128, (u128(0x7fff000000000000) << 64) | u128(0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);78 test__subtf3(@bitCast(f128, (@as(u128, 0x7fff000000000000) << 64) | @as(u128, 0x800030000000)), 0x1.23456789abcdefp+5, 0x7fff800000000000, 0x0);
7979
80 // inf - any = inf80 // inf - any = inf
81 test__subtf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);81 test__subtf3(inf128, 0x1.23456789abcdefp+5, 0x7fff000000000000, 0x0);
lib/std/special/compiler_rt/comparedf2.zig+10-10
...@@ -13,19 +13,19 @@ const srep_t = i64;...@@ -13,19 +13,19 @@ const srep_t = i64;
13const typeWidth = rep_t.bit_count;13const typeWidth = rep_t.bit_count;
14const significandBits = std.math.floatMantissaBits(fp_t);14const significandBits = std.math.floatMantissaBits(fp_t);
15const exponentBits = std.math.floatExponentBits(fp_t);15const exponentBits = std.math.floatExponentBits(fp_t);
16const signBit = (rep_t(1) << (significandBits + exponentBits));16const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
17const absMask = signBit - 1;17const absMask = signBit - 1;
18const implicitBit = rep_t(1) << significandBits;18const implicitBit = @as(rep_t, 1) << significandBits;
19const significandMask = implicitBit - 1;19const significandMask = implicitBit - 1;
20const exponentMask = absMask ^ significandMask;20const exponentMask = absMask ^ significandMask;
21const infRep = @bitCast(rep_t, std.math.inf(fp_t));21const infRep = @bitCast(rep_t, std.math.inf(fp_t));
2222
23// TODO https://github.com/ziglang/zig/issues/64123// TODO https://github.com/ziglang/zig/issues/641
24// and then make the return types of some of these functions the enum instead of c_int24// and then make the return types of some of these functions the enum instead of c_int
25const LE_LESS = c_int(-1);25const LE_LESS = @as(c_int, -1);
26const LE_EQUAL = c_int(0);26const LE_EQUAL = @as(c_int, 0);
27const LE_GREATER = c_int(1);27const LE_GREATER = @as(c_int, 1);
28const LE_UNORDERED = c_int(1);28const LE_UNORDERED = @as(c_int, 1);
2929
30pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {30pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {
31 @setRuntimeSafety(is_test);31 @setRuntimeSafety(is_test);
...@@ -65,10 +65,10 @@ pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {...@@ -65,10 +65,10 @@ pub extern fn __ledf2(a: fp_t, b: fp_t) c_int {
6565
66// TODO https://github.com/ziglang/zig/issues/64166// TODO https://github.com/ziglang/zig/issues/641
67// and then make the return types of some of these functions the enum instead of c_int67// and then make the return types of some of these functions the enum instead of c_int
68const GE_LESS = c_int(-1);68const GE_LESS = @as(c_int, -1);
69const GE_EQUAL = c_int(0);69const GE_EQUAL = @as(c_int, 0);
70const GE_GREATER = c_int(1);70const GE_GREATER = @as(c_int, 1);
71const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED71const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
7272
73pub extern fn __gedf2(a: fp_t, b: fp_t) c_int {73pub extern fn __gedf2(a: fp_t, b: fp_t) c_int {
74 @setRuntimeSafety(is_test);74 @setRuntimeSafety(is_test);
lib/std/special/compiler_rt/comparesf2.zig+10-10
...@@ -13,19 +13,19 @@ const srep_t = i32;...@@ -13,19 +13,19 @@ const srep_t = i32;
13const typeWidth = rep_t.bit_count;13const typeWidth = rep_t.bit_count;
14const significandBits = std.math.floatMantissaBits(fp_t);14const significandBits = std.math.floatMantissaBits(fp_t);
15const exponentBits = std.math.floatExponentBits(fp_t);15const exponentBits = std.math.floatExponentBits(fp_t);
16const signBit = (rep_t(1) << (significandBits + exponentBits));16const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
17const absMask = signBit - 1;17const absMask = signBit - 1;
18const implicitBit = rep_t(1) << significandBits;18const implicitBit = @as(rep_t, 1) << significandBits;
19const significandMask = implicitBit - 1;19const significandMask = implicitBit - 1;
20const exponentMask = absMask ^ significandMask;20const exponentMask = absMask ^ significandMask;
21const infRep = @bitCast(rep_t, std.math.inf(fp_t));21const infRep = @bitCast(rep_t, std.math.inf(fp_t));
2222
23// TODO https://github.com/ziglang/zig/issues/64123// TODO https://github.com/ziglang/zig/issues/641
24// and then make the return types of some of these functions the enum instead of c_int24// and then make the return types of some of these functions the enum instead of c_int
25const LE_LESS = c_int(-1);25const LE_LESS = @as(c_int, -1);
26const LE_EQUAL = c_int(0);26const LE_EQUAL = @as(c_int, 0);
27const LE_GREATER = c_int(1);27const LE_GREATER = @as(c_int, 1);
28const LE_UNORDERED = c_int(1);28const LE_UNORDERED = @as(c_int, 1);
2929
30pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {30pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {
31 @setRuntimeSafety(is_test);31 @setRuntimeSafety(is_test);
...@@ -65,10 +65,10 @@ pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {...@@ -65,10 +65,10 @@ pub extern fn __lesf2(a: fp_t, b: fp_t) c_int {
6565
66// TODO https://github.com/ziglang/zig/issues/64166// TODO https://github.com/ziglang/zig/issues/641
67// and then make the return types of some of these functions the enum instead of c_int67// and then make the return types of some of these functions the enum instead of c_int
68const GE_LESS = c_int(-1);68const GE_LESS = @as(c_int, -1);
69const GE_EQUAL = c_int(0);69const GE_EQUAL = @as(c_int, 0);
70const GE_GREATER = c_int(1);70const GE_GREATER = @as(c_int, 1);
71const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED71const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
7272
73pub extern fn __gesf2(a: fp_t, b: fp_t) c_int {73pub extern fn __gesf2(a: fp_t, b: fp_t) c_int {
74 @setRuntimeSafety(is_test);74 @setRuntimeSafety(is_test);
lib/std/special/compiler_rt/comparetf2.zig+10-10
...@@ -1,9 +1,9 @@...@@ -1,9 +1,9 @@
1// TODO https://github.com/ziglang/zig/issues/6411// TODO https://github.com/ziglang/zig/issues/641
2// and then make the return types of some of these functions the enum instead of c_int2// and then make the return types of some of these functions the enum instead of c_int
3const LE_LESS = c_int(-1);3const LE_LESS = @as(c_int, -1);
4const LE_EQUAL = c_int(0);4const LE_EQUAL = @as(c_int, 0);
5const LE_GREATER = c_int(1);5const LE_GREATER = @as(c_int, 1);
6const LE_UNORDERED = c_int(1);6const LE_UNORDERED = @as(c_int, 1);
77
8const rep_t = u128;8const rep_t = u128;
9const srep_t = i128;9const srep_t = i128;
...@@ -11,9 +11,9 @@ const srep_t = i128;...@@ -11,9 +11,9 @@ const srep_t = i128;
11const typeWidth = rep_t.bit_count;11const typeWidth = rep_t.bit_count;
12const significandBits = 112;12const significandBits = 112;
13const exponentBits = (typeWidth - significandBits - 1);13const exponentBits = (typeWidth - significandBits - 1);
14const signBit = (rep_t(1) << (significandBits + exponentBits));14const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
15const absMask = signBit - 1;15const absMask = signBit - 1;
16const implicitBit = rep_t(1) << significandBits;16const implicitBit = @as(rep_t, 1) << significandBits;
17const significandMask = implicitBit - 1;17const significandMask = implicitBit - 1;
18const exponentMask = absMask ^ significandMask;18const exponentMask = absMask ^ significandMask;
19const infRep = exponentMask;19const infRep = exponentMask;
...@@ -60,10 +60,10 @@ pub extern fn __letf2(a: f128, b: f128) c_int {...@@ -60,10 +60,10 @@ pub extern fn __letf2(a: f128, b: f128) c_int {
6060
61// TODO https://github.com/ziglang/zig/issues/64161// TODO https://github.com/ziglang/zig/issues/641
62// and then make the return types of some of these functions the enum instead of c_int62// and then make the return types of some of these functions the enum instead of c_int
63const GE_LESS = c_int(-1);63const GE_LESS = @as(c_int, -1);
64const GE_EQUAL = c_int(0);64const GE_EQUAL = @as(c_int, 0);
65const GE_GREATER = c_int(1);65const GE_GREATER = @as(c_int, 1);
66const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED66const GE_UNORDERED = @as(c_int, -1); // Note: different from LE_UNORDERED
6767
68pub extern fn __getf2(a: f128, b: f128) c_int {68pub extern fn __getf2(a: f128, b: f128) c_int {
69 @setRuntimeSafety(is_test);69 @setRuntimeSafety(is_test);
lib/std/special/compiler_rt/divdf3.zig+33-33
...@@ -14,11 +14,11 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {...@@ -14,11 +14,11 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
14 const significandBits = std.math.floatMantissaBits(f64);14 const significandBits = std.math.floatMantissaBits(f64);
15 const exponentBits = std.math.floatExponentBits(f64);15 const exponentBits = std.math.floatExponentBits(f64);
1616
17 const signBit = (Z(1) << (significandBits + exponentBits));17 const signBit = (@as(Z, 1) << (significandBits + exponentBits));
18 const maxExponent = ((1 << exponentBits) - 1);18 const maxExponent = ((1 << exponentBits) - 1);
19 const exponentBias = (maxExponent >> 1);19 const exponentBias = (maxExponent >> 1);
2020
21 const implicitBit = (Z(1) << significandBits);21 const implicitBit = (@as(Z, 1) << significandBits);
22 const quietBit = implicitBit >> 1;22 const quietBit = implicitBit >> 1;
23 const significandMask = implicitBit - 1;23 const significandMask = implicitBit - 1;
2424
...@@ -91,7 +91,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {...@@ -91,7 +91,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
91 // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This91 // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
92 // is accurate to about 3.5 binary digits.92 // is accurate to about 3.5 binary digits.
93 const q31b: u32 = @truncate(u32, bSignificand >> 21);93 const q31b: u32 = @truncate(u32, bSignificand >> 21);
94 var recip32 = u32(0x7504f333) -% q31b;94 var recip32 = @as(u32, 0x7504f333) -% q31b;
9595
96 // Now refine the reciprocal estimate using a Newton-Raphson iteration:96 // Now refine the reciprocal estimate using a Newton-Raphson iteration:
97 //97 //
...@@ -101,12 +101,12 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {...@@ -101,12 +101,12 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
101 // with each iteration, so after three iterations, we have about 28 binary101 // with each iteration, so after three iterations, we have about 28 binary
102 // digits of accuracy.102 // digits of accuracy.
103 var correction32: u32 = undefined;103 var correction32: u32 = undefined;
104 correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);104 correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
105 recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);105 recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
106 correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);106 correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
107 recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);107 recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
108 correction32 = @truncate(u32, ~(u64(recip32) *% q31b >> 32) +% 1);108 correction32 = @truncate(u32, ~(@as(u64, recip32) *% q31b >> 32) +% 1);
109 recip32 = @truncate(u32, u64(recip32) *% correction32 >> 31);109 recip32 = @truncate(u32, @as(u64, recip32) *% correction32 >> 31);
110110
111 // recip32 might have overflowed to exactly zero in the preceding111 // recip32 might have overflowed to exactly zero in the preceding
112 // computation if the high word of b is exactly 1.0. This would sabotage112 // computation if the high word of b is exactly 1.0. This would sabotage
...@@ -119,10 +119,10 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {...@@ -119,10 +119,10 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
119 const q63blo: u32 = @truncate(u32, bSignificand << 11);119 const q63blo: u32 = @truncate(u32, bSignificand << 11);
120 var correction: u64 = undefined;120 var correction: u64 = undefined;
121 var reciprocal: u64 = undefined;121 var reciprocal: u64 = undefined;
122 correction = ~(u64(recip32) *% q31b +% (u64(recip32) *% q63blo >> 32)) +% 1;122 correction = ~(@as(u64, recip32) *% q31b +% (@as(u64, recip32) *% q63blo >> 32)) +% 1;
123 const cHi = @truncate(u32, correction >> 32);123 const cHi = @truncate(u32, correction >> 32);
124 const cLo = @truncate(u32, correction);124 const cLo = @truncate(u32, correction);
125 reciprocal = u64(recip32) *% cHi +% (u64(recip32) *% cLo >> 32);125 reciprocal = @as(u64, recip32) *% cHi +% (@as(u64, recip32) *% cLo >> 32);
126126
127 // We already adjusted the 32-bit estimate, now we need to adjust the final127 // We already adjusted the 32-bit estimate, now we need to adjust the final
128 // 64-bit reciprocal estimate downward to ensure that it is strictly smaller128 // 64-bit reciprocal estimate downward to ensure that it is strictly smaller
...@@ -195,7 +195,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {...@@ -195,7 +195,7 @@ pub extern fn __divdf3(a: f64, b: f64) f64 {
195 // Clear the implicit bit195 // Clear the implicit bit
196 var absResult = quotient & significandMask;196 var absResult = quotient & significandMask;
197 // Insert the exponent197 // Insert the exponent
198 absResult |= @bitCast(Z, SignedZ(writtenExponent)) << significandBits;198 absResult |= @bitCast(Z, @as(SignedZ, writtenExponent)) << significandBits;
199 // Round199 // Round
200 absResult +%= round;200 absResult +%= round;
201 // Insert the sign and return201 // Insert the sign and return
...@@ -208,7 +208,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -208,7 +208,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
208 switch (Z) {208 switch (Z) {
209 u32 => {209 u32 => {
210 // 32x32 --> 64 bit multiply210 // 32x32 --> 64 bit multiply
211 const product = u64(a) * u64(b);211 const product = @as(u64, a) * @as(u64, b);
212 hi.* = @truncate(u32, product >> 32);212 hi.* = @truncate(u32, product >> 32);
213 lo.* = @truncate(u32, product);213 lo.* = @truncate(u32, product);
214 },214 },
...@@ -237,9 +237,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -237,9 +237,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
237 hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;237 hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
238 },238 },
239 u128 => {239 u128 => {
240 const Word_LoMask = u64(0x00000000ffffffff);240 const Word_LoMask = @as(u64, 0x00000000ffffffff);
241 const Word_HiMask = u64(0xffffffff00000000);241 const Word_HiMask = @as(u64, 0xffffffff00000000);
242 const Word_FullMask = u64(0xffffffffffffffff);242 const Word_FullMask = @as(u64, 0xffffffffffffffff);
243 const S = struct {243 const S = struct {
244 fn Word_1(x: u128) u64 {244 fn Word_1(x: u128) u64 {
245 return @truncate(u32, x >> 96);245 return @truncate(u32, x >> 96);
...@@ -275,22 +275,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -275,22 +275,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
275 const product43: u64 = S.Word_4(a) * S.Word_3(b);275 const product43: u64 = S.Word_4(a) * S.Word_3(b);
276 const product44: u64 = S.Word_4(a) * S.Word_4(b);276 const product44: u64 = S.Word_4(a) * S.Word_4(b);
277277
278 const sum0: u128 = u128(product44);278 const sum0: u128 = @as(u128, product44);
279 const sum1: u128 = u128(product34) +%279 const sum1: u128 = @as(u128, product34) +%
280 u128(product43);280 @as(u128, product43);
281 const sum2: u128 = u128(product24) +%281 const sum2: u128 = @as(u128, product24) +%
282 u128(product33) +%282 @as(u128, product33) +%
283 u128(product42);283 @as(u128, product42);
284 const sum3: u128 = u128(product14) +%284 const sum3: u128 = @as(u128, product14) +%
285 u128(product23) +%285 @as(u128, product23) +%
286 u128(product32) +%286 @as(u128, product32) +%
287 u128(product41);287 @as(u128, product41);
288 const sum4: u128 = u128(product13) +%288 const sum4: u128 = @as(u128, product13) +%
289 u128(product22) +%289 @as(u128, product22) +%
290 u128(product31);290 @as(u128, product31);
291 const sum5: u128 = u128(product12) +%291 const sum5: u128 = @as(u128, product12) +%
292 u128(product21);292 @as(u128, product21);
293 const sum6: u128 = u128(product11);293 const sum6: u128 = @as(u128, product11);
294294
295 const r0: u128 = (sum0 & Word_FullMask) +%295 const r0: u128 = (sum0 & Word_FullMask) +%
296 ((sum1 & Word_LoMask) << 32);296 ((sum1 & Word_LoMask) << 32);
...@@ -316,7 +316,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {...@@ -316,7 +316,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
316 @setRuntimeSafety(builtin.is_test);316 @setRuntimeSafety(builtin.is_test);
317 const Z = @IntType(false, T.bit_count);317 const Z = @IntType(false, T.bit_count);
318 const significandBits = std.math.floatMantissaBits(T);318 const significandBits = std.math.floatMantissaBits(T);
319 const implicitBit = Z(1) << significandBits;319 const implicitBit = @as(Z, 1) << significandBits;
320320
321 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);321 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
322 significand.* <<= @intCast(std.math.Log2Int(Z), shift);322 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
lib/std/special/compiler_rt/divsf3.zig+11-11
...@@ -13,11 +13,11 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {...@@ -13,11 +13,11 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
13 const significandBits = std.math.floatMantissaBits(f32);13 const significandBits = std.math.floatMantissaBits(f32);
14 const exponentBits = std.math.floatExponentBits(f32);14 const exponentBits = std.math.floatExponentBits(f32);
1515
16 const signBit = (Z(1) << (significandBits + exponentBits));16 const signBit = (@as(Z, 1) << (significandBits + exponentBits));
17 const maxExponent = ((1 << exponentBits) - 1);17 const maxExponent = ((1 << exponentBits) - 1);
18 const exponentBias = (maxExponent >> 1);18 const exponentBias = (maxExponent >> 1);
1919
20 const implicitBit = (Z(1) << significandBits);20 const implicitBit = (@as(Z, 1) << significandBits);
21 const quietBit = implicitBit >> 1;21 const quietBit = implicitBit >> 1;
22 const significandMask = implicitBit - 1;22 const significandMask = implicitBit - 1;
2323
...@@ -90,7 +90,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {...@@ -90,7 +90,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
90 // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This90 // polynomial approximation: reciprocal = 3/4 + 1/sqrt(2) - b/2. This
91 // is accurate to about 3.5 binary digits.91 // is accurate to about 3.5 binary digits.
92 const q31b = bSignificand << 8;92 const q31b = bSignificand << 8;
93 var reciprocal = u32(0x7504f333) -% q31b;93 var reciprocal = @as(u32, 0x7504f333) -% q31b;
9494
95 // Now refine the reciprocal estimate using a Newton-Raphson iteration:95 // Now refine the reciprocal estimate using a Newton-Raphson iteration:
96 //96 //
...@@ -100,12 +100,12 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {...@@ -100,12 +100,12 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
100 // with each iteration, so after three iterations, we have about 28 binary100 // with each iteration, so after three iterations, we have about 28 binary
101 // digits of accuracy.101 // digits of accuracy.
102 var correction: u32 = undefined;102 var correction: u32 = undefined;
103 correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);103 correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
104 reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);104 reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
105 correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);105 correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
106 reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);106 reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
107 correction = @truncate(u32, ~(u64(reciprocal) *% q31b >> 32) +% 1);107 correction = @truncate(u32, ~(@as(u64, reciprocal) *% q31b >> 32) +% 1);
108 reciprocal = @truncate(u32, u64(reciprocal) *% correction >> 31);108 reciprocal = @truncate(u32, @as(u64, reciprocal) *% correction >> 31);
109109
110 // Exhaustive testing shows that the error in reciprocal after three steps110 // Exhaustive testing shows that the error in reciprocal after three steps
111 // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our111 // is in the interval [-0x1.f58108p-31, 0x1.d0e48cp-29], in line with our
...@@ -127,7 +127,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {...@@ -127,7 +127,7 @@ pub extern fn __divsf3(a: f32, b: f32) f32 {
127 // is the error in the reciprocal of b scaled by the maximum127 // is the error in the reciprocal of b scaled by the maximum
128 // possible value of a. As a consequence of this error bound,128 // possible value of a. As a consequence of this error bound,
129 // either q or nextafter(q) is the correctly rounded129 // either q or nextafter(q) is the correctly rounded
130 var quotient: Z = @truncate(u32, u64(reciprocal) *% (aSignificand << 1) >> 32);130 var quotient: Z = @truncate(u32, @as(u64, reciprocal) *% (aSignificand << 1) >> 32);
131131
132 // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).132 // Two cases: quotient is in [0.5, 1.0) or quotient is in [1.0, 2.0).
133 // In either case, we are going to compute a residual of the form133 // In either case, we are going to compute a residual of the form
...@@ -189,7 +189,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {...@@ -189,7 +189,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
189 @setRuntimeSafety(builtin.is_test);189 @setRuntimeSafety(builtin.is_test);
190 const Z = @IntType(false, T.bit_count);190 const Z = @IntType(false, T.bit_count);
191 const significandBits = std.math.floatMantissaBits(T);191 const significandBits = std.math.floatMantissaBits(T);
192 const implicitBit = Z(1) << significandBits;192 const implicitBit = @as(Z, 1) << significandBits;
193193
194 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);194 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
195 significand.* <<= @intCast(std.math.Log2Int(Z), shift);195 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
lib/std/special/compiler_rt/divti3_test.zig+4-4
...@@ -14,8 +14,8 @@ test "divti3" {...@@ -14,8 +14,8 @@ test "divti3" {
14 test__divti3(-2, 1, -2);14 test__divti3(-2, 1, -2);
15 test__divti3(-2, -1, 2);15 test__divti3(-2, -1, 2);
1616
17 test__divti3(@bitCast(i128, u128(0x8 << 124)), 1, @bitCast(i128, u128(0x8 << 124)));17 test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 1, @bitCast(i128, @as(u128, 0x8 << 124)));
18 test__divti3(@bitCast(i128, u128(0x8 << 124)), -1, @bitCast(i128, u128(0x8 << 124)));18 test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -1, @bitCast(i128, @as(u128, 0x8 << 124)));
19 test__divti3(@bitCast(i128, u128(0x8 << 124)), -2, @bitCast(i128, u128(0x4 << 124)));19 test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), -2, @bitCast(i128, @as(u128, 0x4 << 124)));
20 test__divti3(@bitCast(i128, u128(0x8 << 124)), 2, @bitCast(i128, u128(0xc << 124)));20 test__divti3(@bitCast(i128, @as(u128, 0x8 << 124)), 2, @bitCast(i128, @as(u128, 0xc << 124)));
21}21}
lib/std/special/compiler_rt/extendXfYf2.zig+7-7
...@@ -49,7 +49,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t...@@ -49,7 +49,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
49 const dstInfExp = (1 << dstExpBits) - 1;49 const dstInfExp = (1 << dstExpBits) - 1;
50 const dstExpBias = dstInfExp >> 1;50 const dstExpBias = dstInfExp >> 1;
5151
52 const dstMinNormal: dst_rep_t = dst_rep_t(1) << dstSigBits;52 const dstMinNormal: dst_rep_t = @as(dst_rep_t, 1) << dstSigBits;
5353
54 // Break a into a sign and representation of the absolute value54 // Break a into a sign and representation of the absolute value
55 const aRep: src_rep_t = @bitCast(src_rep_t, a);55 const aRep: src_rep_t = @bitCast(src_rep_t, a);
...@@ -61,7 +61,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t...@@ -61,7 +61,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
61 // a is a normal number.61 // a is a normal number.
62 // Extend to the destination type by shifting the significand and62 // Extend to the destination type by shifting the significand and
63 // exponent into the proper position and rebiasing the exponent.63 // exponent into the proper position and rebiasing the exponent.
64 absResult = dst_rep_t(aAbs) << (dstSigBits - srcSigBits);64 absResult = @as(dst_rep_t, aAbs) << (dstSigBits - srcSigBits);
65 absResult += (dstExpBias - srcExpBias) << dstSigBits;65 absResult += (dstExpBias - srcExpBias) << dstSigBits;
66 } else if (aAbs >= srcInfinity) {66 } else if (aAbs >= srcInfinity) {
67 // a is NaN or infinity.67 // a is NaN or infinity.
...@@ -69,15 +69,15 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t...@@ -69,15 +69,15 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
69 // bit (if needed) and right-aligning the rest of the trailing NaN69 // bit (if needed) and right-aligning the rest of the trailing NaN
70 // payload field.70 // payload field.
71 absResult = dstInfExp << dstSigBits;71 absResult = dstInfExp << dstSigBits;
72 absResult |= dst_rep_t(aAbs & srcQNaN) << (dstSigBits - srcSigBits);72 absResult |= @as(dst_rep_t, aAbs & srcQNaN) << (dstSigBits - srcSigBits);
73 absResult |= dst_rep_t(aAbs & srcNaNCode) << (dstSigBits - srcSigBits);73 absResult |= @as(dst_rep_t, aAbs & srcNaNCode) << (dstSigBits - srcSigBits);
74 } else if (aAbs != 0) {74 } else if (aAbs != 0) {
75 // a is denormal.75 // a is denormal.
76 // renormalize the significand and clear the leading bit, then insert76 // renormalize the significand and clear the leading bit, then insert
77 // the correct adjusted exponent in the destination type.77 // the correct adjusted exponent in the destination type.
78 const scale: u32 = @clz(src_rep_t, aAbs) -78 const scale: u32 = @clz(src_rep_t, aAbs) -
79 @clz(src_rep_t, src_rep_t(srcMinNormal));79 @clz(src_rep_t, @as(src_rep_t, srcMinNormal));
80 absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);80 absResult = @as(dst_rep_t, aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);
81 absResult ^= dstMinNormal;81 absResult ^= dstMinNormal;
82 const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;82 const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
83 absResult |= @intCast(dst_rep_t, resultExponent) << dstSigBits;83 absResult |= @intCast(dst_rep_t, resultExponent) << dstSigBits;
...@@ -87,7 +87,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t...@@ -87,7 +87,7 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
87 }87 }
8888
89 // Apply the signbit to (dst_t)abs(a).89 // Apply the signbit to (dst_t)abs(a).
90 const result: dst_rep_t align(@alignOf(dst_t)) = absResult | dst_rep_t(sign) << (dstBits - srcBits);90 const result: dst_rep_t align(@alignOf(dst_t)) = absResult | @as(dst_rep_t, sign) << (dstBits - srcBits);
91 return @bitCast(dst_t, result);91 return @bitCast(dst_t, result);
92}92}
9393
lib/std/special/compiler_rt/extendXfYf2_test.zig+4-4
...@@ -134,11 +134,11 @@ test "extendsftf2" {...@@ -134,11 +134,11 @@ test "extendsftf2" {
134}134}
135135
136fn makeQNaN64() f64 {136fn makeQNaN64() f64 {
137 return @bitCast(f64, u64(0x7ff8000000000000));137 return @bitCast(f64, @as(u64, 0x7ff8000000000000));
138}138}
139139
140fn makeInf64() f64 {140fn makeInf64() f64 {
141 return @bitCast(f64, u64(0x7ff0000000000000));141 return @bitCast(f64, @as(u64, 0x7ff0000000000000));
142}142}
143143
144fn makeNaN64(rand: u64) f64 {144fn makeNaN64(rand: u64) f64 {
...@@ -146,7 +146,7 @@ fn makeNaN64(rand: u64) f64 {...@@ -146,7 +146,7 @@ fn makeNaN64(rand: u64) f64 {
146}146}
147147
148fn makeQNaN32() f32 {148fn makeQNaN32() f32 {
149 return @bitCast(f32, u32(0x7fc00000));149 return @bitCast(f32, @as(u32, 0x7fc00000));
150}150}
151151
152fn makeNaN32(rand: u32) f32 {152fn makeNaN32(rand: u32) f32 {
...@@ -154,5 +154,5 @@ fn makeNaN32(rand: u32) f32 {...@@ -154,5 +154,5 @@ fn makeNaN32(rand: u32) f32 {
154}154}
155155
156fn makeInf32() f32 {156fn makeInf32() f32 {
157 return @bitCast(f32, u32(0x7f800000));157 return @bitCast(f32, @as(u32, 0x7f800000));
158}158}
lib/std/special/compiler_rt/fixdfdi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixdfdi(a: f64, expected: i64) void {7fn test__fixdfdi(a: f64, expected: i64) void {
8 const x = __fixdfdi(a);8 const x = __fixdfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u64, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixdfsi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixdfsi(a: f64, expected: i32) void {7fn test__fixdfsi(a: f64, expected: i32) void {
8 const x = __fixdfsi(a);8 const x = __fixdfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u32, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixdfti_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixdfti(a: f64, expected: i128) void {7fn test__fixdfti(a: f64, expected: i128) void {
8 const x = __fixdfti(a);8 const x = __fixdfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u64, a), x, x, expected, expected, @bitCast(u128, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixint.zig+3-3
...@@ -25,11 +25,11 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {...@@ -25,11 +25,11 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
2525
26 const typeWidth = rep_t.bit_count;26 const typeWidth = rep_t.bit_count;
27 const exponentBits = (typeWidth - significandBits - 1);27 const exponentBits = (typeWidth - significandBits - 1);
28 const signBit = (rep_t(1) << (significandBits + exponentBits));28 const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
29 const maxExponent = ((1 << exponentBits) - 1);29 const maxExponent = ((1 << exponentBits) - 1);
30 const exponentBias = (maxExponent >> 1);30 const exponentBias = (maxExponent >> 1);
3131
32 const implicitBit = (rep_t(1) << significandBits);32 const implicitBit = (@as(rep_t, 1) << significandBits);
33 const significandMask = (implicitBit - 1);33 const significandMask = (implicitBit - 1);
3434
35 // Break a into sign, exponent, significand35 // Break a into sign, exponent, significand
...@@ -51,7 +51,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {...@@ -51,7 +51,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
5151
52 // If the value is too large for the integer type, saturate.52 // If the value is too large for the integer type, saturate.
53 if (@intCast(usize, exponent) >= fixint_t.bit_count) {53 if (@intCast(usize, exponent) >= fixint_t.bit_count) {
54 return if (negative) fixint_t(minInt(fixint_t)) else fixint_t(maxInt(fixint_t));54 return if (negative) @as(fixint_t, minInt(fixint_t)) else @as(fixint_t, maxInt(fixint_t));
55 }55 }
5656
57 // If 0 <= exponent < significandBits, right shift else left shift57 // If 0 <= exponent < significandBits, right shift else left shift
lib/std/special/compiler_rt/fixint_test.zig+13-13
...@@ -81,8 +81,8 @@ test "fixint.i3" {...@@ -81,8 +81,8 @@ test "fixint.i3" {
81test "fixint.i32" {81test "fixint.i32" {
82 test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));82 test__fixint(f64, i32, -math.inf_f64, math.minInt(i32));
83 test__fixint(f64, i32, -math.f64_max, math.minInt(i32));83 test__fixint(f64, i32, -math.f64_max, math.minInt(i32));
84 test__fixint(f64, i32, f64(math.minInt(i32)), math.minInt(i32));84 test__fixint(f64, i32, @as(f64, math.minInt(i32)), math.minInt(i32));
85 test__fixint(f64, i32, f64(math.minInt(i32)) + 1, math.minInt(i32) + 1);85 test__fixint(f64, i32, @as(f64, math.minInt(i32)) + 1, math.minInt(i32) + 1);
86 test__fixint(f64, i32, -2.0, -2);86 test__fixint(f64, i32, -2.0, -2);
87 test__fixint(f64, i32, -1.9, -1);87 test__fixint(f64, i32, -1.9, -1);
88 test__fixint(f64, i32, -1.1, -1);88 test__fixint(f64, i32, -1.1, -1);
...@@ -96,8 +96,8 @@ test "fixint.i32" {...@@ -96,8 +96,8 @@ test "fixint.i32" {
96 test__fixint(f64, i32, 0.1, 0);96 test__fixint(f64, i32, 0.1, 0);
97 test__fixint(f64, i32, 0.9, 0);97 test__fixint(f64, i32, 0.9, 0);
98 test__fixint(f64, i32, 1.0, 1);98 test__fixint(f64, i32, 1.0, 1);
99 test__fixint(f64, i32, f64(math.maxInt(i32)) - 1, math.maxInt(i32) - 1);99 test__fixint(f64, i32, @as(f64, math.maxInt(i32)) - 1, math.maxInt(i32) - 1);
100 test__fixint(f64, i32, f64(math.maxInt(i32)), math.maxInt(i32));100 test__fixint(f64, i32, @as(f64, math.maxInt(i32)), math.maxInt(i32));
101 test__fixint(f64, i32, math.f64_max, math.maxInt(i32));101 test__fixint(f64, i32, math.f64_max, math.maxInt(i32));
102 test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));102 test__fixint(f64, i32, math.inf_f64, math.maxInt(i32));
103}103}
...@@ -105,9 +105,9 @@ test "fixint.i32" {...@@ -105,9 +105,9 @@ test "fixint.i32" {
105test "fixint.i64" {105test "fixint.i64" {
106 test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));106 test__fixint(f64, i64, -math.inf_f64, math.minInt(i64));
107 test__fixint(f64, i64, -math.f64_max, math.minInt(i64));107 test__fixint(f64, i64, -math.f64_max, math.minInt(i64));
108 test__fixint(f64, i64, f64(math.minInt(i64)), math.minInt(i64));108 test__fixint(f64, i64, @as(f64, math.minInt(i64)), math.minInt(i64));
109 test__fixint(f64, i64, f64(math.minInt(i64)) + 1, math.minInt(i64));109 test__fixint(f64, i64, @as(f64, math.minInt(i64)) + 1, math.minInt(i64));
110 test__fixint(f64, i64, f64(math.minInt(i64) / 2), math.minInt(i64) / 2);110 test__fixint(f64, i64, @as(f64, math.minInt(i64) / 2), math.minInt(i64) / 2);
111 test__fixint(f64, i64, -2.0, -2);111 test__fixint(f64, i64, -2.0, -2);
112 test__fixint(f64, i64, -1.9, -1);112 test__fixint(f64, i64, -1.9, -1);
113 test__fixint(f64, i64, -1.1, -1);113 test__fixint(f64, i64, -1.1, -1);
...@@ -121,8 +121,8 @@ test "fixint.i64" {...@@ -121,8 +121,8 @@ test "fixint.i64" {
121 test__fixint(f64, i64, 0.1, 0);121 test__fixint(f64, i64, 0.1, 0);
122 test__fixint(f64, i64, 0.9, 0);122 test__fixint(f64, i64, 0.9, 0);
123 test__fixint(f64, i64, 1.0, 1);123 test__fixint(f64, i64, 1.0, 1);
124 test__fixint(f64, i64, f64(math.maxInt(i64)) - 1, math.maxInt(i64));124 test__fixint(f64, i64, @as(f64, math.maxInt(i64)) - 1, math.maxInt(i64));
125 test__fixint(f64, i64, f64(math.maxInt(i64)), math.maxInt(i64));125 test__fixint(f64, i64, @as(f64, math.maxInt(i64)), math.maxInt(i64));
126 test__fixint(f64, i64, math.f64_max, math.maxInt(i64));126 test__fixint(f64, i64, math.f64_max, math.maxInt(i64));
127 test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));127 test__fixint(f64, i64, math.inf_f64, math.maxInt(i64));
128}128}
...@@ -130,8 +130,8 @@ test "fixint.i64" {...@@ -130,8 +130,8 @@ test "fixint.i64" {
130test "fixint.i128" {130test "fixint.i128" {
131 test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));131 test__fixint(f64, i128, -math.inf_f64, math.minInt(i128));
132 test__fixint(f64, i128, -math.f64_max, math.minInt(i128));132 test__fixint(f64, i128, -math.f64_max, math.minInt(i128));
133 test__fixint(f64, i128, f64(math.minInt(i128)), math.minInt(i128));133 test__fixint(f64, i128, @as(f64, math.minInt(i128)), math.minInt(i128));
134 test__fixint(f64, i128, f64(math.minInt(i128)) + 1, math.minInt(i128));134 test__fixint(f64, i128, @as(f64, math.minInt(i128)) + 1, math.minInt(i128));
135 test__fixint(f64, i128, -2.0, -2);135 test__fixint(f64, i128, -2.0, -2);
136 test__fixint(f64, i128, -1.9, -1);136 test__fixint(f64, i128, -1.9, -1);
137 test__fixint(f64, i128, -1.1, -1);137 test__fixint(f64, i128, -1.1, -1);
...@@ -145,8 +145,8 @@ test "fixint.i128" {...@@ -145,8 +145,8 @@ test "fixint.i128" {
145 test__fixint(f64, i128, 0.1, 0);145 test__fixint(f64, i128, 0.1, 0);
146 test__fixint(f64, i128, 0.9, 0);146 test__fixint(f64, i128, 0.9, 0);
147 test__fixint(f64, i128, 1.0, 1);147 test__fixint(f64, i128, 1.0, 1);
148 test__fixint(f64, i128, f64(math.maxInt(i128)) - 1, math.maxInt(i128));148 test__fixint(f64, i128, @as(f64, math.maxInt(i128)) - 1, math.maxInt(i128));
149 test__fixint(f64, i128, f64(math.maxInt(i128)), math.maxInt(i128));149 test__fixint(f64, i128, @as(f64, math.maxInt(i128)), math.maxInt(i128));
150 test__fixint(f64, i128, math.f64_max, math.maxInt(i128));150 test__fixint(f64, i128, math.f64_max, math.maxInt(i128));
151 test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));151 test__fixint(f64, i128, math.inf_f64, math.maxInt(i128));
152}152}
lib/std/special/compiler_rt/fixsfdi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixsfdi(a: f32, expected: i64) void {7fn test__fixsfdi(a: f32, expected: i64) void {
8 const x = __fixsfdi(a);8 const x = __fixsfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u64, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixsfsi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixsfsi(a: f32, expected: i32) void {7fn test__fixsfsi(a: f32, expected: i32) void {
8 const x = __fixsfsi(a);8 const x = __fixsfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u32, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixsfti_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixsfti(a: f32, expected: i128) void {7fn test__fixsfti(a: f32, expected: i128) void {
8 const x = __fixsfti(a);8 const x = __fixsfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", a, @bitCast(u32, a), x, x, expected, expected, @bitCast(u128, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixtfdi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixtfdi(a: f128, expected: i64) void {7fn test__fixtfdi(a: f128, expected: i64) void {
8 const x = __fixtfdi(a);8 const x = __fixtfdi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u64({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u64, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u64, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixtfsi_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixtfsi(a: f128, expected: i32) void {7fn test__fixtfsi(a: f128, expected: i32) void {
8 const x = __fixtfsi(a);8 const x = __fixtfsi(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u32({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u32, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u32, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixtfti_test.zig+1-1
...@@ -6,7 +6,7 @@ const warn = std.debug.warn;...@@ -6,7 +6,7 @@ const warn = std.debug.warn;
66
7fn test__fixtfti(a: f128, expected: i128) void {7fn test__fixtfti(a: f128, expected: i128) void {
8 const x = __fixtfti(a);8 const x = __fixtfti(a);
9 //warn("a={}:{x} x={}:{x} expected={}:{x}:u128({x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));9 //warn("a={}:{x} x={}:{x} expected={}:{x}:@as(u128, {x})\n", a, @bitCast(u128, a), x, x, expected, expected, @bitCast(u128, expected));
10 testing.expect(x == expected);10 testing.expect(x == expected);
11}11}
1212
lib/std/special/compiler_rt/fixuint.zig+4-4
...@@ -19,11 +19,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -19,11 +19,11 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
19 };19 };
20 const typeWidth = rep_t.bit_count;20 const typeWidth = rep_t.bit_count;
21 const exponentBits = (typeWidth - significandBits - 1);21 const exponentBits = (typeWidth - significandBits - 1);
22 const signBit = (rep_t(1) << (significandBits + exponentBits));22 const signBit = (@as(rep_t, 1) << (significandBits + exponentBits));
23 const maxExponent = ((1 << exponentBits) - 1);23 const maxExponent = ((1 << exponentBits) - 1);
24 const exponentBias = (maxExponent >> 1);24 const exponentBias = (maxExponent >> 1);
2525
26 const implicitBit = (rep_t(1) << significandBits);26 const implicitBit = (@as(rep_t, 1) << significandBits);
27 const significandMask = (implicitBit - 1);27 const significandMask = (implicitBit - 1);
2828
29 // Break a into sign, exponent, significand29 // Break a into sign, exponent, significand
...@@ -31,7 +31,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -31,7 +31,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
31 const absMask = signBit - 1;31 const absMask = signBit - 1;
32 const aAbs: rep_t = aRep & absMask;32 const aAbs: rep_t = aRep & absMask;
3333
34 const sign = if ((aRep & signBit) != 0) i32(-1) else i32(1);34 const sign = if ((aRep & signBit) != 0) @as(i32, -1) else @as(i32, 1);
35 const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;35 const exponent = @intCast(i32, aAbs >> significandBits) - exponentBias;
36 const significand: rep_t = (aAbs & significandMask) | implicitBit;36 const significand: rep_t = (aAbs & significandMask) | implicitBit;
3737
...@@ -39,7 +39,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -39,7 +39,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
39 if (sign == -1 or exponent < 0) return 0;39 if (sign == -1 or exponent < 0) return 0;
4040
41 // If the value is too large for the integer type, saturate.41 // If the value is too large for the integer type, saturate.
42 if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~fixuint_t(0);42 if (@intCast(c_uint, exponent) >= fixuint_t.bit_count) return ~@as(fixuint_t, 0);
4343
44 // If 0 <= exponent < significandBits, right shift to get the result.44 // If 0 <= exponent < significandBits, right shift to get the result.
45 // Otherwise, shift left.45 // Otherwise, shift left.
lib/std/special/compiler_rt/fixunstfsi_test.zig+1-1
...@@ -6,7 +6,7 @@ fn test__fixunstfsi(a: f128, expected: u32) void {...@@ -6,7 +6,7 @@ fn test__fixunstfsi(a: f128, expected: u32) void {
6 testing.expect(x == expected);6 testing.expect(x == expected);
7}7}
88
9const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));9const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
1010
11test "fixunstfsi" {11test "fixunstfsi" {
12 test__fixunstfsi(inf128, 0xffffffff);12 test__fixunstfsi(inf128, 0xffffffff);
lib/std/special/compiler_rt/fixunstfti_test.zig+1-1
...@@ -6,7 +6,7 @@ fn test__fixunstfti(a: f128, expected: u128) void {...@@ -6,7 +6,7 @@ fn test__fixunstfti(a: f128, expected: u128) void {
6 testing.expect(x == expected);6 testing.expect(x == expected);
7}7}
88
9const inf128 = @bitCast(f128, u128(0x7fff0000000000000000000000000000));9const inf128 = @bitCast(f128, @as(u128, 0x7fff0000000000000000000000000000));
1010
11test "fixunstfti" {11test "fixunstfti" {
12 test__fixunstfti(inf128, 0xffffffffffffffffffffffffffffffff);12 test__fixunstfti(inf128, 0xffffffffffffffffffffffffffffffff);
lib/std/special/compiler_rt/floatsiXf.zig+5-5
...@@ -6,24 +6,24 @@ fn floatsiXf(comptime T: type, a: i32) T {...@@ -6,24 +6,24 @@ fn floatsiXf(comptime T: type, a: i32) T {
6 @setRuntimeSafety(builtin.is_test);6 @setRuntimeSafety(builtin.is_test);
77
8 const Z = @IntType(false, T.bit_count);8 const Z = @IntType(false, T.bit_count);
9 const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));9 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
1010
11 if (a == 0) {11 if (a == 0) {
12 return T(0.0);12 return @as(T, 0.0);
13 }13 }
1414
15 const significandBits = std.math.floatMantissaBits(T);15 const significandBits = std.math.floatMantissaBits(T);
16 const exponentBits = std.math.floatExponentBits(T);16 const exponentBits = std.math.floatExponentBits(T);
17 const exponentBias = ((1 << exponentBits - 1) - 1);17 const exponentBias = ((1 << exponentBits - 1) - 1);
1818
19 const implicitBit = Z(1) << significandBits;19 const implicitBit = @as(Z, 1) << significandBits;
20 const signBit = Z(1 << Z.bit_count - 1);20 const signBit = @as(Z, 1 << Z.bit_count - 1);
2121
22 const sign = a >> 31;22 const sign = a >> 31;
23 // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).23 // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).
24 const abs_a = (a ^ sign) -% sign;24 const abs_a = (a ^ sign) -% sign;
25 // The exponent is the width of abs(a)25 // The exponent is the width of abs(a)
26 const exp = Z(31 - @clz(i32, abs_a));26 const exp = @as(Z, 31 - @clz(i32, abs_a));
2727
28 const sign_bit = if (sign < 0) signBit else 0;28 const sign_bit = if (sign < 0) signBit else 0;
2929
lib/std/special/compiler_rt/floattidf.zig+1-1
...@@ -47,7 +47,7 @@ pub extern fn __floattidf(arg: i128) f64 {...@@ -47,7 +47,7 @@ pub extern fn __floattidf(arg: i128) f64 {
47 a += 1; // round - this step may add a significant bit47 a += 1; // round - this step may add a significant bit
48 a >>= 2; // dump Q and R48 a >>= 2; // dump Q and R
49 // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits49 // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
50 if ((a & (u128(1) << DBL_MANT_DIG)) != 0) {50 if ((a & (@as(u128, 1) << DBL_MANT_DIG)) != 0) {
51 a >>= 1;51 a >>= 1;
52 e += 1;52 e += 1;
53 }53 }
lib/std/special/compiler_rt/floattisf.zig+1-1
...@@ -48,7 +48,7 @@ pub extern fn __floattisf(arg: i128) f32 {...@@ -48,7 +48,7 @@ pub extern fn __floattisf(arg: i128) f32 {
48 a += 1; // round - this step may add a significant bit48 a += 1; // round - this step may add a significant bit
49 a >>= 2; // dump Q and R49 a >>= 2; // dump Q and R
50 // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits50 // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
51 if ((a & (u128(1) << FLT_MANT_DIG)) != 0) {51 if ((a & (@as(u128, 1) << FLT_MANT_DIG)) != 0) {
52 a >>= 1;52 a >>= 1;
53 e += 1;53 e += 1;
54 }54 }
lib/std/special/compiler_rt/floattitf.zig+1-1
...@@ -47,7 +47,7 @@ pub extern fn __floattitf(arg: i128) f128 {...@@ -47,7 +47,7 @@ pub extern fn __floattitf(arg: i128) f128 {
47 a += 1; // round - this step may add a significant bit47 a += 1; // round - this step may add a significant bit
48 a >>= 2; // dump Q and R48 a >>= 2; // dump Q and R
49 // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits49 // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
50 if ((a & (u128(1) << LDBL_MANT_DIG)) != 0) {50 if ((a & (@as(u128, 1) << LDBL_MANT_DIG)) != 0) {
51 a >>= 1;51 a >>= 1;
52 e += 1;52 e += 1;
53 }53 }
lib/std/special/compiler_rt/floatunsidf.zig+3-3
...@@ -2,7 +2,7 @@ const builtin = @import("builtin");...@@ -2,7 +2,7 @@ const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
3const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
44
5const implicitBit = u64(1) << 52;5const implicitBit = @as(u64, 1) << 52;
66
7pub extern fn __floatunsidf(arg: u32) f64 {7pub extern fn __floatunsidf(arg: u32) f64 {
8 @setRuntimeSafety(builtin.is_test);8 @setRuntimeSafety(builtin.is_test);
...@@ -10,10 +10,10 @@ pub extern fn __floatunsidf(arg: u32) f64 {...@@ -10,10 +10,10 @@ pub extern fn __floatunsidf(arg: u32) f64 {
10 if (arg == 0) return 0.0;10 if (arg == 0) return 0.0;
1111
12 // The exponent is the width of abs(a)12 // The exponent is the width of abs(a)
13 const exp = u64(31) - @clz(u32, arg);13 const exp = @as(u64, 31) - @clz(u32, arg);
14 // Shift a into the significand field and clear the implicit bit14 // Shift a into the significand field and clear the implicit bit
15 const shift = @intCast(u6, 52 - exp);15 const shift = @intCast(u6, 52 - exp);
16 const mant = u64(arg) << shift ^ implicitBit;16 const mant = @as(u64, arg) << shift ^ implicitBit;
1717
18 return @bitCast(f64, mant | (exp + 1023) << 52);18 return @bitCast(f64, mant | (exp + 1023) << 52);
19}19}
lib/std/special/compiler_rt/floatuntidf.zig+2-2
...@@ -32,7 +32,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {...@@ -32,7 +32,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
32 const shift_amt = @bitCast(i32, N + (DBL_MANT_DIG + 2)) - sd;32 const shift_amt = @bitCast(i32, N + (DBL_MANT_DIG + 2)) - sd;
33 const shift_amt_u7 = @intCast(u7, shift_amt);33 const shift_amt_u7 = @intCast(u7, shift_amt);
34 a = (a >> @intCast(u7, sd - (DBL_MANT_DIG + 2))) |34 a = (a >> @intCast(u7, sd - (DBL_MANT_DIG + 2))) |
35 @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);35 @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
36 },36 },
37 }37 }
38 // finish38 // finish
...@@ -40,7 +40,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {...@@ -40,7 +40,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
40 a += 1; // round - this step may add a significant bit40 a += 1; // round - this step may add a significant bit
41 a >>= 2; // dump Q and R41 a >>= 2; // dump Q and R
42 // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits42 // a is now rounded to DBL_MANT_DIG or DBL_MANT_DIG+1 bits
43 if ((a & (u128(1) << DBL_MANT_DIG)) != 0) {43 if ((a & (@as(u128, 1) << DBL_MANT_DIG)) != 0) {
44 a >>= 1;44 a >>= 1;
45 e += 1;45 e += 1;
46 }46 }
lib/std/special/compiler_rt/floatuntisf.zig+2-2
...@@ -32,7 +32,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {...@@ -32,7 +32,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
32 const shift_amt = @bitCast(i32, N + (FLT_MANT_DIG + 2)) - sd;32 const shift_amt = @bitCast(i32, N + (FLT_MANT_DIG + 2)) - sd;
33 const shift_amt_u7 = @intCast(u7, shift_amt);33 const shift_amt_u7 = @intCast(u7, shift_amt);
34 a = (a >> @intCast(u7, sd - (FLT_MANT_DIG + 2))) |34 a = (a >> @intCast(u7, sd - (FLT_MANT_DIG + 2))) |
35 @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);35 @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
36 },36 },
37 }37 }
38 // finish38 // finish
...@@ -40,7 +40,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {...@@ -40,7 +40,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
40 a += 1; // round - this step may add a significant bit40 a += 1; // round - this step may add a significant bit
41 a >>= 2; // dump Q and R41 a >>= 2; // dump Q and R
42 // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits42 // a is now rounded to FLT_MANT_DIG or FLT_MANT_DIG+1 bits
43 if ((a & (u128(1) << FLT_MANT_DIG)) != 0) {43 if ((a & (@as(u128, 1) << FLT_MANT_DIG)) != 0) {
44 a >>= 1;44 a >>= 1;
45 e += 1;45 e += 1;
46 }46 }
lib/std/special/compiler_rt/floatuntitf.zig+2-2
...@@ -32,7 +32,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {...@@ -32,7 +32,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
32 const shift_amt = @bitCast(i32, N + (LDBL_MANT_DIG + 2)) - sd;32 const shift_amt = @bitCast(i32, N + (LDBL_MANT_DIG + 2)) - sd;
33 const shift_amt_u7 = @intCast(u7, shift_amt);33 const shift_amt_u7 = @intCast(u7, shift_amt);
34 a = (a >> @intCast(u7, sd - (LDBL_MANT_DIG + 2))) |34 a = (a >> @intCast(u7, sd - (LDBL_MANT_DIG + 2))) |
35 @boolToInt((a & (u128(maxInt(u128)) >> shift_amt_u7)) != 0);35 @boolToInt((a & (@as(u128, maxInt(u128)) >> shift_amt_u7)) != 0);
36 },36 },
37 }37 }
38 // finish38 // finish
...@@ -40,7 +40,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {...@@ -40,7 +40,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
40 a += 1; // round - this step may add a significant bit40 a += 1; // round - this step may add a significant bit
41 a >>= 2; // dump Q and R41 a >>= 2; // dump Q and R
42 // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits42 // a is now rounded to LDBL_MANT_DIG or LDBL_MANT_DIG+1 bits
43 if ((a & (u128(1) << LDBL_MANT_DIG)) != 0) {43 if ((a & (@as(u128, 1) << LDBL_MANT_DIG)) != 0) {
44 a >>= 1;44 a >>= 1;
45 e += 1;45 e += 1;
46 }46 }
lib/std/special/compiler_rt/mulXf3.zig+25-25
...@@ -24,11 +24,11 @@ fn mulXf3(comptime T: type, a: T, b: T) T {...@@ -24,11 +24,11 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
24 const significandBits = std.math.floatMantissaBits(T);24 const significandBits = std.math.floatMantissaBits(T);
25 const exponentBits = std.math.floatExponentBits(T);25 const exponentBits = std.math.floatExponentBits(T);
2626
27 const signBit = (Z(1) << (significandBits + exponentBits));27 const signBit = (@as(Z, 1) << (significandBits + exponentBits));
28 const maxExponent = ((1 << exponentBits) - 1);28 const maxExponent = ((1 << exponentBits) - 1);
29 const exponentBias = (maxExponent >> 1);29 const exponentBias = (maxExponent >> 1);
3030
31 const implicitBit = (Z(1) << significandBits);31 const implicitBit = (@as(Z, 1) << significandBits);
32 const quietBit = implicitBit >> 1;32 const quietBit = implicitBit >> 1;
33 const significandMask = implicitBit - 1;33 const significandMask = implicitBit - 1;
3434
...@@ -122,7 +122,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {...@@ -122,7 +122,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
122 // a zero of the appropriate sign. Mathematically there is no need to122 // a zero of the appropriate sign. Mathematically there is no need to
123 // handle this case separately, but we make it a special case to123 // handle this case separately, but we make it a special case to
124 // simplify the shift logic.124 // simplify the shift logic.
125 const shift: u32 = @truncate(u32, Z(1) -% @bitCast(u32, productExponent));125 const shift: u32 = @truncate(u32, @as(Z, 1) -% @bitCast(u32, productExponent));
126 if (shift >= typeWidth) return @bitCast(T, productSign);126 if (shift >= typeWidth) return @bitCast(T, productSign);
127127
128 // Otherwise, shift the significand of the result so that the round128 // Otherwise, shift the significand of the result so that the round
...@@ -131,7 +131,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {...@@ -131,7 +131,7 @@ fn mulXf3(comptime T: type, a: T, b: T) T {
131 } else {131 } else {
132 // Result is normal before rounding; insert the exponent.132 // Result is normal before rounding; insert the exponent.
133 productHi &= significandMask;133 productHi &= significandMask;
134 productHi |= Z(@bitCast(u32, productExponent)) << significandBits;134 productHi |= @as(Z, @bitCast(u32, productExponent)) << significandBits;
135 }135 }
136136
137 // Insert the sign of the result:137 // Insert the sign of the result:
...@@ -150,7 +150,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -150,7 +150,7 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
150 switch (Z) {150 switch (Z) {
151 u32 => {151 u32 => {
152 // 32x32 --> 64 bit multiply152 // 32x32 --> 64 bit multiply
153 const product = u64(a) * u64(b);153 const product = @as(u64, a) * @as(u64, b);
154 hi.* = @truncate(u32, product >> 32);154 hi.* = @truncate(u32, product >> 32);
155 lo.* = @truncate(u32, product);155 lo.* = @truncate(u32, product);
156 },156 },
...@@ -179,9 +179,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -179,9 +179,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
179 hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;179 hi.* = S.hiWord(plohi) +% S.hiWord(philo) +% S.hiWord(r1) +% phihi;
180 },180 },
181 u128 => {181 u128 => {
182 const Word_LoMask = u64(0x00000000ffffffff);182 const Word_LoMask = @as(u64, 0x00000000ffffffff);
183 const Word_HiMask = u64(0xffffffff00000000);183 const Word_HiMask = @as(u64, 0xffffffff00000000);
184 const Word_FullMask = u64(0xffffffffffffffff);184 const Word_FullMask = @as(u64, 0xffffffffffffffff);
185 const S = struct {185 const S = struct {
186 fn Word_1(x: u128) u64 {186 fn Word_1(x: u128) u64 {
187 return @truncate(u32, x >> 96);187 return @truncate(u32, x >> 96);
...@@ -217,22 +217,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -217,22 +217,22 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
217 const product43: u64 = S.Word_4(a) * S.Word_3(b);217 const product43: u64 = S.Word_4(a) * S.Word_3(b);
218 const product44: u64 = S.Word_4(a) * S.Word_4(b);218 const product44: u64 = S.Word_4(a) * S.Word_4(b);
219219
220 const sum0: u128 = u128(product44);220 const sum0: u128 = @as(u128, product44);
221 const sum1: u128 = u128(product34) +%221 const sum1: u128 = @as(u128, product34) +%
222 u128(product43);222 @as(u128, product43);
223 const sum2: u128 = u128(product24) +%223 const sum2: u128 = @as(u128, product24) +%
224 u128(product33) +%224 @as(u128, product33) +%
225 u128(product42);225 @as(u128, product42);
226 const sum3: u128 = u128(product14) +%226 const sum3: u128 = @as(u128, product14) +%
227 u128(product23) +%227 @as(u128, product23) +%
228 u128(product32) +%228 @as(u128, product32) +%
229 u128(product41);229 @as(u128, product41);
230 const sum4: u128 = u128(product13) +%230 const sum4: u128 = @as(u128, product13) +%
231 u128(product22) +%231 @as(u128, product22) +%
232 u128(product31);232 @as(u128, product31);
233 const sum5: u128 = u128(product12) +%233 const sum5: u128 = @as(u128, product12) +%
234 u128(product21);234 @as(u128, product21);
235 const sum6: u128 = u128(product11);235 const sum6: u128 = @as(u128, product11);
236236
237 const r0: u128 = (sum0 & Word_FullMask) +%237 const r0: u128 = (sum0 & Word_FullMask) +%
238 ((sum1 & Word_LoMask) << 32);238 ((sum1 & Word_LoMask) << 32);
...@@ -258,7 +258,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {...@@ -258,7 +258,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
258 @setRuntimeSafety(builtin.is_test);258 @setRuntimeSafety(builtin.is_test);
259 const Z = @IntType(false, T.bit_count);259 const Z = @IntType(false, T.bit_count);
260 const significandBits = std.math.floatMantissaBits(T);260 const significandBits = std.math.floatMantissaBits(T);
261 const implicitBit = Z(1) << significandBits;261 const implicitBit = @as(Z, 1) << significandBits;
262262
263 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);263 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
264 significand.* <<= @intCast(std.math.Log2Int(Z), shift);264 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
lib/std/special/compiler_rt/mulXf3_test.zig+9-9
...@@ -2,8 +2,8 @@...@@ -2,8 +2,8 @@
2//2//
3// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c3// https://github.com/llvm/llvm-project/blob/2ffb1b0413efa9a24eb3c49e710e36f92e2cb50b/compiler-rt/test/builtins/Unit/multf3_test.c
44
5const qnan128 = @bitCast(f128, u128(0x7fff800000000000) << 64);5const qnan128 = @bitCast(f128, @as(u128, 0x7fff800000000000) << 64);
6const inf128 = @bitCast(f128, u128(0x7fff000000000000) << 64);6const inf128 = @bitCast(f128, @as(u128, 0x7fff000000000000) << 64);
77
8const __multf3 = @import("mulXf3.zig").__multf3;8const __multf3 = @import("mulXf3.zig").__multf3;
99
...@@ -39,7 +39,7 @@ fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {...@@ -39,7 +39,7 @@ fn test__multf3(a: f128, b: f128, expected_hi: u64, expected_lo: u64) void {
39}39}
4040
41fn makeNaN128(rand: u64) f128 {41fn makeNaN128(rand: u64) f128 {
42 const int_result = u128(0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;42 const int_result = @as(u128, 0x7fff000000000000 | (rand & 0xffffffffffff)) << 64;
43 const float_result = @bitCast(f128, int_result);43 const float_result = @bitCast(f128, int_result);
44 return float_result;44 return float_result;
45}45}
...@@ -55,15 +55,15 @@ test "multf3" {...@@ -55,15 +55,15 @@ test "multf3" {
5555
56 // any * any56 // any * any
57 test__multf3(57 test__multf3(
58 @bitCast(f128, u128(0x40042eab345678439abcdefea5678234)),58 @bitCast(f128, @as(u128, 0x40042eab345678439abcdefea5678234)),
59 @bitCast(f128, u128(0x3ffeedcb34a235253948765432134675)),59 @bitCast(f128, @as(u128, 0x3ffeedcb34a235253948765432134675)),
60 0x400423e7f9e3c9fc,60 0x400423e7f9e3c9fc,
61 0xd906c2c2a85777c4,61 0xd906c2c2a85777c4,
62 );62 );
6363
64 test__multf3(64 test__multf3(
65 @bitCast(f128, u128(0x3fcd353e45674d89abacc3a2ebf3ff50)),65 @bitCast(f128, @as(u128, 0x3fcd353e45674d89abacc3a2ebf3ff50)),
66 @bitCast(f128, u128(0x3ff6ed8764648369535adf4be3214568)),66 @bitCast(f128, @as(u128, 0x3ff6ed8764648369535adf4be3214568)),
67 0x3fc52a163c6223fc,67 0x3fc52a163c6223fc,
68 0xc94c4bf0430768b4,68 0xc94c4bf0430768b4,
69 );69 );
...@@ -76,8 +76,8 @@ test "multf3" {...@@ -76,8 +76,8 @@ test "multf3" {
76 );76 );
7777
78 test__multf3(78 test__multf3(
79 @bitCast(f128, u128(0x3f154356473c82a9fabf2d22ace345df)),79 @bitCast(f128, @as(u128, 0x3f154356473c82a9fabf2d22ace345df)),
80 @bitCast(f128, u128(0x3e38eda98765476743ab21da23d45679)),80 @bitCast(f128, @as(u128, 0x3e38eda98765476743ab21da23d45679)),
81 0x3d4f37c1a3137cae,81 0x3d4f37c1a3137cae,
82 0xfc6807048bc2836a,82 0xfc6807048bc2836a,
83 );83 );
lib/std/special/compiler_rt/muldi3.zig+1-1
...@@ -21,7 +21,7 @@ fn __muldsi3(a: u32, b: u32) i64 {...@@ -21,7 +21,7 @@ fn __muldsi3(a: u32, b: u32) i64 {
21 @setRuntimeSafety(builtin.is_test);21 @setRuntimeSafety(builtin.is_test);
2222
23 const bits_in_word_2 = @sizeOf(i32) * 8 / 2;23 const bits_in_word_2 = @sizeOf(i32) * 8 / 2;
24 const lower_mask = (~u32(0)) >> bits_in_word_2;24 const lower_mask = (~@as(u32, 0)) >> bits_in_word_2;
2525
26 var r: dwords = undefined;26 var r: dwords = undefined;
27 r.s.low = (a & lower_mask) *% (b & lower_mask);27 r.s.low = (a & lower_mask) *% (b & lower_mask);
lib/std/special/compiler_rt/mulodi4.zig+1-1
...@@ -6,7 +6,7 @@ const minInt = std.math.minInt;...@@ -6,7 +6,7 @@ const minInt = std.math.minInt;
6pub extern fn __mulodi4(a: i64, b: i64, overflow: *c_int) i64 {6pub extern fn __mulodi4(a: i64, b: i64, overflow: *c_int) i64 {
7 @setRuntimeSafety(builtin.is_test);7 @setRuntimeSafety(builtin.is_test);
88
9 const min = @bitCast(i64, u64(1 << (i64.bit_count - 1)));9 const min = @bitCast(i64, @as(u64, 1 << (i64.bit_count - 1)));
10 const max = ~min;10 const max = ~min;
1111
12 overflow.* = 0;12 overflow.* = 0;
lib/std/special/compiler_rt/mulodi4_test.zig+24-24
...@@ -52,34 +52,34 @@ test "mulodi4" {...@@ -52,34 +52,34 @@ test "mulodi4" {
5252
53 test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1);53 test__mulodi4(0x7FFFFFFFFFFFFFFF, -2, 2, 1);
54 test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);54 test__mulodi4(-2, 0x7FFFFFFFFFFFFFFF, 2, 1);
55 test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, u64(0x8000000000000001)), 0);55 test__mulodi4(0x7FFFFFFFFFFFFFFF, -1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
56 test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 0);56 test__mulodi4(-1, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
57 test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0);57 test__mulodi4(0x7FFFFFFFFFFFFFFF, 0, 0, 0);
58 test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0);58 test__mulodi4(0, 0x7FFFFFFFFFFFFFFF, 0, 0);
59 test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);59 test__mulodi4(0x7FFFFFFFFFFFFFFF, 1, 0x7FFFFFFFFFFFFFFF, 0);
60 test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);60 test__mulodi4(1, 0x7FFFFFFFFFFFFFFF, 0x7FFFFFFFFFFFFFFF, 0);
61 test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, u64(0x8000000000000001)), 1);61 test__mulodi4(0x7FFFFFFFFFFFFFFF, 2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
62 test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, u64(0x8000000000000001)), 1);62 test__mulodi4(2, 0x7FFFFFFFFFFFFFFF, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
6363
64 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -2, @bitCast(i64, u64(0x8000000000000000)), 1);64 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
65 test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);65 test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
66 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), -1, @bitCast(i64, u64(0x8000000000000000)), 1);66 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), -1, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
67 test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);67 test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
68 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 0, 0, 0);68 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0, 0);
69 test__mulodi4(0, @bitCast(i64, u64(0x8000000000000000)), 0, 0);69 test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000000)), 0, 0);
70 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 1, @bitCast(i64, u64(0x8000000000000000)), 0);70 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 1, @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
71 test__mulodi4(1, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 0);71 test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 0);
72 test__mulodi4(@bitCast(i64, u64(0x8000000000000000)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);72 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000000)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
73 test__mulodi4(2, @bitCast(i64, u64(0x8000000000000000)), @bitCast(i64, u64(0x8000000000000000)), 1);73 test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000000)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
7474
75 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -2, @bitCast(i64, u64(0x8000000000000001)), 1);75 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -2, @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
76 test__mulodi4(-2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 1);76 test__mulodi4(-2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 1);
77 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);77 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), -1, 0x7FFFFFFFFFFFFFFF, 0);
78 test__mulodi4(-1, @bitCast(i64, u64(0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);78 test__mulodi4(-1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0x7FFFFFFFFFFFFFFF, 0);
79 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 0, 0, 0);79 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0, 0);
80 test__mulodi4(0, @bitCast(i64, u64(0x8000000000000001)), 0, 0);80 test__mulodi4(0, @bitCast(i64, @as(u64, 0x8000000000000001)), 0, 0);
81 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 1, @bitCast(i64, u64(0x8000000000000001)), 0);81 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 1, @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
82 test__mulodi4(1, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000001)), 0);82 test__mulodi4(1, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000001)), 0);
83 test__mulodi4(@bitCast(i64, u64(0x8000000000000001)), 2, @bitCast(i64, u64(0x8000000000000000)), 1);83 test__mulodi4(@bitCast(i64, @as(u64, 0x8000000000000001)), 2, @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
84 test__mulodi4(2, @bitCast(i64, u64(0x8000000000000001)), @bitCast(i64, u64(0x8000000000000000)), 1);84 test__mulodi4(2, @bitCast(i64, @as(u64, 0x8000000000000001)), @bitCast(i64, @as(u64, 0x8000000000000000)), 1);
85}85}
lib/std/special/compiler_rt/muloti4.zig+1-1
...@@ -4,7 +4,7 @@ const compiler_rt = @import("../compiler_rt.zig");...@@ -4,7 +4,7 @@ const compiler_rt = @import("../compiler_rt.zig");
4pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {4pub extern fn __muloti4(a: i128, b: i128, overflow: *c_int) i128 {
5 @setRuntimeSafety(builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
66
7 const min = @bitCast(i128, u128(1 << (i128.bit_count - 1)));7 const min = @bitCast(i128, @as(u128, 1 << (i128.bit_count - 1)));
8 const max = ~min;8 const max = ~min;
9 overflow.* = 0;9 overflow.* = 0;
1010
lib/std/special/compiler_rt/muloti4_test.zig+31-31
...@@ -39,38 +39,38 @@ test "muloti4" {...@@ -39,38 +39,38 @@ test "muloti4" {
39 test__muloti4(2097152, -4398046511103, -9223372036852678656, 0);39 test__muloti4(2097152, -4398046511103, -9223372036852678656, 0);
40 test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0);40 test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0);
4141
42 test__muloti4(@bitCast(i128, u128(0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, u128(0x000000000000000000B504F333F9DE5B)), @bitCast(i128, u128(0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0);42 test__muloti4(@bitCast(i128, @as(u128, 0x00000000000000B504F333F9DE5BE000)), @bitCast(i128, @as(u128, 0x000000000000000000B504F333F9DE5B)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFF328DF915DA296E8A000)), 0);
43 test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);43 test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
44 test__muloti4(-2, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);44 test__muloti4(-2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
4545
46 test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -1, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);46 test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
47 test__muloti4(-1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);47 test__muloti4(-1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
48 test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0);48 test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0, 0);
49 test__muloti4(0, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0);49 test__muloti4(0, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0, 0);
50 test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);50 test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
51 test__muloti4(1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);51 test__muloti4(1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
52 test__muloti4(@bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);52 test__muloti4(@bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
53 test__muloti4(2, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);53 test__muloti4(2, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
5454
55 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), -2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);55 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
56 test__muloti4(-2, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);56 test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
57 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), -1, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);57 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), -1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
58 test__muloti4(-1, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);58 test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
59 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 0, 0, 0);59 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0, 0);
60 test__muloti4(0, @bitCast(i128, u128(0x80000000000000000000000000000000)), 0, 0);60 test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0, 0);
61 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 1, @bitCast(i128, u128(0x80000000000000000000000000000000)), 0);61 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
62 test__muloti4(1, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 0);62 test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 0);
63 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000000)), 2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);63 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
64 test__muloti4(2, @bitCast(i128, u128(0x80000000000000000000000000000000)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);64 test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
6565
66 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), -2, @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);66 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
67 test__muloti4(-2, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 1);67 test__muloti4(-2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1);
68 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), -1, @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);68 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), -1, @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
69 test__muloti4(-1, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);69 test__muloti4(-1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)), 0);
70 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 0, 0, 0);70 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0, 0);
71 test__muloti4(0, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0, 0);71 test__muloti4(0, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0, 0);
72 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 1, @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);72 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
73 test__muloti4(1, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000001)), 0);73 test__muloti4(1, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 0);
74 test__muloti4(@bitCast(i128, u128(0x80000000000000000000000000000001)), 2, @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);74 test__muloti4(@bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), 2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
75 test__muloti4(2, @bitCast(i128, u128(0x80000000000000000000000000000001)), @bitCast(i128, u128(0x80000000000000000000000000000000)), 1);75 test__muloti4(2, @bitCast(i128, @as(u128, 0x80000000000000000000000000000001)), @bitCast(i128, @as(u128, 0x80000000000000000000000000000000)), 1);
76}76}
lib/std/special/compiler_rt/multi3.zig+1-1
...@@ -21,7 +21,7 @@ pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 {...@@ -21,7 +21,7 @@ pub extern fn __multi3_windows_x86_64(a: v128, b: v128) v128 {
2121
22fn __mulddi3(a: u64, b: u64) i128 {22fn __mulddi3(a: u64, b: u64) i128 {
23 const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2;23 const bits_in_dword_2 = (@sizeOf(i64) * 8) / 2;
24 const lower_mask = ~u64(0) >> bits_in_dword_2;24 const lower_mask = ~@as(u64, 0) >> bits_in_dword_2;
25 var r: twords = undefined;25 var r: twords = undefined;
26 r.s.low = (a & lower_mask) *% (b & lower_mask);26 r.s.low = (a & lower_mask) *% (b & lower_mask);
27 var t: u64 = r.s.low >> bits_in_dword_2;27 var t: u64 = r.s.low >> bits_in_dword_2;
lib/std/special/compiler_rt/negXf2.zig+1-1
...@@ -15,7 +15,7 @@ fn negXf2(comptime T: type, a: T) T {...@@ -15,7 +15,7 @@ fn negXf2(comptime T: type, a: T) T {
15 const significandBits = std.math.floatMantissaBits(T);15 const significandBits = std.math.floatMantissaBits(T);
16 const exponentBits = std.math.floatExponentBits(T);16 const exponentBits = std.math.floatExponentBits(T);
1717
18 const signBit = (Z(1) << (significandBits + exponentBits));18 const signBit = (@as(Z, 1) << (significandBits + exponentBits));
1919
20 return @bitCast(T, @bitCast(Z, a) ^ signBit);20 return @bitCast(T, @bitCast(Z, a) ^ signBit);
21}21}
lib/std/special/compiler_rt/popcountdi2_test.zig+3-3
...@@ -20,8 +20,8 @@ test "popcountdi2" {...@@ -20,8 +20,8 @@ test "popcountdi2" {
20 test__popcountdi2(0);20 test__popcountdi2(0);
21 test__popcountdi2(1);21 test__popcountdi2(1);
22 test__popcountdi2(2);22 test__popcountdi2(2);
23 test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFD)));23 test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFD)));
24 test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFE)));24 test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFE)));
25 test__popcountdi2(@bitCast(i64, u64(0xFFFFFFFFFFFFFFFF)));25 test__popcountdi2(@bitCast(i64, @as(u64, 0xFFFFFFFFFFFFFFFF)));
26 // TODO some fuzz testing26 // TODO some fuzz testing
27}27}
lib/std/special/compiler_rt/truncXfYf2.zig+1-1
...@@ -69,7 +69,7 @@ inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t...@@ -69,7 +69,7 @@ inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t
69 // destination format. We can convert by simply right-shifting with69 // destination format. We can convert by simply right-shifting with
70 // rounding and adjusting the exponent.70 // rounding and adjusting the exponent.
71 absResult = @truncate(dst_rep_t, aAbs >> (srcSigBits - dstSigBits));71 absResult = @truncate(dst_rep_t, aAbs >> (srcSigBits - dstSigBits));
72 absResult -%= dst_rep_t(srcExpBias - dstExpBias) << dstSigBits;72 absResult -%= @as(dst_rep_t, srcExpBias - dstExpBias) << dstSigBits;
7373
74 const roundBits: src_rep_t = aAbs & roundMask;74 const roundBits: src_rep_t = aAbs & roundMask;
75 if (roundBits > halfway) {75 if (roundBits > halfway) {
lib/std/special/compiler_rt/truncXfYf2_test.zig+10-10
...@@ -152,11 +152,11 @@ fn test__trunctfsf2(a: f128, expected: u32) void {...@@ -152,11 +152,11 @@ fn test__trunctfsf2(a: f128, expected: u32) void {
152152
153test "trunctfsf2" {153test "trunctfsf2" {
154 // qnan154 // qnan
155 test__trunctfsf2(@bitCast(f128, u128(0x7fff800000000000 << 64)), 0x7fc00000);155 test__trunctfsf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7fc00000);
156 // nan156 // nan
157 test__trunctfsf2(@bitCast(f128, u128((0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);157 test__trunctfsf2(@bitCast(f128, @as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7fc08000);
158 // inf158 // inf
159 test__trunctfsf2(@bitCast(f128, u128(0x7fff000000000000 << 64)), 0x7f800000);159 test__trunctfsf2(@bitCast(f128, @as(u128, 0x7fff000000000000 << 64)), 0x7f800000);
160 // zero160 // zero
161 test__trunctfsf2(0.0, 0x0);161 test__trunctfsf2(0.0, 0x0);
162162
...@@ -187,11 +187,11 @@ fn test__trunctfdf2(a: f128, expected: u64) void {...@@ -187,11 +187,11 @@ fn test__trunctfdf2(a: f128, expected: u64) void {
187187
188test "trunctfdf2" {188test "trunctfdf2" {
189 // qnan189 // qnan
190 test__trunctfdf2(@bitCast(f128, u128(0x7fff800000000000 << 64)), 0x7ff8000000000000);190 test__trunctfdf2(@bitCast(f128, @as(u128, 0x7fff800000000000 << 64)), 0x7ff8000000000000);
191 // nan191 // nan
192 test__trunctfdf2(@bitCast(f128, u128((0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);192 test__trunctfdf2(@bitCast(f128, @as(u128, (0x7fff000000000000 | (0x810000000000 & 0xffffffffffff)) << 64)), 0x7ff8100000000000);
193 // inf193 // inf
194 test__trunctfdf2(@bitCast(f128, u128(0x7fff000000000000 << 64)), 0x7ff0000000000000);194 test__trunctfdf2(@bitCast(f128, @as(u128, 0x7fff000000000000 << 64)), 0x7ff0000000000000);
195 // zero195 // zero
196 test__trunctfdf2(0.0, 0x0);196 test__trunctfdf2(0.0, 0x0);
197197
...@@ -224,11 +224,11 @@ fn test__truncdfsf2(a: f64, expected: u32) void {...@@ -224,11 +224,11 @@ fn test__truncdfsf2(a: f64, expected: u32) void {
224224
225test "truncdfsf2" {225test "truncdfsf2" {
226 // nan & qnan226 // nan & qnan
227 test__truncdfsf2(@bitCast(f64, u64(0x7ff8000000000000)), 0x7fc00000);227 test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff8000000000000)), 0x7fc00000);
228 test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000001)), 0x7fc00000);228 test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff0000000000001)), 0x7fc00000);
229 // inf229 // inf
230 test__truncdfsf2(@bitCast(f64, u64(0x7ff0000000000000)), 0x7f800000);230 test__truncdfsf2(@bitCast(f64, @as(u64, 0x7ff0000000000000)), 0x7f800000);
231 test__truncdfsf2(@bitCast(f64, u64(0xfff0000000000000)), 0xff800000);231 test__truncdfsf2(@bitCast(f64, @as(u64, 0xfff0000000000000)), 0xff800000);
232232
233 test__truncdfsf2(0.0, 0x0);233 test__truncdfsf2(0.0, 0x0);
234 test__truncdfsf2(1.0, 0x3f800000);234 test__truncdfsf2(1.0, 0x3f800000);
lib/std/special/compiler_rt/udivmod.zig+3-3
...@@ -76,7 +76,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -76,7 +76,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
76 // K K76 // K K
77 // ---77 // ---
78 // K 078 // K 0
79 sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));79 sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
80 // 0 <= sr <= SingleInt.bit_count - 2 or sr large80 // 0 <= sr <= SingleInt.bit_count - 2 or sr large
81 if (sr > SingleInt.bit_count - 2) {81 if (sr > SingleInt.bit_count - 2) {
82 if (maybe_rem) |rem| {82 if (maybe_rem) |rem| {
...@@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
114 // K X114 // K X
115 // ---115 // ---
116 // 0 K116 // 0 K
117 sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high]));117 sr = 1 + SingleInt.bit_count + @as(c_uint, @clz(SingleInt, d[low])) - @as(c_uint, @clz(SingleInt, n[high]));
118 // 2 <= sr <= DoubleInt.bit_count - 1118 // 2 <= sr <= DoubleInt.bit_count - 1
119 // q.all = a << (DoubleInt.bit_count - sr);119 // q.all = a << (DoubleInt.bit_count - sr);
120 // r.all = a >> sr;120 // r.all = a >> sr;
...@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
140 // K X140 // K X
141 // ---141 // ---
142 // K K142 // K K
143 sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));143 sr = @bitCast(c_uint, @as(c_int, @clz(SingleInt, d[high])) - @as(c_int, @clz(SingleInt, n[high])));
144 // 0 <= sr <= SingleInt.bit_count - 1 or sr large144 // 0 <= sr <= SingleInt.bit_count - 1 or sr large
145 if (sr > SingleInt.bit_count - 1) {145 if (sr > SingleInt.bit_count - 1) {
146 if (maybe_rem) |rem| {146 if (maybe_rem) |rem| {
lib/std/special/docs/index.html+1-1
...@@ -484,7 +484,7 @@...@@ -484,7 +484,7 @@
484 doc comments.484 doc comments.
485 </p>485 </p>
486 </div>486 </div>
487 <div id="fnDocs" class="hidden"></div>487 <div id="tldDocs" class="hidden"></div>
488 <div id="sectFnErrors" class="hidden">488 <div id="sectFnErrors" class="hidden">
489 <h2>Errors</h2>489 <h2>Errors</h2>
490 <div id="fnErrorsAnyError">490 <div id="fnErrorsAnyError">
lib/std/special/docs/main.js+19-12
...@@ -20,7 +20,7 @@...@@ -20,7 +20,7 @@
20 var domListValues = document.getElementById("listValues");20 var domListValues = document.getElementById("listValues");
21 var domFnProto = document.getElementById("fnProto");21 var domFnProto = document.getElementById("fnProto");
22 var domFnProtoCode = document.getElementById("fnProtoCode");22 var domFnProtoCode = document.getElementById("fnProtoCode");
23 var domFnDocs = document.getElementById("fnDocs");23 var domTldDocs = document.getElementById("tldDocs");
24 var domSectFnErrors = document.getElementById("sectFnErrors");24 var domSectFnErrors = document.getElementById("sectFnErrors");
25 var domListFnErrors = document.getElementById("listFnErrors");25 var domListFnErrors = document.getElementById("listFnErrors");
26 var domTableFnErrors = document.getElementById("tableFnErrors");26 var domTableFnErrors = document.getElementById("tableFnErrors");
...@@ -34,7 +34,6 @@...@@ -34,7 +34,6 @@
34 var domListSearchResults = document.getElementById("listSearchResults");34 var domListSearchResults = document.getElementById("listSearchResults");
35 var domSectSearchNoResults = document.getElementById("sectSearchNoResults");35 var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
36 var domSectInfo = document.getElementById("sectInfo");36 var domSectInfo = document.getElementById("sectInfo");
37 var domListInfo = document.getElementById("listInfo");
38 var domTdTarget = document.getElementById("tdTarget");37 var domTdTarget = document.getElementById("tdTarget");
39 var domTdZigVer = document.getElementById("tdZigVer");38 var domTdZigVer = document.getElementById("tdZigVer");
40 var domHdrName = document.getElementById("hdrName");39 var domHdrName = document.getElementById("hdrName");
...@@ -102,7 +101,7 @@...@@ -102,7 +101,7 @@
102 function render() {101 function render() {
103 domStatus.classList.add("hidden");102 domStatus.classList.add("hidden");
104 domFnProto.classList.add("hidden");103 domFnProto.classList.add("hidden");
105 domFnDocs.classList.add("hidden");104 domTldDocs.classList.add("hidden");
106 domSectPkgs.classList.add("hidden");105 domSectPkgs.classList.add("hidden");
107 domSectTypes.classList.add("hidden");106 domSectTypes.classList.add("hidden");
108 domSectNamespaces.classList.add("hidden");107 domSectNamespaces.classList.add("hidden");
...@@ -190,11 +189,11 @@...@@ -190,11 +189,11 @@
190189
191 var docs = zigAnalysis.astNodes[decl.src].docs;190 var docs = zigAnalysis.astNodes[decl.src].docs;
192 if (docs != null) {191 if (docs != null) {
193 domFnDocs.innerHTML = markdown(docs);192 domTldDocs.innerHTML = markdown(docs);
194 } else {193 } else {
195 domFnDocs.innerHTML = '<p>There are no doc comments for this declaration.</p>';194 domTldDocs.innerHTML = '<p>There are no doc comments for this declaration.</p>';
196 }195 }
197 domFnDocs.classList.remove("hidden");196 domTldDocs.classList.remove("hidden");
198 }197 }
199198
200 function typeIsErrSet(typeIndex) {199 function typeIsErrSet(typeIndex) {
...@@ -274,8 +273,8 @@...@@ -274,8 +273,8 @@
274 docsSource = protoSrcNode.docs;273 docsSource = protoSrcNode.docs;
275 }274 }
276 if (docsSource != null) {275 if (docsSource != null) {
277 domFnDocs.innerHTML = markdown(docsSource);276 domTldDocs.innerHTML = markdown(docsSource);
278 domFnDocs.classList.remove("hidden");277 domTldDocs.classList.remove("hidden");
279 }278 }
280 domFnProto.classList.remove("hidden");279 domFnProto.classList.remove("hidden");
281 }280 }
...@@ -893,8 +892,8 @@...@@ -893,8 +892,8 @@
893892
894 var docs = zigAnalysis.astNodes[decl.src].docs;893 var docs = zigAnalysis.astNodes[decl.src].docs;
895 if (docs != null) {894 if (docs != null) {
896 domFnDocs.innerHTML = markdown(docs);895 domTldDocs.innerHTML = markdown(docs);
897 domFnDocs.classList.remove("hidden");896 domTldDocs.classList.remove("hidden");
898 }897 }
899898
900 domFnProto.classList.remove("hidden");899 domFnProto.classList.remove("hidden");
...@@ -906,8 +905,8 @@...@@ -906,8 +905,8 @@
906905
907 var docs = zigAnalysis.astNodes[decl.src].docs;906 var docs = zigAnalysis.astNodes[decl.src].docs;
908 if (docs != null) {907 if (docs != null) {
909 domFnDocs.innerHTML = markdown(docs);908 domTldDocs.innerHTML = markdown(docs);
910 domFnDocs.classList.remove("hidden");909 domTldDocs.classList.remove("hidden");
911 }910 }
912911
913 domFnProto.classList.remove("hidden");912 domFnProto.classList.remove("hidden");
...@@ -957,6 +956,14 @@...@@ -957,6 +956,14 @@
957 varsList.sort(byNameProperty);956 varsList.sort(byNameProperty);
958 valsList.sort(byNameProperty);957 valsList.sort(byNameProperty);
959958
959 if (container.src != null) {
960 var docs = zigAnalysis.astNodes[container.src].docs;
961 if (docs != null) {
962 domTldDocs.innerHTML = markdown(docs);
963 domTldDocs.classList.remove("hidden");
964 }
965 }
966
960 if (typesList.length !== 0) {967 if (typesList.length !== 0) {
961 resizeDomList(domListTypes, typesList.length, '<li><a href="#"></a></li>');968 resizeDomList(domListTypes, typesList.length, '<li><a href="#"></a></li>');
962 for (var i = 0; i < typesList.length; i += 1) {969 for (var i = 0; i < typesList.length; i += 1) {
lib/std/special/start.zig+1-1
...@@ -214,7 +214,7 @@ inline fn initEventLoopAndCallMain() u8 {...@@ -214,7 +214,7 @@ inline fn initEventLoopAndCallMain() u8 {
214 return @inlineCall(callMain);214 return @inlineCall(callMain);
215}215}
216216
217fn callMainAsync(loop: *std.event.Loop) u8 {217async fn callMainAsync(loop: *std.event.Loop) u8 {
218 // This prevents the event loop from terminating at least until main() has returned.218 // This prevents the event loop from terminating at least until main() has returned.
219 loop.beginOneEvent();219 loop.beginOneEvent();
220 defer loop.finishOneEvent();220 defer loop.finishOneEvent();
lib/std/spinlock.zig+41-4
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const std = @import("std.zig");1const std = @import("std.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const AtomicOrder = builtin.AtomicOrder;
4const AtomicRmwOp = builtin.AtomicRmwOp;
5const assert = std.debug.assert;3const assert = std.debug.assert;
4const time = std.time;
5const os = std.os;
66
7pub const SpinLock = struct {7pub const SpinLock = struct {
8 lock: u8, // TODO use a bool or enum8 lock: u8, // TODO use a bool or enum
...@@ -11,7 +11,7 @@ pub const SpinLock = struct {...@@ -11,7 +11,7 @@ pub const SpinLock = struct {
11 spinlock: *SpinLock,11 spinlock: *SpinLock,
1212
13 pub fn release(self: Held) void {13 pub fn release(self: Held) void {
14 assert(@atomicRmw(u8, &self.spinlock.lock, builtin.AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst) == 1);14 @atomicStore(u8, &self.spinlock.lock, 0, .Release);
15 }15 }
16 };16 };
1717
...@@ -20,9 +20,46 @@ pub const SpinLock = struct {...@@ -20,9 +20,46 @@ pub const SpinLock = struct {
20 }20 }
2121
22 pub fn acquire(self: *SpinLock) Held {22 pub fn acquire(self: *SpinLock) Held {
23 while (@atomicRmw(u8, &self.lock, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst) != 0) {}23 var backoff = Backoff.init();
24 while (@atomicRmw(u8, &self.lock, .Xchg, 1, .Acquire) != 0)
25 backoff.yield();
24 return Held{ .spinlock = self };26 return Held{ .spinlock = self };
25 }27 }
28
29 pub fn yield(iterations: usize) void {
30 var i = iterations;
31 while (i != 0) : (i -= 1) {
32 switch (builtin.arch) {
33 .i386, .x86_64 => asm volatile ("pause"),
34 .arm, .aarch64 => asm volatile ("yield"),
35 else => time.sleep(0),
36 }
37 }
38 }
39
40 /// Provides a method to incrementally yield longer each time its called.
41 pub const Backoff = struct {
42 iteration: usize,
43
44 pub fn init() @This() {
45 return @This(){ .iteration = 0 };
46 }
47
48 /// Modified hybrid yielding from
49 /// http://www.1024cores.net/home/lock-free-algorithms/tricks/spinning
50 pub fn yield(self: *@This()) void {
51 defer self.iteration +%= 1;
52 if (self.iteration < 20) {
53 SpinLock.yield(self.iteration);
54 } else if (self.iteration < 24) {
55 os.sched_yield() catch time.sleep(1);
56 } else if (self.iteration < 26) {
57 time.sleep(1 * time.millisecond);
58 } else {
59 time.sleep(10 * time.millisecond);
60 }
61 }
62 };
26};63};
2764
28test "spinlock" {65test "spinlock" {
lib/std/statically_initialized_mutex.zig deleted-105
...@@ -1,105 +0,0 @@
1const std = @import("std.zig");
2const builtin = @import("builtin");
3const AtomicOrder = builtin.AtomicOrder;
4const AtomicRmwOp = builtin.AtomicRmwOp;
5const assert = std.debug.assert;
6const expect = std.testing.expect;
7const windows = std.os.windows;
8
9/// Lock may be held only once. If the same thread
10/// tries to acquire the same mutex twice, it deadlocks.
11/// This type is intended to be initialized statically. If you don't
12/// require static initialization, use std.Mutex.
13/// On Windows, this mutex allocates resources when it is
14/// first used, and the resources cannot be freed.
15/// On Linux, this is an alias of std.Mutex.
16pub const StaticallyInitializedMutex = switch (builtin.os) {
17 builtin.Os.linux => std.Mutex,
18 builtin.Os.windows => struct {
19 lock: windows.CRITICAL_SECTION,
20 init_once: windows.RTL_RUN_ONCE,
21
22 pub const Held = struct {
23 mutex: *StaticallyInitializedMutex,
24
25 pub fn release(self: Held) void {
26 windows.kernel32.LeaveCriticalSection(&self.mutex.lock);
27 }
28 };
29
30 pub fn init() StaticallyInitializedMutex {
31 return StaticallyInitializedMutex{
32 .lock = undefined,
33 .init_once = windows.INIT_ONCE_STATIC_INIT,
34 };
35 }
36
37 extern fn initCriticalSection(
38 InitOnce: *windows.RTL_RUN_ONCE,
39 Parameter: ?*c_void,
40 Context: ?*c_void,
41 ) windows.BOOL {
42 const lock = @ptrCast(*windows.CRITICAL_SECTION, @alignCast(@alignOf(windows.CRITICAL_SECTION), Parameter));
43 windows.kernel32.InitializeCriticalSection(lock);
44 return windows.TRUE;
45 }
46
47 /// TODO: once https://github.com/ziglang/zig/issues/287 is solved and std.Mutex has a better
48 /// implementation of a runtime initialized mutex, remove this function.
49 pub fn deinit(self: *StaticallyInitializedMutex) void {
50 windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
51 windows.kernel32.DeleteCriticalSection(&self.lock);
52 }
53
54 pub fn acquire(self: *StaticallyInitializedMutex) Held {
55 windows.InitOnceExecuteOnce(&self.init_once, initCriticalSection, &self.lock, null);
56 windows.kernel32.EnterCriticalSection(&self.lock);
57 return Held{ .mutex = self };
58 }
59 },
60 else => std.Mutex,
61};
62
63test "std.StaticallyInitializedMutex" {
64 const TestContext = struct {
65 data: i128,
66
67 const TestContext = @This();
68 const incr_count = 10000;
69
70 var mutex = StaticallyInitializedMutex.init();
71
72 fn worker(ctx: *TestContext) void {
73 var i: usize = 0;
74 while (i != TestContext.incr_count) : (i += 1) {
75 const held = mutex.acquire();
76 defer held.release();
77
78 ctx.data += 1;
79 }
80 }
81 };
82
83 var plenty_of_memory = try std.heap.direct_allocator.alloc(u8, 300 * 1024);
84 defer std.heap.direct_allocator.free(plenty_of_memory);
85
86 var fixed_buffer_allocator = std.heap.ThreadSafeFixedBufferAllocator.init(plenty_of_memory);
87 var a = &fixed_buffer_allocator.allocator;
88
89 var context = TestContext{ .data = 0 };
90
91 if (builtin.single_threaded) {
92 TestContext.worker(&context);
93 expect(context.data == TestContext.incr_count);
94 } else {
95 const thread_count = 10;
96 var threads: [thread_count]*std.Thread = undefined;
97 for (threads) |*t| {
98 t.* = try std.Thread.spawn(&context, TestContext.worker);
99 }
100 for (threads) |t|
101 t.wait();
102
103 expect(context.data == thread_count * TestContext.incr_count);
104 }
105}
lib/std/std.zig+1-1
...@@ -19,11 +19,11 @@ pub const Progress = @import("progress.zig").Progress;...@@ -19,11 +19,11 @@ pub const Progress = @import("progress.zig").Progress;
19pub const SegmentedList = @import("segmented_list.zig").SegmentedList;19pub const SegmentedList = @import("segmented_list.zig").SegmentedList;
20pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;20pub const SinglyLinkedList = @import("linked_list.zig").SinglyLinkedList;
21pub const SpinLock = @import("spinlock.zig").SpinLock;21pub const SpinLock = @import("spinlock.zig").SpinLock;
22pub const StaticallyInitializedMutex = @import("statically_initialized_mutex.zig").StaticallyInitializedMutex;
23pub const StringHashMap = @import("hash_map.zig").StringHashMap;22pub const StringHashMap = @import("hash_map.zig").StringHashMap;
24pub const TailQueue = @import("linked_list.zig").TailQueue;23pub const TailQueue = @import("linked_list.zig").TailQueue;
25pub const Target = @import("target.zig").Target;24pub const Target = @import("target.zig").Target;
26pub const Thread = @import("thread.zig").Thread;25pub const Thread = @import("thread.zig").Thread;
26pub const ThreadParker = @import("parker.zig").ThreadParker;
2727
28pub const atomic = @import("atomic.zig");28pub const atomic = @import("atomic.zig");
29pub const base64 = @import("base64.zig");29pub const base64 = @import("base64.zig");
lib/std/target.zig+36-2
...@@ -218,6 +218,40 @@ pub const Target = union(enum) {...@@ -218,6 +218,40 @@ pub const Target = union(enum) {
218 );218 );
219 }219 }
220220
221 /// Returned slice must be freed by the caller.
222 pub fn vcpkgTriplet(allocator: *mem.Allocator, target: Target, linkage: std.build.VcpkgLinkage) ![]const u8 {
223 const arch = switch (target.getArch()) {
224 .i386 => "x86",
225 .x86_64 => "x64",
226
227 .arm,
228 .armeb,
229 .thumb,
230 .thumbeb,
231 .aarch64_32,
232 => "arm",
233
234 .aarch64,
235 .aarch64_be,
236 => "arm64",
237
238 else => return error.VcpkgNoSuchArchitecture,
239 };
240
241 const os = switch (target.getOs()) {
242 .windows => "windows",
243 .linux => "linux",
244 .macosx => "macos",
245 else => return error.VcpkgNoSuchOs,
246 };
247
248 if (linkage == .Static) {
249 return try mem.join(allocator, "-", [_][]const u8{ arch, os, "static" });
250 } else {
251 return try mem.join(allocator, "-", [_][]const u8{ arch, os });
252 }
253 }
254
221 pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {255 pub fn allocDescription(self: Target, allocator: *mem.Allocator) ![]u8 {
222 // TODO is there anything else worthy of the description that is not256 // TODO is there anything else worthy of the description that is not
223 // already captured in the triple?257 // already captured in the triple?
...@@ -319,7 +353,7 @@ pub const Target = union(enum) {...@@ -319,7 +353,7 @@ pub const Target = union(enum) {
319 inline for (info.Union.fields) |field| {353 inline for (info.Union.fields) |field| {
320 if (mem.eql(u8, text, field.name)) {354 if (mem.eql(u8, text, field.name)) {
321 if (field.field_type == void) {355 if (field.field_type == void) {
322 return (Arch)(@field(Arch, field.name));356 return @as(Arch, @field(Arch, field.name));
323 } else {357 } else {
324 const sub_info = @typeInfo(field.field_type);358 const sub_info = @typeInfo(field.field_type);
325 inline for (sub_info.Enum.fields) |sub_field| {359 inline for (sub_info.Enum.fields) |sub_field| {
...@@ -581,7 +615,7 @@ pub const Target = union(enum) {...@@ -581,7 +615,7 @@ pub const Target = union(enum) {
581 };615 };
582616
583 pub fn getExternalExecutor(self: Target) Executor {617 pub fn getExternalExecutor(self: Target) Executor {
584 if (@TagType(Target)(self) == .Native) return .native;618 if (@as(@TagType(Target), self) == .Native) return .native;
585619
586 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.620 // If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
587 if (self.getOs() == builtin.os) {621 if (self.getOs() == builtin.os) {
lib/std/testing.zig+1-1
...@@ -62,7 +62,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {...@@ -62,7 +62,7 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
62 builtin.TypeInfo.Pointer.Size.C,62 builtin.TypeInfo.Pointer.Size.C,
63 => {63 => {
64 if (actual != expected) {64 if (actual != expected) {
65 std.debug.panic("expected {}, found {}", expected, actual);65 std.debug.panic("expected {*}, found {*}", expected, actual);
66 }66 }
67 },67 },
6868
lib/std/thread.zig+1-1
...@@ -344,7 +344,7 @@ pub const Thread = struct {...@@ -344,7 +344,7 @@ pub const Thread = struct {
344 pub fn cpuCount() CpuCountError!usize {344 pub fn cpuCount() CpuCountError!usize {
345 if (builtin.os == .linux) {345 if (builtin.os == .linux) {
346 const cpu_set = try os.sched_getaffinity(0);346 const cpu_set = try os.sched_getaffinity(0);
347 return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast347 return @as(usize, os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
348 }348 }
349 if (builtin.os == .windows) {349 if (builtin.os == .windows) {
350 var system_info: windows.SYSTEM_INFO = undefined;350 var system_info: windows.SYSTEM_INFO = undefined;
lib/std/time.zig+4-4
...@@ -38,7 +38,7 @@ pub fn milliTimestamp() u64 {...@@ -38,7 +38,7 @@ pub fn milliTimestamp() u64 {
38 const hns_per_ms = (ns_per_s / 100) / ms_per_s;38 const hns_per_ms = (ns_per_s / 100) / ms_per_s;
39 const epoch_adj = epoch.windows * ms_per_s;39 const epoch_adj = epoch.windows * ms_per_s;
4040
41 const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;41 const ft64 = (@as(u64, ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
42 return @divFloor(ft64, hns_per_ms) - -epoch_adj;42 return @divFloor(ft64, hns_per_ms) - -epoch_adj;
43 }43 }
44 if (builtin.os == .wasi and !builtin.link_libc) {44 if (builtin.os == .wasi and !builtin.link_libc) {
...@@ -142,10 +142,10 @@ pub const Timer = struct {...@@ -142,10 +142,10 @@ pub const Timer = struct {
142 // seccomp is going to block us it will at least do so consistently142 // seccomp is going to block us it will at least do so consistently
143 var ts: os.timespec = undefined;143 var ts: os.timespec = undefined;
144 os.clock_getres(monotonic_clock_id, &ts) catch return error.TimerUnsupported;144 os.clock_getres(monotonic_clock_id, &ts) catch return error.TimerUnsupported;
145 self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);145 self.resolution = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
146146
147 os.clock_gettime(monotonic_clock_id, &ts) catch return error.TimerUnsupported;147 os.clock_gettime(monotonic_clock_id, &ts) catch return error.TimerUnsupported;
148 self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);148 self.start_time = @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
149 }149 }
150150
151 return self;151 return self;
...@@ -185,7 +185,7 @@ pub const Timer = struct {...@@ -185,7 +185,7 @@ pub const Timer = struct {
185 }185 }
186 var ts: os.timespec = undefined;186 var ts: os.timespec = undefined;
187 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;187 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
188 return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec);188 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
189 }189 }
190};190};
191191
lib/std/unicode.zig+13-13
...@@ -7,10 +7,10 @@ const mem = std.mem;...@@ -7,10 +7,10 @@ const mem = std.mem;
7/// Returns how many bytes the UTF-8 representation would require7/// Returns how many bytes the UTF-8 representation would require
8/// for the given codepoint.8/// for the given codepoint.
9pub fn utf8CodepointSequenceLength(c: u32) !u3 {9pub fn utf8CodepointSequenceLength(c: u32) !u3 {
10 if (c < 0x80) return u3(1);10 if (c < 0x80) return @as(u3, 1);
11 if (c < 0x800) return u3(2);11 if (c < 0x800) return @as(u3, 2);
12 if (c < 0x10000) return u3(3);12 if (c < 0x10000) return @as(u3, 3);
13 if (c < 0x110000) return u3(4);13 if (c < 0x110000) return @as(u3, 4);
14 return error.CodepointTooLarge;14 return error.CodepointTooLarge;
15}15}
1616
...@@ -18,10 +18,10 @@ pub fn utf8CodepointSequenceLength(c: u32) !u3 {...@@ -18,10 +18,10 @@ pub fn utf8CodepointSequenceLength(c: u32) !u3 {
18/// returns a number 1-4 indicating the total length of the codepoint in bytes.18/// returns a number 1-4 indicating the total length of the codepoint in bytes.
19/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.19/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
20pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {20pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {
21 if (first_byte < 0b10000000) return u3(1);21 if (first_byte < 0b10000000) return @as(u3, 1);
22 if (first_byte & 0b11100000 == 0b11000000) return u3(2);22 if (first_byte & 0b11100000 == 0b11000000) return @as(u3, 2);
23 if (first_byte & 0b11110000 == 0b11100000) return u3(3);23 if (first_byte & 0b11110000 == 0b11100000) return @as(u3, 3);
24 if (first_byte & 0b11111000 == 0b11110000) return u3(4);24 if (first_byte & 0b11111000 == 0b11110000) return @as(u3, 4);
25 return error.Utf8InvalidStartByte;25 return error.Utf8InvalidStartByte;
26}26}
2727
...@@ -68,7 +68,7 @@ const Utf8DecodeError = Utf8Decode2Error || Utf8Decode3Error || Utf8Decode4Error...@@ -68,7 +68,7 @@ const Utf8DecodeError = Utf8Decode2Error || Utf8Decode3Error || Utf8Decode4Error
68/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.68/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
69pub fn utf8Decode(bytes: []const u8) Utf8DecodeError!u32 {69pub fn utf8Decode(bytes: []const u8) Utf8DecodeError!u32 {
70 return switch (bytes.len) {70 return switch (bytes.len) {
71 1 => u32(bytes[0]),71 1 => @as(u32, bytes[0]),
72 2 => utf8Decode2(bytes),72 2 => utf8Decode2(bytes),
73 3 => utf8Decode3(bytes),73 3 => utf8Decode3(bytes),
74 4 => utf8Decode4(bytes),74 4 => utf8Decode4(bytes),
...@@ -226,7 +226,7 @@ pub const Utf8Iterator = struct {...@@ -226,7 +226,7 @@ pub const Utf8Iterator = struct {
226 const slice = it.nextCodepointSlice() orelse return null;226 const slice = it.nextCodepointSlice() orelse return null;
227227
228 switch (slice.len) {228 switch (slice.len) {
229 1 => return u32(slice[0]),229 1 => return @as(u32, slice[0]),
230 2 => return utf8Decode2(slice) catch unreachable,230 2 => return utf8Decode2(slice) catch unreachable,
231 3 => return utf8Decode3(slice) catch unreachable,231 3 => return utf8Decode3(slice) catch unreachable,
232 4 => return utf8Decode4(slice) catch unreachable,232 4 => return utf8Decode4(slice) catch unreachable,
...@@ -250,15 +250,15 @@ pub const Utf16LeIterator = struct {...@@ -250,15 +250,15 @@ pub const Utf16LeIterator = struct {
250 assert(it.i <= it.bytes.len);250 assert(it.i <= it.bytes.len);
251 if (it.i == it.bytes.len) return null;251 if (it.i == it.bytes.len) return null;
252 const c0: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);252 const c0: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
253 if (c0 & ~u32(0x03ff) == 0xd800) {253 if (c0 & ~@as(u32, 0x03ff) == 0xd800) {
254 // surrogate pair254 // surrogate pair
255 it.i += 2;255 it.i += 2;
256 if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf;256 if (it.i >= it.bytes.len) return error.DanglingSurrogateHalf;
257 const c1: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);257 const c1: u32 = mem.readIntSliceLittle(u16, it.bytes[it.i .. it.i + 2]);
258 if (c1 & ~u32(0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf;258 if (c1 & ~@as(u32, 0x03ff) != 0xdc00) return error.ExpectedSecondSurrogateHalf;
259 it.i += 2;259 it.i += 2;
260 return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff));260 return 0x10000 + (((c0 & 0x03ff) << 10) | (c1 & 0x03ff));
261 } else if (c0 & ~u32(0x03ff) == 0xdc00) {261 } else if (c0 & ~@as(u32, 0x03ff) == 0xdc00) {
262 return error.UnexpectedSecondSurrogateHalf;262 return error.UnexpectedSecondSurrogateHalf;
263 } else {263 } else {
264 it.i += 2;264 it.i += 2;
lib/std/unicode/throughput_test.zig+1-3
...@@ -2,9 +2,7 @@ const builtin = @import("builtin");...@@ -2,9 +2,7 @@ const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
33
4pub fn main() !void {4pub fn main() !void {
5 var stdout_file = try std.io.getStdOut();5 const stdout = &std.io.getStdOut().outStream().stream;
6 var stdout_out_stream = stdout_file.outStream();
7 const stdout = &stdout_out_stream.stream;
86
9 const args = try std.process.argsAlloc(std.heap.direct_allocator);7 const args = try std.process.argsAlloc(std.heap.direct_allocator);
108
lib/std/valgrind.zig+45-35
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const math = @import("index.zig").math;2const std = @import("std.zig");
3const math = std.math;
34
4pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize) usize {5pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize) usize {
5 if (!builtin.valgrind_support) {6 if (!builtin.valgrind_support) {
...@@ -13,7 +14,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:...@@ -13,7 +14,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
13 \\ roll $29, %%edi ; roll $19, %%edi14 \\ roll $29, %%edi ; roll $19, %%edi
14 \\ xchgl %%ebx,%%ebx15 \\ xchgl %%ebx,%%ebx
15 : [_] "={edx}" (-> usize)16 : [_] "={edx}" (-> usize)
16 : [_] "{eax}" (&[]usize{ request, a1, a2, a3, a4, a5 }),17 : [_] "{eax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
17 [_] "0" (default)18 [_] "0" (default)
18 : "cc", "memory"19 : "cc", "memory"
19 );20 );
...@@ -24,7 +25,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:...@@ -24,7 +25,7 @@ pub fn doClientRequest(default: usize, request: usize, a1: usize, a2: usize, a3:
24 \\ rolq $61, %%rdi ; rolq $51, %%rdi25 \\ rolq $61, %%rdi ; rolq $51, %%rdi
25 \\ xchgq %%rbx,%%rbx26 \\ xchgq %%rbx,%%rbx
26 : [_] "={rdx}" (-> usize)27 : [_] "={rdx}" (-> usize)
27 : [_] "{rax}" (&[]usize{ request, a1, a2, a3, a4, a5 }),28 : [_] "{rax}" (&[_]usize{ request, a1, a2, a3, a4, a5 }),
28 [_] "0" (default)29 [_] "0" (default)
29 : "cc", "memory"30 : "cc", "memory"
30 );31 );
...@@ -76,7 +77,7 @@ pub const ClientRequest = extern enum {...@@ -76,7 +77,7 @@ pub const ClientRequest = extern enum {
76 InnerThreads = 6402,77 InnerThreads = 6402,
77};78};
78pub fn ToolBase(base: [2]u8) u32 {79pub fn ToolBase(base: [2]u8) u32 {
79 return (u32(base[0] & 0xff) << 24) | (u32(base[1] & 0xff) << 16);80 return (@as(u32, base[0] & 0xff) << 24) | (@as(u32, base[1] & 0xff) << 16);
80}81}
81pub fn IsTool(base: [2]u8, code: usize) bool {82pub fn IsTool(base: [2]u8, code: usize) bool {
82 return ToolBase(base) == (code & 0xffff0000);83 return ToolBase(base) == (code & 0xffff0000);
...@@ -95,48 +96,52 @@ fn doClientRequestStmt(request: ClientRequest, a1: usize, a2: usize, a3: usize,...@@ -95,48 +96,52 @@ fn doClientRequestStmt(request: ClientRequest, a1: usize, a2: usize, a3: usize,
95/// running under Valgrind which is running under another Valgrind,96/// running under Valgrind which is running under another Valgrind,
96/// etc.97/// etc.
97pub fn runningOnValgrind() usize {98pub fn runningOnValgrind() usize {
98 return doClientRequestExpr(0, ClientRequest.RunningOnValgrind, 0, 0, 0, 0, 0);99 return doClientRequestExpr(0, .RunningOnValgrind, 0, 0, 0, 0, 0);
100}
101
102test "works whether running on valgrind or not" {
103 _ = runningOnValgrind();
99}104}
100105
101/// Discard translation of code in the slice qzz. Useful if you are debugging106/// Discard translation of code in the slice qzz. Useful if you are debugging
102/// a JITter or some such, since it provides a way to make sure valgrind will107/// a JITter or some such, since it provides a way to make sure valgrind will
103/// retranslate the invalidated area. Returns no value.108/// retranslate the invalidated area. Returns no value.
104pub fn discardTranslations(qzz: []const u8) void {109pub fn discardTranslations(qzz: []const u8) void {
105 doClientRequestStmt(ClientRequest.DiscardTranslations, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);110 doClientRequestStmt(.DiscardTranslations, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
106}111}
107112
108pub fn innerThreads(qzz: [*]u8) void {113pub fn innerThreads(qzz: [*]u8) void {
109 doClientRequestStmt(ClientRequest.InnerThreads, qzz, 0, 0, 0, 0);114 doClientRequestStmt(.InnerThreads, qzz, 0, 0, 0, 0);
110}115}
111116
112//pub fn printf(format: [*]const u8, args: ...) usize {117//pub fn printf(format: [*]const u8, args: ...) usize {
113// return doClientRequestExpr(0,118// return doClientRequestExpr(0,
114// ClientRequest.PrintfValistByRef,119// .PrintfValistByRef,
115// @ptrToInt(format), @ptrToInt(args),120// @ptrToInt(format), @ptrToInt(args),
116// 0, 0, 0);121// 0, 0, 0);
117//}122//}
118123
119//pub fn printfBacktrace(format: [*]const u8, args: ...) usize {124//pub fn printfBacktrace(format: [*]const u8, args: ...) usize {
120// return doClientRequestExpr(0,125// return doClientRequestExpr(0,
121// ClientRequest.PrintfBacktraceValistByRef,126// .PrintfBacktraceValistByRef,
122// @ptrToInt(format), @ptrToInt(args),127// @ptrToInt(format), @ptrToInt(args),
123// 0, 0, 0);128// 0, 0, 0);
124//}129//}
125130
126pub fn nonSIMDCall0(func: fn (usize) usize) usize {131pub fn nonSIMDCall0(func: fn (usize) usize) usize {
127 return doClientRequestExpr(0, ClientRequest.ClientCall0, @ptrToInt(func), 0, 0, 0, 0);132 return doClientRequestExpr(0, .ClientCall0, @ptrToInt(func), 0, 0, 0, 0);
128}133}
129134
130pub fn nonSIMDCall1(func: fn (usize, usize) usize, a1: usize) usize {135pub fn nonSIMDCall1(func: fn (usize, usize) usize, a1: usize) usize {
131 return doClientRequestExpr(0, ClientRequest.ClientCall1, @ptrToInt(func), a1, 0, 0, 0);136 return doClientRequestExpr(0, .ClientCall1, @ptrToInt(func), a1, 0, 0, 0);
132}137}
133138
134pub fn nonSIMDCall2(func: fn (usize, usize, usize) usize, a1: usize, a2: usize) usize {139pub fn nonSIMDCall2(func: fn (usize, usize, usize) usize, a1: usize, a2: usize) usize {
135 return doClientRequestExpr(0, ClientRequest.ClientCall2, @ptrToInt(func), a1, a2, 0, 0);140 return doClientRequestExpr(0, .ClientCall2, @ptrToInt(func), a1, a2, 0, 0);
136}141}
137142
138pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2: usize, a3: usize) usize {143pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2: usize, a3: usize) usize {
139 return doClientRequestExpr(0, ClientRequest.ClientCall3, @ptrToInt(func), a1, a2, a3, 0);144 return doClientRequestExpr(0, .ClientCall3, @ptrToInt(func), a1, a2, a3, 0);
140}145}
141146
142/// Counts the number of errors that have been recorded by a tool. Nb:147/// Counts the number of errors that have been recorded by a tool. Nb:
...@@ -144,19 +149,19 @@ pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2:...@@ -144,19 +149,19 @@ pub fn nonSIMDCall3(func: fn (usize, usize, usize, usize) usize, a1: usize, a2:
144/// VG_(unique_error)() for them to be counted.149/// VG_(unique_error)() for them to be counted.
145pub fn countErrors() usize {150pub fn countErrors() usize {
146 return doClientRequestExpr(0, // default return151 return doClientRequestExpr(0, // default return
147 ClientRequest.CountErrors, 0, 0, 0, 0, 0);152 .CountErrors, 0, 0, 0, 0, 0);
148}153}
149154
150pub fn mallocLikeBlock(mem: []u8, rzB: usize, is_zeroed: bool) void {155pub fn mallocLikeBlock(mem: []u8, rzB: usize, is_zeroed: bool) void {
151 doClientRequestStmt(ClientRequest.MalloclikeBlock, @ptrToInt(mem.ptr), mem.len, rzB, @boolToInt(is_zeroed), 0);156 doClientRequestStmt(.MalloclikeBlock, @ptrToInt(mem.ptr), mem.len, rzB, @boolToInt(is_zeroed), 0);
152}157}
153158
154pub fn resizeInPlaceBlock(oldmem: []u8, newsize: usize, rzB: usize) void {159pub fn resizeInPlaceBlock(oldmem: []u8, newsize: usize, rzB: usize) void {
155 doClientRequestStmt(ClientRequest.ResizeinplaceBlock, @ptrToInt(oldmem.ptr), oldmem.len, newsize, rzB, 0);160 doClientRequestStmt(.ResizeinplaceBlock, @ptrToInt(oldmem.ptr), oldmem.len, newsize, rzB, 0);
156}161}
157162
158pub fn freeLikeBlock(addr: [*]u8, rzB: usize) void {163pub fn freeLikeBlock(addr: [*]u8, rzB: usize) void {
159 doClientRequestStmt(ClientRequest.FreelikeBlock, @ptrToInt(addr), rzB, 0, 0, 0);164 doClientRequestStmt(.FreelikeBlock, @ptrToInt(addr), rzB, 0, 0, 0);
160}165}
161166
162/// Create a memory pool.167/// Create a memory pool.
...@@ -165,66 +170,66 @@ pub const MempoolFlags = extern enum {...@@ -165,66 +170,66 @@ pub const MempoolFlags = extern enum {
165 MetaPool = 2,170 MetaPool = 2,
166};171};
167pub fn createMempool(pool: [*]u8, rzB: usize, is_zeroed: bool, flags: usize) void {172pub fn createMempool(pool: [*]u8, rzB: usize, is_zeroed: bool, flags: usize) void {
168 doClientRequestStmt(ClientRequest.CreateMempool, @ptrToInt(pool), rzB, @boolToInt(is_zeroed), flags, 0);173 doClientRequestStmt(.CreateMempool, @ptrToInt(pool), rzB, @boolToInt(is_zeroed), flags, 0);
169}174}
170175
171/// Destroy a memory pool.176/// Destroy a memory pool.
172pub fn destroyMempool(pool: [*]u8) void {177pub fn destroyMempool(pool: [*]u8) void {
173 doClientRequestStmt(ClientRequest.DestroyMempool, pool, 0, 0, 0, 0);178 doClientRequestStmt(.DestroyMempool, pool, 0, 0, 0, 0);
174}179}
175180
176/// Associate a piece of memory with a memory pool.181/// Associate a piece of memory with a memory pool.
177pub fn mempoolAlloc(pool: [*]u8, mem: []u8) void {182pub fn mempoolAlloc(pool: [*]u8, mem: []u8) void {
178 doClientRequestStmt(ClientRequest.MempoolAlloc, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);183 doClientRequestStmt(.MempoolAlloc, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
179}184}
180185
181/// Disassociate a piece of memory from a memory pool.186/// Disassociate a piece of memory from a memory pool.
182pub fn mempoolFree(pool: [*]u8, addr: [*]u8) void {187pub fn mempoolFree(pool: [*]u8, addr: [*]u8) void {
183 doClientRequestStmt(ClientRequest.MempoolFree, @ptrToInt(pool), @ptrToInt(addr), 0, 0, 0);188 doClientRequestStmt(.MempoolFree, @ptrToInt(pool), @ptrToInt(addr), 0, 0, 0);
184}189}
185190
186/// Disassociate any pieces outside a particular range.191/// Disassociate any pieces outside a particular range.
187pub fn mempoolTrim(pool: [*]u8, mem: []u8) void {192pub fn mempoolTrim(pool: [*]u8, mem: []u8) void {
188 doClientRequestStmt(ClientRequest.MempoolTrim, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);193 doClientRequestStmt(.MempoolTrim, @ptrToInt(pool), @ptrToInt(mem.ptr), mem.len, 0, 0);
189}194}
190195
191/// Resize and/or move a piece associated with a memory pool.196/// Resize and/or move a piece associated with a memory pool.
192pub fn moveMempool(poolA: [*]u8, poolB: [*]u8) void {197pub fn moveMempool(poolA: [*]u8, poolB: [*]u8) void {
193 doClientRequestStmt(ClientRequest.MoveMempool, @ptrToInt(poolA), @ptrToInt(poolB), 0, 0, 0);198 doClientRequestStmt(.MoveMempool, @ptrToInt(poolA), @ptrToInt(poolB), 0, 0, 0);
194}199}
195200
196/// Resize and/or move a piece associated with a memory pool.201/// Resize and/or move a piece associated with a memory pool.
197pub fn mempoolChange(pool: [*]u8, addrA: [*]u8, mem: []u8) void {202pub fn mempoolChange(pool: [*]u8, addrA: [*]u8, mem: []u8) void {
198 doClientRequestStmt(ClientRequest.MempoolChange, @ptrToInt(pool), @ptrToInt(addrA), @ptrToInt(mem.ptr), mem.len, 0);203 doClientRequestStmt(.MempoolChange, @ptrToInt(pool), @ptrToInt(addrA), @ptrToInt(mem.ptr), mem.len, 0);
199}204}
200205
201/// Return if a mempool exists.206/// Return if a mempool exists.
202pub fn mempoolExists(pool: [*]u8) bool {207pub fn mempoolExists(pool: [*]u8) bool {
203 return doClientRequestExpr(0, ClientRequest.MempoolExists, @ptrToInt(pool), 0, 0, 0, 0) != 0;208 return doClientRequestExpr(0, .MempoolExists, @ptrToInt(pool), 0, 0, 0, 0) != 0;
204}209}
205210
206/// Mark a piece of memory as being a stack. Returns a stack id.211/// Mark a piece of memory as being a stack. Returns a stack id.
207/// start is the lowest addressable stack byte, end is the highest212/// start is the lowest addressable stack byte, end is the highest
208/// addressable stack byte.213/// addressable stack byte.
209pub fn stackRegister(stack: []u8) usize {214pub fn stackRegister(stack: []u8) usize {
210 return doClientRequestExpr(0, ClientRequest.StackRegister, @ptrToInt(stack.ptr), @ptrToInt(stack.ptr) + stack.len, 0, 0, 0);215 return doClientRequestExpr(0, .StackRegister, @ptrToInt(stack.ptr), @ptrToInt(stack.ptr) + stack.len, 0, 0, 0);
211}216}
212217
213/// Unmark the piece of memory associated with a stack id as being a stack.218/// Unmark the piece of memory associated with a stack id as being a stack.
214pub fn stackDeregister(id: usize) void {219pub fn stackDeregister(id: usize) void {
215 doClientRequestStmt(ClientRequest.StackDeregister, id, 0, 0, 0, 0);220 doClientRequestStmt(.StackDeregister, id, 0, 0, 0, 0);
216}221}
217222
218/// Change the start and end address of the stack id.223/// Change the start and end address of the stack id.
219/// start is the new lowest addressable stack byte, end is the new highest224/// start is the new lowest addressable stack byte, end is the new highest
220/// addressable stack byte.225/// addressable stack byte.
221pub fn stackChange(id: usize, newstack: []u8) void {226pub fn stackChange(id: usize, newstack: []u8) void {
222 doClientRequestStmt(ClientRequest.StackChange, id, @ptrToInt(newstack.ptr), @ptrToInt(newstack.ptr) + newstack.len, 0, 0);227 doClientRequestStmt(.StackChange, id, @ptrToInt(newstack.ptr), @ptrToInt(newstack.ptr) + newstack.len, 0, 0);
223}228}
224229
225// Load PDB debug info for Wine PE image_map.230// Load PDB debug info for Wine PE image_map.
226// pub fn loadPdbDebuginfo(fd, ptr, total_size, delta) void {231// pub fn loadPdbDebuginfo(fd, ptr, total_size, delta) void {
227// doClientRequestStmt(ClientRequest.LoadPdbDebuginfo,232// doClientRequestStmt(.LoadPdbDebuginfo,
228// fd, ptr, total_size, delta,233// fd, ptr, total_size, delta,
229// 0);234// 0);
230// }235// }
...@@ -234,7 +239,7 @@ pub fn stackChange(id: usize, newstack: []u8) void {...@@ -234,7 +239,7 @@ pub fn stackChange(id: usize, newstack: []u8) void {
234/// result will be dumped in there and is guaranteed to be zero239/// result will be dumped in there and is guaranteed to be zero
235/// terminated. If no info is found, the first byte is set to zero.240/// terminated. If no info is found, the first byte is set to zero.
236pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {241pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {
237 return doClientRequestExpr(0, ClientRequest.MapIpToSrcloc, @ptrToInt(addr), @ptrToInt(&buf64[0]), 0, 0, 0);242 return doClientRequestExpr(0, .MapIpToSrcloc, @ptrToInt(addr), @ptrToInt(&buf64[0]), 0, 0, 0);
238}243}
239244
240/// Disable error reporting for this thread. Behaves in a stack like245/// Disable error reporting for this thread. Behaves in a stack like
...@@ -246,12 +251,12 @@ pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {...@@ -246,12 +251,12 @@ pub fn mapIpToSrcloc(addr: *const u8, buf64: [64]u8) usize {
246/// reporting. Child threads do not inherit this setting from their251/// reporting. Child threads do not inherit this setting from their
247/// parents -- they are always created with reporting enabled.252/// parents -- they are always created with reporting enabled.
248pub fn disableErrorReporting() void {253pub fn disableErrorReporting() void {
249 doClientRequestStmt(ClientRequest.ChangeErrDisablement, 1, 0, 0, 0, 0);254 doClientRequestStmt(.ChangeErrDisablement, 1, 0, 0, 0, 0);
250}255}
251256
252/// Re-enable error reporting, (see disableErrorReporting())257/// Re-enable error reporting, (see disableErrorReporting())
253pub fn enableErrorReporting() void {258pub fn enableErrorReporting() void {
254 doClientRequestStmt(ClientRequest.ChangeErrDisablement, math.maxInt(usize), 0, 0, 0, 0);259 doClientRequestStmt(.ChangeErrDisablement, math.maxInt(usize), 0, 0, 0, 0);
255}260}
256261
257/// Execute a monitor command from the client program.262/// Execute a monitor command from the client program.
...@@ -260,8 +265,13 @@ pub fn enableErrorReporting() void {...@@ -260,8 +265,13 @@ pub fn enableErrorReporting() void {
260/// If no connection is opened, output will go to the log output.265/// If no connection is opened, output will go to the log output.
261/// Returns 1 if command not recognised, 0 otherwise.266/// Returns 1 if command not recognised, 0 otherwise.
262pub fn monitorCommand(command: [*]u8) bool {267pub fn monitorCommand(command: [*]u8) bool {
263 return doClientRequestExpr(0, ClientRequest.GdbMonitorCommand, @ptrToInt(command.ptr), 0, 0, 0, 0) != 0;268 return doClientRequestExpr(0, .GdbMonitorCommand, @ptrToInt(command.ptr), 0, 0, 0, 0) != 0;
264}269}
265270
266pub const memcheck = @import("memcheck.zig");271pub const memcheck = @import("valgrind/memcheck.zig");
267pub const callgrind = @import("callgrind.zig");272pub const callgrind = @import("valgrind/callgrind.zig");
273
274test "" {
275 _ = @import("valgrind/memcheck.zig");
276 _ = @import("valgrind/callgrind.zig");
277}
lib/std/valgrind/callgrind.zig+7-7
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1const std = @import("../index.zig");1const std = @import("../std.zig");
2const valgrind = std.valgrind;2const valgrind = std.valgrind;
33
4pub const CallgrindClientRequest = extern enum {4pub const CallgrindClientRequest = extern enum {
...@@ -20,7 +20,7 @@ fn doCallgrindClientRequestStmt(request: CallgrindClientRequest, a1: usize, a2:...@@ -20,7 +20,7 @@ fn doCallgrindClientRequestStmt(request: CallgrindClientRequest, a1: usize, a2:
2020
21/// Dump current state of cost centers, and zero them afterwards21/// Dump current state of cost centers, and zero them afterwards
22pub fn dumpStats() void {22pub fn dumpStats() void {
23 doCallgrindClientRequestStmt(CallgrindClientRequest.DumpStats, 0, 0, 0, 0, 0);23 doCallgrindClientRequestStmt(.DumpStats, 0, 0, 0, 0, 0);
24}24}
2525
26/// Dump current state of cost centers, and zero them afterwards.26/// Dump current state of cost centers, and zero them afterwards.
...@@ -28,12 +28,12 @@ pub fn dumpStats() void {...@@ -28,12 +28,12 @@ pub fn dumpStats() void {
28/// the dump. This string is written as a description field into the28/// the dump. This string is written as a description field into the
29/// profile data dump.29/// profile data dump.
30pub fn dumpStatsAt(pos_str: [*]u8) void {30pub fn dumpStatsAt(pos_str: [*]u8) void {
31 doCallgrindClientRequestStmt(CallgrindClientRequest.DumpStatsAt, @ptrToInt(pos_str), 0, 0, 0, 0);31 doCallgrindClientRequestStmt(.DumpStatsAt, @ptrToInt(pos_str), 0, 0, 0, 0);
32}32}
3333
34/// Zero cost centers34/// Zero cost centers
35pub fn zeroStats() void {35pub fn zeroStats() void {
36 doCallgrindClientRequestStmt(CallgrindClientRequest.ZeroStats, 0, 0, 0, 0, 0);36 doCallgrindClientRequestStmt(.ZeroStats, 0, 0, 0, 0, 0);
37}37}
3838
39/// Toggles collection state.39/// Toggles collection state.
...@@ -41,7 +41,7 @@ pub fn zeroStats() void {...@@ -41,7 +41,7 @@ pub fn zeroStats() void {
41/// should be noted or if they are to be ignored. Events are noted41/// should be noted or if they are to be ignored. Events are noted
42/// by increment of counters in a cost center42/// by increment of counters in a cost center
43pub fn toggleCollect() void {43pub fn toggleCollect() void {
44 doCallgrindClientRequestStmt(CallgrindClientRequest.ToggleCollect, 0, 0, 0, 0, 0);44 doCallgrindClientRequestStmt(.ToggleCollect, 0, 0, 0, 0, 0);
45}45}
4646
47/// Start full callgrind instrumentation if not already switched on.47/// Start full callgrind instrumentation if not already switched on.
...@@ -49,7 +49,7 @@ pub fn toggleCollect() void {...@@ -49,7 +49,7 @@ pub fn toggleCollect() void {
49/// this will lead to an artificial cache warmup phase afterwards with49/// this will lead to an artificial cache warmup phase afterwards with
50/// cache misses which would not have happened in reality.50/// cache misses which would not have happened in reality.
51pub fn startInstrumentation() void {51pub fn startInstrumentation() void {
52 doCallgrindClientRequestStmt(CallgrindClientRequest.StartInstrumentation, 0, 0, 0, 0, 0);52 doCallgrindClientRequestStmt(.StartInstrumentation, 0, 0, 0, 0, 0);
53}53}
5454
55/// Stop full callgrind instrumentation if not already switched off.55/// Stop full callgrind instrumentation if not already switched off.
...@@ -60,5 +60,5 @@ pub fn startInstrumentation() void {...@@ -60,5 +60,5 @@ pub fn startInstrumentation() void {
60/// To start Callgrind in this mode to ignore the setup phase, use60/// To start Callgrind in this mode to ignore the setup phase, use
61/// the option "--instr-atstart=no".61/// the option "--instr-atstart=no".
62pub fn stopInstrumentation() void {62pub fn stopInstrumentation() void {
63 doCallgrindClientRequestStmt(CallgrindClientRequest.StopInstrumentation, 0, 0, 0, 0, 0);63 doCallgrindClientRequestStmt(.StopInstrumentation, 0, 0, 0, 0, 0);
64}64}
lib/std/valgrind/memcheck.zig+60-21
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("../index.zig");1const std = @import("../std.zig");
2const testing = std.testing;
2const valgrind = std.valgrind;3const valgrind = std.valgrind;
34
4pub const MemCheckClientRequest = extern enum {5pub const MemCheckClientRequest = extern enum {
...@@ -31,7 +32,7 @@ fn doMemCheckClientRequestStmt(request: MemCheckClientRequest, a1: usize, a2: us...@@ -31,7 +32,7 @@ fn doMemCheckClientRequestStmt(request: MemCheckClientRequest, a1: usize, a2: us
31/// This returns -1 when run on Valgrind and 0 otherwise.32/// This returns -1 when run on Valgrind and 0 otherwise.
32pub fn makeMemNoAccess(qzz: []u8) i1 {33pub fn makeMemNoAccess(qzz: []u8) i1 {
33 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return34 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
34 MemCheckClientRequest.MakeMemNoAccess, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));35 .MakeMemNoAccess, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
35}36}
3637
37/// Similarly, mark memory at qzz.ptr as addressable but undefined38/// Similarly, mark memory at qzz.ptr as addressable but undefined
...@@ -39,7 +40,7 @@ pub fn makeMemNoAccess(qzz: []u8) i1 {...@@ -39,7 +40,7 @@ pub fn makeMemNoAccess(qzz: []u8) i1 {
39/// This returns -1 when run on Valgrind and 0 otherwise.40/// This returns -1 when run on Valgrind and 0 otherwise.
40pub fn makeMemUndefined(qzz: []u8) i1 {41pub fn makeMemUndefined(qzz: []u8) i1 {
41 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return42 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
42 MemCheckClientRequest.MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));43 .MakeMemUndefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
43}44}
4445
45/// Similarly, mark memory at qzz.ptr as addressable and defined46/// Similarly, mark memory at qzz.ptr as addressable and defined
...@@ -47,7 +48,7 @@ pub fn makeMemUndefined(qzz: []u8) i1 {...@@ -47,7 +48,7 @@ pub fn makeMemUndefined(qzz: []u8) i1 {
47pub fn makeMemDefined(qzz: []u8) i1 {48pub fn makeMemDefined(qzz: []u8) i1 {
48 // This returns -1 when run on Valgrind and 0 otherwise.49 // This returns -1 when run on Valgrind and 0 otherwise.
49 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return50 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
50 MemCheckClientRequest.MakeMemDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));51 .MakeMemDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
51}52}
5253
53/// Similar to makeMemDefined except that addressability is54/// Similar to makeMemDefined except that addressability is
...@@ -56,7 +57,7 @@ pub fn makeMemDefined(qzz: []u8) i1 {...@@ -56,7 +57,7 @@ pub fn makeMemDefined(qzz: []u8) i1 {
56/// This returns -1 when run on Valgrind and 0 otherwise.57/// This returns -1 when run on Valgrind and 0 otherwise.
57pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {58pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {
58 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return59 return @intCast(i1, doMemCheckClientRequestExpr(0, // default return
59 MemCheckClientRequest.MakeMemDefinedIfAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));60 .MakeMemDefinedIfAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0));
60}61}
6162
62/// Create a block-description handle. The description is an ascii63/// Create a block-description handle. The description is an ascii
...@@ -65,14 +66,14 @@ pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {...@@ -65,14 +66,14 @@ pub fn makeMemDefinedIfAddressable(qzz: []u8) i1 {
65/// properties of the memory range.66/// properties of the memory range.
66pub fn createBlock(qzz: []u8, desc: [*]u8) usize {67pub fn createBlock(qzz: []u8, desc: [*]u8) usize {
67 return doMemCheckClientRequestExpr(0, // default return68 return doMemCheckClientRequestExpr(0, // default return
68 MemCheckClientRequest.CreateBlock, @ptrToInt(qzz.ptr), qzz.len, @ptrToInt(desc), 0, 0);69 .CreateBlock, @ptrToInt(qzz.ptr), qzz.len, @ptrToInt(desc), 0, 0);
69}70}
7071
71/// Discard a block-description-handle. Returns 1 for an72/// Discard a block-description-handle. Returns 1 for an
72/// invalid handle, 0 for a valid handle.73/// invalid handle, 0 for a valid handle.
73pub fn discard(blkindex) bool {74pub fn discard(blkindex) bool {
74 return doMemCheckClientRequestExpr(0, // default return75 return doMemCheckClientRequestExpr(0, // default return
75 MemCheckClientRequest.Discard, 0, blkindex, 0, 0, 0) != 0;76 .Discard, 0, blkindex, 0, 0, 0) != 0;
76}77}
7778
78/// Check that memory at qzz.ptr is addressable for qzz.len bytes.79/// Check that memory at qzz.ptr is addressable for qzz.len bytes.
...@@ -80,7 +81,7 @@ pub fn discard(blkindex) bool {...@@ -80,7 +81,7 @@ pub fn discard(blkindex) bool {
80/// error message and returns the address of the first offending byte.81/// error message and returns the address of the first offending byte.
81/// Otherwise it returns zero.82/// Otherwise it returns zero.
82pub fn checkMemIsAddressable(qzz: []u8) usize {83pub fn checkMemIsAddressable(qzz: []u8) usize {
83 return doMemCheckClientRequestExpr(0, MemCheckClientRequest.CheckMemIsAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);84 return doMemCheckClientRequestExpr(0, .CheckMemIsAddressable, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
84}85}
8586
86/// Check that memory at qzz.ptr is addressable and defined for87/// Check that memory at qzz.ptr is addressable and defined for
...@@ -88,31 +89,31 @@ pub fn checkMemIsAddressable(qzz: []u8) usize {...@@ -88,31 +89,31 @@ pub fn checkMemIsAddressable(qzz: []u8) usize {
88/// established, Valgrind prints an error message and returns the89/// established, Valgrind prints an error message and returns the
89/// address of the first offending byte. Otherwise it returns zero.90/// address of the first offending byte. Otherwise it returns zero.
90pub fn checkMemIsDefined(qzz: []u8) usize {91pub fn checkMemIsDefined(qzz: []u8) usize {
91 return doMemCheckClientRequestExpr(0, MemCheckClientRequest.CheckMemIsDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);92 return doMemCheckClientRequestExpr(0, .CheckMemIsDefined, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
92}93}
9394
94/// Do a full memory leak check (like --leak-check=full) mid-execution.95/// Do a full memory leak check (like --leak-check=full) mid-execution.
95pub fn doLeakCheck() void {96pub fn doLeakCheck() void {
96 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 0, 0, 0, 0);97 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 0, 0, 0, 0);
97}98}
9899
99/// Same as doLeakCheck() but only showing the entries for100/// Same as doLeakCheck() but only showing the entries for
100/// which there was an increase in leaked bytes or leaked nr of blocks101/// which there was an increase in leaked bytes or leaked nr of blocks
101/// since the previous leak search.102/// since the previous leak search.
102pub fn doAddedLeakCheck() void {103pub fn doAddedLeakCheck() void {
103 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 1, 0, 0, 0);104 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 1, 0, 0, 0);
104}105}
105106
106/// Same as doAddedLeakCheck() but showing entries with107/// Same as doAddedLeakCheck() but showing entries with
107/// increased or decreased leaked bytes/blocks since previous leak108/// increased or decreased leaked bytes/blocks since previous leak
108/// search.109/// search.
109pub fn doChangedLeakCheck() void {110pub fn doChangedLeakCheck() void {
110 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 0, 2, 0, 0, 0);111 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 0, 2, 0, 0, 0);
111}112}
112113
113/// Do a summary memory leak check (like --leak-check=summary) mid-execution.114/// Do a summary memory leak check (like --leak-check=summary) mid-execution.
114pub fn doQuickLeakCheck() void {115pub fn doQuickLeakCheck() void {
115 doMemCheckClientRequestStmt(MemCheckClientRequest.DO_LEAK_CHECK, 1, 0, 0, 0, 0);116 doMemCheckClientRequestStmt(.DO_LEAK_CHECK, 1, 0, 0, 0, 0);
116}117}
117118
118/// Return number of leaked, dubious, reachable and suppressed bytes found by119/// Return number of leaked, dubious, reachable and suppressed bytes found by
...@@ -125,27 +126,65 @@ const CountResult = struct {...@@ -125,27 +126,65 @@ const CountResult = struct {
125};126};
126127
127pub fn countLeaks() CountResult {128pub fn countLeaks() CountResult {
128 var res = CountResult{129 var res: CountResult = .{
129 .leaked = 0,130 .leaked = 0,
130 .dubious = 0,131 .dubious = 0,
131 .reachable = 0,132 .reachable = 0,
132 .suppressed = 0,133 .suppressed = 0,
133 };134 };
134 doMemCheckClientRequestStmt(MemCheckClientRequest.CountLeaks, &res.leaked, &res.dubious, &res.reachable, &res.suppressed, 0);135 doMemCheckClientRequestStmt(
136 .CountLeaks,
137 @ptrToInt(&res.leaked),
138 @ptrToInt(&res.dubious),
139 @ptrToInt(&res.reachable),
140 @ptrToInt(&res.suppressed),
141 0,
142 );
135 return res;143 return res;
136}144}
137145
146test "countLeaks" {
147 testing.expectEqual(
148 @as(CountResult, .{
149 .leaked = 0,
150 .dubious = 0,
151 .reachable = 0,
152 .suppressed = 0,
153 }),
154 countLeaks(),
155 );
156}
157
138pub fn countLeakBlocks() CountResult {158pub fn countLeakBlocks() CountResult {
139 var res = CountResult{159 var res: CountResult = .{
140 .leaked = 0,160 .leaked = 0,
141 .dubious = 0,161 .dubious = 0,
142 .reachable = 0,162 .reachable = 0,
143 .suppressed = 0,163 .suppressed = 0,
144 };164 };
145 doMemCheckClientRequestStmt(MemCheckClientRequest.CountLeakBlocks, &res.leaked, &res.dubious, &res.reachable, &res.suppressed, 0);165 doMemCheckClientRequestStmt(
166 .CountLeakBlocks,
167 @ptrToInt(&res.leaked),
168 @ptrToInt(&res.dubious),
169 @ptrToInt(&res.reachable),
170 @ptrToInt(&res.suppressed),
171 0,
172 );
146 return res;173 return res;
147}174}
148175
176test "countLeakBlocks" {
177 testing.expectEqual(
178 @as(CountResult, .{
179 .leaked = 0,
180 .dubious = 0,
181 .reachable = 0,
182 .suppressed = 0,
183 }),
184 countLeakBlocks(),
185 );
186}
187
149/// Get the validity data for addresses zza and copy it188/// Get the validity data for addresses zza and copy it
150/// into the provided zzvbits array. Return values:189/// into the provided zzvbits array. Return values:
151/// 0 if not running on valgrind190/// 0 if not running on valgrind
...@@ -156,7 +195,7 @@ pub fn countLeakBlocks() CountResult {...@@ -156,7 +195,7 @@ pub fn countLeakBlocks() CountResult {
156/// impossible to segfault your system by using this call.195/// impossible to segfault your system by using this call.
157pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {196pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
158 std.debug.assert(zzvbits.len >= zza.len / 8);197 std.debug.assert(zzvbits.len >= zza.len / 8);
159 return @intCast(u2, doMemCheckClientRequestExpr(0, MemCheckClientRequest.GetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));198 return @intCast(u2, doMemCheckClientRequestExpr(0, .GetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
160}199}
161200
162/// Set the validity data for addresses zza, copying it201/// Set the validity data for addresses zza, copying it
...@@ -169,17 +208,17 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {...@@ -169,17 +208,17 @@ pub fn getVbits(zza: []u8, zzvbits: []u8) u2 {
169/// impossible to segfault your system by using this call.208/// impossible to segfault your system by using this call.
170pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {209pub fn setVbits(zzvbits: []u8, zza: []u8) u2 {
171 std.debug.assert(zzvbits.len >= zza.len / 8);210 std.debug.assert(zzvbits.len >= zza.len / 8);
172 return @intCast(u2, doMemCheckClientRequestExpr(0, MemCheckClientRequest.SetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));211 return @intCast(u2, doMemCheckClientRequestExpr(0, .SetVbits, @ptrToInt(zza.ptr), @ptrToInt(zzvbits), zza.len, 0, 0));
173}212}
174213
175/// Disable and re-enable reporting of addressing errors in the214/// Disable and re-enable reporting of addressing errors in the
176/// specified address range.215/// specified address range.
177pub fn disableAddrErrorReportingInRange(qzz: []u8) usize {216pub fn disableAddrErrorReportingInRange(qzz: []u8) usize {
178 return doMemCheckClientRequestExpr(0, // default return217 return doMemCheckClientRequestExpr(0, // default return
179 MemCheckClientRequest.DisableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);218 .DisableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
180}219}
181220
182pub fn enableAddrErrorReportingInRange(qzz: []u8) usize {221pub fn enableAddrErrorReportingInRange(qzz: []u8) usize {
183 return doMemCheckClientRequestExpr(0, // default return222 return doMemCheckClientRequestExpr(0, // default return
184 MemCheckClientRequest.EnableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);223 .EnableAddrErrorReportingInRange, @ptrToInt(qzz.ptr), qzz.len, 0, 0, 0);
185}224}
lib/std/zig/ast.zig+17-6
...@@ -576,7 +576,6 @@ pub const Node = struct {...@@ -576,7 +576,6 @@ pub const Node = struct {
576576
577 pub const Root = struct {577 pub const Root = struct {
578 base: Node,578 base: Node,
579 doc_comments: ?*DocComment,
580 decls: DeclList,579 decls: DeclList,
581 eof_token: TokenIndex,580 eof_token: TokenIndex,
582581
...@@ -1648,10 +1647,15 @@ pub const Node = struct {...@@ -1648,10 +1647,15 @@ pub const Node = struct {
16481647
1649 pub const SuffixOp = struct {1648 pub const SuffixOp = struct {
1650 base: Node,1649 base: Node,
1651 lhs: *Node,1650 lhs: Lhs,
1652 op: Op,1651 op: Op,
1653 rtoken: TokenIndex,1652 rtoken: TokenIndex,
16541653
1654 pub const Lhs = union(enum) {
1655 node: *Node,
1656 dot: TokenIndex,
1657 };
1658
1655 pub const Op = union(enum) {1659 pub const Op = union(enum) {
1656 Call: Call,1660 Call: Call,
1657 ArrayAccess: *Node,1661 ArrayAccess: *Node,
...@@ -1679,8 +1683,13 @@ pub const Node = struct {...@@ -1679,8 +1683,13 @@ pub const Node = struct {
1679 pub fn iterate(self: *SuffixOp, index: usize) ?*Node {1683 pub fn iterate(self: *SuffixOp, index: usize) ?*Node {
1680 var i = index;1684 var i = index;
16811685
1682 if (i < 1) return self.lhs;1686 switch (self.lhs) {
1683 i -= 1;1687 .node => |node| {
1688 if (i == 0) return node;
1689 i -= 1;
1690 },
1691 .dot => {},
1692 }
16841693
1685 switch (self.op) {1694 switch (self.op) {
1686 .Call => |*call_info| {1695 .Call => |*call_info| {
...@@ -1721,7 +1730,10 @@ pub const Node = struct {...@@ -1721,7 +1730,10 @@ pub const Node = struct {
1721 .Call => |*call_info| if (call_info.async_token) |async_token| return async_token,1730 .Call => |*call_info| if (call_info.async_token) |async_token| return async_token,
1722 else => {},1731 else => {},
1723 }1732 }
1724 return self.lhs.firstToken();1733 switch (self.lhs) {
1734 .node => |node| return node.firstToken(),
1735 .dot => |dot| return dot,
1736 }
1725 }1737 }
17261738
1727 pub fn lastToken(self: *const SuffixOp) TokenIndex {1739 pub fn lastToken(self: *const SuffixOp) TokenIndex {
...@@ -2241,7 +2253,6 @@ pub const Node = struct {...@@ -2241,7 +2253,6 @@ pub const Node = struct {
2241test "iterate" {2253test "iterate" {
2242 var root = Node.Root{2254 var root = Node.Root{
2243 .base = Node{ .id = Node.Id.Root },2255 .base = Node{ .id = Node.Id.Root },
2244 .doc_comments = null,
2245 .decls = Node.Root.DeclList.init(std.debug.global_allocator),2256 .decls = Node.Root.DeclList.init(std.debug.global_allocator),
2246 .eof_token = 0,2257 .eof_token = 0,
2247 };2258 };
lib/std/zig/parse.zig+65-28
...@@ -58,13 +58,6 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error...@@ -58,13 +58,6 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
58 node.* = Node.Root{58 node.* = Node.Root{
59 .base = Node{ .id = .Root },59 .base = Node{ .id = .Root },
60 .decls = undefined,60 .decls = undefined,
61 // TODO: Because zig fmt collapses consecutive comments separated by blank lines into
62 // a single multi-line comment, it is currently impossible to have a container-level
63 // doc comment and NO doc comment on the first decl. For now, simply
64 // ignore the problem and assume that there will be no container-level
65 // doc comments.
66 // See: https://github.com/ziglang/zig/issues/2288
67 .doc_comments = null,
68 .eof_token = undefined,61 .eof_token = undefined,
69 };62 };
70 node.decls = parseContainerMembers(arena, it, tree) catch |err| {63 node.decls = parseContainerMembers(arena, it, tree) catch |err| {
...@@ -94,6 +87,11 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -94,6 +87,11 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
94 var list = Node.Root.DeclList.init(arena);87 var list = Node.Root.DeclList.init(arena);
9588
96 while (true) {89 while (true) {
90 if (try parseContainerDocComments(arena, it, tree)) |node| {
91 try list.push(node);
92 continue;
93 }
94
97 const doc_comments = try parseDocComment(arena, it, tree);95 const doc_comments = try parseDocComment(arena, it, tree);
9896
99 if (try parseTestDecl(arena, it, tree)) |node| {97 if (try parseTestDecl(arena, it, tree)) |node| {
...@@ -155,12 +153,35 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -155,12 +153,35 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
155 continue;153 continue;
156 }154 }
157155
156 // Dangling doc comment
157 if (doc_comments != null) {
158 try tree.errors.push(AstError{
159 .UnattachedDocComment = AstError.UnattachedDocComment{ .token = doc_comments.?.firstToken() },
160 });
161 }
158 break;162 break;
159 }163 }
160164
161 return list;165 return list;
162}166}
163167
168/// Eat a multiline container doc comment
169fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
170 var lines = Node.DocComment.LineList.init(arena);
171 while (eatToken(it, .ContainerDocComment)) |line| {
172 try lines.push(line);
173 }
174
175 if (lines.len == 0) return null;
176
177 const node = try arena.create(Node.DocComment);
178 node.* = Node.DocComment{
179 .base = Node{ .id = .DocComment },
180 .lines = lines,
181 };
182 return &node.base;
183}
184
164/// TestDecl <- KEYWORD_test STRINGLITERAL Block185/// TestDecl <- KEYWORD_test STRINGLITERAL Block
165fn parseTestDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {186fn parseTestDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
166 const test_token = eatToken(it, .Keyword_test) orelse return null;187 const test_token = eatToken(it, .Keyword_test) orelse return null;
...@@ -1026,16 +1047,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1026,16 +1047,16 @@ fn parseWhileExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1026/// CurlySuffixExpr <- TypeExpr InitList?1047/// CurlySuffixExpr <- TypeExpr InitList?
1027fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1048fn parseCurlySuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1028 const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null;1049 const type_expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
1029 const init_list = (try parseInitList(arena, it, tree)) orelse return type_expr;1050 const suffix_op = (try parseInitList(arena, it, tree)) orelse return type_expr;
1030 init_list.cast(Node.SuffixOp).?.lhs = type_expr;1051 suffix_op.lhs.node = type_expr;
1031 return init_list;1052 return &suffix_op.base;
1032}1053}
10331054
1034/// InitList1055/// InitList
1035/// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE1056/// <- LBRACE FieldInit (COMMA FieldInit)* COMMA? RBRACE
1036/// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE1057/// / LBRACE Expr (COMMA Expr)* COMMA? RBRACE
1037/// / LBRACE RBRACE1058/// / LBRACE RBRACE
1038fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1059fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.SuffixOp {
1039 const lbrace = eatToken(it, .LBrace) orelse return null;1060 const lbrace = eatToken(it, .LBrace) orelse return null;
1040 var init_list = Node.SuffixOp.Op.InitList.init(arena);1061 var init_list = Node.SuffixOp.Op.InitList.init(arena);
10411062
...@@ -1064,11 +1085,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1064,11 +1085,11 @@ fn parseInitList(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1064 const node = try arena.create(Node.SuffixOp);1085 const node = try arena.create(Node.SuffixOp);
1065 node.* = Node.SuffixOp{1086 node.* = Node.SuffixOp{
1066 .base = Node{ .id = .SuffixOp },1087 .base = Node{ .id = .SuffixOp },
1067 .lhs = undefined, // set by caller1088 .lhs = .{.node = undefined}, // set by caller
1068 .op = op,1089 .op = op,
1069 .rtoken = try expectToken(it, tree, .RBrace),1090 .rtoken = try expectToken(it, tree, .RBrace),
1070 };1091 };
1071 return &node.base;1092 return node;
1072}1093}
10731094
1074/// TypeExpr <- PrefixTypeOp* ErrorUnionExpr1095/// TypeExpr <- PrefixTypeOp* ErrorUnionExpr
...@@ -1117,7 +1138,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1117,7 +1138,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11171138
1118 while (try parseSuffixOp(arena, it, tree)) |node| {1139 while (try parseSuffixOp(arena, it, tree)) |node| {
1119 switch (node.id) {1140 switch (node.id) {
1120 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,1141 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
1121 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,1142 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
1122 else => unreachable,1143 else => unreachable,
1123 }1144 }
...@@ -1133,7 +1154,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1133,7 +1154,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1133 const node = try arena.create(Node.SuffixOp);1154 const node = try arena.create(Node.SuffixOp);
1134 node.* = Node.SuffixOp{1155 node.* = Node.SuffixOp{
1135 .base = Node{ .id = .SuffixOp },1156 .base = Node{ .id = .SuffixOp },
1136 .lhs = res,1157 .lhs = .{.node = res},
1137 .op = Node.SuffixOp.Op{1158 .op = Node.SuffixOp.Op{
1138 .Call = Node.SuffixOp.Op.Call{1159 .Call = Node.SuffixOp.Op.Call{
1139 .params = params.list,1160 .params = params.list,
...@@ -1150,7 +1171,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1150,7 +1171,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1150 while (true) {1171 while (true) {
1151 if (try parseSuffixOp(arena, it, tree)) |node| {1172 if (try parseSuffixOp(arena, it, tree)) |node| {
1152 switch (node.id) {1173 switch (node.id) {
1153 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = res,1174 .SuffixOp => node.cast(Node.SuffixOp).?.lhs = .{.node = res},
1154 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,1175 .InfixOp => node.cast(Node.InfixOp).?.lhs = res,
1155 else => unreachable,1176 else => unreachable,
1156 }1177 }
...@@ -1161,7 +1182,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1161,7 +1182,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1161 const call = try arena.create(Node.SuffixOp);1182 const call = try arena.create(Node.SuffixOp);
1162 call.* = Node.SuffixOp{1183 call.* = Node.SuffixOp{
1163 .base = Node{ .id = .SuffixOp },1184 .base = Node{ .id = .SuffixOp },
1164 .lhs = res,1185 .lhs = .{.node = res},
1165 .op = Node.SuffixOp.Op{1186 .op = Node.SuffixOp.Op{
1166 .Call = Node.SuffixOp.Op.Call{1187 .Call = Node.SuffixOp.Op.Call{
1167 .params = params.list,1188 .params = params.list,
...@@ -1215,7 +1236,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N...@@ -1215,7 +1236,7 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
1215 return &node.base;1236 return &node.base;
1216 }1237 }
1217 if (try parseContainerDecl(arena, it, tree)) |node| return node;1238 if (try parseContainerDecl(arena, it, tree)) |node| return node;
1218 if (try parseEnumLiteral(arena, it, tree)) |node| return node;1239 if (try parseAnonLiteral(arena, it, tree)) |node| return node;
1219 if (try parseErrorSetDecl(arena, it, tree)) |node| return node;1240 if (try parseErrorSetDecl(arena, it, tree)) |node| return node;
1220 if (try parseFloatLiteral(arena, it, tree)) |node| return node;1241 if (try parseFloatLiteral(arena, it, tree)) |node| return node;
1221 if (try parseFnProto(arena, it, tree)) |node| return node;1242 if (try parseFnProto(arena, it, tree)) |node| return node;
...@@ -1494,16 +1515,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1494,16 +1515,28 @@ fn parseAsmExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1494}1515}
14951516
1496/// DOT IDENTIFIER1517/// DOT IDENTIFIER
1497fn parseEnumLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1518fn parseAnonLiteral(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1498 const dot = eatToken(it, .Period) orelse return null;1519 const dot = eatToken(it, .Period) orelse return null;
1499 const name = try expectToken(it, tree, .Identifier);1520
1500 const node = try arena.create(Node.EnumLiteral);1521 // anon enum literal
1501 node.* = Node.EnumLiteral{1522 if (eatToken(it, .Identifier)) |name| {
1502 .base = Node{ .id = .EnumLiteral },1523 const node = try arena.create(Node.EnumLiteral);
1503 .dot = dot,1524 node.* = Node.EnumLiteral{
1504 .name = name,1525 .base = Node{ .id = .EnumLiteral },
1505 };1526 .dot = dot,
1506 return &node.base;1527 .name = name,
1528 };
1529 return &node.base;
1530 }
1531
1532 // anon container literal
1533 if (try parseInitList(arena, it, tree)) |node| {
1534 node.lhs = .{.dot = dot};
1535 return &node.base;
1536 }
1537
1538 putBackToken(it, dot);
1539 return null;
1507}1540}
15081541
1509/// AsmOutput <- COLON AsmOutputList AsmInput?1542/// AsmOutput <- COLON AsmOutputList AsmInput?
...@@ -1618,7 +1651,11 @@ fn parseBlockLabel(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?TokenInd...@@ -1618,7 +1651,11 @@ fn parseBlockLabel(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?TokenInd
1618/// FieldInit <- DOT IDENTIFIER EQUAL Expr1651/// FieldInit <- DOT IDENTIFIER EQUAL Expr
1619fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1652fn parseFieldInit(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1620 const period_token = eatToken(it, .Period) orelse return null;1653 const period_token = eatToken(it, .Period) orelse return null;
1621 const name_token = try expectToken(it, tree, .Identifier);1654 const name_token = eatToken(it, .Identifier) orelse {
1655 // Because of anon literals `.{` is also valid.
1656 putBackToken(it, period_token);
1657 return null;
1658 };
1622 const eq_token = eatToken(it, .Equal) orelse {1659 const eq_token = eatToken(it, .Equal) orelse {
1623 // `.Name` may also be an enum literal, which is a later rule.1660 // `.Name` may also be an enum literal, which is a later rule.
1624 putBackToken(it, name_token);1661 putBackToken(it, name_token);
lib/std/zig/parse_string_literal.zig+1-1
...@@ -19,7 +19,7 @@ pub fn parseStringLiteral(...@@ -19,7 +19,7 @@ pub fn parseStringLiteral(
19 bytes: []const u8,19 bytes: []const u8,
20 bad_index: *usize, // populated if error.InvalidCharacter is returned20 bad_index: *usize, // populated if error.InvalidCharacter is returned
21) ParseStringLiteralError![]u8 {21) ParseStringLiteralError![]u8 {
22 const first_index = if (bytes[0] == 'c') usize(2) else usize(1);22 const first_index = if (bytes[0] == 'c') @as(usize, 2) else @as(usize, 1);
23 assert(bytes[bytes.len - 1] == '"');23 assert(bytes[bytes.len - 1] == '"');
2424
25 var list = std.ArrayList(u8).init(allocator);25 var list = std.ArrayList(u8).init(allocator);
lib/std/zig/parser_test.zig+85-13
...@@ -1,9 +1,26 @@...@@ -1,9 +1,26 @@
1// TODO remove `use` keyword eventually: https://github.com/ziglang/zig/issues/25911test "zig fmt: anon literal in array" {
2test "zig fmt: change use to usingnamespace" {2 try testCanonical(
3 try testTransform(3 \\var arr: [2]Foo = .{
4 \\use @import("std");4 \\ .{ .a = 2 },
5 ,5 \\ .{ .b = 3 },
6 \\usingnamespace @import("std");6 \\};
7 \\
8 );
9}
10
11test "zig fmt: anon struct literal syntax" {
12 try testCanonical(
13 \\const x = .{
14 \\ .a = b,
15 \\ .c = d,
16 \\};
17 \\
18 );
19}
20
21test "zig fmt: anon list literal syntax" {
22 try testCanonical(
23 \\const x = .{ a, b, c };
7 \\24 \\
8 );25 );
9}26}
...@@ -37,7 +54,7 @@ test "zig fmt: while else err prong with no block" {...@@ -37,7 +54,7 @@ test "zig fmt: while else err prong with no block" {
37 \\test "" {54 \\test "" {
38 \\ const result = while (returnError()) |value| {55 \\ const result = while (returnError()) |value| {
39 \\ break value;56 \\ break value;
40 \\ } else |err| i32(2);57 \\ } else |err| @as(i32, 2);
41 \\ expect(result == 2);58 \\ expect(result == 2);
42 \\}59 \\}
43 \\60 \\
...@@ -1444,11 +1461,11 @@ test "zig fmt: preserve spacing" {...@@ -1444,11 +1461,11 @@ test "zig fmt: preserve spacing" {
1444 \\const std = @import("std");1461 \\const std = @import("std");
1445 \\1462 \\
1446 \\pub fn main() !void {1463 \\pub fn main() !void {
1447 \\ var stdout_file = try std.io.getStdOut;1464 \\ var stdout_file = std.io.getStdOut;
1448 \\ var stdout_file = try std.io.getStdOut;1465 \\ var stdout_file = std.io.getStdOut;
1449 \\1466 \\
1450 \\ var stdout_file = try std.io.getStdOut;1467 \\ var stdout_file = std.io.getStdOut;
1451 \\ var stdout_file = try std.io.getStdOut;1468 \\ var stdout_file = std.io.getStdOut;
1452 \\}1469 \\}
1453 \\1470 \\
1454 );1471 );
...@@ -2549,6 +2566,62 @@ test "zig fmt: comments at several places in struct init" {...@@ -2549,6 +2566,62 @@ test "zig fmt: comments at several places in struct init" {
2549 );2566 );
2550}2567}
25512568
2569test "zig fmt: top level doc comments" {
2570 try testCanonical(
2571 \\//! tld 1
2572 \\//! tld 2
2573 \\//! tld 3
2574 \\
2575 \\// comment
2576 \\
2577 \\/// A doc
2578 \\const A = struct {
2579 \\ //! A tld 1
2580 \\ //! A tld 2
2581 \\ //! A tld 3
2582 \\};
2583 \\
2584 \\/// B doc
2585 \\const B = struct {
2586 \\ //! B tld 1
2587 \\ //! B tld 2
2588 \\ //! B tld 3
2589 \\
2590 \\ /// b doc
2591 \\ b: u32,
2592 \\};
2593 \\
2594 \\/// C doc
2595 \\const C = struct {
2596 \\ //! C tld 1
2597 \\ //! C tld 2
2598 \\ //! C tld 3
2599 \\
2600 \\ /// c1 doc
2601 \\ c1: u32,
2602 \\
2603 \\ //! C tld 4
2604 \\ //! C tld 5
2605 \\ //! C tld 6
2606 \\
2607 \\ /// c2 doc
2608 \\ c2: u32,
2609 \\};
2610 \\
2611 );
2612 try testCanonical(
2613 \\//! Top-level documentation.
2614 \\
2615 \\/// This is A
2616 \\pub const A = usize;
2617 \\
2618 );
2619 try testCanonical(
2620 \\//! Nothing here
2621 \\
2622 );
2623}
2624
2552const std = @import("std");2625const std = @import("std");
2553const mem = std.mem;2626const mem = std.mem;
2554const warn = std.debug.warn;2627const warn = std.debug.warn;
...@@ -2558,8 +2631,7 @@ const maxInt = std.math.maxInt;...@@ -2558,8 +2631,7 @@ const maxInt = std.math.maxInt;
2558var fixed_buffer_mem: [100 * 1024]u8 = undefined;2631var fixed_buffer_mem: [100 * 1024]u8 = undefined;
25592632
2560fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {2633fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *bool) ![]u8 {
2561 var stderr_file = try io.getStdErr();2634 const stderr = &io.getStdErr().outStream().stream;
2562 var stderr = &stderr_file.outStream().stream;
25632635
2564 const tree = try std.zig.parse(allocator, source);2636 const tree = try std.zig.parse(allocator, source);
2565 defer tree.deinit();2637 defer tree.deinit();
lib/std/zig/render.zig+57-21
...@@ -226,9 +226,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i...@@ -226,9 +226,7 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
226 if (use_decl.visib_token) |visib_token| {226 if (use_decl.visib_token) |visib_token| {
227 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub227 try renderToken(tree, stream, visib_token, indent, start_col, Space.Space); // pub
228 }228 }
229 // TODO after depracating use, go back to this:229 try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace
230 //try renderToken(tree, stream, use_decl.use_token, indent, start_col, Space.Space); // usingnamespace
231 try stream.write("usingnamespace ");
232 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);230 try renderExpression(allocator, stream, tree, indent, start_col, use_decl.expr, Space.None);
233 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;231 try renderToken(tree, stream, use_decl.semicolon_token, indent, start_col, Space.Newline); // ;
234 },232 },
...@@ -301,6 +299,17 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i...@@ -301,6 +299,17 @@ fn renderTopLevelDecl(allocator: *mem.Allocator, stream: var, tree: *ast.Tree, i
301 assert(!decl.requireSemiColon());299 assert(!decl.requireSemiColon());
302 try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Newline);300 try renderExpression(allocator, stream, tree, indent, start_col, decl, Space.Newline);
303 },301 },
302
303 ast.Node.Id.DocComment => {
304 const comment = @fieldParentPtr(ast.Node.DocComment, "base", decl);
305 var it = comment.lines.iterator(0);
306 while (it.next()) |line_token_index| {
307 try renderToken(tree, stream, line_token_index.*, indent, start_col, Space.Newline);
308 if (it.peek()) |_| {
309 try stream.writeByteNTimes(' ', indent);
310 }
311 }
312 },
304 else => unreachable,313 else => unreachable,
305 }314 }
306}315}
...@@ -410,8 +419,8 @@ fn renderExpression(...@@ -410,8 +419,8 @@ fn renderExpression(
410 switch (prefix_op_node.op) {419 switch (prefix_op_node.op) {
411 ast.Node.PrefixOp.Op.PtrType => |ptr_info| {420 ast.Node.PrefixOp.Op.PtrType => |ptr_info| {
412 const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) {421 const star_offset = switch (tree.tokens.at(prefix_op_node.op_token).id) {
413 Token.Id.AsteriskAsterisk => usize(1),422 Token.Id.AsteriskAsterisk => @as(usize, 1),
414 else => usize(0),423 else => @as(usize, 0),
415 };424 };
416 try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // *425 try renderTokenOffset(tree, stream, prefix_op_node.op_token, indent, start_col, Space.None, star_offset); // *
417 if (ptr_info.allowzero_token) |allowzero_token| {426 if (ptr_info.allowzero_token) |allowzero_token| {
...@@ -540,9 +549,9 @@ fn renderExpression(...@@ -540,9 +549,9 @@ fn renderExpression(
540 try renderToken(tree, stream, async_token, indent, start_col, Space.Space);549 try renderToken(tree, stream, async_token, indent, start_col, Space.Space);
541 }550 }
542551
543 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);552 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
544553
545 const lparen = tree.nextToken(suffix_op.lhs.lastToken());554 const lparen = tree.nextToken(suffix_op.lhs.node.lastToken());
546555
547 if (call_info.params.len == 0) {556 if (call_info.params.len == 0) {
548 try renderToken(tree, stream, lparen, indent, start_col, Space.None);557 try renderToken(tree, stream, lparen, indent, start_col, Space.None);
...@@ -600,7 +609,7 @@ fn renderExpression(...@@ -600,7 +609,7 @@ fn renderExpression(
600 const lbracket = tree.prevToken(index_expr.firstToken());609 const lbracket = tree.prevToken(index_expr.firstToken());
601 const rbracket = tree.nextToken(index_expr.lastToken());610 const rbracket = tree.nextToken(index_expr.lastToken());
602611
603 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);612 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
604 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [613 try renderToken(tree, stream, lbracket, indent, start_col, Space.None); // [
605614
606 const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment;615 const starts_with_comment = tree.tokens.at(lbracket + 1).id == .LineComment;
...@@ -618,18 +627,18 @@ fn renderExpression(...@@ -618,18 +627,18 @@ fn renderExpression(
618 },627 },
619628
620 ast.Node.SuffixOp.Op.Deref => {629 ast.Node.SuffixOp.Op.Deref => {
621 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);630 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
622 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .*631 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // .*
623 },632 },
624633
625 ast.Node.SuffixOp.Op.UnwrapOptional => {634 ast.Node.SuffixOp.Op.UnwrapOptional => {
626 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);635 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
627 try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .636 try renderToken(tree, stream, tree.prevToken(suffix_op.rtoken), indent, start_col, Space.None); // .
628 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ?637 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space); // ?
629 },638 },
630639
631 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {640 @TagType(ast.Node.SuffixOp.Op).Slice => |range| {
632 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);641 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs.node, Space.None);
633642
634 const lbracket = tree.prevToken(range.start.firstToken());643 const lbracket = tree.prevToken(range.start.firstToken());
635 const dotdot = tree.nextToken(range.start.lastToken());644 const dotdot = tree.nextToken(range.start.lastToken());
...@@ -649,10 +658,16 @@ fn renderExpression(...@@ -649,10 +658,16 @@ fn renderExpression(
649 },658 },
650659
651 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {660 ast.Node.SuffixOp.Op.StructInitializer => |*field_inits| {
652 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());661 const lbrace = switch (suffix_op.lhs) {
662 .dot => |dot| tree.nextToken(dot),
663 .node => |node| tree.nextToken(node.lastToken()),
664 };
653665
654 if (field_inits.len == 0) {666 if (field_inits.len == 0) {
655 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);667 switch (suffix_op.lhs) {
668 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
669 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
670 }
656 try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None);671 try renderToken(tree, stream, lbrace, indent + indent_delta, start_col, Space.None);
657 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);672 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
658 }673 }
...@@ -693,7 +708,10 @@ fn renderExpression(...@@ -693,7 +708,10 @@ fn renderExpression(
693 break :blk;708 break :blk;
694 }709 }
695710
696 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);711 switch (suffix_op.lhs) {
712 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
713 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
714 }
697 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);715 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
698 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);716 try renderExpression(allocator, stream, tree, indent, start_col, &field_init.base, Space.Space);
699 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);717 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
...@@ -701,7 +719,10 @@ fn renderExpression(...@@ -701,7 +719,10 @@ fn renderExpression(
701719
702 if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {720 if (!src_has_trailing_comma and src_same_line and expr_outputs_one_line) {
703 // render all on one line, no trailing comma721 // render all on one line, no trailing comma
704 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);722 switch (suffix_op.lhs) {
723 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
724 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
725 }
705 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);726 try renderToken(tree, stream, lbrace, indent, start_col, Space.Space);
706727
707 var it = field_inits.iterator(0);728 var it = field_inits.iterator(0);
...@@ -721,7 +742,10 @@ fn renderExpression(...@@ -721,7 +742,10 @@ fn renderExpression(
721742
722 const new_indent = indent + indent_delta;743 const new_indent = indent + indent_delta;
723744
724 try renderExpression(allocator, stream, tree, new_indent, start_col, suffix_op.lhs, Space.None);745 switch (suffix_op.lhs) {
746 .dot => |dot| try renderToken(tree, stream, dot, new_indent, start_col, Space.None),
747 .node => |node| try renderExpression(allocator, stream, tree, new_indent, start_col, node, Space.None),
748 }
725 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);749 try renderToken(tree, stream, lbrace, new_indent, start_col, Space.Newline);
726750
727 var it = field_inits.iterator(0);751 var it = field_inits.iterator(0);
...@@ -745,23 +769,35 @@ fn renderExpression(...@@ -745,23 +769,35 @@ fn renderExpression(
745 },769 },
746770
747 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {771 ast.Node.SuffixOp.Op.ArrayInitializer => |*exprs| {
748 const lbrace = tree.nextToken(suffix_op.lhs.lastToken());772 const lbrace = switch (suffix_op.lhs) {
773 .dot => |dot| tree.nextToken(dot),
774 .node => |node| tree.nextToken(node.lastToken()),
775 };
749776
750 if (exprs.len == 0) {777 if (exprs.len == 0) {
751 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);778 switch (suffix_op.lhs) {
779 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
780 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
781 }
752 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);782 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
753 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);783 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
754 }784 }
755 if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) {785 if (exprs.len == 1 and tree.tokens.at(exprs.at(0).*.lastToken() + 1).id == .RBrace) {
756 const expr = exprs.at(0).*;786 const expr = exprs.at(0).*;
757787
758 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);788 switch (suffix_op.lhs) {
789 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
790 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
791 }
759 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);792 try renderToken(tree, stream, lbrace, indent, start_col, Space.None);
760 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);793 try renderExpression(allocator, stream, tree, indent, start_col, expr, Space.None);
761 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);794 return renderToken(tree, stream, suffix_op.rtoken, indent, start_col, space);
762 }795 }
763796
764 try renderExpression(allocator, stream, tree, indent, start_col, suffix_op.lhs, Space.None);797 switch (suffix_op.lhs) {
798 .dot => |dot| try renderToken(tree, stream, dot, indent, start_col, Space.None),
799 .node => |node| try renderExpression(allocator, stream, tree, indent, start_col, node, Space.None),
800 }
765801
766 // scan to find row size802 // scan to find row size
767 const maybe_row_size: ?usize = blk: {803 const maybe_row_size: ?usize = blk: {
...@@ -2097,7 +2133,7 @@ fn renderTokenOffset(...@@ -2097,7 +2133,7 @@ fn renderTokenOffset(
20972133
2098 while (true) {2134 while (true) {
2099 assert(loc.line != 0);2135 assert(loc.line != 0);
2100 const newline_count = if (loc.line == 1) u8(1) else u8(2);2136 const newline_count = if (loc.line == 1) @as(u8, 1) else @as(u8, 2);
2101 try stream.writeByteNTimes('\n', newline_count);2137 try stream.writeByteNTimes('\n', newline_count);
2102 try stream.writeByteNTimes(' ', indent);2138 try stream.writeByteNTimes(' ', indent);
2103 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));2139 try stream.write(mem.trimRight(u8, tree.tokenSlicePtr(next_token), " "));
lib/std/zig/tokenizer.zig+32-24
...@@ -59,7 +59,6 @@ pub const Token = struct {...@@ -59,7 +59,6 @@ pub const Token = struct {
59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },59 Keyword{ .bytes = "undefined", .id = Id.Keyword_undefined },
60 Keyword{ .bytes = "union", .id = Id.Keyword_union },60 Keyword{ .bytes = "union", .id = Id.Keyword_union },
61 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },61 Keyword{ .bytes = "unreachable", .id = Id.Keyword_unreachable },
62 Keyword{ .bytes = "use", .id = Id.Keyword_usingnamespace },
63 Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace },62 Keyword{ .bytes = "usingnamespace", .id = Id.Keyword_usingnamespace },
64 Keyword{ .bytes = "var", .id = Id.Keyword_var },63 Keyword{ .bytes = "var", .id = Id.Keyword_var },
65 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },64 Keyword{ .bytes = "volatile", .id = Id.Keyword_volatile },
...@@ -143,6 +142,7 @@ pub const Token = struct {...@@ -143,6 +142,7 @@ pub const Token = struct {
143 FloatLiteral,142 FloatLiteral,
144 LineComment,143 LineComment,
145 DocComment,144 DocComment,
145 ContainerDocComment,
146 BracketStarBracket,146 BracketStarBracket,
147 BracketStarCBracket,147 BracketStarCBracket,
148 ShebangLine,148 ShebangLine,
...@@ -212,6 +212,7 @@ pub const Token = struct {...@@ -212,6 +212,7 @@ pub const Token = struct {
212 .FloatLiteral => "FloatLiteral",212 .FloatLiteral => "FloatLiteral",
213 .LineComment => "LineComment",213 .LineComment => "LineComment",
214 .DocComment => "DocComment",214 .DocComment => "DocComment",
215 .ContainerDocComment => "ContainerDocComment",
215 .ShebangLine => "ShebangLine",216 .ShebangLine => "ShebangLine",
216217
217 .Bang => "!",218 .Bang => "!",
...@@ -337,26 +338,13 @@ pub const Tokenizer = struct {...@@ -337,26 +338,13 @@ pub const Tokenizer = struct {
337 }338 }
338339
339 pub fn init(buffer: []const u8) Tokenizer {340 pub fn init(buffer: []const u8) Tokenizer {
340 if (mem.startsWith(u8, buffer, "#!")) {341 // Skip the UTF-8 BOM if present
341 const src_start = if (mem.indexOfScalar(u8, buffer, '\n')) |i| i + 1 else buffer.len;342 const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else @as(usize, 0);
342 return Tokenizer{343 return Tokenizer{
343 .buffer = buffer,344 .buffer = buffer,
344 .index = src_start,345 .index = src_start,
345 .pending_invalid_token = Token{346 .pending_invalid_token = null,
346 .id = Token.Id.ShebangLine,347 };
347 .start = 0,
348 .end = src_start,
349 },
350 };
351 } else {
352 // Skip the UTF-8 BOM if present
353 const src_start = if (mem.startsWith(u8, buffer, "\xEF\xBB\xBF")) 3 else usize(0);
354 return Tokenizer{
355 .buffer = buffer,
356 .index = src_start,
357 .pending_invalid_token = null,
358 };
359 }
360 }348 }
361349
362 const State = enum {350 const State = enum {
...@@ -388,6 +376,7 @@ pub const Tokenizer = struct {...@@ -388,6 +376,7 @@ pub const Tokenizer = struct {
388 LineComment,376 LineComment,
389 DocCommentStart,377 DocCommentStart,
390 DocComment,378 DocComment,
379 ContainerDocComment,
391 Zero,380 Zero,
392 IntegerLiteral,381 IntegerLiteral,
393 IntegerLiteralWithRadix,382 IntegerLiteralWithRadix,
...@@ -763,12 +752,12 @@ pub const Tokenizer = struct {...@@ -763,12 +752,12 @@ pub const Tokenizer = struct {
763 self.index += 1;752 self.index += 1;
764 break;753 break;
765 },754 },
766 '\n' => break, // Look for this error later.755 '\n', '\r' => break, // Look for this error later.
767 else => self.checkLiteralCharacter(),756 else => self.checkLiteralCharacter(),
768 },757 },
769758
770 State.StringLiteralBackslash => switch (c) {759 State.StringLiteralBackslash => switch (c) {
771 '\n' => break, // Look for this error later.760 '\n', '\r' => break, // Look for this error later.
772 else => {761 else => {
773 state = State.StringLiteral;762 state = State.StringLiteral;
774 },763 },
...@@ -1077,6 +1066,10 @@ pub const Tokenizer = struct {...@@ -1077,6 +1066,10 @@ pub const Tokenizer = struct {
1077 '/' => {1066 '/' => {
1078 state = State.DocCommentStart;1067 state = State.DocCommentStart;
1079 },1068 },
1069 '!' => {
1070 result.id = Token.Id.ContainerDocComment;
1071 state = State.ContainerDocComment;
1072 },
1080 '\n' => break,1073 '\n' => break,
1081 else => {1074 else => {
1082 state = State.LineComment;1075 state = State.LineComment;
...@@ -1097,7 +1090,7 @@ pub const Tokenizer = struct {...@@ -1097,7 +1090,7 @@ pub const Tokenizer = struct {
1097 self.checkLiteralCharacter();1090 self.checkLiteralCharacter();
1098 },1091 },
1099 },1092 },
1100 State.LineComment, State.DocComment => switch (c) {1093 State.LineComment, State.DocComment, State.ContainerDocComment => switch (c) {
1101 '\n' => break,1094 '\n' => break,
1102 else => self.checkLiteralCharacter(),1095 else => self.checkLiteralCharacter(),
1103 },1096 },
...@@ -1235,6 +1228,9 @@ pub const Tokenizer = struct {...@@ -1235,6 +1228,9 @@ pub const Tokenizer = struct {
1235 State.DocComment, State.DocCommentStart => {1228 State.DocComment, State.DocCommentStart => {
1236 result.id = Token.Id.DocComment;1229 result.id = Token.Id.DocComment;
1237 },1230 },
1231 State.ContainerDocComment => {
1232 result.id = Token.Id.ContainerDocComment;
1233 },
12381234
1239 State.NumberDot,1235 State.NumberDot,
1240 State.NumberDotHex,1236 State.NumberDotHex,
...@@ -1602,6 +1598,8 @@ test "tokenizer - line comment and doc comment" {...@@ -1602,6 +1598,8 @@ test "tokenizer - line comment and doc comment" {
1602 testTokenize("/// a", [_]Token.Id{Token.Id.DocComment});1598 testTokenize("/// a", [_]Token.Id{Token.Id.DocComment});
1603 testTokenize("///", [_]Token.Id{Token.Id.DocComment});1599 testTokenize("///", [_]Token.Id{Token.Id.DocComment});
1604 testTokenize("////", [_]Token.Id{Token.Id.LineComment});1600 testTokenize("////", [_]Token.Id{Token.Id.LineComment});
1601 testTokenize("//!", [_]Token.Id{Token.Id.ContainerDocComment});
1602 testTokenize("//!!", [_]Token.Id{Token.Id.ContainerDocComment});
1605}1603}
16061604
1607test "tokenizer - line comment followed by identifier" {1605test "tokenizer - line comment followed by identifier" {
...@@ -1625,6 +1623,16 @@ test "tokenizer - UTF-8 BOM is recognized and skipped" {...@@ -1625,6 +1623,16 @@ test "tokenizer - UTF-8 BOM is recognized and skipped" {
1625 });1623 });
1626}1624}
16271625
1626test "correctly parse pointer assignment" {
1627 testTokenize("b.*=3;\n", [_]Token.Id{
1628 Token.Id.Identifier,
1629 Token.Id.PeriodAsterisk,
1630 Token.Id.Equal,
1631 Token.Id.IntegerLiteral,
1632 Token.Id.Semicolon,
1633 });
1634}
1635
1628fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {1636fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
1629 var tokenizer = Tokenizer.init(source);1637 var tokenizer = Tokenizer.init(source);
1630 for (expected_tokens) |expected_token_id| {1638 for (expected_tokens) |expected_token_id| {
src-self-hosted/clang.zig+4
...@@ -42,6 +42,7 @@ pub const struct_ZigClangImplicitCastExpr = @OpaqueType();...@@ -42,6 +42,7 @@ pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
42pub const struct_ZigClangIncompleteArrayType = @OpaqueType();42pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
43pub const struct_ZigClangIntegerLiteral = @OpaqueType();43pub const struct_ZigClangIntegerLiteral = @OpaqueType();
44pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();44pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
45pub const struct_ZigClangMacroQualifiedType = @OpaqueType();
45pub const struct_ZigClangMemberExpr = @OpaqueType();46pub const struct_ZigClangMemberExpr = @OpaqueType();
46pub const struct_ZigClangNamedDecl = @OpaqueType();47pub const struct_ZigClangNamedDecl = @OpaqueType();
47pub const struct_ZigClangNone = @OpaqueType();48pub const struct_ZigClangNone = @OpaqueType();
...@@ -831,6 +832,7 @@ pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;...@@ -831,6 +832,7 @@ pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
831pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;832pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
832pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;833pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
833pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;834pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
835pub const ZigClangMacroQualifiedType = struct_ZigClangMacroQualifiedType;
834pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;836pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
835pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;837pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
836pub const ZigClangNone = struct_ZigClangNone;838pub const ZigClangNone = struct_ZigClangNone;
...@@ -937,6 +939,8 @@ pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType)...@@ -937,6 +939,8 @@ pub extern fn ZigClangElaboratedType_getNamedType(*const ZigClangElaboratedType)
937939
938pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType;940pub extern fn ZigClangAttributedType_getEquivalentType(*const ZigClangAttributedType) ZigClangQualType;
939941
942pub extern fn ZigClangMacroQualifiedType_getModifiedType(*const ZigClangMacroQualifiedType) ZigClangQualType;
943
940pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation;944pub extern fn ZigClangCStyleCastExpr_getBeginLoc(*const ZigClangCStyleCastExpr) ZigClangSourceLocation;
941pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;945pub extern fn ZigClangCStyleCastExpr_getSubExpr(*const ZigClangCStyleCastExpr) *const ZigClangExpr;
942pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;946pub extern fn ZigClangCStyleCastExpr_getType(*const ZigClangCStyleCastExpr) ZigClangQualType;
src-self-hosted/main.zig+4-7
...@@ -58,13 +58,10 @@ pub fn main() !void {...@@ -58,13 +58,10 @@ pub fn main() !void {
58 // libc allocator is guaranteed to have this property.58 // libc allocator is guaranteed to have this property.
59 const allocator = std.heap.c_allocator;59 const allocator = std.heap.c_allocator;
6060
61 var stdout_file = try std.io.getStdOut();61 stdout = &std.io.getStdOut().outStream().stream;
62 var stdout_out_stream = stdout_file.outStream();
63 stdout = &stdout_out_stream.stream;
6462
65 stderr_file = try std.io.getStdErr();63 stderr_file = std.io.getStdErr();
66 var stderr_out_stream = stderr_file.outStream();64 stderr = &stderr_file.outStream().stream;
67 stderr = &stderr_out_stream.stream;
6865
69 const args = try process.argsAlloc(allocator);66 const args = try process.argsAlloc(allocator);
70 // TODO I'm getting unreachable code here, which shouldn't happen67 // TODO I'm getting unreachable code here, which shouldn't happen
...@@ -610,7 +607,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {...@@ -610,7 +607,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void {
610 process.exit(1);607 process.exit(1);
611 }608 }
612609
613 var stdin_file = try io.getStdIn();610 var stdin_file = io.getStdIn();
614 var stdin = stdin_file.inStream();611 var stdin = stdin_file.inStream();
615612
616 const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);613 const source_code = try stdin.stream.readAllAlloc(allocator, max_src_size);
src-self-hosted/stage1.zig+5-9
...@@ -165,13 +165,9 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {...@@ -165,13 +165,9 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
165 try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));165 try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));
166 }166 }
167167
168 var stdout_file = try std.io.getStdOut();168 stdout = &std.io.getStdOut().outStream().stream;
169 var stdout_out_stream = stdout_file.outStream();169 stderr_file = std.io.getStdErr();
170 stdout = &stdout_out_stream.stream;170 stderr = &stderr_file.outStream().stream;
171
172 stderr_file = try std.io.getStdErr();
173 var stderr_out_stream = stderr_file.outStream();
174 stderr = &stderr_out_stream.stream;
175171
176 const args = args_list.toSliceConst();172 const args = args_list.toSliceConst();
177 var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[2..]);173 var flags = try Args.parse(allocator, self_hosted_main.args_fmt_spec, args[2..]);
...@@ -202,7 +198,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {...@@ -202,7 +198,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
202 process.exit(1);198 process.exit(1);
203 }199 }
204200
205 var stdin_file = try io.getStdIn();201 const stdin_file = io.getStdIn();
206 var stdin = stdin_file.inStream();202 var stdin = stdin_file.inStream();
207203
208 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);204 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
...@@ -223,7 +219,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {...@@ -223,7 +219,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*]const u8) !void {
223 }219 }
224 if (flags.present("check")) {220 if (flags.present("check")) {
225 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);221 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
226 const code = if (anything_changed) u8(1) else u8(0);222 const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
227 process.exit(code);223 process.exit(code);
228 }224 }
229225
src-self-hosted/test.zig+3-3
...@@ -171,8 +171,8 @@ pub const TestContext = struct {...@@ -171,8 +171,8 @@ pub const TestContext = struct {
171 return error.OutputMismatch;171 return error.OutputMismatch;
172 }172 }
173 },173 },
174 .Error => |err| return err,174 Compilation.Event.Error => |err| return err,
175 .Fail => |msgs| {175 Compilation.Event.Fail => |msgs| {
176 var stderr = try std.io.getStdErr();176 var stderr = try std.io.getStdErr();
177 try stderr.write("build incorrectly failed:\n");177 try stderr.write("build incorrectly failed:\n");
178 for (msgs) |msg| {178 for (msgs) |msg| {
...@@ -223,7 +223,7 @@ pub const TestContext = struct {...@@ -223,7 +223,7 @@ pub const TestContext = struct {
223 text,223 text,
224 );224 );
225 std.debug.warn("\n====found:========\n");225 std.debug.warn("\n====found:========\n");
226 var stderr = try std.io.getStdErr();226 const stderr = std.io.getStdErr();
227 for (msgs) |msg| {227 for (msgs) |msg| {
228 defer msg.destroy();228 defer msg.destroy();
229 try msg.printToFile(stderr, errmsg.Color.Auto);229 try msg.printToFile(stderr, errmsg.Color.Auto);
src-self-hosted/translate_c.zig+11-8
...@@ -122,7 +122,7 @@ const Context = struct {...@@ -122,7 +122,7 @@ const Context = struct {
122 fn locStr(c: *Context, loc: ZigClangSourceLocation) ![]u8 {122 fn locStr(c: *Context, loc: ZigClangSourceLocation) ![]u8 {
123 const spelling_loc = ZigClangSourceManager_getSpellingLoc(c.source_manager, loc);123 const spelling_loc = ZigClangSourceManager_getSpellingLoc(c.source_manager, loc);
124 const filename_c = ZigClangSourceManager_getFilename(c.source_manager, spelling_loc);124 const filename_c = ZigClangSourceManager_getFilename(c.source_manager, spelling_loc);
125 const filename = if (filename_c) |s| try c.str(s) else ([]const u8)("(no file)");125 const filename = if (filename_c) |s| try c.str(s) else @as([]const u8, "(no file)");
126126
127 const line = ZigClangSourceManager_getSpellingLineNumber(c.source_manager, spelling_loc);127 const line = ZigClangSourceManager_getSpellingLineNumber(c.source_manager, spelling_loc);
128 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);128 const column = ZigClangSourceManager_getSpellingColumnNumber(c.source_manager, spelling_loc);
...@@ -173,7 +173,6 @@ pub fn translate(...@@ -173,7 +173,6 @@ pub fn translate(
173 tree.root_node.* = ast.Node.Root{173 tree.root_node.* = ast.Node.Root{
174 .base = ast.Node{ .id = ast.Node.Id.Root },174 .base = ast.Node{ .id = ast.Node.Id.Root },
175 .decls = ast.Node.Root.DeclList.init(arena),175 .decls = ast.Node.Root.DeclList.init(arena),
176 .doc_comments = null,
177 // initialized with the eof token at the end176 // initialized with the eof token at the end
178 .eof_token = undefined,177 .eof_token = undefined,
179 };178 };
...@@ -773,12 +772,14 @@ fn transCCast(...@@ -773,12 +772,14 @@ fn transCCast(
773 if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))772 if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
774 return transCPtrCast(rp, loc, dst_type, src_type, expr);773 return transCPtrCast(rp, loc, dst_type, src_type, expr);
775 if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {774 if (cIsUnsignedInteger(dst_type) and qualTypeIsPtr(src_type)) {
776 const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));775 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
776 try cast_node.params.push(try transQualType(rp, dst_type, loc));
777 _ = try appendToken(rp.c, .Comma, ",");
777 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");778 const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@ptrToInt");
778 try builtin_node.params.push(expr);779 try builtin_node.params.push(expr);
779 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");780 builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
780 try cast_node.op.Call.params.push(&builtin_node.base);781 try cast_node.params.push(&builtin_node.base);
781 cast_node.rtoken = try appendToken(rp.c, .RParen, ")");782 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
782 return &cast_node.base;783 return &cast_node.base;
783 }784 }
784 if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {785 if (cIsUnsignedInteger(src_type) and qualTypeIsPtr(dst_type)) {
...@@ -792,9 +793,11 @@ fn transCCast(...@@ -792,9 +793,11 @@ fn transCCast(
792 // TODO: maybe widen to increase size793 // TODO: maybe widen to increase size
793 // TODO: maybe bitcast to change sign794 // TODO: maybe bitcast to change sign
794 // TODO: maybe truncate to reduce size795 // TODO: maybe truncate to reduce size
795 const cast_node = try transCreateNodeFnCall(rp.c, try transQualType(rp, dst_type, loc));796 const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@as");
796 try cast_node.op.Call.params.push(expr);797 try cast_node.params.push(try transQualType(rp, dst_type, loc));
797 cast_node.rtoken = try appendToken(rp.c, .RParen, ")");798 _ = try appendToken(rp.c, .Comma, ",");
799 try cast_node.params.push(expr);
800 cast_node.rparen_token = try appendToken(rp.c, .RParen, ")");
798 return &cast_node.base;801 return &cast_node.base;
799}802}
800803
src/all_types.hpp+50-13
...@@ -48,6 +48,7 @@ struct ResultLoc;...@@ -48,6 +48,7 @@ struct ResultLoc;
48struct ResultLocPeer;48struct ResultLocPeer;
49struct ResultLocPeerParent;49struct ResultLocPeerParent;
50struct ResultLocBitCast;50struct ResultLocBitCast;
51struct ResultLocCast;
51struct ResultLocReturn;52struct ResultLocReturn;
5253
53enum PtrLen {54enum PtrLen {
...@@ -151,7 +152,7 @@ struct ConstParent {...@@ -151,7 +152,7 @@ struct ConstParent {
151};152};
152153
153struct ConstStructValue {154struct ConstStructValue {
154 ConstExprValue *fields;155 ConstExprValue **fields;
155};156};
156157
157struct ConstUnionValue {158struct ConstUnionValue {
...@@ -967,6 +968,7 @@ struct AstNodeContainerDecl {...@@ -967,6 +968,7 @@ struct AstNodeContainerDecl {
967 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))968 AstNode *init_arg_expr; // enum(T), struct(endianness), or union(T), or union(enum(T))
968 ZigList<AstNode *> fields;969 ZigList<AstNode *> fields;
969 ZigList<AstNode *> decls;970 ZigList<AstNode *> decls;
971 Buf doc_comments;
970972
971 ContainerKind kind;973 ContainerKind kind;
972 ContainerLayout layout;974 ContainerLayout layout;
...@@ -1186,10 +1188,22 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);...@@ -1186,10 +1188,22 @@ bool fn_type_id_eql(FnTypeId *a, FnTypeId *b);
1186static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;1188static const uint32_t VECTOR_INDEX_NONE = UINT32_MAX;
1187static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;1189static const uint32_t VECTOR_INDEX_RUNTIME = UINT32_MAX - 1;
11881190
1191struct InferredStructField {
1192 ZigType *inferred_struct_type;
1193 Buf *field_name;
1194};
1195
1189struct ZigTypePointer {1196struct ZigTypePointer {
1190 ZigType *child_type;1197 ZigType *child_type;
1191 ZigType *slice_parent;1198 ZigType *slice_parent;
11921199
1200 // Anonymous struct literal syntax uses this when the result location has
1201 // no type in it. This field is null if this pointer does not refer to
1202 // a field of a currently-being-inferred struct type.
1203 // When this is non-null, the pointer is pointing to the base of the inferred
1204 // struct.
1205 InferredStructField *inferred_struct_field;
1206
1193 PtrLen ptr_len;1207 PtrLen ptr_len;
1194 uint32_t explicit_alignment; // 0 means use ABI alignment1208 uint32_t explicit_alignment; // 0 means use ABI alignment
11951209
...@@ -1236,6 +1250,7 @@ struct TypeStructField {...@@ -1236,6 +1250,7 @@ struct TypeStructField {
1236enum ResolveStatus {1250enum ResolveStatus {
1237 ResolveStatusUnstarted,1251 ResolveStatusUnstarted,
1238 ResolveStatusInvalid,1252 ResolveStatusInvalid,
1253 ResolveStatusBeingInferred,
1239 ResolveStatusZeroBitsKnown,1254 ResolveStatusZeroBitsKnown,
1240 ResolveStatusAlignmentKnown,1255 ResolveStatusAlignmentKnown,
1241 ResolveStatusSizeKnown,1256 ResolveStatusSizeKnown,
...@@ -1265,7 +1280,7 @@ struct RootStruct {...@@ -1265,7 +1280,7 @@ struct RootStruct {
12651280
1266struct ZigTypeStruct {1281struct ZigTypeStruct {
1267 AstNode *decl_node;1282 AstNode *decl_node;
1268 TypeStructField *fields;1283 TypeStructField **fields;
1269 ScopeDecls *decls_scope;1284 ScopeDecls *decls_scope;
1270 HashMap<Buf *, TypeStructField *, buf_hash, buf_eql_buf> fields_by_name;1285 HashMap<Buf *, TypeStructField *, buf_hash, buf_eql_buf> fields_by_name;
1271 RootStruct *root_struct;1286 RootStruct *root_struct;
...@@ -1284,6 +1299,7 @@ struct ZigTypeStruct {...@@ -1284,6 +1299,7 @@ struct ZigTypeStruct {
1284 bool requires_comptime;1299 bool requires_comptime;
1285 bool resolve_loop_flag_zero_bits;1300 bool resolve_loop_flag_zero_bits;
1286 bool resolve_loop_flag_other;1301 bool resolve_loop_flag_other;
1302 bool is_inferred;
1287};1303};
12881304
1289struct ZigTypeOptional {1305struct ZigTypeOptional {
...@@ -1685,12 +1701,14 @@ enum BuiltinFnId {...@@ -1685,12 +1701,14 @@ enum BuiltinFnId {
1685 BuiltinFnIdErrorReturnTrace,1701 BuiltinFnIdErrorReturnTrace,
1686 BuiltinFnIdAtomicRmw,1702 BuiltinFnIdAtomicRmw,
1687 BuiltinFnIdAtomicLoad,1703 BuiltinFnIdAtomicLoad,
1704 BuiltinFnIdAtomicStore,
1688 BuiltinFnIdHasDecl,1705 BuiltinFnIdHasDecl,
1689 BuiltinFnIdUnionInit,1706 BuiltinFnIdUnionInit,
1690 BuiltinFnIdFrameAddress,1707 BuiltinFnIdFrameAddress,
1691 BuiltinFnIdFrameType,1708 BuiltinFnIdFrameType,
1692 BuiltinFnIdFrameHandle,1709 BuiltinFnIdFrameHandle,
1693 BuiltinFnIdFrameSize,1710 BuiltinFnIdFrameSize,
1711 BuiltinFnIdAs,
1694};1712};
16951713
1696struct BuiltinFnEntry {1714struct BuiltinFnEntry {
...@@ -1739,6 +1757,7 @@ struct TypeId {...@@ -1739,6 +1757,7 @@ struct TypeId {
1739 union {1757 union {
1740 struct {1758 struct {
1741 ZigType *child_type;1759 ZigType *child_type;
1760 InferredStructField *inferred_struct_field;
1742 PtrLen ptr_len;1761 PtrLen ptr_len;
1743 uint32_t alignment;1762 uint32_t alignment;
17441763
...@@ -2552,6 +2571,7 @@ enum IrInstructionId {...@@ -2552,6 +2571,7 @@ enum IrInstructionId {
2552 IrInstructionIdErrorUnion,2571 IrInstructionIdErrorUnion,
2553 IrInstructionIdAtomicRmw,2572 IrInstructionIdAtomicRmw,
2554 IrInstructionIdAtomicLoad,2573 IrInstructionIdAtomicLoad,
2574 IrInstructionIdAtomicStore,
2555 IrInstructionIdSaveErrRetAddr,2575 IrInstructionIdSaveErrRetAddr,
2556 IrInstructionIdAddImplicitReturnType,2576 IrInstructionIdAddImplicitReturnType,
2557 IrInstructionIdErrSetCast,2577 IrInstructionIdErrSetCast,
...@@ -2810,7 +2830,7 @@ struct IrInstructionElemPtr {...@@ -2810,7 +2830,7 @@ struct IrInstructionElemPtr {
28102830
2811 IrInstruction *array_ptr;2831 IrInstruction *array_ptr;
2812 IrInstruction *elem_index;2832 IrInstruction *elem_index;
2813 IrInstruction *init_array_type;2833 AstNode *init_array_type_source_node;
2814 PtrLen ptr_len;2834 PtrLen ptr_len;
2815 bool safety_check_on;2835 bool safety_check_on;
2816};2836};
...@@ -2907,11 +2927,11 @@ struct IrInstructionResizeSlice {...@@ -2907,11 +2927,11 @@ struct IrInstructionResizeSlice {
2907struct IrInstructionContainerInitList {2927struct IrInstructionContainerInitList {
2908 IrInstruction base;2928 IrInstruction base;
29092929
2910 IrInstruction *container_type;
2911 IrInstruction *elem_type;2930 IrInstruction *elem_type;
2912 size_t item_count;2931 size_t item_count;
2913 IrInstruction **elem_result_loc_list;2932 IrInstruction **elem_result_loc_list;
2914 IrInstruction *result_loc;2933 IrInstruction *result_loc;
2934 AstNode *init_array_type_source_node;
2915};2935};
29162936
2917struct IrInstructionContainerInitFieldsField {2937struct IrInstructionContainerInitFieldsField {
...@@ -2924,7 +2944,6 @@ struct IrInstructionContainerInitFieldsField {...@@ -2924,7 +2944,6 @@ struct IrInstructionContainerInitFieldsField {
2924struct IrInstructionContainerInitFields {2944struct IrInstructionContainerInitFields {
2925 IrInstruction base;2945 IrInstruction base;
29262946
2927 IrInstruction *container_type;
2928 size_t field_count;2947 size_t field_count;
2929 IrInstructionContainerInitFieldsField *fields;2948 IrInstructionContainerInitFieldsField *fields;
2930 IrInstruction *result_loc;2949 IrInstruction *result_loc;
...@@ -3458,6 +3477,13 @@ struct IrInstructionPtrCastGen {...@@ -3458,6 +3477,13 @@ struct IrInstructionPtrCastGen {
3458 bool safety_check_on;3477 bool safety_check_on;
3459};3478};
34603479
3480struct IrInstructionImplicitCast {
3481 IrInstruction base;
3482
3483 IrInstruction *operand;
3484 ResultLocCast *result_loc_cast;
3485};
3486
3461struct IrInstructionBitCastSrc {3487struct IrInstructionBitCastSrc {
3462 IrInstruction base;3488 IrInstruction base;
34633489
...@@ -3642,6 +3668,7 @@ struct IrInstructionArgType {...@@ -3642,6 +3668,7 @@ struct IrInstructionArgType {
36423668
3643 IrInstruction *fn_type;3669 IrInstruction *fn_type;
3644 IrInstruction *arg_index;3670 IrInstruction *arg_index;
3671 bool allow_var;
3645};3672};
36463673
3647struct IrInstructionExport {3674struct IrInstructionExport {
...@@ -3690,6 +3717,16 @@ struct IrInstructionAtomicLoad {...@@ -3690,6 +3717,16 @@ struct IrInstructionAtomicLoad {
3690 AtomicOrder resolved_ordering;3717 AtomicOrder resolved_ordering;
3691};3718};
36923719
3720struct IrInstructionAtomicStore {
3721 IrInstruction base;
3722
3723 IrInstruction *operand_type;
3724 IrInstruction *ptr;
3725 IrInstruction *value;
3726 IrInstruction *ordering;
3727 AtomicOrder resolved_ordering;
3728};
3729
3693struct IrInstructionSaveErrRetAddr {3730struct IrInstructionSaveErrRetAddr {
3694 IrInstruction base;3731 IrInstruction base;
3695};3732};
...@@ -3823,14 +3860,6 @@ struct IrInstructionEndExpr {...@@ -3823,14 +3860,6 @@ struct IrInstructionEndExpr {
3823 ResultLoc *result_loc;3860 ResultLoc *result_loc;
3824};3861};
38253862
3826struct IrInstructionImplicitCast {
3827 IrInstruction base;
3828
3829 IrInstruction *dest_type;
3830 IrInstruction *target;
3831 ResultLoc *result_loc;
3832};
3833
3834// This one is for writing through the result pointer.3863// This one is for writing through the result pointer.
3835struct IrInstructionResolveResult {3864struct IrInstructionResolveResult {
3836 IrInstruction base;3865 IrInstruction base;
...@@ -3928,6 +3957,7 @@ enum ResultLocId {...@@ -3928,6 +3957,7 @@ enum ResultLocId {
3928 ResultLocIdPeerParent,3957 ResultLocIdPeerParent,
3929 ResultLocIdInstruction,3958 ResultLocIdInstruction,
3930 ResultLocIdBitCast,3959 ResultLocIdBitCast,
3960 ResultLocIdCast,
3931};3961};
39323962
3933// Additions to this struct may need to be handled in3963// Additions to this struct may need to be handled in
...@@ -3995,6 +4025,13 @@ struct ResultLocBitCast {...@@ -3995,6 +4025,13 @@ struct ResultLocBitCast {
3995 ResultLoc *parent;4025 ResultLoc *parent;
3996};4026};
39974027
4028// The source_instruction is the destination type
4029struct ResultLocCast {
4030 ResultLoc base;
4031
4032 ResultLoc *parent;
4033};
4034
3998static const size_t slice_ptr_index = 0;4035static const size_t slice_ptr_index = 0;
3999static const size_t slice_len_index = 1;4036static const size_t slice_len_index = 1;
40004037
src/analyze.cpp+196-92
...@@ -140,7 +140,6 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope...@@ -140,7 +140,6 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope
140static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,140static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
141 ZigType *import, Buf *bare_name)141 ZigType *import, Buf *bare_name)
142{142{
143 assert(node == nullptr || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
144 ScopeDecls *scope = allocate<ScopeDecls>(1);143 ScopeDecls *scope = allocate<ScopeDecls>(1);
145 init_scope(g, &scope->base, ScopeIdDecls, node, parent);144 init_scope(g, &scope->base, ScopeIdDecls, node, parent);
146 scope->decl_table.init(4);145 scope->decl_table.init(4);
...@@ -346,6 +345,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {...@@ -346,6 +345,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
346 switch (status) {345 switch (status) {
347 case ResolveStatusInvalid:346 case ResolveStatusInvalid:
348 zig_unreachable();347 zig_unreachable();
348 case ResolveStatusBeingInferred:
349 zig_unreachable();
349 case ResolveStatusUnstarted:350 case ResolveStatusUnstarted:
350 case ResolveStatusZeroBitsKnown:351 case ResolveStatusZeroBitsKnown:
351 return true;352 return true;
...@@ -362,6 +363,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {...@@ -362,6 +363,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
362 switch (status) {363 switch (status) {
363 case ResolveStatusInvalid:364 case ResolveStatusInvalid:
364 zig_unreachable();365 zig_unreachable();
366 case ResolveStatusBeingInferred:
367 zig_unreachable();
365 case ResolveStatusUnstarted:368 case ResolveStatusUnstarted:
366 return true;369 return true;
367 case ResolveStatusZeroBitsKnown:370 case ResolveStatusZeroBitsKnown:
...@@ -483,7 +486,7 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {...@@ -483,7 +486,7 @@ ZigType *get_fn_frame_type(CodeGen *g, ZigFn *fn) {
483ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,486ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_const,
484 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,487 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment,
485 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,488 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero,
486 uint32_t vector_index)489 uint32_t vector_index, InferredStructField *inferred_struct_field)
487{490{
488 assert(ptr_len != PtrLenC || allow_zero);491 assert(ptr_len != PtrLenC || allow_zero);
489 assert(!type_is_invalid(child_type));492 assert(!type_is_invalid(child_type));
...@@ -506,7 +509,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -506,7 +509,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
506 TypeId type_id = {};509 TypeId type_id = {};
507 ZigType **parent_pointer = nullptr;510 ZigType **parent_pointer = nullptr;
508 if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||511 if (host_int_bytes != 0 || is_volatile || byte_alignment != 0 || ptr_len != PtrLenSingle ||
509 allow_zero || vector_index != VECTOR_INDEX_NONE)512 allow_zero || vector_index != VECTOR_INDEX_NONE || inferred_struct_field != nullptr)
510 {513 {
511 type_id.id = ZigTypeIdPointer;514 type_id.id = ZigTypeIdPointer;
512 type_id.data.pointer.child_type = child_type;515 type_id.data.pointer.child_type = child_type;
...@@ -518,6 +521,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -518,6 +521,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
518 type_id.data.pointer.ptr_len = ptr_len;521 type_id.data.pointer.ptr_len = ptr_len;
519 type_id.data.pointer.allow_zero = allow_zero;522 type_id.data.pointer.allow_zero = allow_zero;
520 type_id.data.pointer.vector_index = vector_index;523 type_id.data.pointer.vector_index = vector_index;
524 type_id.data.pointer.inferred_struct_field = inferred_struct_field;
521525
522 auto existing_entry = g->type_table.maybe_get(type_id);526 auto existing_entry = g->type_table.maybe_get(type_id);
523 if (existing_entry)527 if (existing_entry)
...@@ -545,8 +549,15 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -545,8 +549,15 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
545 }549 }
546 buf_resize(&entry->name, 0);550 buf_resize(&entry->name, 0);
547 if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {551 if (host_int_bytes == 0 && byte_alignment == 0 && vector_index == VECTOR_INDEX_NONE) {
548 buf_appendf(&entry->name, "%s%s%s%s%s",552 if (inferred_struct_field == nullptr) {
549 star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));553 buf_appendf(&entry->name, "%s%s%s%s%s",
554 star_str, const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
555 } else {
556 buf_appendf(&entry->name, "(%s%s%s%s field '%s' of %s)",
557 star_str, const_str, volatile_str, allow_zero_str,
558 buf_ptr(inferred_struct_field->field_name),
559 buf_ptr(&inferred_struct_field->inferred_struct_type->name));
560 }
550 } else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {561 } else if (host_int_bytes == 0 && vector_index == VECTOR_INDEX_NONE) {
551 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,562 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s%s", star_str, byte_alignment,
552 const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));563 const_str, volatile_str, allow_zero_str, buf_ptr(&child_type->name));
...@@ -603,6 +614,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con...@@ -603,6 +614,7 @@ ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type, bool is_con
603 entry->data.pointer.host_int_bytes = host_int_bytes;614 entry->data.pointer.host_int_bytes = host_int_bytes;
604 entry->data.pointer.allow_zero = allow_zero;615 entry->data.pointer.allow_zero = allow_zero;
605 entry->data.pointer.vector_index = vector_index;616 entry->data.pointer.vector_index = vector_index;
617 entry->data.pointer.inferred_struct_field = inferred_struct_field;
606618
607 if (parent_pointer) {619 if (parent_pointer) {
608 *parent_pointer = entry;620 *parent_pointer = entry;
...@@ -617,12 +629,12 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons...@@ -617,12 +629,12 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type, bool is_cons
617 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)629 uint32_t bit_offset_in_host, uint32_t host_int_bytes, bool allow_zero)
618{630{
619 return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,631 return get_pointer_to_type_extra2(g, child_type, is_const, is_volatile, ptr_len,
620 byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE);632 byte_alignment, bit_offset_in_host, host_int_bytes, allow_zero, VECTOR_INDEX_NONE, nullptr);
621}633}
622634
623ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {635ZigType *get_pointer_to_type(CodeGen *g, ZigType *child_type, bool is_const) {
624 return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,636 return get_pointer_to_type_extra2(g, child_type, is_const, false, PtrLenSingle, 0, 0, 0, false,
625 VECTOR_INDEX_NONE);637 VECTOR_INDEX_NONE, nullptr);
626}638}
627639
628ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {640ZigType *get_optional_type(CodeGen *g, ZigType *child_type) {
...@@ -791,19 +803,19 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {...@@ -791,19 +803,19 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
791 entry->data.structure.is_slice = true;803 entry->data.structure.is_slice = true;
792 entry->data.structure.src_field_count = element_count;804 entry->data.structure.src_field_count = element_count;
793 entry->data.structure.gen_field_count = element_count;805 entry->data.structure.gen_field_count = element_count;
794 entry->data.structure.fields = allocate<TypeStructField>(element_count);806 entry->data.structure.fields = alloc_type_struct_fields(element_count);
795 entry->data.structure.fields_by_name.init(element_count);807 entry->data.structure.fields_by_name.init(element_count);
796 entry->data.structure.fields[slice_ptr_index].name = ptr_field_name;808 entry->data.structure.fields[slice_ptr_index]->name = ptr_field_name;
797 entry->data.structure.fields[slice_ptr_index].type_entry = ptr_type;809 entry->data.structure.fields[slice_ptr_index]->type_entry = ptr_type;
798 entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index;810 entry->data.structure.fields[slice_ptr_index]->src_index = slice_ptr_index;
799 entry->data.structure.fields[slice_ptr_index].gen_index = 0;811 entry->data.structure.fields[slice_ptr_index]->gen_index = 0;
800 entry->data.structure.fields[slice_len_index].name = len_field_name;812 entry->data.structure.fields[slice_len_index]->name = len_field_name;
801 entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize;813 entry->data.structure.fields[slice_len_index]->type_entry = g->builtin_types.entry_usize;
802 entry->data.structure.fields[slice_len_index].src_index = slice_len_index;814 entry->data.structure.fields[slice_len_index]->src_index = slice_len_index;
803 entry->data.structure.fields[slice_len_index].gen_index = 1;815 entry->data.structure.fields[slice_len_index]->gen_index = 1;
804816
805 entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]);817 entry->data.structure.fields_by_name.put(ptr_field_name, entry->data.structure.fields[slice_ptr_index]);
806 entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]);818 entry->data.structure.fields_by_name.put(len_field_name, entry->data.structure.fields[slice_len_index]);
807819
808 switch (type_requires_comptime(g, ptr_type)) {820 switch (type_requires_comptime(g, ptr_type)) {
809 case ReqCompTimeInvalid:821 case ReqCompTimeInvalid:
...@@ -816,8 +828,8 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {...@@ -816,8 +828,8 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type) {
816828
817 if (!type_has_bits(ptr_type)) {829 if (!type_has_bits(ptr_type)) {
818 entry->data.structure.gen_field_count = 1;830 entry->data.structure.gen_field_count = 1;
819 entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX;831 entry->data.structure.fields[slice_ptr_index]->gen_index = SIZE_MAX;
820 entry->data.structure.fields[slice_len_index].gen_index = 0;832 entry->data.structure.fields[slice_len_index]->gen_index = 0;
821 }833 }
822834
823 ZigType *child_type = ptr_type->data.pointer.child_type;835 ZigType *child_type = ptr_type->data.pointer.child_type;
...@@ -1449,8 +1461,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **...@@ -1449,8 +1461,8 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
1449 if (type_is_invalid(result_val->type))1461 if (type_is_invalid(result_val->type))
1450 return false;1462 return false;
14511463
1452 ConstExprValue *ptr_field = &result_val->data.x_struct.fields[slice_ptr_index];1464 ConstExprValue *ptr_field = result_val->data.x_struct.fields[slice_ptr_index];
1453 ConstExprValue *len_field = &result_val->data.x_struct.fields[slice_len_index];1465 ConstExprValue *len_field = result_val->data.x_struct.fields[slice_len_index];
14541466
1455 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);1467 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
1456 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;1468 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
...@@ -1972,12 +1984,12 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel...@@ -1972,12 +1984,12 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
1972 struct_type->data.structure.src_field_count = field_count;1984 struct_type->data.structure.src_field_count = field_count;
1973 struct_type->data.structure.gen_field_count = 0;1985 struct_type->data.structure.gen_field_count = 0;
1974 struct_type->data.structure.resolve_status = ResolveStatusSizeKnown;1986 struct_type->data.structure.resolve_status = ResolveStatusSizeKnown;
1975 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);1987 struct_type->data.structure.fields = alloc_type_struct_fields(field_count);
1976 struct_type->data.structure.fields_by_name.init(field_count);1988 struct_type->data.structure.fields_by_name.init(field_count);
19771989
1978 size_t abi_align = min_abi_align;1990 size_t abi_align = min_abi_align;
1979 for (size_t i = 0; i < field_count; i += 1) {1991 for (size_t i = 0; i < field_count; i += 1) {
1980 TypeStructField *field = &struct_type->data.structure.fields[i];1992 TypeStructField *field = struct_type->data.structure.fields[i];
1981 field->name = buf_create_from_str(fields[i].name);1993 field->name = buf_create_from_str(fields[i].name);
1982 field->type_entry = fields[i].ty;1994 field->type_entry = fields[i].ty;
1983 field->src_index = i;1995 field->src_index = i;
...@@ -1997,7 +2009,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel...@@ -1997,7 +2009,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
19972009
1998 size_t next_offset = 0;2010 size_t next_offset = 0;
1999 for (size_t i = 0; i < field_count; i += 1) {2011 for (size_t i = 0; i < field_count; i += 1) {
2000 TypeStructField *field = &struct_type->data.structure.fields[i];2012 TypeStructField *field = struct_type->data.structure.fields[i];
2001 if (!type_has_bits(field->type_entry))2013 if (!type_has_bits(field->type_entry))
2002 continue;2014 continue;
20032015
...@@ -2006,7 +2018,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel...@@ -2006,7 +2018,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
2006 // find the next non-zero-byte field for offset calculations2018 // find the next non-zero-byte field for offset calculations
2007 size_t next_src_field_index = i + 1;2019 size_t next_src_field_index = i + 1;
2008 for (; next_src_field_index < field_count; next_src_field_index += 1) {2020 for (; next_src_field_index < field_count; next_src_field_index += 1) {
2009 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))2021 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
2010 break;2022 break;
2011 }2023 }
2012 size_t next_abi_align;2024 size_t next_abi_align;
...@@ -2014,7 +2026,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel...@@ -2014,7 +2026,7 @@ static ZigType *get_struct_type(CodeGen *g, const char *type_name, SrcField fiel
2014 next_abi_align = abi_align;2026 next_abi_align = abi_align;
2015 } else {2027 } else {
2016 next_abi_align = max(fields[next_src_field_index].align,2028 next_abi_align = max(fields[next_src_field_index].align,
2017 struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align);2029 struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align);
2018 }2030 }
2019 next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);2031 next_offset = next_field_offset(next_offset, abi_align, field->type_entry->abi_size, next_abi_align);
2020 }2032 }
...@@ -2079,7 +2091,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2079,7 +2091,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2079 }2091 }
20802092
2081 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);2093 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
2082 assert(decl_node->type == NodeTypeContainerDecl);2094 assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
20832095
2084 size_t field_count = struct_type->data.structure.src_field_count;2096 size_t field_count = struct_type->data.structure.src_field_count;
20852097
...@@ -2097,7 +2109,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2097,7 +2109,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
20972109
2098 // Calculate offsets2110 // Calculate offsets
2099 for (size_t i = 0; i < field_count; i += 1) {2111 for (size_t i = 0; i < field_count; i += 1) {
2100 TypeStructField *field = &struct_type->data.structure.fields[i];2112 TypeStructField *field = struct_type->data.structure.fields[i];
2101 if (field->gen_index == SIZE_MAX)2113 if (field->gen_index == SIZE_MAX)
2102 continue;2114 continue;
21032115
...@@ -2166,12 +2178,12 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2166,12 +2178,12 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
2166 gen_field_index += 1;2178 gen_field_index += 1;
2167 size_t next_src_field_index = i + 1;2179 size_t next_src_field_index = i + 1;
2168 for (; next_src_field_index < field_count; next_src_field_index += 1) {2180 for (; next_src_field_index < field_count; next_src_field_index += 1) {
2169 if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) {2181 if (struct_type->data.structure.fields[next_src_field_index]->gen_index != SIZE_MAX) {
2170 break;2182 break;
2171 }2183 }
2172 }2184 }
2173 size_t next_align = (next_src_field_index == field_count) ?2185 size_t next_align = (next_src_field_index == field_count) ?
2174 abi_align : struct_type->data.structure.fields[next_src_field_index].align;2186 abi_align : struct_type->data.structure.fields[next_src_field_index]->align;
2175 next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align);2187 next_offset = next_field_offset(next_offset, abi_align, field_abi_size, next_align);
2176 size_in_bits = next_offset * 8;2188 size_in_bits = next_offset * 8;
2177 }2189 }
...@@ -2194,7 +2206,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {...@@ -2194,7 +2206,7 @@ static Error resolve_struct_type(CodeGen *g, ZigType *struct_type) {
21942206
2195 // Resolve types for fields2207 // Resolve types for fields
2196 for (size_t i = 0; i < field_count; i += 1) {2208 for (size_t i = 0; i < field_count; i += 1) {
2197 TypeStructField *field = &struct_type->data.structure.fields[i];2209 TypeStructField *field = struct_type->data.structure.fields[i];
2198 ZigType *field_type = resolve_struct_field_type(g, field);2210 ZigType *field_type = resolve_struct_field_type(g, field);
2199 if (field_type == nullptr) {2211 if (field_type == nullptr) {
2200 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2212 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
...@@ -2667,7 +2679,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2667,7 +2679,6 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2667 return ErrorNone;2679 return ErrorNone;
26682680
2669 AstNode *decl_node = struct_type->data.structure.decl_node;2681 AstNode *decl_node = struct_type->data.structure.decl_node;
2670 assert(decl_node->type == NodeTypeContainerDecl);
26712682
2672 if (struct_type->data.structure.resolve_loop_flag_zero_bits) {2683 if (struct_type->data.structure.resolve_loop_flag_zero_bits) {
2673 if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {2684 if (struct_type->data.structure.resolve_status != ResolveStatusInvalid) {
...@@ -2678,29 +2689,46 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2678,29 +2689,46 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2678 }2689 }
2679 return ErrorSemanticAnalyzeFail;2690 return ErrorSemanticAnalyzeFail;
2680 }2691 }
2681
2682 struct_type->data.structure.resolve_loop_flag_zero_bits = true;2692 struct_type->data.structure.resolve_loop_flag_zero_bits = true;
26832693
2684 assert(!struct_type->data.structure.fields);2694 size_t field_count;
2685 size_t field_count = decl_node->data.container_decl.fields.length;2695 if (decl_node->type == NodeTypeContainerDecl) {
2686 struct_type->data.structure.src_field_count = (uint32_t)field_count;2696 field_count = decl_node->data.container_decl.fields.length;
2687 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);2697 struct_type->data.structure.src_field_count = (uint32_t)field_count;
2698
2699 src_assert(struct_type->data.structure.fields == nullptr, decl_node);
2700 struct_type->data.structure.fields = alloc_type_struct_fields(field_count);
2701 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2702 src_assert(struct_type->data.structure.is_inferred, decl_node);
2703 src_assert(struct_type->data.structure.fields != nullptr, decl_node);
2704
2705 field_count = struct_type->data.structure.src_field_count;
2706 } else zig_unreachable();
2707
2688 struct_type->data.structure.fields_by_name.init(field_count);2708 struct_type->data.structure.fields_by_name.init(field_count);
26892709
2690 Scope *scope = &struct_type->data.structure.decls_scope->base;2710 Scope *scope = &struct_type->data.structure.decls_scope->base;
26912711
2692 size_t gen_field_index = 0;2712 size_t gen_field_index = 0;
2693 for (size_t i = 0; i < field_count; i += 1) {2713 for (size_t i = 0; i < field_count; i += 1) {
2694 AstNode *field_node = decl_node->data.container_decl.fields.at(i);2714 TypeStructField *type_struct_field = struct_type->data.structure.fields[i];
2695 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
2696 type_struct_field->name = field_node->data.struct_field.name;
2697 type_struct_field->decl_node = field_node;
26982715
2699 if (field_node->data.struct_field.type == nullptr) {2716 AstNode *field_node;
2700 add_node_error(g, field_node, buf_sprintf("struct field missing type"));2717 if (decl_node->type == NodeTypeContainerDecl) {
2701 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2718 field_node = decl_node->data.container_decl.fields.at(i);
2702 return ErrorSemanticAnalyzeFail;2719 type_struct_field->name = field_node->data.struct_field.name;
2703 }2720 type_struct_field->decl_node = field_node;
2721
2722 if (field_node->data.struct_field.type == nullptr) {
2723 add_node_error(g, field_node, buf_sprintf("struct field missing type"));
2724 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2725 return ErrorSemanticAnalyzeFail;
2726 }
2727 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2728 field_node = type_struct_field->decl_node;
2729
2730 src_assert(type_struct_field->type_entry != nullptr, field_node);
2731 } else zig_unreachable();
27042732
2705 auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);2733 auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field);
2706 if (field_entry != nullptr) {2734 if (field_entry != nullptr) {
...@@ -2711,16 +2739,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {...@@ -2711,16 +2739,21 @@ static Error resolve_struct_zero_bits(CodeGen *g, ZigType *struct_type) {
2711 return ErrorSemanticAnalyzeFail;2739 return ErrorSemanticAnalyzeFail;
2712 }2740 }
27132741
2714 ConstExprValue *field_type_val = analyze_const_value(g, scope,2742 ConstExprValue *field_type_val;
2715 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);2743 if (decl_node->type == NodeTypeContainerDecl) {
2716 if (type_is_invalid(field_type_val->type)) {2744 field_type_val = analyze_const_value(g, scope,
2717 struct_type->data.structure.resolve_status = ResolveStatusInvalid;2745 field_node->data.struct_field.type, g->builtin_types.entry_type, nullptr, LazyOkNoUndef);
2718 return ErrorSemanticAnalyzeFail;2746 if (type_is_invalid(field_type_val->type)) {
2719 }2747 struct_type->data.structure.resolve_status = ResolveStatusInvalid;
2720 assert(field_type_val->special != ConstValSpecialRuntime);2748 return ErrorSemanticAnalyzeFail;
2721 type_struct_field->type_val = field_type_val;2749 }
2722 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)2750 assert(field_type_val->special != ConstValSpecialRuntime);
2723 return ErrorSemanticAnalyzeFail;2751 type_struct_field->type_val = field_type_val;
2752 if (struct_type->data.structure.resolve_status == ResolveStatusInvalid)
2753 return ErrorSemanticAnalyzeFail;
2754 } else if (decl_node->type == NodeTypeContainerInitExpr) {
2755 field_type_val = type_struct_field->type_val;
2756 } else zig_unreachable();
27242757
2725 bool field_is_opaque_type;2758 bool field_is_opaque_type;
2726 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {2759 if ((err = type_val_resolve_is_opaque_type(g, field_type_val, &field_is_opaque_type))) {
...@@ -2804,17 +2837,18 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {...@@ -2804,17 +2837,18 @@ static Error resolve_struct_alignment(CodeGen *g, ZigType *struct_type) {
2804 }2837 }
28052838
2806 struct_type->data.structure.resolve_loop_flag_other = true;2839 struct_type->data.structure.resolve_loop_flag_other = true;
2807 assert(decl_node->type == NodeTypeContainerDecl);2840 assert(decl_node->type == NodeTypeContainerDecl || decl_node->type == NodeTypeContainerInitExpr);
28082841
2809 size_t field_count = struct_type->data.structure.src_field_count;2842 size_t field_count = struct_type->data.structure.src_field_count;
2810 bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;2843 bool packed = struct_type->data.structure.layout == ContainerLayoutPacked;
28112844
2812 for (size_t i = 0; i < field_count; i += 1) {2845 for (size_t i = 0; i < field_count; i += 1) {
2813 TypeStructField *field = &struct_type->data.structure.fields[i];2846 TypeStructField *field = struct_type->data.structure.fields[i];
2814 if (field->gen_index == SIZE_MAX)2847 if (field->gen_index == SIZE_MAX)
2815 continue;2848 continue;
28162849
2817 AstNode *align_expr = field->decl_node->data.struct_field.align_expr;2850 AstNode *align_expr = (field->decl_node->type == NodeTypeStructField) ?
2851 field->decl_node->data.struct_field.align_expr : nullptr;
2818 if (align_expr != nullptr) {2852 if (align_expr != nullptr) {
2819 if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,2853 if (!analyze_const_align(g, &struct_type->data.structure.decls_scope->base, align_expr,
2820 &field->align))2854 &field->align))
...@@ -5249,7 +5283,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {...@@ -5249,7 +5283,7 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
5249 zig_unreachable();5283 zig_unreachable();
5250 case ZigTypeIdStruct:5284 case ZigTypeIdStruct:
5251 for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {5285 for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) {
5252 if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i]))5286 if (can_mutate_comptime_var_state(value->data.x_struct.fields[i]))
5253 return true;5287 return true;
5254 }5288 }
5255 return false;5289 return false;
...@@ -5398,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {...@@ -5398,7 +5432,7 @@ bool fn_eval_eql(Scope *a, Scope *b) {
5398 return false;5432 return false;
5399}5433}
54005434
5401// Whether the type has bits at runtime.5435// Deprecated. Use type_has_bits2.
5402bool type_has_bits(ZigType *type_entry) {5436bool type_has_bits(ZigType *type_entry) {
5403 assert(type_entry != nullptr);5437 assert(type_entry != nullptr);
5404 assert(!type_is_invalid(type_entry));5438 assert(!type_is_invalid(type_entry));
...@@ -5406,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {...@@ -5406,6 +5440,27 @@ bool type_has_bits(ZigType *type_entry) {
5406 return type_entry->abi_size != 0;5440 return type_entry->abi_size != 0;
5407}5441}
54085442
5443// Whether the type has bits at runtime.
5444Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result) {
5445 Error err;
5446
5447 if (type_is_invalid(type_entry))
5448 return ErrorSemanticAnalyzeFail;
5449
5450 if (type_entry->id == ZigTypeIdStruct &&
5451 type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
5452 {
5453 *result = true;
5454 return ErrorNone;
5455 }
5456
5457 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5458 return err;
5459
5460 *result = type_entry->abi_size != 0;
5461 return ErrorNone;
5462}
5463
5409// Whether you can infer the value based solely on the type.5464// Whether you can infer the value based solely on the type.
5410OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {5465OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5411 assert(type_entry != nullptr);5466 assert(type_entry != nullptr);
...@@ -5413,6 +5468,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -5413,6 +5468,12 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5413 if (type_entry->one_possible_value != OnePossibleValueInvalid)5468 if (type_entry->one_possible_value != OnePossibleValueInvalid)
5414 return type_entry->one_possible_value;5469 return type_entry->one_possible_value;
54155470
5471 if (type_entry->id == ZigTypeIdStruct &&
5472 type_entry->data.structure.resolve_status == ResolveStatusBeingInferred)
5473 {
5474 return OnePossibleValueNo;
5475 }
5476
5416 Error err;5477 Error err;
5417 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))5478 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
5418 return OnePossibleValueInvalid;5479 return OnePossibleValueInvalid;
...@@ -5445,7 +5506,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {...@@ -5445,7 +5506,7 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
5445 return type_has_one_possible_value(g, type_entry->data.array.child_type);5506 return type_has_one_possible_value(g, type_entry->data.array.child_type);
5446 case ZigTypeIdStruct:5507 case ZigTypeIdStruct:
5447 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {5508 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
5448 TypeStructField *field = &type_entry->data.structure.fields[i];5509 TypeStructField *field = type_entry->data.structure.fields[i];
5449 OnePossibleValue opv = (field->type_entry != nullptr) ?5510 OnePossibleValue opv = (field->type_entry != nullptr) ?
5450 type_has_one_possible_value(g, field->type_entry) :5511 type_has_one_possible_value(g, field->type_entry) :
5451 type_val_resolve_has_one_possible_value(g, field->type_val);5512 type_val_resolve_has_one_possible_value(g, field->type_val);
...@@ -5737,11 +5798,11 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr...@@ -5737,11 +5798,11 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
57375798
5738 const_val->special = ConstValSpecialStatic;5799 const_val->special = ConstValSpecialStatic;
5739 const_val->type = get_slice_type(g, ptr_type);5800 const_val->type = get_slice_type(g, ptr_type);
5740 const_val->data.x_struct.fields = create_const_vals(2);5801 const_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
57415802
5742 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,5803 init_const_ptr_array(g, const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
5743 PtrLenUnknown);5804 PtrLenUnknown);
5744 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);5805 init_const_usize(g, const_val->data.x_struct.fields[slice_len_index], len);
5745}5806}
57465807
5747ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {5808ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) {
...@@ -5825,6 +5886,38 @@ ConstExprValue *create_const_vals(size_t count) {...@@ -5825,6 +5886,38 @@ ConstExprValue *create_const_vals(size_t count) {
5825 return vals;5886 return vals;
5826}5887}
58275888
5889ConstExprValue **alloc_const_vals_ptrs(size_t count) {
5890 return realloc_const_vals_ptrs(nullptr, 0, count);
5891}
5892
5893ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count) {
5894 assert(new_count >= old_count);
5895
5896 size_t new_item_count = new_count - old_count;
5897 ConstExprValue **result = reallocate(ptr, old_count, new_count, "ConstExprValue*");
5898 ConstExprValue *vals = create_const_vals(new_item_count);
5899 for (size_t i = old_count; i < new_count; i += 1) {
5900 result[i] = &vals[i - old_count];
5901 }
5902 return result;
5903}
5904
5905TypeStructField **alloc_type_struct_fields(size_t count) {
5906 return realloc_type_struct_fields(nullptr, 0, count);
5907}
5908
5909TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count) {
5910 assert(new_count >= old_count);
5911
5912 size_t new_item_count = new_count - old_count;
5913 TypeStructField **result = reallocate(ptr, old_count, new_count, "TypeStructField*");
5914 TypeStructField *vals = allocate<TypeStructField>(new_item_count, "TypeStructField");
5915 for (size_t i = old_count; i < new_count; i += 1) {
5916 result[i] = &vals[i - old_count];
5917 }
5918 return result;
5919}
5920
5828static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {5921static ZigType *get_async_fn_type(CodeGen *g, ZigType *orig_fn_type) {
5829 if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)5922 if (orig_fn_type->data.fn.fn_type_id.cc == CallingConventionAsync)
5830 return orig_fn_type;5923 return orig_fn_type;
...@@ -6132,6 +6225,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {...@@ -6132,6 +6225,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
6132 continue;6225 continue;
6133 if (instruction->ref_count == 0)6226 if (instruction->ref_count == 0)
6134 continue;6227 continue;
6228 if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown)))
6229 return ErrorSemanticAnalyzeFail;
6135 if (!type_has_bits(instruction->value.type))6230 if (!type_has_bits(instruction->value.type))
6136 continue;6231 continue;
6137 if (scope_needs_spill(instruction->scope)) {6232 if (scope_needs_spill(instruction->scope)) {
...@@ -6271,6 +6366,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {...@@ -6271,6 +6366,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
6271 switch (status) {6366 switch (status) {
6272 case ResolveStatusUnstarted:6367 case ResolveStatusUnstarted:
6273 return ErrorNone;6368 return ErrorNone;
6369 case ResolveStatusBeingInferred:
6370 zig_unreachable();
6274 case ResolveStatusInvalid:6371 case ResolveStatusInvalid:
6275 zig_unreachable();6372 zig_unreachable();
6276 case ResolveStatusZeroBitsKnown:6373 case ResolveStatusZeroBitsKnown:
...@@ -6502,8 +6599,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {...@@ -6502,8 +6599,8 @@ bool const_values_equal(CodeGen *g, ConstExprValue *a, ConstExprValue *b) {
6502 }6599 }
6503 case ZigTypeIdStruct:6600 case ZigTypeIdStruct:
6504 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {6601 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
6505 ConstExprValue *field_a = &a->data.x_struct.fields[i];6602 ConstExprValue *field_a = a->data.x_struct.fields[i];
6506 ConstExprValue *field_b = &b->data.x_struct.fields[i];6603 ConstExprValue *field_b = b->data.x_struct.fields[i];
6507 if (!const_values_equal(g, field_a, field_b))6604 if (!const_values_equal(g, field_a, field_b))
6508 return false;6605 return false;
6509 }6606 }
...@@ -6811,10 +6908,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -6811,10 +6908,10 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
6811 case ZigTypeIdStruct:6908 case ZigTypeIdStruct:
6812 {6909 {
6813 if (is_slice(type_entry)) {6910 if (is_slice(type_entry)) {
6814 ConstExprValue *len_val = &const_val->data.x_struct.fields[slice_len_index];6911 ConstExprValue *len_val = const_val->data.x_struct.fields[slice_len_index];
6815 size_t len = bigint_as_usize(&len_val->data.x_bigint);6912 size_t len = bigint_as_usize(&len_val->data.x_bigint);
68166913
6817 ConstExprValue *ptr_val = &const_val->data.x_struct.fields[slice_ptr_index];6914 ConstExprValue *ptr_val = const_val->data.x_struct.fields[slice_ptr_index];
6818 if (ptr_val->special == ConstValSpecialUndef) {6915 if (ptr_val->special == ConstValSpecialUndef) {
6819 assert(len == 0);6916 assert(len == 0);
6820 buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name));6917 buf_appendf(buf, "((%s)(undefined))[0..0]", buf_ptr(&type_entry->name));
...@@ -6995,7 +7092,16 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -6995,7 +7092,16 @@ bool type_id_eql(TypeId a, TypeId b) {
6995 a.data.pointer.alignment == b.data.pointer.alignment &&7092 a.data.pointer.alignment == b.data.pointer.alignment &&
6996 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&7093 a.data.pointer.bit_offset_in_host == b.data.pointer.bit_offset_in_host &&
6997 a.data.pointer.vector_index == b.data.pointer.vector_index &&7094 a.data.pointer.vector_index == b.data.pointer.vector_index &&
6998 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes;7095 a.data.pointer.host_int_bytes == b.data.pointer.host_int_bytes &&
7096 (
7097 a.data.pointer.inferred_struct_field == b.data.pointer.inferred_struct_field ||
7098 (a.data.pointer.inferred_struct_field != nullptr &&
7099 b.data.pointer.inferred_struct_field != nullptr &&
7100 a.data.pointer.inferred_struct_field->inferred_struct_type ==
7101 b.data.pointer.inferred_struct_field->inferred_struct_type &&
7102 buf_eql_buf(a.data.pointer.inferred_struct_field->field_name,
7103 b.data.pointer.inferred_struct_field->field_name))
7104 );
6999 case ZigTypeIdArray:7105 case ZigTypeIdArray:
7000 return a.data.array.child_type == b.data.array.child_type &&7106 return a.data.array.child_type == b.data.array.child_type &&
7001 a.data.array.size == b.data.array.size;7107 a.data.array.size == b.data.array.size;
...@@ -7082,10 +7188,10 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {...@@ -7082,10 +7188,10 @@ static void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
70827188
7083 const_val->special = ConstValSpecialStatic;7189 const_val->special = ConstValSpecialStatic;
7084 size_t field_count = wanted_type->data.structure.src_field_count;7190 size_t field_count = wanted_type->data.structure.src_field_count;
7085 const_val->data.x_struct.fields = create_const_vals(field_count);7191 const_val->data.x_struct.fields = alloc_const_vals_ptrs(field_count);
7086 for (size_t i = 0; i < field_count; i += 1) {7192 for (size_t i = 0; i < field_count; i += 1) {
7087 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];7193 ConstExprValue *field_val = const_val->data.x_struct.fields[i];
7088 field_val->type = wanted_type->data.structure.fields[i].type_entry;7194 field_val->type = resolve_struct_field_type(g, wanted_type->data.structure.fields[i]);
7089 assert(field_val->type);7195 assert(field_val->type);
7090 init_const_undefined(g, field_val);7196 init_const_undefined(g, field_val);
7091 field_val->parent.id = ConstParentIdStruct;7197 field_val->parent.id = ConstParentIdStruct;
...@@ -7517,7 +7623,7 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size...@@ -7517,7 +7623,7 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size
7517 }7623 }
7518 X64CABIClass working_class = X64CABIClass_Unknown;7624 X64CABIClass working_class = X64CABIClass_Unknown;
7519 for (uint32_t i = 0; i < ty->data.structure.src_field_count; i += 1) {7625 for (uint32_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
7520 X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields->type_entry);7626 X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields[0]->type_entry);
7521 if (field_class == X64CABIClass_Unknown)7627 if (field_class == X64CABIClass_Unknown)
7522 return X64CABIClass_Unknown;7628 return X64CABIClass_Unknown;
7523 if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) {7629 if (i == 0 || field_class == X64CABIClass_MEMORY || working_class == X64CABIClass_SSE) {
...@@ -7649,7 +7755,7 @@ Buf *type_h_name(ZigType *t) {...@@ -7649,7 +7755,7 @@ Buf *type_h_name(ZigType *t) {
7649static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {7755static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7650 if (type->data.structure.resolve_status >= wanted_resolve_status) return;7756 if (type->data.structure.resolve_status >= wanted_resolve_status) return;
76517757
7652 ZigType *ptr_type = type->data.structure.fields[slice_ptr_index].type_entry;7758 ZigType *ptr_type = type->data.structure.fields[slice_ptr_index]->type_entry;
7653 ZigType *child_type = ptr_type->data.pointer.child_type;7759 ZigType *child_type = ptr_type->data.pointer.child_type;
7654 ZigType *usize_type = g->builtin_types.entry_usize;7760 ZigType *usize_type = g->builtin_types.entry_usize;
76557761
...@@ -7671,7 +7777,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa...@@ -7671,7 +7777,7 @@ static void resolve_llvm_types_slice(CodeGen *g, ZigType *type, ResolveStatus wa
7671 // If the child type is []const T then we need to make sure the type ref7777 // If the child type is []const T then we need to make sure the type ref
7672 // and debug info is the same as if the child type were []T.7778 // and debug info is the same as if the child type were []T.
7673 if (is_slice(child_type)) {7779 if (is_slice(child_type)) {
7674 ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry;7780 ZigType *child_ptr_type = child_type->data.structure.fields[slice_ptr_index]->type_entry;
7675 assert(child_ptr_type->id == ZigTypeIdPointer);7781 assert(child_ptr_type->id == ZigTypeIdPointer);
7676 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||7782 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile ||
7677 child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)7783 child_ptr_type->data.pointer.explicit_alignment != 0 || child_ptr_type->data.pointer.allow_zero)
...@@ -7808,7 +7914,6 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7808,7 +7914,6 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7808 ZigLLVMDIScope *di_scope;7914 ZigLLVMDIScope *di_scope;
7809 unsigned line;7915 unsigned line;
7810 if (decl_node != nullptr) {7916 if (decl_node != nullptr) {
7811 assert(decl_node->type == NodeTypeContainerDecl);
7812 Scope *scope = &struct_type->data.structure.decls_scope->base;7917 Scope *scope = &struct_type->data.structure.decls_scope->base;
7813 ZigType *import = get_scope_import(scope);7918 ZigType *import = get_scope_import(scope);
7814 di_file = import->data.structure.root_struct->di_file;7919 di_file = import->data.structure.root_struct->di_file;
...@@ -7849,7 +7954,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7849,7 +7954,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
78497954
7850 // trigger all the recursive get_llvm_type calls7955 // trigger all the recursive get_llvm_type calls
7851 for (size_t i = 0; i < field_count; i += 1) {7956 for (size_t i = 0; i < field_count; i += 1) {
7852 TypeStructField *field = &struct_type->data.structure.fields[i];7957 TypeStructField *field = struct_type->data.structure.fields[i];
7853 ZigType *field_type = field->type_entry;7958 ZigType *field_type = field->type_entry;
7854 if (!type_has_bits(field_type))7959 if (!type_has_bits(field_type))
7855 continue;7960 continue;
...@@ -7863,7 +7968,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7863,7 +7968,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7863 // inserting padding bytes where LLVM would do it automatically.7968 // inserting padding bytes where LLVM would do it automatically.
7864 size_t llvm_struct_abi_align = 0;7969 size_t llvm_struct_abi_align = 0;
7865 for (size_t i = 0; i < field_count; i += 1) {7970 for (size_t i = 0; i < field_count; i += 1) {
7866 ZigType *field_type = struct_type->data.structure.fields[i].type_entry;7971 ZigType *field_type = struct_type->data.structure.fields[i]->type_entry;
7867 if (!type_has_bits(field_type))7972 if (!type_has_bits(field_type))
7868 continue;7973 continue;
7869 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);7974 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
...@@ -7872,7 +7977,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7872,7 +7977,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7872 }7977 }
78737978
7874 for (size_t i = 0; i < field_count; i += 1) {7979 for (size_t i = 0; i < field_count; i += 1) {
7875 TypeStructField *field = &struct_type->data.structure.fields[i];7980 TypeStructField *field = struct_type->data.structure.fields[i];
7876 ZigType *field_type = field->type_entry;7981 ZigType *field_type = field->type_entry;
78777982
7878 if (!type_has_bits(field_type)) {7983 if (!type_has_bits(field_type)) {
...@@ -7922,23 +8027,23 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7922,23 +8027,23 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7922 // find the next non-zero-byte field for offset calculations8027 // find the next non-zero-byte field for offset calculations
7923 size_t next_src_field_index = i + 1;8028 size_t next_src_field_index = i + 1;
7924 for (; next_src_field_index < field_count; next_src_field_index += 1) {8029 for (; next_src_field_index < field_count; next_src_field_index += 1) {
7925 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))8030 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index]->type_entry))
7926 break;8031 break;
7927 }8032 }
7928 size_t next_abi_align;8033 size_t next_abi_align;
7929 if (next_src_field_index == field_count) {8034 if (next_src_field_index == field_count) {
7930 next_abi_align = struct_type->abi_align;8035 next_abi_align = struct_type->abi_align;
7931 } else {8036 } else {
7932 if (struct_type->data.structure.fields[next_src_field_index].align == 0) {8037 if (struct_type->data.structure.fields[next_src_field_index]->align == 0) {
7933 next_abi_align = struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;8038 next_abi_align = struct_type->data.structure.fields[next_src_field_index]->type_entry->abi_align;
7934 } else {8039 } else {
7935 next_abi_align = struct_type->data.structure.fields[next_src_field_index].align;8040 next_abi_align = struct_type->data.structure.fields[next_src_field_index]->align;
7936 }8041 }
7937 }8042 }
7938 size_t llvm_next_abi_align = (next_src_field_index == field_count) ?8043 size_t llvm_next_abi_align = (next_src_field_index == field_count) ?
7939 llvm_struct_abi_align :8044 llvm_struct_abi_align :
7940 LLVMABIAlignmentOfType(g->target_data_ref,8045 LLVMABIAlignmentOfType(g->target_data_ref,
7941 get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry));8046 get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index]->type_entry));
79428047
7943 size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,8048 size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,
7944 field_type->abi_size, next_abi_align);8049 field_type->abi_size, next_abi_align);
...@@ -7977,7 +8082,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -7977,7 +8082,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
7977 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);8082 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
7978 size_t debug_field_index = 0;8083 size_t debug_field_index = 0;
7979 for (size_t i = 0; i < field_count; i += 1) {8084 for (size_t i = 0; i < field_count; i += 1) {
7980 TypeStructField *field = &struct_type->data.structure.fields[i];8085 TypeStructField *field = struct_type->data.structure.fields[i];
7981 size_t gen_field_index = field->gen_index;8086 size_t gen_field_index = field->gen_index;
7982 if (gen_field_index == SIZE_MAX) {8087 if (gen_field_index == SIZE_MAX) {
7983 continue;8088 continue;
...@@ -8011,7 +8116,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -8011,7 +8116,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
8011 }8116 }
8012 unsigned line;8117 unsigned line;
8013 if (decl_node != nullptr) {8118 if (decl_node != nullptr) {
8014 AstNode *field_node = decl_node->data.container_decl.fields.at(i);8119 AstNode *field_node = field->decl_node;
8015 line = field_node->line + 1;8120 line = field_node->line + 1;
8016 } else {8121 } else {
8017 line = 0;8122 line = 0;
...@@ -8307,12 +8412,12 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus...@@ -8307,12 +8412,12 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus
8307 if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {8412 if (type->data.pointer.vector_index == VECTOR_INDEX_NONE) {
8308 peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,8413 peer_type = get_pointer_to_type_extra2(g, elem_type, false, false,
8309 PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,8414 PtrLenSingle, 0, 0, type->data.pointer.host_int_bytes, false,
8310 VECTOR_INDEX_NONE);8415 VECTOR_INDEX_NONE, nullptr);
8311 } else {8416 } else {
8312 uint32_t host_vec_len = type->data.pointer.host_int_bytes;8417 uint32_t host_vec_len = type->data.pointer.host_int_bytes;
8313 ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);8418 ZigType *host_vec_type = get_vector_type(g, host_vec_len, elem_type);
8314 peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,8419 peer_type = get_pointer_to_type_extra2(g, host_vec_type, false, false,
8315 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE);8420 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr);
8316 }8421 }
8317 type->llvm_type = get_llvm_type(g, peer_type);8422 type->llvm_type = get_llvm_type(g, peer_type);
8318 type->llvm_di_type = get_llvm_di_type(g, peer_type);8423 type->llvm_di_type = get_llvm_di_type(g, peer_type);
...@@ -9038,4 +9143,3 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,...@@ -9038,4 +9143,3 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
9038 *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);9143 *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
9039 return ErrorNone;9144 return ErrorNone;
9040}9145}
9041
src/analyze.hpp+8-1
...@@ -24,7 +24,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,...@@ -24,7 +24,7 @@ ZigType *get_pointer_to_type_extra(CodeGen *g, ZigType *child_type,
24ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,24ZigType *get_pointer_to_type_extra2(CodeGen *g, ZigType *child_type,
25 bool is_const, bool is_volatile, PtrLen ptr_len,25 bool is_const, bool is_volatile, PtrLen ptr_len,
26 uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,26 uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count,
27 bool allow_zero, uint32_t vector_index);27 bool allow_zero, uint32_t vector_index, InferredStructField *inferred_struct_field);
28uint64_t type_size(CodeGen *g, ZigType *type_entry);28uint64_t type_size(CodeGen *g, ZigType *type_entry);
29uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);29uint64_t type_size_bits(CodeGen *g, ZigType *type_entry);
30ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);30ZigType *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
...@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);...@@ -46,6 +46,8 @@ ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
46bool handle_is_ptr(ZigType *type_entry);46bool handle_is_ptr(ZigType *type_entry);
4747
48bool type_has_bits(ZigType *type_entry);48bool type_has_bits(ZigType *type_entry);
49Error type_has_bits2(CodeGen *g, ZigType *type_entry, bool *result);
50
49Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);51Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result);
50bool ptr_allows_addr_zero(ZigType *ptr_type);52bool ptr_allows_addr_zero(ZigType *ptr_type);
51bool type_is_nonnull_ptr(ZigType *type);53bool type_is_nonnull_ptr(ZigType *type);
...@@ -175,6 +177,11 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde...@@ -175,6 +177,11 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
175ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);177ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
176178
177ConstExprValue *create_const_vals(size_t count);179ConstExprValue *create_const_vals(size_t count);
180ConstExprValue **alloc_const_vals_ptrs(size_t count);
181ConstExprValue **realloc_const_vals_ptrs(ConstExprValue **ptr, size_t old_count, size_t new_count);
182
183TypeStructField **alloc_type_struct_fields(size_t count);
184TypeStructField **realloc_type_struct_fields(TypeStructField **ptr, size_t old_count, size_t new_count);
178185
179ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);186ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
180void expand_undef_array(CodeGen *g, ConstExprValue *const_val);187void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
src/ast_render.cpp+17-5
...@@ -821,7 +821,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -821,7 +821,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
821 break;821 break;
822 }822 }
823 case NodeTypeContainerInitExpr:823 case NodeTypeContainerInitExpr:
824 render_node_ungrouped(ar, node->data.container_init_expr.type);824 if (node->data.container_init_expr.type != nullptr) {
825 render_node_ungrouped(ar, node->data.container_init_expr.type);
826 }
825 if (node->data.container_init_expr.kind == ContainerInitKindStruct) {827 if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
826 fprintf(ar->f, "{\n");828 fprintf(ar->f, "{\n");
827 ar->indent += ar->indent_size;829 ar->indent += ar->indent_size;
...@@ -1137,10 +1139,20 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1137,10 +1139,20 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
11371139
1138 for (size_t i = 0; i < node->data.err_set_decl.decls.length; i += 1) {1140 for (size_t i = 0; i < node->data.err_set_decl.decls.length; i += 1) {
1139 AstNode *field_node = node->data.err_set_decl.decls.at(i);1141 AstNode *field_node = node->data.err_set_decl.decls.at(i);
1140 assert(field_node->type == NodeTypeSymbol);1142 switch (field_node->type) {
1141 print_indent(ar);1143 case NodeTypeSymbol:
1142 print_symbol(ar, field_node->data.symbol_expr.symbol);1144 print_indent(ar);
1143 fprintf(ar->f, ",\n");1145 print_symbol(ar, field_node->data.symbol_expr.symbol);
1146 fprintf(ar->f, ",\n");
1147 break;
1148 case NodeTypeErrorSetField:
1149 print_indent(ar);
1150 print_symbol(ar, field_node->data.err_set_field.field_name->data.symbol_expr.symbol);
1151 fprintf(ar->f, ",\n");
1152 break;
1153 default:
1154 zig_unreachable();
1155 }
1144 }1156 }
11451157
1146 ar->indent -= ar->indent_size;1158 ar->indent -= ar->indent_size;
src/codegen.cpp+112-72
...@@ -1108,15 +1108,15 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {...@@ -1108,15 +1108,15 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) {
1108 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0);1108 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0);
1109 LLVMValueRef address_value = LLVMGetParam(fn_val, 1);1109 LLVMValueRef address_value = LLVMGetParam(fn_val, 1);
11101110
1111 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;1111 size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
1112 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, "");1112 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, "");
1113 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;1113 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
1114 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");1114 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, "");
11151115
1116 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;1116 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
1117 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;1117 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
1118 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");1118 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
1119 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;1119 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
1120 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");1120 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
11211121
1122 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");1122 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, "");
...@@ -1699,6 +1699,10 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {...@@ -1699,6 +1699,10 @@ static void gen_var_debug_decl(CodeGen *g, ZigVar *var) {
1699}1699}
17001700
1701static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {1701static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) {
1702 Error err;
1703 if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown))) {
1704 codegen_report_errors_and_exit(g);
1705 }
1702 if (!type_has_bits(instruction->value.type))1706 if (!type_has_bits(instruction->value.type))
1703 return nullptr;1707 return nullptr;
1704 if (!instruction->llvm_value) {1708 if (!instruction->llvm_value) {
...@@ -2172,16 +2176,16 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {...@@ -2172,16 +2176,16 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) {
2172 LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block);2176 LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block);
21732177
2174 LLVMPositionBuilderAtEnd(g->builder, non_null_block);2178 LLVMPositionBuilderAtEnd(g->builder, non_null_block);
2175 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;2179 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
2176 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;2180 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
2177 LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,2181 LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
2178 (unsigned)src_index_field_index, "");2182 (unsigned)src_index_field_index, "");
2179 LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,2183 LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr,
2180 (unsigned)src_addresses_field_index, "");2184 (unsigned)src_addresses_field_index, "");
2181 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;2185 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
2182 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;2186 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
2183 LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");2187 LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, "");
2184 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;2188 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
2185 LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");2189 LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, "");
2186 LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");2190 LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, "");
2187 LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");2191 LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, "");
...@@ -3006,21 +3010,21 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,...@@ -3006,21 +3010,21 @@ static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable,
3006 assert(actual_type->id == ZigTypeIdStruct);3010 assert(actual_type->id == ZigTypeIdStruct);
3007 assert(actual_type->data.structure.is_slice);3011 assert(actual_type->data.structure.is_slice);
30083012
3009 ZigType *actual_pointer_type = actual_type->data.structure.fields[0].type_entry;3013 ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry;
3010 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;3014 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
3011 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0].type_entry;3015 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry;
3012 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;3016 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
30133017
30143018
3015 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index].gen_index;3019 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index;
3016 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index].gen_index;3020 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index;
3017 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index].gen_index;3021 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index;
3018 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index].gen_index;3022 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index;
30193023
3020 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");3024 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
3021 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");3025 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
3022 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,3026 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
3023 get_llvm_type(g, wanted_type->data.structure.fields[0].type_entry), "");3027 get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), "");
3024 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,3028 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
3025 (unsigned)wanted_ptr_index, "");3029 (unsigned)wanted_ptr_index, "");
3026 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);3030 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
...@@ -3136,9 +3140,9 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex...@@ -3136,9 +3140,9 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *ex
3136{3140{
3137 ZigType *actual_type = instruction->operand->value.type;3141 ZigType *actual_type = instruction->operand->value.type;
3138 ZigType *slice_type = instruction->base.value.type;3142 ZigType *slice_type = instruction->base.value.type;
3139 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index].type_entry;3143 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
3140 size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;3144 size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
3141 size_t len_index = slice_type->data.structure.fields[slice_len_index].gen_index;3145 size_t len_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
31423146
3143 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);3147 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
31443148
...@@ -3504,7 +3508,7 @@ static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val) {...@@ -3504,7 +3508,7 @@ static bool value_is_all_undef(CodeGen *g, ConstExprValue *const_val) {
3504 case ConstValSpecialStatic:3508 case ConstValSpecialStatic:
3505 if (const_val->type->id == ZigTypeIdStruct) {3509 if (const_val->type->id == ZigTypeIdStruct) {
3506 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {3510 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) {
3507 if (!value_is_all_undef(g, &const_val->data.x_struct.fields[i]))3511 if (!value_is_all_undef(g, const_val->data.x_struct.fields[i]))
3508 return false;3512 return false;
3509 }3513 }
3510 return true;3514 return true;
...@@ -3618,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_...@@ -3618,9 +3622,14 @@ static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_
3618}3622}
36193623
3620static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {3624static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) {
3625 Error err;
3626
3621 ZigType *ptr_type = instruction->ptr->value.type;3627 ZigType *ptr_type = instruction->ptr->value.type;
3622 assert(ptr_type->id == ZigTypeIdPointer);3628 assert(ptr_type->id == ZigTypeIdPointer);
3623 if (!type_has_bits(ptr_type))3629 bool ptr_type_has_bits;
3630 if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits)))
3631 codegen_report_errors_and_exit(g);
3632 if (!ptr_type_has_bits)
3624 return nullptr;3633 return nullptr;
3625 if (instruction->ptr->ref_count == 0) {3634 if (instruction->ptr->ref_count == 0) {
3626 // In this case, this StorePtr instruction should be elided. Something happened like this:3635 // In this case, this StorePtr instruction should be elided. Something happened like this:
...@@ -3757,14 +3766,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -3757,14 +3766,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
3757 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);3766 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
37583767
3759 if (safety_check_on) {3768 if (safety_check_on) {
3760 size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index;3769 size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
3761 assert(len_index != SIZE_MAX);3770 assert(len_index != SIZE_MAX);
3762 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");3771 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
3763 LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");3772 LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, "");
3764 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);3773 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, len);
3765 }3774 }
37663775
3767 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index;3776 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
3768 assert(ptr_index != SIZE_MAX);3777 assert(ptr_index != SIZE_MAX);
3769 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");3778 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, "");
3770 LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");3779 LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, "");
...@@ -3856,7 +3865,7 @@ static void render_async_spills(CodeGen *g) {...@@ -3856,7 +3865,7 @@ static void render_async_spills(CodeGen *g) {
3856 if (instruction->field_index == SIZE_MAX)3865 if (instruction->field_index == SIZE_MAX)
3857 continue;3866 continue;
38583867
3859 size_t gen_index = frame_type->data.structure.fields[instruction->field_index].gen_index;3868 size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index;
3860 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,3869 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
3861 instruction->name_hint);3870 instruction->name_hint);
3862 }3871 }
...@@ -4342,17 +4351,32 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -4342,17 +4351,32 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
4342 TypeUnionField *field = instruction->field;4351 TypeUnionField *field = instruction->field;
43434352
4344 if (!type_has_bits(field->type_entry)) {4353 if (!type_has_bits(field->type_entry)) {
4345 if (union_type->data.unionation.gen_tag_index == SIZE_MAX) {4354 ZigType *tag_type = union_type->data.unionation.tag_type;
4355 if (!instruction->initializing || !type_has_bits(tag_type))
4346 return nullptr;4356 return nullptr;
4357
4358 // The field has no bits but we still have to change the discriminant
4359 // value here
4360 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);
4361
4362 LLVMTypeRef tag_type_ref = get_llvm_type(g, tag_type);
4363 LLVMValueRef tag_field_ptr = nullptr;
4364 if (union_type->data.unionation.gen_field_count == 0) {
4365 assert(union_type->data.unionation.gen_tag_index == SIZE_MAX);
4366 // The whole union is collapsed into the discriminant
4367 tag_field_ptr = LLVMBuildBitCast(g->builder, union_ptr,
4368 LLVMPointerType(tag_type_ref, 0), "");
4369 } else {
4370 assert(union_type->data.unionation.gen_tag_index != SIZE_MAX);
4371 tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,
4372 union_type->data.unionation.gen_tag_index, "");
4347 }4373 }
4348 if (instruction->initializing) {4374
4349 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr);4375 LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref,
4350 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr,4376 &field->enum_field->value);
4351 union_type->data.unionation.gen_tag_index, "");4377 assert(tag_field_ptr != nullptr);
4352 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type),4378 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
4353 &field->enum_field->value);4379
4354 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false);
4355 }
4356 return nullptr;4380 return nullptr;
4357 }4381 }
43584382
...@@ -4983,10 +5007,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I...@@ -4983,10 +5007,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
4983 align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment;5007 align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment;
4984 ptr_val = target_val;5008 ptr_val = target_val;
4985 } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) {5009 } else if (target_type->id == ZigTypeIdStruct && target_type->data.structure.is_slice) {
4986 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;5010 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry;
4987 align_bytes = get_ptr_align(g, slice_ptr_type);5011 align_bytes = get_ptr_align(g, slice_ptr_type);
49885012
4989 size_t ptr_index = target_type->data.structure.fields[slice_ptr_index].gen_index;5013 size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index;
4990 LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, "");5014 LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, "");
4991 ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, "");5015 ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, "");
4992 } else {5016 } else {
...@@ -5128,7 +5152,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns...@@ -5128,7 +5152,7 @@ static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrIns
51285152
5129 bool val_is_undef = value_is_all_undef(g, &instruction->byte->value);5153 bool val_is_undef = value_is_all_undef(g, &instruction->byte->value);
5130 LLVMValueRef fill_char;5154 LLVMValueRef fill_char;
5131 if (val_is_undef) {5155 if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.scope)) {
5132 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);5156 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);
5133 } else {5157 } else {
5134 fill_char = ir_llvm_value(g, instruction->byte);5158 fill_char = ir_llvm_value(g, instruction->byte);
...@@ -5231,13 +5255,13 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -5231,13 +5255,13 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
5231 }5255 }
52325256
5233 if (type_has_bits(array_type)) {5257 if (type_has_bits(array_type)) {
5234 size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index].gen_index;5258 size_t gen_ptr_index = instruction->base.value.type->data.structure.fields[slice_ptr_index]->gen_index;
5235 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");5259 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, "");
5236 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");5260 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, "");
5237 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);5261 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false);
5238 }5262 }
52395263
5240 size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index].gen_index;5264 size_t gen_len_index = instruction->base.value.type->data.structure.fields[slice_len_index]->gen_index;
5241 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");5265 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, "");
5242 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");5266 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
5243 gen_store_untyped(g, len_value, len_field_ptr, 0, false);5267 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
...@@ -5249,9 +5273,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -5249,9 +5273,9 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
5249 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);5273 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind);
5250 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind);5274 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind);
52515275
5252 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index].gen_index;5276 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index;
5253 assert(ptr_index != SIZE_MAX);5277 assert(ptr_index != SIZE_MAX);
5254 size_t len_index = array_type->data.structure.fields[slice_len_index].gen_index;5278 size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index;
5255 assert(len_index != SIZE_MAX);5279 assert(len_index != SIZE_MAX);
52565280
5257 LLVMValueRef prev_end = nullptr;5281 LLVMValueRef prev_end = nullptr;
...@@ -5646,6 +5670,17 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,...@@ -5646,6 +5670,17 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable,
5646 return load_inst;5670 return load_inst;
5647}5671}
56485672
5673static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable,
5674 IrInstructionAtomicStore *instruction)
5675{
5676 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering);
5677 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
5678 LLVMValueRef value = ir_llvm_value(g, instruction->value);
5679 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value.type);
5680 LLVMSetOrdering(store_inst, ordering);
5681 return nullptr;
5682}
5683
5649static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {5684static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) {
5650 LLVMValueRef op = ir_llvm_value(g, instruction->op1);5685 LLVMValueRef op = ir_llvm_value(g, instruction->op1);
5651 assert(instruction->base.value.type->id == ZigTypeIdFloat);5686 assert(instruction->base.value.type->id == ZigTypeIdFloat);
...@@ -6249,6 +6284,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -6249,6 +6284,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
6249 return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);6284 return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction);
6250 case IrInstructionIdAtomicLoad:6285 case IrInstructionIdAtomicLoad:
6251 return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);6286 return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction);
6287 case IrInstructionIdAtomicStore:
6288 return ir_render_atomic_store(g, executable, (IrInstructionAtomicStore *)instruction);
6252 case IrInstructionIdSaveErrRetAddr:6289 case IrInstructionIdSaveErrRetAddr:
6253 return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);6290 return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction);
6254 case IrInstructionIdFloatOp:6291 case IrInstructionIdFloatOp:
...@@ -6546,11 +6583,11 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -6546,11 +6583,11 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
6546 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);6583 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);
6547 size_t used_bits = 0;6584 size_t used_bits = 0;
6548 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {6585 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
6549 TypeStructField *field = &type_entry->data.structure.fields[i];6586 TypeStructField *field = type_entry->data.structure.fields[i];
6550 if (field->gen_index == SIZE_MAX) {6587 if (field->gen_index == SIZE_MAX) {
6551 continue;6588 continue;
6552 }6589 }
6553 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, &const_val->data.x_struct.fields[i]);6590 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]);
6554 uint32_t packed_bits_size = type_size_bits(g, field->type_entry);6591 uint32_t packed_bits_size = type_size_bits(g, field->type_entry);
6555 if (is_big_endian) {6592 if (is_big_endian) {
6556 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false);6593 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false);
...@@ -6625,7 +6662,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con...@@ -6625,7 +6662,7 @@ static LLVMValueRef gen_const_val_ptr(CodeGen *g, ConstExprValue *const_val, con
6625 return const_val->global_refs->llvm_value;6662 return const_val->global_refs->llvm_value;
6626 }6663 }
6627 size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;6664 size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index;
6628 size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index].gen_index;6665 size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index]->gen_index;
6629 LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,6666 LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val,
6630 gen_field_index);6667 gen_field_index);
6631 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type));6668 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type));
...@@ -6804,7 +6841,7 @@ check: switch (const_val->special) {...@@ -6804,7 +6841,7 @@ check: switch (const_val->special) {
6804 if (type_entry->data.structure.layout == ContainerLayoutPacked) {6841 if (type_entry->data.structure.layout == ContainerLayoutPacked) {
6805 size_t src_field_index = 0;6842 size_t src_field_index = 0;
6806 while (src_field_index < src_field_count) {6843 while (src_field_index < src_field_count) {
6807 TypeStructField *type_struct_field = &type_entry->data.structure.fields[src_field_index];6844 TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index];
6808 if (type_struct_field->gen_index == SIZE_MAX) {6845 if (type_struct_field->gen_index == SIZE_MAX) {
6809 src_field_index += 1;6846 src_field_index += 1;
6810 continue;6847 continue;
...@@ -6812,13 +6849,13 @@ check: switch (const_val->special) {...@@ -6812,13 +6849,13 @@ check: switch (const_val->special) {
68126849
6813 size_t src_field_index_end = src_field_index + 1;6850 size_t src_field_index_end = src_field_index + 1;
6814 for (; src_field_index_end < src_field_count; src_field_index_end += 1) {6851 for (; src_field_index_end < src_field_count; src_field_index_end += 1) {
6815 TypeStructField *it_field = &type_entry->data.structure.fields[src_field_index_end];6852 TypeStructField *it_field = type_entry->data.structure.fields[src_field_index_end];
6816 if (it_field->gen_index != type_struct_field->gen_index)6853 if (it_field->gen_index != type_struct_field->gen_index)
6817 break;6854 break;
6818 }6855 }
68196856
6820 if (src_field_index + 1 == src_field_index_end) {6857 if (src_field_index + 1 == src_field_index_end) {
6821 ConstExprValue *field_val = &const_val->data.x_struct.fields[src_field_index];6858 ConstExprValue *field_val = const_val->data.x_struct.fields[src_field_index];
6822 LLVMValueRef val = gen_const_val(g, field_val, "");6859 LLVMValueRef val = gen_const_val(g, field_val, "");
6823 fields[type_struct_field->gen_index] = val;6860 fields[type_struct_field->gen_index] = val;
6824 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);6861 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
...@@ -6831,12 +6868,12 @@ check: switch (const_val->special) {...@@ -6831,12 +6868,12 @@ check: switch (const_val->special) {
6831 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);6868 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false);
6832 size_t used_bits = 0;6869 size_t used_bits = 0;
6833 for (size_t i = src_field_index; i < src_field_index_end; i += 1) {6870 for (size_t i = src_field_index; i < src_field_index_end; i += 1) {
6834 TypeStructField *it_field = &type_entry->data.structure.fields[i];6871 TypeStructField *it_field = type_entry->data.structure.fields[i];
6835 if (it_field->gen_index == SIZE_MAX) {6872 if (it_field->gen_index == SIZE_MAX) {
6836 continue;6873 continue;
6837 }6874 }
6838 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,6875 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref,
6839 &const_val->data.x_struct.fields[i]);6876 const_val->data.x_struct.fields[i]);
6840 uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry);6877 uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry);
6841 if (is_big_endian) {6878 if (is_big_endian) {
6842 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,6879 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref,
...@@ -6871,11 +6908,11 @@ check: switch (const_val->special) {...@@ -6871,11 +6908,11 @@ check: switch (const_val->special) {
6871 }6908 }
6872 } else {6909 } else {
6873 for (uint32_t i = 0; i < src_field_count; i += 1) {6910 for (uint32_t i = 0; i < src_field_count; i += 1) {
6874 TypeStructField *type_struct_field = &type_entry->data.structure.fields[i];6911 TypeStructField *type_struct_field = type_entry->data.structure.fields[i];
6875 if (type_struct_field->gen_index == SIZE_MAX) {6912 if (type_struct_field->gen_index == SIZE_MAX) {
6876 continue;6913 continue;
6877 }6914 }
6878 ConstExprValue *field_val = &const_val->data.x_struct.fields[i];6915 ConstExprValue *field_val = const_val->data.x_struct.fields[i];
6879 assert(field_val->type != nullptr);6916 assert(field_val->type != nullptr);
6880 if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val,6917 if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val,
6881 type_struct_field->type_entry)))6918 type_struct_field->type_entry)))
...@@ -6888,10 +6925,10 @@ check: switch (const_val->special) {...@@ -6888,10 +6925,10 @@ check: switch (const_val->special) {
6888 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);6925 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
68896926
6890 size_t end_pad_gen_index = (i + 1 < src_field_count) ?6927 size_t end_pad_gen_index = (i + 1 < src_field_count) ?
6891 type_entry->data.structure.fields[i + 1].gen_index :6928 type_entry->data.structure.fields[i + 1]->gen_index :
6892 type_entry->data.structure.gen_field_count;6929 type_entry->data.structure.gen_field_count;
6893 size_t next_offset = (i + 1 < src_field_count) ?6930 size_t next_offset = (i + 1 < src_field_count) ?
6894 type_entry->data.structure.fields[i + 1].offset : type_entry->abi_size;6931 type_entry->data.structure.fields[i + 1]->offset : type_entry->abi_size;
6895 if (end_pad_gen_index != SIZE_MAX) {6932 if (end_pad_gen_index != SIZE_MAX) {
6896 for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index;6933 for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index;
6897 gen_i += 1)6934 gen_i += 1)
...@@ -7050,16 +7087,12 @@ check: switch (const_val->special) {...@@ -7050,16 +7087,12 @@ check: switch (const_val->special) {
7050 case ZigTypeIdEnum:7087 case ZigTypeIdEnum:
7051 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_enum_tag);7088 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_enum_tag);
7052 case ZigTypeIdFn:7089 case ZigTypeIdFn:
7053 if (const_val->data.x_ptr.special == ConstPtrSpecialFunction) {7090 if (const_val->data.x_ptr.special == ConstPtrSpecialFunction &&
7054 assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);7091 const_val->data.x_ptr.mut != ConstPtrMutComptimeConst) {
7055 return fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry);
7056 } else if (const_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
7057 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
7058 uint64_t addr = const_val->data.x_ptr.data.hard_coded_addr.addr;
7059 return LLVMConstIntToPtr(LLVMConstInt(usize_type_ref, addr, false), get_llvm_type(g, type_entry));
7060 } else {
7061 zig_unreachable();7092 zig_unreachable();
7062 }7093 }
7094 // Treat it the same as we do for pointers
7095 return gen_const_val_ptr(g, const_val, name);
7063 case ZigTypeIdPointer:7096 case ZigTypeIdPointer:
7064 return gen_const_val_ptr(g, const_val, name);7097 return gen_const_val_ptr(g, const_val, name);
7065 case ZigTypeIdErrorUnion:7098 case ZigTypeIdErrorUnion:
...@@ -7558,15 +7591,15 @@ static void do_code_gen(CodeGen *g) {...@@ -7558,15 +7591,15 @@ static void do_code_gen(CodeGen *g) {
7558 // finishing error return trace setup. we have to do this after all the allocas.7591 // finishing error return trace setup. we have to do this after all the allocas.
7559 if (have_err_ret_trace_stack) {7592 if (have_err_ret_trace_stack) {
7560 ZigType *usize = g->builtin_types.entry_usize;7593 ZigType *usize = g->builtin_types.entry_usize;
7561 size_t index_field_index = g->stack_trace_type->data.structure.fields[0].gen_index;7594 size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index;
7562 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");7595 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, "");
7563 gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false);7596 gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false);
75647597
7565 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1].gen_index;7598 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index;
7566 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");7599 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, "");
75677600
7568 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1].type_entry;7601 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry;
7569 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index].gen_index;7602 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index;
7570 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");7603 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, "");
7571 LLVMValueRef zero = LLVMConstNull(usize->llvm_type);7604 LLVMValueRef zero = LLVMConstNull(usize->llvm_type);
7572 LLVMValueRef indices[] = {zero, zero};7605 LLVMValueRef indices[] = {zero, zero};
...@@ -7575,7 +7608,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7575,7 +7608,7 @@ static void do_code_gen(CodeGen *g) {
7575 ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false);7608 ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false);
7576 gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type);7609 gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type);
75777610
7578 size_t len_field_index = slice_type->data.structure.fields[slice_len_index].gen_index;7611 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index;
7579 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");7612 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, "");
7580 gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));7613 gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
7581 }7614 }
...@@ -7692,7 +7725,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7692,7 +7725,7 @@ static void do_code_gen(CodeGen *g) {
76927725
7693 char *error = nullptr;7726 char *error = nullptr;
7694 if (LLVMVerifyModule(g->module, LLVMReturnStatusAction, &error)) {7727 if (LLVMVerifyModule(g->module, LLVMReturnStatusAction, &error)) {
7695 zig_panic("broken LLVM module found: %s", error);7728 zig_panic("broken LLVM module found: %s\nThis is a bug in the Zig compiler.", error);
7696 }7729 }
7697}7730}
76987731
...@@ -7820,6 +7853,11 @@ static void define_builtin_types(CodeGen *g) {...@@ -7820,6 +7853,11 @@ static void define_builtin_types(CodeGen *g) {
7820 buf_init_from_str(&entry->name, "(null)");7853 buf_init_from_str(&entry->name, "(null)");
7821 g->builtin_types.entry_null = entry;7854 g->builtin_types.entry_null = entry;
7822 }7855 }
7856 {
7857 ZigType *entry = new_type_table_entry(ZigTypeIdOpaque);
7858 buf_init_from_str(&entry->name, "(var)");
7859 g->builtin_types.entry_var = entry;
7860 }
7823 {7861 {
7824 ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);7862 ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
7825 buf_init_from_str(&entry->name, "(args)");7863 buf_init_from_str(&entry->name, "(args)");
...@@ -8064,6 +8102,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8064,6 +8102,7 @@ static void define_builtin_fns(CodeGen *g) {
8064 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);8102 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
8065 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);8103 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
8066 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);8104 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
8105 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);
8067 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);8106 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
8068 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);8107 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
8069 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);8108 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
...@@ -8074,6 +8113,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8074,6 +8113,7 @@ static void define_builtin_fns(CodeGen *g) {
8074 create_builtin_fn(g, BuiltinFnIdFrameType, "Frame", 1);8113 create_builtin_fn(g, BuiltinFnIdFrameType, "Frame", 1);
8075 create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0);8114 create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0);
8076 create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1);8115 create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1);
8116 create_builtin_fn(g, BuiltinFnIdAs, "as", 2);
8077}8117}
80788118
8079static const char *bool_to_str(bool b) {8119static const char *bool_to_str(bool b) {
...@@ -9049,13 +9089,13 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {...@@ -9049,13 +9089,13 @@ static void create_test_compile_var_and_add_test_runner(CodeGen *g) {
9049 this_val->parent.id = ConstParentIdArray;9089 this_val->parent.id = ConstParentIdArray;
9050 this_val->parent.data.p_array.array_val = test_fn_array;9090 this_val->parent.data.p_array.array_val = test_fn_array;
9051 this_val->parent.data.p_array.elem_index = i;9091 this_val->parent.data.p_array.elem_index = i;
9052 this_val->data.x_struct.fields = create_const_vals(2);9092 this_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
90539093
9054 ConstExprValue *name_field = &this_val->data.x_struct.fields[0];9094 ConstExprValue *name_field = this_val->data.x_struct.fields[0];
9055 ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);9095 ConstExprValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name);
9056 init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true);9096 init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true);
90579097
9058 ConstExprValue *fn_field = &this_val->data.x_struct.fields[1];9098 ConstExprValue *fn_field = this_val->data.x_struct.fields[1];
9059 fn_field->type = fn_type;9099 fn_field->type = fn_type;
9060 fn_field->special = ConstValSpecialStatic;9100 fn_field->special = ConstValSpecialStatic;
9061 fn_field->data.x_ptr.special = ConstPtrSpecialFunction;9101 fn_field->data.x_ptr.special = ConstPtrSpecialFunction;
...@@ -9483,7 +9523,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e...@@ -9483,7 +9523,7 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
9483 return;9523 return;
9484 case ZigTypeIdStruct:9524 case ZigTypeIdStruct:
9485 for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {9525 for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
9486 TypeStructField *field = &type_entry->data.structure.fields[i];9526 TypeStructField *field = type_entry->data.structure.fields[i];
9487 prepend_c_type_to_decl_list(g, gen_h, field->type_entry);9527 prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
9488 }9528 }
9489 gen_h->types_to_declare.append(type_entry);9529 gen_h->types_to_declare.append(type_entry);
...@@ -9849,7 +9889,7 @@ static void gen_h_file(CodeGen *g) {...@@ -9849,7 +9889,7 @@ static void gen_h_file(CodeGen *g) {
9849 if (type_entry->data.structure.layout == ContainerLayoutExtern) {9889 if (type_entry->data.structure.layout == ContainerLayoutExtern) {
9850 fprintf(out_h, "struct %s {\n", buf_ptr(type_h_name(type_entry)));9890 fprintf(out_h, "struct %s {\n", buf_ptr(type_h_name(type_entry)));
9851 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {9891 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
9852 TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];9892 TypeStructField *struct_field = type_entry->data.structure.fields[field_i];
98539893
9854 Buf *type_name_buf = buf_alloc();9894 Buf *type_name_buf = buf_alloc();
9855 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);9895 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
src/dump_analysis.cpp+4-3
...@@ -268,7 +268,7 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) {...@@ -268,7 +268,7 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) {
268 ZigList<ZigType *> children = {};268 ZigList<ZigType *> children = {};
269 uint64_t sum_from_fields = 0;269 uint64_t sum_from_fields = 0;
270 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {270 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
271 TypeStructField *field = &struct_type->data.structure.fields[i];271 TypeStructField *field = struct_type->data.structure.fields[i];
272 children.append(field->type_entry);272 children.append(field->type_entry);
273 sum_from_fields += field->type_entry->abi_size;273 sum_from_fields += field->type_entry->abi_size;
274 }274 }
...@@ -747,7 +747,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {...@@ -747,7 +747,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
747 if (ty->data.structure.is_slice) {747 if (ty->data.structure.is_slice) {
748 jw_object_field(jw, "len");748 jw_object_field(jw, "len");
749 jw_int(jw, 2);749 jw_int(jw, 2);
750 anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index].type_entry);750 anal_dump_pointer_attrs(ctx, ty->data.structure.fields[slice_ptr_index]->type_entry);
751 break;751 break;
752 }752 }
753753
...@@ -803,7 +803,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {...@@ -803,7 +803,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) {
803803
804 for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {804 for(size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
805 jw_array_elem(jw);805 jw_array_elem(jw);
806 anal_dump_type_ref(ctx, ty->data.structure.fields[i].type_entry);806 anal_dump_type_ref(ctx, ty->data.structure.fields[i]->type_entry);
807 }807 }
808 jw_end_array(jw);808 jw_end_array(jw);
809 }809 }
...@@ -1088,6 +1088,7 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {...@@ -1088,6 +1088,7 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) {
1088 break;1088 break;
1089 case NodeTypeContainerDecl:1089 case NodeTypeContainerDecl:
1090 field_nodes = &node->data.container_decl.fields;1090 field_nodes = &node->data.container_decl.fields;
1091 doc_comments_buf = &node->data.container_decl.doc_comments;
1091 break;1092 break;
1092 default:1093 default:
1093 break;1094 break;
src/ir.cpp+1121-482
...@@ -200,6 +200,13 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo...@@ -200,6 +200,13 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo
200static void ir_reset_result(ResultLoc *result_loc);200static void ir_reset_result(ResultLoc *result_loc);
201static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,201static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,
202 Scope *scope, AstNode *source_node, Buf *out_bare_name);202 Scope *scope, AstNode *source_node, Buf *out_bare_name);
203static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
204 ResultLoc *parent_result_loc);
205static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
206 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
207static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
208 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
209static ResultLoc *no_result_loc(void);
203210
204static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {211static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
205 assert(get_src_ptr_type(const_val->type) != nullptr);212 assert(get_src_ptr_type(const_val->type) != nullptr);
...@@ -233,7 +240,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c...@@ -233,7 +240,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
233 case ConstPtrSpecialBaseStruct: {240 case ConstPtrSpecialBaseStruct: {
234 ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;241 ConstExprValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val;
235 expand_undef_struct(g, struct_val);242 expand_undef_struct(g, struct_val);
236 result = &struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];243 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index];
237 break;244 break;
238 }245 }
239 case ConstPtrSpecialBaseErrorUnionCode:246 case ConstPtrSpecialBaseErrorUnionCode:
...@@ -270,7 +277,7 @@ static bool is_slice(ZigType *type) {...@@ -270,7 +277,7 @@ static bool is_slice(ZigType *type) {
270277
271static bool slice_is_const(ZigType *type) {278static bool slice_is_const(ZigType *type) {
272 assert(is_slice(type));279 assert(is_slice(type));
273 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;280 return type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
274}281}
275282
276// This function returns true when you can change the type of a ConstExprValue and the283// This function returns true when you can change the type of a ConstExprValue and the
...@@ -1003,6 +1010,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) {...@@ -1003,6 +1010,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) {
1003 return IrInstructionIdAtomicLoad;1010 return IrInstructionIdAtomicLoad;
1004}1011}
10051012
1013static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicStore *) {
1014 return IrInstructionIdAtomicStore;
1015}
1016
1006static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) {1017static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) {
1007 return IrInstructionIdSaveErrRetAddr;1018 return IrInstructionIdSaveErrRetAddr;
1008}1019}
...@@ -1348,18 +1359,17 @@ static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_...@@ -1348,18 +1359,17 @@ static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_
13481359
1349static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1360static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1350 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len,1361 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len,
1351 IrInstruction *init_array_type)1362 AstNode *init_array_type_source_node)
1352{1363{
1353 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);1364 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
1354 instruction->array_ptr = array_ptr;1365 instruction->array_ptr = array_ptr;
1355 instruction->elem_index = elem_index;1366 instruction->elem_index = elem_index;
1356 instruction->safety_check_on = safety_check_on;1367 instruction->safety_check_on = safety_check_on;
1357 instruction->ptr_len = ptr_len;1368 instruction->ptr_len = ptr_len;
1358 instruction->init_array_type = init_array_type;1369 instruction->init_array_type_source_node = init_array_type_source_node;
13591370
1360 ir_ref_instruction(array_ptr, irb->current_basic_block);1371 ir_ref_instruction(array_ptr, irb->current_basic_block);
1361 ir_ref_instruction(elem_index, irb->current_basic_block);1372 ir_ref_instruction(elem_index, irb->current_basic_block);
1362 if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block);
13631373
1364 return &instruction->base;1374 return &instruction->base;
1365}1375}
...@@ -1573,17 +1583,16 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *sour...@@ -1573,17 +1583,16 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *sour
1573}1583}
15741584
1575static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,1585static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
1576 IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list,1586 size_t item_count, IrInstruction **elem_result_loc_list, IrInstruction *result_loc,
1577 IrInstruction *result_loc)1587 AstNode *init_array_type_source_node)
1578{1588{
1579 IrInstructionContainerInitList *container_init_list_instruction =1589 IrInstructionContainerInitList *container_init_list_instruction =
1580 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);1590 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);
1581 container_init_list_instruction->container_type = container_type;
1582 container_init_list_instruction->item_count = item_count;1591 container_init_list_instruction->item_count = item_count;
1583 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;1592 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
1584 container_init_list_instruction->result_loc = result_loc;1593 container_init_list_instruction->result_loc = result_loc;
1594 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
15851595
1586 ir_ref_instruction(container_type, irb->current_basic_block);
1587 for (size_t i = 0; i < item_count; i += 1) {1596 for (size_t i = 0; i < item_count; i += 1) {
1588 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);1597 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
1589 }1598 }
...@@ -1593,17 +1602,14 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope,...@@ -1593,17 +1602,14 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope,
1593}1602}
15941603
1595static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,1604static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
1596 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields,1605 size_t field_count, IrInstructionContainerInitFieldsField *fields, IrInstruction *result_loc)
1597 IrInstruction *result_loc)
1598{1606{
1599 IrInstructionContainerInitFields *container_init_fields_instruction =1607 IrInstructionContainerInitFields *container_init_fields_instruction =
1600 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);1608 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);
1601 container_init_fields_instruction->container_type = container_type;
1602 container_init_fields_instruction->field_count = field_count;1609 container_init_fields_instruction->field_count = field_count;
1603 container_init_fields_instruction->fields = fields;1610 container_init_fields_instruction->fields = fields;
1604 container_init_fields_instruction->result_loc = result_loc;1611 container_init_fields_instruction->result_loc = result_loc;
16051612
1606 ir_ref_instruction(container_type, irb->current_basic_block);
1607 for (size_t i = 0; i < field_count; i += 1) {1613 for (size_t i = 0; i < field_count; i += 1) {
1608 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);1614 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
1609 }1615 }
...@@ -2766,6 +2772,18 @@ static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *sourc...@@ -2766,6 +2772,18 @@ static IrInstruction *ir_build_load_ptr_gen(IrAnalyze *ira, IrInstruction *sourc
2766 return &instruction->base;2772 return &instruction->base;
2767}2773}
27682774
2775static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2776 IrInstruction *operand, ResultLocCast *result_loc_cast)
2777{
2778 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
2779 instruction->operand = operand;
2780 instruction->result_loc_cast = result_loc_cast;
2781
2782 ir_ref_instruction(operand, irb->current_basic_block);
2783
2784 return &instruction->base;
2785}
2786
2769static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,2787static IrInstruction *ir_build_bit_cast_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
2770 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast)2788 IrInstruction *operand, ResultLocBitCast *result_loc_bit_cast)
2771{2789{
...@@ -3063,20 +3081,6 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode...@@ -3063,20 +3081,6 @@ static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode
3063 return &instruction->base;3081 return &instruction->base;
3064}3082}
30653083
3066static IrInstruction *ir_build_implicit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
3067 IrInstruction *dest_type, IrInstruction *target, ResultLoc *result_loc)
3068{
3069 IrInstructionImplicitCast *instruction = ir_build_instruction<IrInstructionImplicitCast>(irb, scope, source_node);
3070 instruction->dest_type = dest_type;
3071 instruction->target = target;
3072 instruction->result_loc = result_loc;
3073
3074 ir_ref_instruction(dest_type, irb->current_basic_block);
3075 ir_ref_instruction(target, irb->current_basic_block);
3076
3077 return &instruction->base;
3078}
3079
3080static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node,3084static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstNode *source_node,
3081 ResultLoc *result_loc, IrInstruction *ty)3085 ResultLoc *result_loc, IrInstruction *ty)
3082{3086{
...@@ -3084,7 +3088,7 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN...@@ -3084,7 +3088,7 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN
3084 instruction->result_loc = result_loc;3088 instruction->result_loc = result_loc;
3085 instruction->ty = ty;3089 instruction->ty = ty;
30863090
3087 ir_ref_instruction(ty, irb->current_basic_block);3091 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block);
30883092
3089 return &instruction->base;3093 return &instruction->base;
3090}3094}
...@@ -3116,11 +3120,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast...@@ -3116,11 +3120,12 @@ static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, Ast
3116}3120}
31173121
3118static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,3122static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
3119 IrInstruction *fn_type, IrInstruction *arg_index)3123 IrInstruction *fn_type, IrInstruction *arg_index, bool allow_var)
3120{3124{
3121 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);3125 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);
3122 instruction->fn_type = fn_type;3126 instruction->fn_type = fn_type;
3123 instruction->arg_index = arg_index;3127 instruction->arg_index = arg_index;
3128 instruction->allow_var = allow_var;
31243129
3125 ir_ref_instruction(fn_type, irb->current_basic_block);3130 ir_ref_instruction(fn_type, irb->current_basic_block);
3126 ir_ref_instruction(arg_index, irb->current_basic_block);3131 ir_ref_instruction(arg_index, irb->current_basic_block);
...@@ -3187,6 +3192,25 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode...@@ -3187,6 +3192,25 @@ static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode
3187 return &instruction->base;3192 return &instruction->base;
3188}3193}
31893194
3195static IrInstruction *ir_build_atomic_store(IrBuilder *irb, Scope *scope, AstNode *source_node,
3196 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *value,
3197 IrInstruction *ordering, AtomicOrder resolved_ordering)
3198{
3199 IrInstructionAtomicStore *instruction = ir_build_instruction<IrInstructionAtomicStore>(irb, scope, source_node);
3200 instruction->operand_type = operand_type;
3201 instruction->ptr = ptr;
3202 instruction->value = value;
3203 instruction->ordering = ordering;
3204 instruction->resolved_ordering = resolved_ordering;
3205
3206 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block);
3207 ir_ref_instruction(ptr, irb->current_basic_block);
3208 ir_ref_instruction(value, irb->current_basic_block);
3209 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block);
3210
3211 return &instruction->base;
3212}
3213
3190static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) {3214static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) {
3191 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node);3215 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node);
3192 return &instruction->base;3216 return &instruction->base;
...@@ -5374,6 +5398,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5374,6 +5398,24 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5374 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);5398 IrInstruction *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast);
5375 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);5399 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc);
5376 }5400 }
5401 case BuiltinFnIdAs:
5402 {
5403 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
5404 IrInstruction *dest_type = ir_gen_node(irb, dest_type_node, scope);
5405 if (dest_type == irb->codegen->invalid_instruction)
5406 return dest_type;
5407
5408 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc);
5409
5410 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5411 IrInstruction *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone,
5412 &result_loc_cast->base);
5413 if (arg1_value == irb->codegen->invalid_instruction)
5414 return arg1_value;
5415
5416 IrInstruction *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast);
5417 return ir_lval_wrap(irb, scope, result, lval, result_loc);
5418 }
5377 case BuiltinFnIdIntToPtr:5419 case BuiltinFnIdIntToPtr:
5378 {5420 {
5379 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5421 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -5630,7 +5672,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5630,7 +5672,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5630 if (arg1_value == irb->codegen->invalid_instruction)5672 if (arg1_value == irb->codegen->invalid_instruction)
5631 return arg1_value;5673 return arg1_value;
56325674
5633 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value);5675 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false);
5634 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);5676 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
5635 }5677 }
5636 case BuiltinFnIdExport:5678 case BuiltinFnIdExport:
...@@ -5713,6 +5755,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -5713,6 +5755,33 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5713 AtomicOrderMonotonic);5755 AtomicOrderMonotonic);
5714 return ir_lval_wrap(irb, scope, inst, lval, result_loc);5756 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
5715 }5757 }
5758 case BuiltinFnIdAtomicStore:
5759 {
5760 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5761 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
5762 if (arg0_value == irb->codegen->invalid_instruction)
5763 return arg0_value;
5764
5765 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5766 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
5767 if (arg1_value == irb->codegen->invalid_instruction)
5768 return arg1_value;
5769
5770 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5771 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope);
5772 if (arg2_value == irb->codegen->invalid_instruction)
5773 return arg2_value;
5774
5775 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
5776 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope);
5777 if (arg3_value == irb->codegen->invalid_instruction)
5778 return arg3_value;
5779
5780 IrInstruction *inst = ir_build_atomic_store(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value,
5781 // this value does not mean anything since we passed non-null values for other arg
5782 AtomicOrderMonotonic);
5783 return ir_lval_wrap(irb, scope, inst, lval, result_loc);
5784 }
5716 case BuiltinFnIdIntToEnum:5785 case BuiltinFnIdIntToEnum:
5717 {5786 {
5718 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);5787 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -5825,13 +5894,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node...@@ -5825,13 +5894,22 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
5825 if (fn_ref == irb->codegen->invalid_instruction)5894 if (fn_ref == irb->codegen->invalid_instruction)
5826 return fn_ref;5895 return fn_ref;
58275896
5897 IrInstruction *fn_type = ir_build_typeof(irb, scope, node, fn_ref);
5898
5828 size_t arg_count = node->data.fn_call_expr.params.length;5899 size_t arg_count = node->data.fn_call_expr.params.length;
5829 IrInstruction **args = allocate<IrInstruction*>(arg_count);5900 IrInstruction **args = allocate<IrInstruction*>(arg_count);
5830 for (size_t i = 0; i < arg_count; i += 1) {5901 for (size_t i = 0; i < arg_count; i += 1) {
5831 AstNode *arg_node = node->data.fn_call_expr.params.at(i);5902 AstNode *arg_node = node->data.fn_call_expr.params.at(i);
5832 args[i] = ir_gen_node(irb, arg_node, scope);5903
5833 if (args[i] == irb->codegen->invalid_instruction)5904 IrInstruction *arg_index = ir_build_const_usize(irb, scope, arg_node, i);
5834 return args[i];5905 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, fn_type, arg_index, true);
5906 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result_loc());
5907
5908 IrInstruction *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base);
5909 if (arg == irb->codegen->invalid_instruction)
5910 return arg;
5911
5912 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast);
5835 }5913 }
58365914
5837 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,5915 IrInstruction *fn_call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, false,
...@@ -6109,28 +6187,46 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6109,28 +6187,46 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6109 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;6187 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
6110 ContainerInitKind kind = container_init_expr->kind;6188 ContainerInitKind kind = container_init_expr->kind;
61116189
6112 IrInstruction *container_type = nullptr;6190 ResultLocCast *result_loc_cast = nullptr;
6113 IrInstruction *elem_type = nullptr;6191 ResultLoc *child_result_loc;
6114 if (container_init_expr->type->type == NodeTypeInferredArrayType) {6192 AstNode *init_array_type_source_node;
6115 elem_type = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.child_type, scope);6193 if (container_init_expr->type != nullptr) {
6116 if (elem_type == irb->codegen->invalid_instruction)6194 IrInstruction *container_type;
6117 return elem_type;6195 if (container_init_expr->type->type == NodeTypeInferredArrayType) {
6118 } else {6196 if (kind == ContainerInitKindStruct) {
6119 container_type = ir_gen_node(irb, container_init_expr->type, scope);
6120 if (container_type == irb->codegen->invalid_instruction)
6121 return container_type;
6122 }
6123
6124 switch (kind) {
6125 case ContainerInitKindStruct: {
6126 if (elem_type != nullptr) {
6127 add_node_error(irb->codegen, container_init_expr->type,6197 add_node_error(irb->codegen, container_init_expr->type,
6128 buf_sprintf("initializing array with struct syntax"));6198 buf_sprintf("initializing array with struct syntax"));
6129 return irb->codegen->invalid_instruction;6199 return irb->codegen->invalid_instruction;
6130 }6200 }
6201 IrInstruction *elem_type = ir_gen_node(irb,
6202 container_init_expr->type->data.inferred_array_type.child_type, scope);
6203 if (elem_type == irb->codegen->invalid_instruction)
6204 return elem_type;
6205 size_t item_count = container_init_expr->entries.length;
6206 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
6207 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
6208 } else {
6209 container_type = ir_gen_node(irb, container_init_expr->type, scope);
6210 if (container_type == irb->codegen->invalid_instruction)
6211 return container_type;
6212 }
61316213
6132 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,6214 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc);
6133 container_type);6215 child_result_loc = &result_loc_cast->base;
6216 init_array_type_source_node = container_type->source_node;
6217 } else {
6218 child_result_loc = parent_result_loc;
6219 if (parent_result_loc->source_instruction != nullptr) {
6220 init_array_type_source_node = parent_result_loc->source_instruction->source_node;
6221 } else {
6222 init_array_type_source_node = node;
6223 }
6224 }
6225
6226 switch (kind) {
6227 case ContainerInitKindStruct: {
6228 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
6229 nullptr);
61346230
6135 size_t field_count = container_init_expr->entries.length;6231 size_t field_count = container_init_expr->entries.length;
6136 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);6232 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
...@@ -6158,29 +6254,27 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6158,29 +6254,27 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6158 fields[i].source_node = entry_node;6254 fields[i].source_node = entry_node;
6159 fields[i].result_loc = field_ptr;6255 fields[i].result_loc = field_ptr;
6160 }6256 }
6161 IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type,6257 IrInstruction *result = ir_build_container_init_fields(irb, scope, node, field_count,
6162 field_count, fields, container_ptr);6258 fields, container_ptr);
61636259
6164 return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc);6260 if (result_loc_cast != nullptr) {
6261 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
6262 }
6263 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
6165 }6264 }
6166 case ContainerInitKindArray: {6265 case ContainerInitKindArray: {
6167 size_t item_count = container_init_expr->entries.length;6266 size_t item_count = container_init_expr->entries.length;
61686267
6169 if (container_type == nullptr) {6268 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
6170 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);6269 nullptr);
6171 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
6172 }
6173
6174 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
6175 container_type);
61766270
6177 IrInstruction **result_locs = allocate<IrInstruction *>(item_count);6271 IrInstruction **result_locs = allocate<IrInstruction *>(item_count);
6178 for (size_t i = 0; i < item_count; i += 1) {6272 for (size_t i = 0; i < item_count; i += 1) {
6179 AstNode *expr_node = container_init_expr->entries.at(i);6273 AstNode *expr_node = container_init_expr->entries.at(i);
61806274
6181 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i);6275 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
6182 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index,6276 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr,
6183 false, PtrLenSingle, container_type);6277 elem_index, false, PtrLenSingle, init_array_type_source_node);
6184 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);6278 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
6185 result_loc_inst->base.id = ResultLocIdInstruction;6279 result_loc_inst->base.id = ResultLocIdInstruction;
6186 result_loc_inst->base.source_instruction = elem_ptr;6280 result_loc_inst->base.source_instruction = elem_ptr;
...@@ -6195,9 +6289,12 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6195,9 +6289,12 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
61956289
6196 result_locs[i] = elem_ptr;6290 result_locs[i] = elem_ptr;
6197 }6291 }
6198 IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type,6292 IrInstruction *result = ir_build_container_init_list(irb, scope, node, item_count,
6199 item_count, result_locs, container_ptr);6293 result_locs, container_ptr, init_array_type_source_node);
6200 return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc);6294 if (result_loc_cast != nullptr) {
6295 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
6296 }
6297 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
6201 }6298 }
6202 }6299 }
6203 zig_unreachable();6300 zig_unreachable();
...@@ -6214,6 +6311,20 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo...@@ -6214,6 +6311,20 @@ static ResultLocVar *ir_build_var_result_loc(IrBuilder *irb, IrInstruction *allo
6214 return result_loc_var;6311 return result_loc_var;
6215}6312}
62166313
6314static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *dest_type,
6315 ResultLoc *parent_result_loc)
6316{
6317 ResultLocCast *result_loc_cast = allocate<ResultLocCast>(1);
6318 result_loc_cast->base.id = ResultLocIdCast;
6319 result_loc_cast->base.source_instruction = dest_type;
6320 ir_ref_instruction(dest_type, irb->current_basic_block);
6321 result_loc_cast->parent = parent_result_loc;
6322
6323 ir_build_reset_result(irb, dest_type->scope, dest_type->source_node, &result_loc_cast->base);
6324
6325 return result_loc_cast;
6326}
6327
6217static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var,6328static void build_decl_var_and_init(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var,
6218 IrInstruction *init, const char *name_hint, IrInstruction *is_comptime)6329 IrInstruction *init, const char *name_hint, IrInstruction *is_comptime)
6219{6330{
...@@ -6282,7 +6393,15 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -6282,7 +6393,15 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
62826393
6283 // Create a result location for the initialization expression.6394 // Create a result location for the initialization expression.
6284 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);6395 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var);
6285 ResultLoc *init_result_loc = (type_instruction == nullptr) ? &result_loc_var->base : nullptr;6396 ResultLoc *init_result_loc;
6397 ResultLocCast *result_loc_cast;
6398 if (type_instruction != nullptr) {
6399 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base);
6400 init_result_loc = &result_loc_cast->base;
6401 } else {
6402 result_loc_cast = nullptr;
6403 init_result_loc = &result_loc_var->base;
6404 }
62866405
6287 Scope *init_scope = is_comptime_scalar ?6406 Scope *init_scope = is_comptime_scalar ?
6288 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope;6407 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope;
...@@ -6298,9 +6417,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -6298,9 +6417,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
6298 if (init_value == irb->codegen->invalid_instruction)6417 if (init_value == irb->codegen->invalid_instruction)
6299 return irb->codegen->invalid_instruction;6418 return irb->codegen->invalid_instruction;
63006419
6301 if (type_instruction != nullptr) {6420 if (result_loc_cast != nullptr) {
6302 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, node, type_instruction, init_value,6421 IrInstruction *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->source_node,
6303 &result_loc_var->base);6422 init_value, result_loc_cast);
6304 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);6423 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base);
6305 }6424 }
63066425
...@@ -7895,14 +8014,14 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o...@@ -7895,14 +8014,14 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o
7895static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,8014static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,
7896 Scope *scope, AstNode *source_node, Buf *out_bare_name)8015 Scope *scope, AstNode *source_node, Buf *out_bare_name)
7897{8016{
7898 if (exec->name) {8017 if (exec != nullptr && exec->name) {
7899 ZigType *import = get_scope_import(scope);8018 ZigType *import = get_scope_import(scope);
7900 Buf *namespace_name = buf_alloc();8019 Buf *namespace_name = buf_alloc();
7901 append_namespace_qualification(codegen, namespace_name, import);8020 append_namespace_qualification(codegen, namespace_name, import);
7902 buf_append_buf(namespace_name, exec->name);8021 buf_append_buf(namespace_name, exec->name);
7903 buf_init_from_buf(out_bare_name, exec->name);8022 buf_init_from_buf(out_bare_name, exec->name);
7904 return namespace_name;8023 return namespace_name;
7905 } else if (exec->name_fn != nullptr) {8024 } else if (exec != nullptr && exec->name_fn != nullptr) {
7906 Buf *name = buf_alloc();8025 Buf *name = buf_alloc();
7907 buf_append_buf(name, &exec->name_fn->symbol_name);8026 buf_append_buf(name, &exec->name_fn->symbol_name);
7908 buf_appendf(name, "(");8027 buf_appendf(name, "(");
...@@ -8009,7 +8128,6 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp...@@ -8009,7 +8128,6 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp
8009 }8128 }
8010 }8129 }
8011 assert(index == count);8130 assert(index == count);
8012 assert(count != 0);
80138131
8014 if (type_name == nullptr) {8132 if (type_name == nullptr) {
8015 buf_appendf(&err_set_type->name, "}");8133 buf_appendf(&err_set_type->name, "}");
...@@ -9571,7 +9689,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -9571,7 +9689,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
9571 }9689 }
95729690
9573 ir_add_error(ira, instruction,9691 ir_add_error(ira, instruction,
9574 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'",9692 buf_sprintf("%s value %s cannot be coerced to type '%s'",
9575 num_lit_str,9693 num_lit_str,
9576 buf_ptr(val_buf),9694 buf_ptr(val_buf),
9577 buf_ptr(&other_type->name)));9695 buf_ptr(&other_type->name)));
...@@ -9739,8 +9857,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -9739,8 +9857,8 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
97399857
9740 // slice const9858 // slice const
9741 if (is_slice(wanted_type) && is_slice(actual_type)) {9859 if (is_slice(wanted_type) && is_slice(actual_type)) {
9742 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry;9860 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry;
9743 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;9861 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
9744 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {9862 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) {
9745 result.id = ConstCastResultIdInvalid;9863 result.id = ConstCastResultIdInvalid;
9746 return result;9864 return result;
...@@ -10494,22 +10612,67 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT...@@ -10494,22 +10612,67 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT
10494 continue;10612 continue;
10495 }10613 }
1049610614
10615 // *[N]T to []T
10616 // *[N]T to E![]T
10617 if (cur_type->id == ZigTypeIdPointer &&
10618 cur_type->data.pointer.child_type->id == ZigTypeIdArray &&
10619 ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) ||
10620 is_slice(prev_type)))
10621 {
10622 ZigType *array_type = cur_type->data.pointer.child_type;
10623 ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ?
10624 prev_type->data.error_union.payload_type : prev_type;
10625 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
10626 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
10627 types_match_const_cast_only(ira,
10628 slice_ptr_type->data.pointer.child_type,
10629 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
10630 {
10631 convert_to_const_slice = false;
10632 continue;
10633 }
10634 }
10635
10636 // *[N]T to []T
10637 // *[N]T to E![]T
10638 if (prev_type->id == ZigTypeIdPointer &&
10639 prev_type->data.pointer.child_type->id == ZigTypeIdArray &&
10640 ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) ||
10641 is_slice(cur_type)))
10642 {
10643 ZigType *array_type = prev_type->data.pointer.child_type;
10644 ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ?
10645 cur_type->data.error_union.payload_type : cur_type;
10646 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
10647 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0) &&
10648 types_match_const_cast_only(ira,
10649 slice_ptr_type->data.pointer.child_type,
10650 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
10651 {
10652 prev_inst = cur_inst;
10653 convert_to_const_slice = false;
10654 continue;
10655 }
10656 }
10657
10658 // [N]T to []T
10497 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) &&10659 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) &&
10498 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||10660 (prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const ||
10499 cur_type->data.array.len == 0) &&10661 cur_type->data.array.len == 0) &&
10500 types_match_const_cast_only(ira,10662 types_match_const_cast_only(ira,
10501 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,10663 prev_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type,
10502 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)10664 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
10503 {10665 {
10504 convert_to_const_slice = false;10666 convert_to_const_slice = false;
10505 continue;10667 continue;
10506 }10668 }
1050710669
10670 // [N]T to []T
10508 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) &&10671 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) &&
10509 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const ||10672 (cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const ||
10510 prev_type->data.array.len == 0) &&10673 prev_type->data.array.len == 0) &&
10511 types_match_const_cast_only(ira,10674 types_match_const_cast_only(ira,
10512 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type,10675 cur_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type,
10513 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)10676 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk)
10514 {10677 {
10515 prev_inst = cur_inst;10678 prev_inst = cur_inst;
...@@ -10620,9 +10783,9 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_...@@ -10620,9 +10783,9 @@ static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_
10620 if (src->special != ConstValSpecialStatic)10783 if (src->special != ConstValSpecialStatic)
10621 return;10784 return;
10622 if (dest->type->id == ZigTypeIdStruct) {10785 if (dest->type->id == ZigTypeIdStruct) {
10623 dest->data.x_struct.fields = create_const_vals(dest->type->data.structure.src_field_count);10786 dest->data.x_struct.fields = alloc_const_vals_ptrs(dest->type->data.structure.src_field_count);
10624 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {10787 for (size_t i = 0; i < dest->type->data.structure.src_field_count; i += 1) {
10625 copy_const_val(&dest->data.x_struct.fields[i], &src->data.x_struct.fields[i], false);10788 copy_const_val(dest->data.x_struct.fields[i], src->data.x_struct.fields[i], false);
10626 }10789 }
10627 }10790 }
10628 }10791 }
...@@ -10814,12 +10977,11 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc...@@ -10814,12 +10977,11 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc
10814 assert(value->value.type->id == ZigTypeIdPointer);10977 assert(value->value.type->id == ZigTypeIdPointer);
10815 ZigType *array_type = value->value.type->data.pointer.child_type;10978 ZigType *array_type = value->value.type->data.pointer.child_type;
10816 assert(is_slice(wanted_type));10979 assert(is_slice(wanted_type));
10817 bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const;10980 bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const;
1081810981
10819 IrInstruction *result = ir_const(ira, source_instr, wanted_type);10982 IrInstruction *result = ir_const(ira, source_instr, wanted_type);
10820 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const);10983 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const);
10821 result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut =10984 result->value.data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = value->value.data.x_ptr.mut;
10822 value->value.data.x_ptr.mut;
10823 result->value.type = wanted_type;10985 result->value.type = wanted_type;
10824 return result;10986 return result;
10825 }10987 }
...@@ -12401,6 +12563,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou...@@ -12401,6 +12563,27 @@ static IrInstruction *ir_analyze_enum_literal(IrAnalyze *ira, IrInstruction *sou
12401 return result;12563 return result;
12402}12564}
1240312565
12566static IrInstruction *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInstruction *source_instr,
12567 IrInstruction *value, ZigType *wanted_type)
12568{
12569 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array"));
12570 return ira->codegen->invalid_instruction;
12571}
12572
12573static IrInstruction *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInstruction *source_instr,
12574 IrInstruction *value, ZigType *wanted_type)
12575{
12576 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct"));
12577 return ira->codegen->invalid_instruction;
12578}
12579
12580static IrInstruction *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInstruction *source_instr,
12581 IrInstruction *value, ZigType *wanted_type)
12582{
12583 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union"));
12584 return ira->codegen->invalid_instruction;
12585}
12586
12404static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,12587static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
12405 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)12588 ZigType *wanted_type, IrInstruction *value, ResultLoc *result_loc)
12406{12589{
...@@ -12412,6 +12595,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12412,6 +12595,11 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12412 return ira->codegen->invalid_instruction;12595 return ira->codegen->invalid_instruction;
12413 }12596 }
1241412597
12598 // This means the wanted type is anything.
12599 if (wanted_type == ira->codegen->builtin_types.entry_var) {
12600 return value;
12601 }
12602
12415 // perfect match or non-const to const12603 // perfect match or non-const to const
12416 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,12604 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type,
12417 source_node, false);12605 source_node, false);
...@@ -12586,7 +12774,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12586,7 +12774,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12586 // cast from [N]T to []const T12774 // cast from [N]T to []const T
12587 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this12775 // TODO: once https://github.com/ziglang/zig/issues/265 lands, remove this
12588 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) {12776 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) {
12589 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;12777 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry;
12590 assert(ptr_type->id == ZigTypeIdPointer);12778 assert(ptr_type->id == ZigTypeIdPointer);
12591 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&12779 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
12592 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12780 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
...@@ -12603,7 +12791,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12603,7 +12791,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12603 actual_type->id == ZigTypeIdArray)12791 actual_type->id == ZigTypeIdArray)
12604 {12792 {
12605 ZigType *ptr_type =12793 ZigType *ptr_type =
12606 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry;12794 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index]->type_entry;
12607 assert(ptr_type->id == ZigTypeIdPointer);12795 assert(ptr_type->id == ZigTypeIdPointer);
12608 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&12796 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
12609 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12797 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
...@@ -12642,12 +12830,71 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12642,12 +12830,71 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12642 }12830 }
1264312831
12644 // *[N]T to []T12832 // *[N]T to []T
12645 if (is_slice(wanted_type) &&12833 // *[N]T to E![]T
12834 if ((is_slice(wanted_type) ||
12835 (wanted_type->id == ZigTypeIdErrorUnion &&
12836 is_slice(wanted_type->data.error_union.payload_type))) &&
12646 actual_type->id == ZigTypeIdPointer &&12837 actual_type->id == ZigTypeIdPointer &&
12647 actual_type->data.pointer.ptr_len == PtrLenSingle &&12838 actual_type->data.pointer.ptr_len == PtrLenSingle &&
12648 actual_type->data.pointer.child_type->id == ZigTypeIdArray)12839 actual_type->data.pointer.child_type->id == ZigTypeIdArray)
12649 {12840 {
12650 ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry;12841 ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ?
12842 wanted_type->data.error_union.payload_type : wanted_type;
12843 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
12844 assert(slice_ptr_type->id == ZigTypeIdPointer);
12845 ZigType *array_type = actual_type->data.pointer.child_type;
12846 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
12847 || !actual_type->data.pointer.is_const);
12848 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type,
12849 array_type->data.array.child_type, source_node,
12850 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk)
12851 {
12852 // If the pointers both have ABI align, it works.
12853 // Or if the array length is 0, alignment doesn't matter.
12854 bool ok_align = array_type->data.array.len == 0 ||
12855 (slice_ptr_type->data.pointer.explicit_alignment == 0 &&
12856 actual_type->data.pointer.explicit_alignment == 0);
12857 if (!ok_align) {
12858 // If either one has non ABI align, we have to resolve them both
12859 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type,
12860 ResolveStatusAlignmentKnown)))
12861 {
12862 return ira->codegen->invalid_instruction;
12863 }
12864 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type,
12865 ResolveStatusAlignmentKnown)))
12866 {
12867 return ira->codegen->invalid_instruction;
12868 }
12869 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);
12870 }
12871 if (ok_align) {
12872 if (wanted_type->id == ZigTypeIdErrorUnion) {
12873 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value, nullptr);
12874 if (type_is_invalid(cast1->value.type))
12875 return ira->codegen->invalid_instruction;
12876
12877 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1, result_loc);
12878 if (type_is_invalid(cast2->value.type))
12879 return ira->codegen->invalid_instruction;
12880
12881 return cast2;
12882 } else {
12883 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, result_loc);
12884 }
12885 }
12886 }
12887 }
12888
12889 // *[N]T to E![]T
12890 if (wanted_type->id == ZigTypeIdErrorUnion &&
12891 is_slice(wanted_type->data.error_union.payload_type) &&
12892 actual_type->id == ZigTypeIdPointer &&
12893 actual_type->data.pointer.ptr_len == PtrLenSingle &&
12894 actual_type->data.pointer.child_type->id == ZigTypeIdArray)
12895 {
12896 ZigType *slice_type = wanted_type->data.error_union.payload_type;
12897 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry;
12651 assert(slice_ptr_type->id == ZigTypeIdPointer);12898 assert(slice_ptr_type->id == ZigTypeIdPointer);
12652 ZigType *array_type = actual_type->data.pointer.child_type;12899 ZigType *array_type = actual_type->data.pointer.child_type;
12653 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 012900 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0
...@@ -12674,7 +12921,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12674,7 +12921,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12674 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);12921 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type);
12675 }12922 }
12676 if (ok_align) {12923 if (ok_align) {
12677 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type, result_loc);12924 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, result_loc);
12678 }12925 }
12679 }12926 }
12680 }12927 }
...@@ -12724,7 +12971,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12724,7 +12971,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12724 actual_type->id == ZigTypeIdArray)12971 actual_type->id == ZigTypeIdArray)
12725 {12972 {
12726 ZigType *ptr_type =12973 ZigType *ptr_type =
12727 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry;12974 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index]->type_entry;
12728 assert(ptr_type->id == ZigTypeIdPointer);12975 assert(ptr_type->id == ZigTypeIdPointer);
12729 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&12976 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) &&
12730 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,12977 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type,
...@@ -12909,6 +13156,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12909,6 +13156,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12909 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);13156 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type);
12910 }13157 }
1291113158
13159 // cast from inferred struct type to array, union, or struct
13160 if (actual_type->id == ZigTypeIdStruct && actual_type->data.structure.is_inferred) {
13161 AstNode *decl_node = actual_type->data.structure.decl_node;
13162 ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr);
13163 ContainerInitKind init_kind = decl_node->data.container_init_expr.kind;
13164 uint32_t field_count = actual_type->data.structure.src_field_count;
13165 if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) &&
13166 wanted_type->data.array.len == field_count)
13167 {
13168 return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type);
13169 } else if (wanted_type->id == ZigTypeIdStruct &&
13170 (init_kind == ContainerInitKindStruct || field_count == 0))
13171 {
13172 return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type);
13173 } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) {
13174 return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type);
13175 }
13176 }
13177
12912 // cast from undefined to anything13178 // cast from undefined to anything
12913 if (actual_type->id == ZigTypeIdUndefined) {13179 if (actual_type->id == ZigTypeIdUndefined) {
12914 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);13180 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
...@@ -12922,8 +13188,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -12922,8 +13188,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
12922 return ira->codegen->invalid_instruction;13188 return ira->codegen->invalid_instruction;
12923}13189}
1292413190
12925static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type,13191static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction *source_instr,
12926 ResultLoc *result_loc)13192 IrInstruction *value, ZigType *expected_type, ResultLoc *result_loc)
12927{13193{
12928 assert(value);13194 assert(value);
12929 assert(value != ira->codegen->invalid_instruction);13195 assert(value != ira->codegen->invalid_instruction);
...@@ -12937,11 +13203,11 @@ static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction...@@ -12937,11 +13203,11 @@ static IrInstruction *ir_implicit_cast_with_result(IrAnalyze *ira, IrInstruction
12937 if (value->value.type->id == ZigTypeIdUnreachable)13203 if (value->value.type->id == ZigTypeIdUnreachable)
12938 return value;13204 return value;
1293913205
12940 return ir_analyze_cast(ira, value, expected_type, value, result_loc);13206 return ir_analyze_cast(ira, source_instr, expected_type, value, result_loc);
12941}13207}
1294213208
12943static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {13209static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) {
12944 return ir_implicit_cast_with_result(ira, value, expected_type, nullptr);13210 return ir_implicit_cast_with_result(ira, value, value, expected_type, nullptr);
12945}13211}
1294613212
12947static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,13213static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr,
...@@ -13223,8 +13489,8 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {...@@ -13223,8 +13489,8 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) {
13223 if (!const_val)13489 if (!const_val)
13224 return nullptr;13490 return nullptr;
1322513491
13226 ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index];13492 ConstExprValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index];
13227 ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index];13493 ConstExprValue *len_field = const_val->data.x_struct.fields[slice_len_index];
1322813494
13229 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);13495 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray);
13230 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;13496 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val;
...@@ -13269,16 +13535,6 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio...@@ -13269,16 +13535,6 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
13269 if (type_is_invalid(operand->value.type))13535 if (type_is_invalid(operand->value.type))
13270 return ir_unreach_error(ira);13536 return ir_unreach_error(ira);
1327113537
13272 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
13273 handle_is_ptr(ira->explicit_return_type))
13274 {
13275 // result location mechanism took care of it.
13276 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
13277 instruction->base.source_node, nullptr);
13278 result->value.type = ira->codegen->builtin_types.entry_unreachable;
13279 return ir_finish_anal(ira, result);
13280 }
13281
13282 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);13538 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type);
13283 if (type_is_invalid(casted_operand->value.type)) {13539 if (type_is_invalid(casted_operand->value.type)) {
13284 AstNode *source_node = ira->explicit_return_type_source_node;13540 AstNode *source_node = ira->explicit_return_type_source_node;
...@@ -13290,6 +13546,16 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio...@@ -13290,6 +13546,16 @@ static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructio
13290 return ir_unreach_error(ira);13546 return ir_unreach_error(ira);
13291 }13547 }
1329213548
13549 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr &&
13550 handle_is_ptr(ira->explicit_return_type))
13551 {
13552 // result location mechanism took care of it.
13553 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope,
13554 instruction->base.source_node, nullptr);
13555 result->value.type = ira->codegen->builtin_types.entry_unreachable;
13556 return ir_finish_anal(ira, result);
13557 }
13558
13293 if (casted_operand->value.special == ConstValSpecialRuntime &&13559 if (casted_operand->value.special == ConstValSpecialRuntime &&
13294 casted_operand->value.type->id == ZigTypeIdPointer &&13560 casted_operand->value.type->id == ZigTypeIdPointer &&
13295 casted_operand->value.data.rh_ptr == RuntimeHintPtrStack)13561 casted_operand->value.data.rh_ptr == RuntimeHintPtrStack)
...@@ -14550,13 +14816,13 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -14550,13 +14816,13 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
14550 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index;14816 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index;
14551 op1_array_end = op1_array_val->type->data.array.len - 1;14817 op1_array_end = op1_array_val->type->data.array.len - 1;
14552 } else if (is_slice(op1_type)) {14818 } else if (is_slice(op1_type)) {
14553 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry;14819 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry;
14554 child_type = ptr_type->data.pointer.child_type;14820 child_type = ptr_type->data.pointer.child_type;
14555 ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index];14821 ConstExprValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index];
14556 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);14822 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
14557 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;14823 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
14558 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;14824 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
14559 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index];14825 ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index];
14560 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint);14826 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint);
14561 } else {14827 } else {
14562 ir_add_error(ira, op1,14828 ir_add_error(ira, op1,
...@@ -14583,13 +14849,13 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -14583,13 +14849,13 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
14583 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;14849 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index;
14584 op2_array_end = op2_array_val->type->data.array.len - 1;14850 op2_array_end = op2_array_val->type->data.array.len - 1;
14585 } else if (is_slice(op2_type)) {14851 } else if (is_slice(op2_type)) {
14586 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry;14852 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry;
14587 op2_type_valid = ptr_type->data.pointer.child_type == child_type;14853 op2_type_valid = ptr_type->data.pointer.child_type == child_type;
14588 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index];14854 ConstExprValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index];
14589 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);14855 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray);
14590 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;14856 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val;
14591 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;14857 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index;
14592 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index];14858 ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index];
14593 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint);14859 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint);
14594 } else {14860 } else {
14595 ir_add_error(ira, op2,14861 ir_add_error(ira, op2,
...@@ -14621,17 +14887,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i...@@ -14621,17 +14887,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i
14621 out_array_val->special = ConstValSpecialStatic;14887 out_array_val->special = ConstValSpecialStatic;
14622 out_array_val->type = get_array_type(ira->codegen, child_type, new_len);14888 out_array_val->type = get_array_type(ira->codegen, child_type, new_len);
1462314889
14624 out_val->data.x_struct.fields = create_const_vals(2);14890 out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
1462514891
14626 out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type;14892 out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type;
14627 out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic;14893 out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic;
14628 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray;14894 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray;
14629 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val;14895 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val;
14630 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0;14896 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0;
1463114897
14632 out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize;14898 out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize;
14633 out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic;14899 out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic;
14634 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len);14900 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len);
14635 } else {14901 } else {
14636 new_len += 1; // null byte14902 new_len += 1; // null byte
1463714903
...@@ -15295,15 +15561,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in...@@ -15295,15 +15561,16 @@ static IrInstruction *ir_analyze_alloca(IrAnalyze *ira, IrInstruction *source_in
15295 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;15561 result->base.value.data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer;
15296 result->base.value.data.x_ptr.data.ref.pointee = pointee;15562 result->base.value.data.x_ptr.data.ref.pointee = pointee;
1529715563
15298 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusZeroBitsKnown)))15564 bool var_type_has_bits;
15565 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits)))
15299 return ira->codegen->invalid_instruction;15566 return ira->codegen->invalid_instruction;
15300 if (align != 0) {15567 if (align != 0) {
15301 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))15568 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown)))
15302 return ira->codegen->invalid_instruction;15569 return ira->codegen->invalid_instruction;
15303 if (!type_has_bits(var_type)) {15570 if (!var_type_has_bits) {
15304 ir_add_error(ira, source_inst,15571 ir_add_error(ira, source_inst,
15305 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",15572 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned",
15306 name_hint, buf_ptr(&var_type->name)));15573 name_hint, buf_ptr(&var_type->name)));
15307 return ira->codegen->invalid_instruction;15574 return ira->codegen->invalid_instruction;
15308 }15575 }
15309 }15576 }
...@@ -15331,6 +15598,7 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspe...@@ -15331,6 +15598,7 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInstruction *suspe
15331 case ResultLocIdNone:15598 case ResultLocIdNone:
15332 case ResultLocIdVar:15599 case ResultLocIdVar:
15333 case ResultLocIdBitCast:15600 case ResultLocIdBitCast:
15601 case ResultLocIdCast:
15334 return nullptr;15602 return nullptr;
15335 case ResultLocIdInstruction:15603 case ResultLocIdInstruction:
15336 return result_loc->source_instruction->child->value.type;15604 return result_loc->source_instruction->child->value.type;
...@@ -15374,24 +15642,51 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {...@@ -15374,24 +15642,51 @@ static void set_up_result_loc_for_inferred_comptime(IrInstruction *ptr) {
15374 ptr->value.data.x_ptr.data.ref.pointee = undef_child;15642 ptr->value.data.x_ptr.data.ref.pointee = undef_child;
15375}15643}
1537615644
15377static bool ir_result_has_type(ResultLoc *result_loc) {15645static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) {
15378 switch (result_loc->id) {15646 switch (result_loc->id) {
15379 case ResultLocIdInvalid:15647 case ResultLocIdInvalid:
15380 case ResultLocIdPeerParent:15648 case ResultLocIdPeerParent:
15381 zig_unreachable();15649 zig_unreachable();
15382 case ResultLocIdNone:15650 case ResultLocIdNone:
15383 case ResultLocIdPeer:15651 case ResultLocIdPeer:
15384 return false;15652 *out = false;
15653 return ErrorNone;
15385 case ResultLocIdReturn:15654 case ResultLocIdReturn:
15386 case ResultLocIdInstruction:15655 case ResultLocIdInstruction:
15387 case ResultLocIdBitCast:15656 case ResultLocIdBitCast:
15388 return true;15657 *out = true;
15658 return ErrorNone;
15659 case ResultLocIdCast: {
15660 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc);
15661 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
15662 if (type_is_invalid(dest_type))
15663 return ErrorSemanticAnalyzeFail;
15664 *out = (dest_type != ira->codegen->builtin_types.entry_var);
15665 return ErrorNone;
15666 }
15389 case ResultLocIdVar:15667 case ResultLocIdVar:
15390 return reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;15668 *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr;
15669 return ErrorNone;
15391 }15670 }
15392 zig_unreachable();15671 zig_unreachable();
15393}15672}
1539415673
15674static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15675 ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime)
15676{
15677 IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
15678 alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
15679 PtrLenSingle, 0, 0, 0, false);
15680 set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
15681 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
15682 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
15683 fn_entry->alloca_gen_list.append(alloca_gen);
15684 }
15685 result_loc->written = true;
15686 result_loc->resolved_loc = &alloca_gen->base;
15687 return result_loc->resolved_loc;
15688}
15689
15395// when calling this function, at the callsite must check for result type noreturn and propagate it up15690// when calling this function, at the callsite must check for result type noreturn and propagate it up
15396static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,15691static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspend_source_instr,
15397 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime)15692 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value, bool force_runtime, bool non_null_comptime)
...@@ -15414,19 +15709,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15414,19 +15709,8 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15414 return nullptr;15709 return nullptr;
15415 }15710 }
15416 // need to return a result location and don't have one. use a stack allocation15711 // need to return a result location and don't have one. use a stack allocation
15417 IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");15712 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
15418 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))15713 force_runtime, non_null_comptime);
15419 return ira->codegen->invalid_instruction;
15420 alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
15421 PtrLenSingle, 0, 0, 0, false);
15422 set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
15423 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
15424 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) {
15425 fn_entry->alloca_gen_list.append(alloca_gen);
15426 }
15427 result_loc->written = true;
15428 result_loc->resolved_loc = &alloca_gen->base;
15429 return result_loc->resolved_loc;
15430 }15714 }
15431 case ResultLocIdVar: {15715 case ResultLocIdVar: {
15432 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc);15716 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc);
...@@ -15529,7 +15813,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15529,7 +15813,10 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15529 }15813 }
15530 return nullptr;15814 return nullptr;
15531 }15815 }
15532 if (ir_result_has_type(peer_parent->parent)) {15816 bool peer_parent_has_type;
15817 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
15818 return ira->codegen->invalid_instruction;
15819 if (peer_parent_has_type) {
15533 if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {15820 if (peer_parent->parent->id == ResultLocIdReturn && value != nullptr) {
15534 reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true;15821 reinterpret_cast<ResultLocReturn *>(peer_parent->parent)->implicit_return_type_done = true;
15535 ira->src_implicit_return_type_list.append(value);15822 ira->src_implicit_return_type_list.append(value);
...@@ -15564,6 +15851,89 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe...@@ -15564,6 +15851,89 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
15564 result_loc->resolved_loc = parent_result_loc;15851 result_loc->resolved_loc = parent_result_loc;
15565 return result_loc->resolved_loc;15852 return result_loc->resolved_loc;
15566 }15853 }
15854 case ResultLocIdCast: {
15855 if (value != nullptr && value->value.special != ConstValSpecialRuntime)
15856 return nullptr;
15857 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc);
15858 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child);
15859 if (type_is_invalid(dest_type))
15860 return ira->codegen->invalid_instruction;
15861
15862 if (dest_type == ira->codegen->builtin_types.entry_var) {
15863 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
15864 force_runtime, non_null_comptime);
15865 }
15866
15867 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, dest_type, value_type,
15868 result_cast->base.source_instruction->source_node, false);
15869 if (const_cast_result.id == ConstCastResultIdInvalid)
15870 return ira->codegen->invalid_instruction;
15871 if (const_cast_result.id != ConstCastResultIdOk) {
15872 // We will not be able to provide a result location for this value. Create
15873 // a new result location.
15874 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
15875 force_runtime, non_null_comptime);
15876 }
15877
15878 // In this case we can pointer cast the result location.
15879 IrInstruction *casted_value;
15880 if (value != nullptr) {
15881 casted_value = ir_implicit_cast(ira, value, dest_type);
15882 } else {
15883 casted_value = nullptr;
15884 }
15885
15886 if (casted_value != nullptr && type_is_invalid(casted_value->value.type)) {
15887 return casted_value;
15888 }
15889
15890 bool old_parent_result_loc_written = result_cast->parent->written;
15891 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent,
15892 dest_type, casted_value, force_runtime, non_null_comptime, true);
15893 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
15894 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
15895 {
15896 return parent_result_loc;
15897 }
15898 ZigType *parent_ptr_type = parent_result_loc->value.type;
15899 assert(parent_ptr_type->id == ZigTypeIdPointer);
15900 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type,
15901 ResolveStatusAlignmentKnown)))
15902 {
15903 return ira->codegen->invalid_instruction;
15904 }
15905 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type);
15906 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) {
15907 return ira->codegen->invalid_instruction;
15908 }
15909 if (!type_has_bits(value_type)) {
15910 parent_ptr_align = 0;
15911 }
15912 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type,
15913 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
15914 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
15915
15916 {
15917 // we also need to check that this cast is OK.
15918 ConstCastOnly const_cast_result = types_match_const_cast_only(ira,
15919 parent_result_loc->value.type, ptr_type,
15920 result_cast->base.source_instruction->source_node, false);
15921 if (const_cast_result.id == ConstCastResultIdInvalid)
15922 return ira->codegen->invalid_instruction;
15923 if (const_cast_result.id != ConstCastResultIdOk) {
15924 // We will not be able to provide a result location for this value. Create
15925 // a new result location.
15926 result_cast->parent->written = old_parent_result_loc_written;
15927 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
15928 force_runtime, non_null_comptime);
15929 }
15930 }
15931
15932 result_loc->written = true;
15933 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
15934 ptr_type, result_cast->base.source_instruction, false);
15935 return result_loc->resolved_loc;
15936 }
15567 case ResultLocIdBitCast: {15937 case ResultLocIdBitCast: {
15568 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc);15938 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc);
15569 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child);15939 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child);
...@@ -15686,22 +16056,40 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s...@@ -15686,22 +16056,40 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
15686 return result_loc;16056 return result_loc;
15687}16057}
1568816058
15689static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {16059static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
15690 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child);16060 IrInstructionResolveResult *instruction)
15691 if (type_is_invalid(dest_type))16061{
15692 return ira->codegen->invalid_instruction;16062 ZigType *implicit_elem_type;
1569316063 if (instruction->ty == nullptr) {
15694 IrInstruction *target = instruction->target->child;16064 if (instruction->result_loc->id == ResultLocIdCast) {
15695 if (type_is_invalid(target->value.type))16065 implicit_elem_type = ir_resolve_type(ira,
15696 return ira->codegen->invalid_instruction;16066 instruction->result_loc->source_instruction->child);
1569716067 if (type_is_invalid(implicit_elem_type))
15698 return ir_implicit_cast_with_result(ira, target, dest_type, instruction->result_loc);16068 return ira->codegen->invalid_instruction;
15699}16069 } else if (instruction->result_loc->id == ResultLocIdReturn) {
16070 implicit_elem_type = ira->explicit_return_type;
16071 if (type_is_invalid(implicit_elem_type))
16072 return ira->codegen->invalid_instruction;
16073 } else {
16074 implicit_elem_type = ira->codegen->builtin_types.entry_var;
16075 }
16076 if (implicit_elem_type == ira->codegen->builtin_types.entry_var) {
16077 Buf *bare_name = buf_alloc();
16078 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
16079 instruction->base.scope, instruction->base.source_node, bare_name);
1570016080
15701static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {16081 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen,
15702 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);16082 instruction->base.scope, ContainerKindStruct, instruction->base.source_node,
15703 if (type_is_invalid(implicit_elem_type))16083 buf_ptr(name), bare_name, ContainerLayoutAuto);
15704 return ira->codegen->invalid_instruction;16084 inferred_struct_type->data.structure.is_inferred = true;
16085 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred;
16086 implicit_elem_type = inferred_struct_type;
16087 }
16088 } else {
16089 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
16090 if (type_is_invalid(implicit_elem_type))
16091 return ira->codegen->invalid_instruction;
16092 }
15705 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,16093 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
15706 implicit_elem_type, nullptr, false, true, true);16094 implicit_elem_type, nullptr, false, true, true);
15707 if (result_loc != nullptr)16095 if (result_loc != nullptr)
...@@ -15760,6 +16148,7 @@ static void ir_reset_result(ResultLoc *result_loc) {...@@ -15760,6 +16148,7 @@ static void ir_reset_result(ResultLoc *result_loc) {
15760 case ResultLocIdNone:16148 case ResultLocIdNone:
15761 case ResultLocIdInstruction:16149 case ResultLocIdInstruction:
15762 case ResultLocIdBitCast:16150 case ResultLocIdBitCast:
16151 case ResultLocIdCast:
15763 break;16152 break;
15764 }16153 }
15765}16154}
...@@ -16062,13 +16451,63 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -16062,13 +16451,63 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
16062 return ir_const_void(ira, source_instr);16451 return ir_const_void(ira, source_instr);
16063 }16452 }
1606416453
16065 ZigType *child_type = ptr->value.type->data.pointer.child_type;16454 InferredStructField *isf = ptr->value.type->data.pointer.inferred_struct_field;
16455 if (allow_write_through_const && isf != nullptr) {
16456 // Now it's time to add the field to the struct type.
16457 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
16458 uint32_t new_field_count = old_field_count + 1;
16459 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
16460 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields(
16461 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count);
16462
16463 TypeStructField *field = isf->inferred_struct_type->data.structure.fields[old_field_count];
16464 field->name = isf->field_name;
16465 field->type_entry = uncasted_value->value.type;
16466 field->type_val = create_const_type(ira->codegen, field->type_entry);
16467 field->src_index = old_field_count;
16468 field->decl_node = uncasted_value->source_node;
16469
16470 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
16471 IrInstruction *casted_ptr;
16472 if (instr_is_comptime(ptr)) {
16473 casted_ptr = ir_const(ira, source_instr, struct_ptr_type);
16474 copy_const_val(&casted_ptr->value, &ptr->value, false);
16475 casted_ptr->value.type = struct_ptr_type;
16476 } else {
16477 casted_ptr = ir_build_cast(&ira->new_irb, source_instr->scope,
16478 source_instr->source_node, struct_ptr_type, ptr, CastOpNoop);
16479 casted_ptr->value.type = struct_ptr_type;
16480 }
16481 if (instr_is_comptime(casted_ptr)) {
16482 ConstExprValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad);
16483 if (!ptr_val)
16484 return ira->codegen->invalid_instruction;
16485 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
16486 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
16487 source_instr->source_node);
16488 struct_val->special = ConstValSpecialStatic;
16489 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(struct_val->data.x_struct.fields,
16490 old_field_count, new_field_count);
16491
16492 ConstExprValue *field_val = struct_val->data.x_struct.fields[old_field_count];
16493 field_val->special = ConstValSpecialUndef;
16494 field_val->type = field->type_entry;
16495 field_val->parent.id = ConstParentIdStruct;
16496 field_val->parent.data.p_struct.struct_val = struct_val;
16497 field_val->parent.data.p_struct.field_index = old_field_count;
16498 }
16499 }
16500
16501 ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, casted_ptr,
16502 isf->inferred_struct_type, true);
16503 }
1606616504
16067 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {16505 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {
16068 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));16506 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
16069 return ira->codegen->invalid_instruction;16507 return ira->codegen->invalid_instruction;
16070 }16508 }
1607116509
16510 ZigType *child_type = ptr->value.type->data.pointer.child_type;
16072 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);16511 IrInstruction *value = ir_implicit_cast(ira, uncasted_value, child_type);
16073 if (value == ira->codegen->invalid_instruction)16512 if (value == ira->codegen->invalid_instruction)
16074 return ira->codegen->invalid_instruction;16513 return ira->codegen->invalid_instruction;
...@@ -16799,25 +17238,14 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC...@@ -16799,25 +17238,14 @@ static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionC
1679917238
16800 if (is_comptime || instr_is_comptime(fn_ref)) {17239 if (is_comptime || instr_is_comptime(fn_ref)) {
16801 if (fn_ref->value.type->id == ZigTypeIdMetaType) {17240 if (fn_ref->value.type->id == ZigTypeIdMetaType) {
16802 ZigType *dest_type = ir_resolve_type(ira, fn_ref);17241 ZigType *ty = ir_resolve_type(ira, fn_ref);
16803 if (type_is_invalid(dest_type))17242 if (ty == nullptr)
16804 return ira->codegen->invalid_instruction;
16805
16806 size_t actual_param_count = call_instruction->arg_count;
16807
16808 if (actual_param_count != 1) {
16809 ir_add_error_node(ira, call_instruction->base.source_node,
16810 buf_sprintf("cast expression expects exactly one parameter"));
16811 return ira->codegen->invalid_instruction;17243 return ira->codegen->invalid_instruction;
16812 }17244 ErrorMsg *msg = ir_add_error_node(ira, fn_ref->source_node,
1681317245 buf_sprintf("type '%s' not a function", buf_ptr(&ty->name)));
16814 IrInstruction *arg = call_instruction->args[0]->child;17246 add_error_note(ira->codegen, msg, call_instruction->base.source_node,
1681517247 buf_sprintf("use @as builtin for type coercion"));
16816 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg,17248 return ira->codegen->invalid_instruction;
16817 call_instruction->result_loc);
16818 if (type_is_invalid(cast_instruction->value.type))
16819 return ira->codegen->invalid_instruction;
16820 return ir_finish_anal(ira, cast_instruction);
16821 } else if (fn_ref->value.type->id == ZigTypeIdFn) {17249 } else if (fn_ref->value.type->id == ZigTypeIdFn) {
16822 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref);17250 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref);
16823 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value.type;17251 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value.type;
...@@ -17215,6 +17643,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira,...@@ -17215,6 +17643,8 @@ static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira,
17215}17643}
1721617644
17217static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {17645static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) {
17646 Error err;
17647
17218 if (ira->const_predecessor_bb) {17648 if (ira->const_predecessor_bb) {
17219 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {17649 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
17220 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];17650 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i];
...@@ -17264,6 +17694,8 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -17264,6 +17694,8 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
17264 peer_parent->resolved_type = ir_resolve_peer_types(ira,17694 peer_parent->resolved_type = ir_resolve_peer_types(ira,
17265 peer_parent->base.source_instruction->source_node, expected_type, instructions,17695 peer_parent->base.source_instruction->source_node, expected_type, instructions,
17266 peer_parent->peers.length);17696 peer_parent->peers.length);
17697 if (type_is_invalid(peer_parent->resolved_type))
17698 return ira->codegen->invalid_instruction;
1726717699
17268 // the logic below assumes there are no instructions in the new current basic block yet17700 // the logic below assumes there are no instructions in the new current basic block yet
17269 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base);17701 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base);
...@@ -17346,20 +17778,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -17346,20 +17778,32 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
17346 }17778 }
1734717779
17348 ZigType *resolved_type;17780 ZigType *resolved_type;
17349 if (peer_parent != nullptr && ir_result_has_type(peer_parent->parent)) {17781 if (peer_parent != nullptr) {
17350 if (peer_parent->parent->id == ResultLocIdReturn) {17782 bool peer_parent_has_type;
17351 resolved_type = ira->explicit_return_type;17783 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type)))
17352 } else {17784 return ira->codegen->invalid_instruction;
17353 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;17785 if (peer_parent_has_type) {
17354 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);17786 if (peer_parent->parent->id == ResultLocIdReturn) {
17355 resolved_type = resolved_loc_ptr_type->data.pointer.child_type;17787 resolved_type = ira->explicit_return_type;
17788 } else if (peer_parent->parent->id == ResultLocIdCast) {
17789 resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child);
17790 if (type_is_invalid(resolved_type))
17791 return ira->codegen->invalid_instruction;
17792 } else {
17793 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value.type;
17794 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base);
17795 resolved_type = resolved_loc_ptr_type->data.pointer.child_type;
17796 }
17797 goto skip_resolve_peer_types;
17356 }17798 }
17357 } else {17799 }
17800 {
17358 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,17801 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr,
17359 new_incoming_values.items, new_incoming_values.length);17802 new_incoming_values.items, new_incoming_values.length);
17360 if (type_is_invalid(resolved_type))17803 if (type_is_invalid(resolved_type))
17361 return ira->codegen->invalid_instruction;17804 return ira->codegen->invalid_instruction;
17362 }17805 }
17806skip_resolve_peer_types:
1736317807
17364 switch (type_has_one_possible_value(ira->codegen, resolved_type)) {17808 switch (type_has_one_possible_value(ira->codegen, resolved_type)) {
17365 case OnePossibleValueInvalid:17809 case OnePossibleValueInvalid:
...@@ -17449,7 +17893,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali...@@ -17449,7 +17893,7 @@ static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_ali
1744917893
17450static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) {17894static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) {
17451 assert(is_slice(slice_type));17895 assert(is_slice(slice_type));
17452 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry,17896 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry,
17453 new_align);17897 new_align);
17454 return get_slice_type(g, ptr_type);17898 return get_slice_type(g, ptr_type);
17455}17899}
...@@ -17535,7 +17979,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17535,7 +17979,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17535 }17979 }
17536 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);17980 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);
17537 } else if (is_slice(array_type)) {17981 } else if (is_slice(array_type)) {
17538 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry,17982 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry,
17539 elem_ptr_instruction->ptr_len);17983 elem_ptr_instruction->ptr_len);
17540 } else if (array_type->id == ZigTypeIdArgTuple) {17984 } else if (array_type->id == ZigTypeIdArgTuple) {
17541 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);17985 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
...@@ -17571,6 +18015,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17571,6 +18015,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17571 } else if (array_type->id == ZigTypeIdVector) {18015 } else if (array_type->id == ZigTypeIdVector) {
17572 // This depends on whether the element index is comptime, so it is computed later.18016 // This depends on whether the element index is comptime, so it is computed later.
17573 return_type = nullptr;18017 return_type = nullptr;
18018 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr &&
18019 array_type->id == ZigTypeIdStruct &&
18020 array_type->data.structure.resolve_status == ResolveStatusBeingInferred)
18021 {
18022 ZigType *usize = ira->codegen->builtin_types.entry_usize;
18023 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize);
18024 if (casted_elem_index == ira->codegen->invalid_instruction)
18025 return ira->codegen->invalid_instruction;
18026 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base);
18027 Buf *field_name = buf_alloc();
18028 bigint_append_buf(field_name, &casted_elem_index->value.data.x_bigint, 10);
18029 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base,
18030 array_ptr, array_type);
17574 } else {18031 } else {
17575 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,18032 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
17576 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));18033 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));
...@@ -17601,7 +18058,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17601,7 +18058,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17601 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,18058 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
17602 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,18059 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
17603 elem_ptr_instruction->ptr_len,18060 elem_ptr_instruction->ptr_len,
17604 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index);18061 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index,
18062 nullptr);
17605 } else if (return_type->data.pointer.explicit_alignment != 0) {18063 } else if (return_type->data.pointer.explicit_alignment != 0) {
17606 // figure out the largest alignment possible18064 // figure out the largest alignment possible
1760718065
...@@ -17639,7 +18097,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17639,7 +18097,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17639 if (array_ptr_val == nullptr)18097 if (array_ptr_val == nullptr)
17640 return ira->codegen->invalid_instruction;18098 return ira->codegen->invalid_instruction;
1764118099
17642 if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) {18100 if (array_ptr_val->special == ConstValSpecialUndef &&
18101 elem_ptr_instruction->init_array_type_source_node != nullptr)
18102 {
17643 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) {18103 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) {
17644 array_ptr_val->data.x_array.special = ConstArraySpecialNone;18104 array_ptr_val->data.x_array.special = ConstArraySpecialNone;
17645 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);18105 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);
...@@ -17653,11 +18113,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17653,11 +18113,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17653 elem_val->parent.data.p_array.elem_index = i;18113 elem_val->parent.data.p_array.elem_index = i;
17654 }18114 }
17655 } else if (is_slice(array_type)) {18115 } else if (is_slice(array_type)) {
17656 ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child);18116 ir_assert(array_ptr->value.type->id == ZigTypeIdPointer, &elem_ptr_instruction->base);
18117 ZigType *actual_array_type = array_ptr->value.type->data.pointer.child_type;
18118
17657 if (type_is_invalid(actual_array_type))18119 if (type_is_invalid(actual_array_type))
17658 return ira->codegen->invalid_instruction;18120 return ira->codegen->invalid_instruction;
17659 if (actual_array_type->id != ZigTypeIdArray) {18121 if (actual_array_type->id != ZigTypeIdArray) {
17660 ir_add_error(ira, elem_ptr_instruction->init_array_type,18122 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
17661 buf_sprintf("expected array type or [_], found slice"));18123 buf_sprintf("expected array type or [_], found slice"));
17662 return ira->codegen->invalid_instruction;18124 return ira->codegen->invalid_instruction;
17663 }18125 }
...@@ -17679,9 +18141,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17679,9 +18141,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1767918141
17680 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len,18142 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len,
17681 false);18143 false);
17682 array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;18144 array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer;
17683 } else {18145 } else {
17684 ir_add_error(ira, elem_ptr_instruction->init_array_type,18146 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
17685 buf_sprintf("expected array type or [_], found '%s'",18147 buf_sprintf("expected array type or [_], found '%s'",
17686 buf_ptr(&array_type->name)));18148 buf_ptr(&array_type->name)));
17687 return ira->codegen->invalid_instruction;18149 return ira->codegen->invalid_instruction;
...@@ -17751,7 +18213,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17751,7 +18213,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17751 }18213 }
17752 return result;18214 return result;
17753 } else if (is_slice(array_type)) {18215 } else if (is_slice(array_type)) {
17754 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index];18216 ConstExprValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index];
17755 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base);18217 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base);
17756 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {18218 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) {
17757 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,18219 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
...@@ -17760,7 +18222,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17760,7 +18222,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17760 result->value.type = return_type;18222 result->value.type = return_type;
17761 return result;18223 return result;
17762 }18224 }
17763 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index];18225 ConstExprValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index];
17764 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type);18226 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type);
17765 ConstExprValue *out_val = &result->value;18227 ConstExprValue *out_val = &result->value;
17766 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint);18228 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint);
...@@ -17814,7 +18276,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17814,7 +18276,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17814 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {18276 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
17815 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,18277 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17816 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,18278 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,
17817 false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);18279 false, elem_ptr_instruction->ptr_len, nullptr);
17818 result->value.type = return_type;18280 result->value.type = return_type;
17819 result->value.special = ConstValSpecialStatic;18281 result->value.special = ConstValSpecialStatic;
17820 } else {18282 } else {
...@@ -17838,7 +18300,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17838,7 +18300,8 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17838 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,18300 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
17839 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,18301 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile,
17840 elem_ptr_instruction->ptr_len,18302 elem_ptr_instruction->ptr_len,
17841 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME);18303 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME,
18304 nullptr);
17842 } else {18305 } else {
17843 // runtime known element index18306 // runtime known element index
17844 switch (type_requires_comptime(ira->codegen, return_type)) {18307 switch (type_requires_comptime(ira->codegen, return_type)) {
...@@ -17875,7 +18338,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17875,7 +18338,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1787518338
17876 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,18339 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
17877 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,18340 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,
17878 elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);18341 elem_ptr_instruction->ptr_len, nullptr);
17879 result->value.type = return_type;18342 result->value.type = return_type;
17880 return result;18343 return result;
17881}18344}
...@@ -17954,43 +18417,47 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -17954,43 +18417,47 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
17954 case OnePossibleValueNo:18417 case OnePossibleValueNo:
17955 break;18418 break;
17956 }18419 }
17957 ResolveStatus needed_resolve_status =
17958 (struct_type->data.structure.layout == ContainerLayoutAuto) ?
17959 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
17960 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
17961 return ira->codegen->invalid_instruction;
17962 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
17963 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
17964 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
17965 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
17966 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
17967 bool is_const = struct_ptr->value.type->data.pointer.is_const;18420 bool is_const = struct_ptr->value.type->data.pointer.is_const;
17968 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;18421 bool is_volatile = struct_ptr->value.type->data.pointer.is_volatile;
17969 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,18422 ZigType *ptr_type;
17970 is_const, is_volatile, PtrLenSingle, field->align,18423 if (struct_type->data.structure.is_inferred) {
17971 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),18424 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
17972 (uint32_t)host_int_bytes_for_result_type, false);18425 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false);
18426 } else {
18427 ResolveStatus needed_resolve_status =
18428 (struct_type->data.structure.layout == ContainerLayoutAuto) ?
18429 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown;
18430 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status)))
18431 return ira->codegen->invalid_instruction;
18432 assert(struct_ptr->value.type->id == ZigTypeIdPointer);
18433 uint32_t ptr_bit_offset = struct_ptr->value.type->data.pointer.bit_offset_in_host;
18434 uint32_t ptr_host_int_bytes = struct_ptr->value.type->data.pointer.host_int_bytes;
18435 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ?
18436 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes;
18437 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type,
18438 is_const, is_volatile, PtrLenSingle, field->align,
18439 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
18440 (uint32_t)host_int_bytes_for_result_type, false);
18441 }
17973 if (instr_is_comptime(struct_ptr)) {18442 if (instr_is_comptime(struct_ptr)) {
17974 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);18443 ConstExprValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad);
17975 if (!ptr_val)18444 if (!ptr_val)
17976 return ira->codegen->invalid_instruction;18445 return ira->codegen->invalid_instruction;
1797718446
17978 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {18447 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
17979 if ((err = type_resolve(ira->codegen, struct_type, ResolveStatusSizeKnown)))
17980 return ira->codegen->invalid_instruction;
17981
17982 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);18448 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
17983 if (struct_val == nullptr)18449 if (struct_val == nullptr)
17984 return ira->codegen->invalid_instruction;18450 return ira->codegen->invalid_instruction;
17985 if (type_is_invalid(struct_val->type))18451 if (type_is_invalid(struct_val->type))
17986 return ira->codegen->invalid_instruction;18452 return ira->codegen->invalid_instruction;
17987 if (initializing && struct_val->special == ConstValSpecialUndef) {18453 if (initializing && struct_val->special == ConstValSpecialUndef) {
17988 struct_val->data.x_struct.fields = create_const_vals(struct_type->data.structure.src_field_count);18454 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(struct_type->data.structure.src_field_count);
17989 struct_val->special = ConstValSpecialStatic;18455 struct_val->special = ConstValSpecialStatic;
17990 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {18456 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) {
17991 ConstExprValue *field_val = &struct_val->data.x_struct.fields[i];18457 ConstExprValue *field_val = struct_val->data.x_struct.fields[i];
17992 field_val->special = ConstValSpecialUndef;18458 field_val->special = ConstValSpecialUndef;
17993 field_val->type = struct_type->data.structure.fields[i].type_entry;18459 field_val->type = resolve_struct_field_type(ira->codegen,
18460 struct_type->data.structure.fields[i]);
17994 field_val->parent.id = ConstParentIdStruct;18461 field_val->parent.id = ConstParentIdStruct;
17995 field_val->parent.data.p_struct.struct_val = struct_val;18462 field_val->parent.data.p_struct.struct_val = struct_val;
17996 field_val->parent.data.p_struct.field_index = i;18463 field_val->parent.data.p_struct.field_index = i;
...@@ -18019,12 +18486,53 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction...@@ -18019,12 +18486,53 @@ static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction
18019 return result;18486 return result;
18020}18487}
1802118488
18489static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
18490 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type)
18491{
18492 // The type of the field is not available until a store using this pointer happens.
18493 // So, here we create a special pointer type which has the inferred struct type and
18494 // field name encoded in the type. Later, when there is a store via this pointer,
18495 // the field type will then be available, and the field will be added to the inferred
18496 // struct.
18497
18498 ZigType *container_ptr_type = container_ptr->value.type;
18499 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr);
18500
18501 InferredStructField *inferred_struct_field = allocate<InferredStructField>(1, "InferredStructField");
18502 inferred_struct_field->inferred_struct_type = container_type;
18503 inferred_struct_field->field_name = field_name;
18504
18505 ZigType *elem_type = ira->codegen->builtin_types.entry_var;
18506 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type,
18507 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile,
18508 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field);
18509
18510 if (instr_is_comptime(container_ptr)) {
18511 IrInstruction *result = ir_const(ira, source_instr, field_ptr_type);
18512 copy_const_val(&result->value, &container_ptr->value, false);
18513 result->value.type = field_ptr_type;
18514 return result;
18515 }
18516
18517 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope,
18518 source_instr->source_node, field_ptr_type, container_ptr, CastOpNoop);
18519 result->value.type = field_ptr_type;
18520 return result;
18521}
18522
18022static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,18523static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name,
18023 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)18524 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type, bool initializing)
18024{18525{
18025 Error err;18526 Error err;
1802618527
18027 ZigType *bare_type = container_ref_type(container_type);18528 ZigType *bare_type = container_ref_type(container_type);
18529
18530 if (initializing && bare_type->id == ZigTypeIdStruct &&
18531 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred)
18532 {
18533 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type);
18534 }
18535
18028 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))18536 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))
18029 return ira->codegen->invalid_instruction;18537 return ira->codegen->invalid_instruction;
1803018538
...@@ -18065,7 +18573,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -18065,7 +18573,8 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
18065 if (!ptr_val)18573 if (!ptr_val)
18066 return ira->codegen->invalid_instruction;18574 return ira->codegen->invalid_instruction;
1806718575
18068 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {18576 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar &&
18577 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) {
18069 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);18578 ConstExprValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node);
18070 if (union_val == nullptr)18579 if (union_val == nullptr)
18071 return ira->codegen->invalid_instruction;18580 return ira->codegen->invalid_instruction;
...@@ -18097,7 +18606,6 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -18097,7 +18606,6 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1809718606
18098 ConstExprValue *payload_val = union_val->data.x_union.payload;18607 ConstExprValue *payload_val = union_val->data.x_union.payload;
1809918608
18100
18101 IrInstruction *result;18609 IrInstruction *result;
18102 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {18610 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
18103 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,18611 result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope,
...@@ -19799,6 +20307,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19799,6 +20307,11 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
19799 return ira->codegen->invalid_instruction;20307 return ira->codegen->invalid_instruction;
19800 }20308 }
1980120309
20310 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) {
20311 // We're now done inferring the type.
20312 container_type->data.structure.resolve_status = ResolveStatusUnstarted;
20313 }
20314
19802 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))20315 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
19803 return ira->codegen->invalid_instruction;20316 return ira->codegen->invalid_instruction;
1980420317
...@@ -19865,14 +20378,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19865,14 +20378,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
19865 if (field_assign_nodes[i] != nullptr) continue;20378 if (field_assign_nodes[i] != nullptr) continue;
1986620379
19867 // look for a default field value20380 // look for a default field value
19868 TypeStructField *field = &container_type->data.structure.fields[i];20381 TypeStructField *field = container_type->data.structure.fields[i];
19869 if (field->init_val == nullptr) {20382 if (field->init_val == nullptr) {
19870 // it's not memoized. time to go analyze it20383 // it's not memoized. time to go analyze it
19871 assert(field->decl_node->type == NodeTypeStructField);20384 AstNode *init_node;
19872 AstNode *init_node = field->decl_node->data.struct_field.value;20385 if (field->decl_node->type == NodeTypeStructField) {
20386 init_node = field->decl_node->data.struct_field.value;
20387 } else {
20388 init_node = nullptr;
20389 }
19873 if (init_node == nullptr) {20390 if (init_node == nullptr) {
19874 ir_add_error_node(ira, instruction->source_node,20391 ir_add_error_node(ira, instruction->source_node,
19875 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));20392 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name)));
19876 any_missing = true;20393 any_missing = true;
19877 continue;20394 continue;
19878 }20395 }
...@@ -19926,14 +20443,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19926,14 +20443,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
19926static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,20443static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
19927 IrInstructionContainerInitList *instruction)20444 IrInstructionContainerInitList *instruction)
19928{20445{
19929 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child);20446 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19930 if (type_is_invalid(container_type))20447 IrInstruction *result_loc = instruction->result_loc->child;
19931 return ira->codegen->invalid_instruction;20448 if (type_is_invalid(result_loc->value.type))
20449 return result_loc;
20450 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
20451
20452 ZigType *container_type = result_loc->value.type->data.pointer.child_type;
1993220453
19933 size_t elem_count = instruction->item_count;20454 size_t elem_count = instruction->item_count;
1993420455
19935 if (is_slice(container_type)) {20456 if (is_slice(container_type)) {
19936 ir_add_error(ira, instruction->container_type,20457 ir_add_error_node(ira, instruction->init_array_type_source_node,
19937 buf_sprintf("expected array type or [_], found slice"));20458 buf_sprintf("expected array type or [_], found slice"));
19938 return ira->codegen->invalid_instruction;20459 return ira->codegen->invalid_instruction;
19939 }20460 }
...@@ -19955,29 +20476,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -19955,29 +20476,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
19955 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);20476 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);
19956 }20477 }
1995720478
19958 if (container_type->id != ZigTypeIdArray) {20479 if (container_type->id == ZigTypeIdArray) {
20480 ZigType *child_type = container_type->data.array.child_type;
20481 if (container_type->data.array.len != elem_count) {
20482 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
20483
20484 ir_add_error(ira, &instruction->base,
20485 buf_sprintf("expected %s literal, found %s literal",
20486 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
20487 return ira->codegen->invalid_instruction;
20488 }
20489 } else if (container_type->id == ZigTypeIdStruct &&
20490 container_type->data.structure.resolve_status == ResolveStatusBeingInferred)
20491 {
20492 // We're now done inferring the type.
20493 container_type->data.structure.resolve_status = ResolveStatusUnstarted;
20494 } else {
19959 ir_add_error_node(ira, instruction->base.source_node,20495 ir_add_error_node(ira, instruction->base.source_node,
19960 buf_sprintf("type '%s' does not support array initialization",20496 buf_sprintf("type '%s' does not support array initialization",
19961 buf_ptr(&container_type->name)));20497 buf_ptr(&container_type->name)));
19962 return ira->codegen->invalid_instruction;20498 return ira->codegen->invalid_instruction;
19963 }20499 }
1996420500
19965 ir_assert(instruction->result_loc != nullptr, &instruction->base);
19966 IrInstruction *result_loc = instruction->result_loc->child;
19967 if (type_is_invalid(result_loc->value.type))
19968 return result_loc;
19969 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
19970
19971 ZigType *child_type = container_type->data.array.child_type;
19972 if (container_type->data.array.len != elem_count) {
19973 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
19974
19975 ir_add_error(ira, &instruction->base,
19976 buf_sprintf("expected %s literal, found %s literal",
19977 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
19978 return ira->codegen->invalid_instruction;
19979 }
19980
19981 switch (type_has_one_possible_value(ira->codegen, container_type)) {20501 switch (type_has_one_possible_value(ira->codegen, container_type)) {
19982 case OnePossibleValueInvalid:20502 case OnePossibleValueInvalid:
19983 return ira->codegen->invalid_instruction;20503 return ira->codegen->invalid_instruction;
...@@ -20064,16 +20584,14 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -20064,16 +20584,14 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
20064static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,20584static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
20065 IrInstructionContainerInitFields *instruction)20585 IrInstructionContainerInitFields *instruction)
20066{20586{
20067 IrInstruction *container_type_value = instruction->container_type->child;
20068 ZigType *container_type = ir_resolve_type(ira, container_type_value);
20069 if (type_is_invalid(container_type))
20070 return ira->codegen->invalid_instruction;
20071
20072 ir_assert(instruction->result_loc != nullptr, &instruction->base);20587 ir_assert(instruction->result_loc != nullptr, &instruction->base);
20073 IrInstruction *result_loc = instruction->result_loc->child;20588 IrInstruction *result_loc = instruction->result_loc->child;
20074 if (type_is_invalid(result_loc->value.type))20589 if (type_is_invalid(result_loc->value.type))
20075 return result_loc;20590 return result_loc;
2007620591
20592 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
20593 ZigType *container_type = result_loc->value.type->data.pointer.child_type;
20594
20077 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,20595 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
20078 instruction->field_count, instruction->fields, result_loc);20596 instruction->field_count, instruction->fields, result_loc);
20079}20597}
...@@ -20472,17 +20990,17 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20472,17 +20990,17 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20472 declaration_val->special = ConstValSpecialStatic;20990 declaration_val->special = ConstValSpecialStatic;
20473 declaration_val->type = type_info_declaration_type;20991 declaration_val->type = type_info_declaration_type;
2047420992
20475 ConstExprValue *inner_fields = create_const_vals(3);20993 ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
20476 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);20994 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key);
20477 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true);20995 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true);
20478 inner_fields[1].special = ConstValSpecialStatic;20996 inner_fields[1]->special = ConstValSpecialStatic;
20479 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;20997 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool;
20480 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub;20998 inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub;
20481 inner_fields[2].special = ConstValSpecialStatic;20999 inner_fields[2]->special = ConstValSpecialStatic;
20482 inner_fields[2].type = type_info_declaration_data_type;21000 inner_fields[2]->type = type_info_declaration_data_type;
20483 inner_fields[2].parent.id = ConstParentIdStruct;21001 inner_fields[2]->parent.id = ConstParentIdStruct;
20484 inner_fields[2].parent.data.p_struct.struct_val = declaration_val;21002 inner_fields[2]->parent.data.p_struct.struct_val = declaration_val;
20485 inner_fields[2].parent.data.p_struct.field_index = 1;21003 inner_fields[2]->parent.data.p_struct.field_index = 1;
2048621004
20487 switch (curr_entry->value->id) {21005 switch (curr_entry->value->id) {
20488 case TldIdVar:21006 case TldIdVar:
...@@ -20494,19 +21012,19 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20494,19 +21012,19 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20494 if (var->const_value->type->id == ZigTypeIdMetaType) {21012 if (var->const_value->type->id == ZigTypeIdMetaType) {
20495 // We have a variable of type 'type', so it's actually a type declaration.21013 // We have a variable of type 'type', so it's actually a type declaration.
20496 // 0: Data.Type: type21014 // 0: Data.Type: type
20497 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);21015 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0);
20498 inner_fields[2].data.x_union.payload = var->const_value;21016 inner_fields[2]->data.x_union.payload = var->const_value;
20499 } else {21017 } else {
20500 // We have a variable of another type, so we store the type of the variable.21018 // We have a variable of another type, so we store the type of the variable.
20501 // 1: Data.Var: type21019 // 1: Data.Var: type
20502 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1);21020 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1);
2050321021
20504 ConstExprValue *payload = create_const_vals(1);21022 ConstExprValue *payload = create_const_vals(1);
20505 payload->special = ConstValSpecialStatic;21023 payload->special = ConstValSpecialStatic;
20506 payload->type = ira->codegen->builtin_types.entry_type;21024 payload->type = ira->codegen->builtin_types.entry_type;
20507 payload->data.x_type = var->const_value->type;21025 payload->data.x_type = var->const_value->type;
2050821026
20509 inner_fields[2].data.x_union.payload = payload;21027 inner_fields[2]->data.x_union.payload = payload;
20510 }21028 }
2051121029
20512 break;21030 break;
...@@ -20514,7 +21032,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20514,7 +21032,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20514 case TldIdFn:21032 case TldIdFn:
20515 {21033 {
20516 // 2: Data.Fn: Data.FnDecl21034 // 2: Data.Fn: Data.FnDecl
20517 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2);21035 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2);
2051821036
20519 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;21037 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
20520 assert(!fn_entry->is_test);21038 assert(!fn_entry->is_test);
...@@ -20530,63 +21048,63 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20530,63 +21048,63 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20530 fn_decl_val->special = ConstValSpecialStatic;21048 fn_decl_val->special = ConstValSpecialStatic;
20531 fn_decl_val->type = type_info_fn_decl_type;21049 fn_decl_val->type = type_info_fn_decl_type;
20532 fn_decl_val->parent.id = ConstParentIdUnion;21050 fn_decl_val->parent.id = ConstParentIdUnion;
20533 fn_decl_val->parent.data.p_union.union_val = &inner_fields[2];21051 fn_decl_val->parent.data.p_union.union_val = inner_fields[2];
2053421052
20535 ConstExprValue *fn_decl_fields = create_const_vals(9);21053 ConstExprValue **fn_decl_fields = alloc_const_vals_ptrs(9);
20536 fn_decl_val->data.x_struct.fields = fn_decl_fields;21054 fn_decl_val->data.x_struct.fields = fn_decl_fields;
2053721055
20538 // fn_type: type21056 // fn_type: type
20539 ensure_field_index(fn_decl_val->type, "fn_type", 0);21057 ensure_field_index(fn_decl_val->type, "fn_type", 0);
20540 fn_decl_fields[0].special = ConstValSpecialStatic;21058 fn_decl_fields[0]->special = ConstValSpecialStatic;
20541 fn_decl_fields[0].type = ira->codegen->builtin_types.entry_type;21059 fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type;
20542 fn_decl_fields[0].data.x_type = fn_entry->type_entry;21060 fn_decl_fields[0]->data.x_type = fn_entry->type_entry;
20543 // inline_type: Data.FnDecl.Inline21061 // inline_type: Data.FnDecl.Inline
20544 ensure_field_index(fn_decl_val->type, "inline_type", 1);21062 ensure_field_index(fn_decl_val->type, "inline_type", 1);
20545 fn_decl_fields[1].special = ConstValSpecialStatic;21063 fn_decl_fields[1]->special = ConstValSpecialStatic;
20546 fn_decl_fields[1].type = type_info_fn_decl_inline_type;21064 fn_decl_fields[1]->type = type_info_fn_decl_inline_type;
20547 bigint_init_unsigned(&fn_decl_fields[1].data.x_enum_tag, fn_entry->fn_inline);21065 bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline);
20548 // calling_convention: TypeInfo.CallingConvention21066 // calling_convention: TypeInfo.CallingConvention
20549 ensure_field_index(fn_decl_val->type, "calling_convention", 2);21067 ensure_field_index(fn_decl_val->type, "calling_convention", 2);
20550 fn_decl_fields[2].special = ConstValSpecialStatic;21068 fn_decl_fields[2]->special = ConstValSpecialStatic;
20551 fn_decl_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);21069 fn_decl_fields[2]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
20552 bigint_init_unsigned(&fn_decl_fields[2].data.x_enum_tag, fn_node->cc);21070 bigint_init_unsigned(&fn_decl_fields[2]->data.x_enum_tag, fn_node->cc);
20553 // is_var_args: bool21071 // is_var_args: bool
20554 ensure_field_index(fn_decl_val->type, "is_var_args", 3);21072 ensure_field_index(fn_decl_val->type, "is_var_args", 3);
20555 bool is_varargs = fn_node->is_var_args;21073 bool is_varargs = fn_node->is_var_args;
20556 fn_decl_fields[3].special = ConstValSpecialStatic;21074 fn_decl_fields[3]->special = ConstValSpecialStatic;
20557 fn_decl_fields[3].type = ira->codegen->builtin_types.entry_bool;21075 fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool;
20558 fn_decl_fields[3].data.x_bool = is_varargs;21076 fn_decl_fields[3]->data.x_bool = is_varargs;
20559 // is_extern: bool21077 // is_extern: bool
20560 ensure_field_index(fn_decl_val->type, "is_extern", 4);21078 ensure_field_index(fn_decl_val->type, "is_extern", 4);
20561 fn_decl_fields[4].special = ConstValSpecialStatic;21079 fn_decl_fields[4]->special = ConstValSpecialStatic;
20562 fn_decl_fields[4].type = ira->codegen->builtin_types.entry_bool;21080 fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool;
20563 fn_decl_fields[4].data.x_bool = fn_node->is_extern;21081 fn_decl_fields[4]->data.x_bool = fn_node->is_extern;
20564 // is_export: bool21082 // is_export: bool
20565 ensure_field_index(fn_decl_val->type, "is_export", 5);21083 ensure_field_index(fn_decl_val->type, "is_export", 5);
20566 fn_decl_fields[5].special = ConstValSpecialStatic;21084 fn_decl_fields[5]->special = ConstValSpecialStatic;
20567 fn_decl_fields[5].type = ira->codegen->builtin_types.entry_bool;21085 fn_decl_fields[5]->type = ira->codegen->builtin_types.entry_bool;
20568 fn_decl_fields[5].data.x_bool = fn_node->is_export;21086 fn_decl_fields[5]->data.x_bool = fn_node->is_export;
20569 // lib_name: ?[]const u821087 // lib_name: ?[]const u8
20570 ensure_field_index(fn_decl_val->type, "lib_name", 6);21088 ensure_field_index(fn_decl_val->type, "lib_name", 6);
20571 fn_decl_fields[6].special = ConstValSpecialStatic;21089 fn_decl_fields[6]->special = ConstValSpecialStatic;
20572 ZigType *u8_ptr = get_pointer_to_type_extra(21090 ZigType *u8_ptr = get_pointer_to_type_extra(
20573 ira->codegen, ira->codegen->builtin_types.entry_u8,21091 ira->codegen, ira->codegen->builtin_types.entry_u8,
20574 true, false, PtrLenUnknown,21092 true, false, PtrLenUnknown,
20575 0, 0, 0, false);21093 0, 0, 0, false);
20576 fn_decl_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));21094 fn_decl_fields[6]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr));
20577 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {21095 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) {
20578 fn_decl_fields[6].data.x_optional = create_const_vals(1);21096 fn_decl_fields[6]->data.x_optional = create_const_vals(1);
20579 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);21097 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name);
20580 init_const_slice(ira->codegen, fn_decl_fields[6].data.x_optional, lib_name, 0,21098 init_const_slice(ira->codegen, fn_decl_fields[6]->data.x_optional, lib_name, 0,
20581 buf_len(fn_node->lib_name), true);21099 buf_len(fn_node->lib_name), true);
20582 } else {21100 } else {
20583 fn_decl_fields[6].data.x_optional = nullptr;21101 fn_decl_fields[6]->data.x_optional = nullptr;
20584 }21102 }
20585 // return_type: type21103 // return_type: type
20586 ensure_field_index(fn_decl_val->type, "return_type", 7);21104 ensure_field_index(fn_decl_val->type, "return_type", 7);
20587 fn_decl_fields[7].special = ConstValSpecialStatic;21105 fn_decl_fields[7]->special = ConstValSpecialStatic;
20588 fn_decl_fields[7].type = ira->codegen->builtin_types.entry_type;21106 fn_decl_fields[7]->type = ira->codegen->builtin_types.entry_type;
20589 fn_decl_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;21107 fn_decl_fields[7]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
20590 // arg_names: [][] const u821108 // arg_names: [][] const u8
20591 ensure_field_index(fn_decl_val->type, "arg_names", 8);21109 ensure_field_index(fn_decl_val->type, "arg_names", 8);
20592 size_t fn_arg_count = fn_entry->variable_list.length;21110 size_t fn_arg_count = fn_entry->variable_list.length;
...@@ -20597,7 +21115,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20597,7 +21115,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20597 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;21115 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone;
20598 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);21116 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
2059921117
20600 init_const_slice(ira->codegen, &fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);21118 init_const_slice(ira->codegen, fn_decl_fields[8], fn_arg_name_array, 0, fn_arg_count, false);
2060121119
20602 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {21120 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
20603 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);21121 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index);
...@@ -20610,7 +21128,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20610,7 +21128,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20610 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;21128 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index;
20611 }21129 }
2061221130
20613 inner_fields[2].data.x_union.payload = fn_decl_val;21131 inner_fields[2]->data.x_union.payload = fn_decl_val;
20614 break;21132 break;
20615 }21133 }
20616 case TldIdContainer:21134 case TldIdContainer:
...@@ -20620,14 +21138,14 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20620,14 +21138,14 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20620 return ErrorSemanticAnalyzeFail;21138 return ErrorSemanticAnalyzeFail;
2062121139
20622 // This is a type.21140 // This is a type.
20623 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0);21141 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0);
2062421142
20625 ConstExprValue *payload = create_const_vals(1);21143 ConstExprValue *payload = create_const_vals(1);
20626 payload->special = ConstValSpecialStatic;21144 payload->special = ConstValSpecialStatic;
20627 payload->type = ira->codegen->builtin_types.entry_type;21145 payload->type = ira->codegen->builtin_types.entry_type;
20628 payload->data.x_type = type_entry;21146 payload->data.x_type = type_entry;
2062921147
20630 inner_fields[2].data.x_union.payload = payload;21148 inner_fields[2]->data.x_union.payload = payload;
2063121149
20632 break;21150 break;
20633 }21151 }
...@@ -20636,7 +21154,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr...@@ -20636,7 +21154,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr
20636 }21154 }
2063721155
20638 declaration_val->data.x_struct.fields = inner_fields;21156 declaration_val->data.x_struct.fields = inner_fields;
20639 declaration_index++;21157 declaration_index += 1;
20640 }21158 }
2064121159
20642 assert(declaration_index == declaration_count);21160 assert(declaration_index == declaration_count);
...@@ -20673,7 +21191,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty...@@ -20673,7 +21191,7 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
20673 ZigType *attrs_type;21191 ZigType *attrs_type;
20674 BuiltinPtrSize size_enum_index;21192 BuiltinPtrSize size_enum_index;
20675 if (is_slice(ptr_type_entry)) {21193 if (is_slice(ptr_type_entry)) {
20676 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry;21194 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry;
20677 size_enum_index = BuiltinPtrSizeSlice;21195 size_enum_index = BuiltinPtrSizeSlice;
20678 } else if (ptr_type_entry->id == ZigTypeIdPointer) {21196 } else if (ptr_type_entry->id == ZigTypeIdPointer) {
20679 attrs_type = ptr_type_entry;21197 attrs_type = ptr_type_entry;
...@@ -20692,42 +21210,42 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty...@@ -20692,42 +21210,42 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty
20692 result->special = ConstValSpecialStatic;21210 result->special = ConstValSpecialStatic;
20693 result->type = type_info_pointer_type;21211 result->type = type_info_pointer_type;
2069421212
20695 ConstExprValue *fields = create_const_vals(6);21213 ConstExprValue **fields = alloc_const_vals_ptrs(6);
20696 result->data.x_struct.fields = fields;21214 result->data.x_struct.fields = fields;
2069721215
20698 // size: Size21216 // size: Size
20699 ensure_field_index(result->type, "size", 0);21217 ensure_field_index(result->type, "size", 0);
20700 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);21218 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type);
20701 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown));21219 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown));
20702 fields[0].special = ConstValSpecialStatic;21220 fields[0]->special = ConstValSpecialStatic;
20703 fields[0].type = type_info_pointer_size_type;21221 fields[0]->type = type_info_pointer_size_type;
20704 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index);21222 bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index);
2070521223
20706 // is_const: bool21224 // is_const: bool
20707 ensure_field_index(result->type, "is_const", 1);21225 ensure_field_index(result->type, "is_const", 1);
20708 fields[1].special = ConstValSpecialStatic;21226 fields[1]->special = ConstValSpecialStatic;
20709 fields[1].type = ira->codegen->builtin_types.entry_bool;21227 fields[1]->type = ira->codegen->builtin_types.entry_bool;
20710 fields[1].data.x_bool = attrs_type->data.pointer.is_const;21228 fields[1]->data.x_bool = attrs_type->data.pointer.is_const;
20711 // is_volatile: bool21229 // is_volatile: bool
20712 ensure_field_index(result->type, "is_volatile", 2);21230 ensure_field_index(result->type, "is_volatile", 2);
20713 fields[2].special = ConstValSpecialStatic;21231 fields[2]->special = ConstValSpecialStatic;
20714 fields[2].type = ira->codegen->builtin_types.entry_bool;21232 fields[2]->type = ira->codegen->builtin_types.entry_bool;
20715 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile;21233 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile;
20716 // alignment: u3221234 // alignment: u32
20717 ensure_field_index(result->type, "alignment", 3);21235 ensure_field_index(result->type, "alignment", 3);
20718 fields[3].special = ConstValSpecialStatic;21236 fields[3]->special = ConstValSpecialStatic;
20719 fields[3].type = ira->codegen->builtin_types.entry_num_lit_int;21237 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int;
20720 bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type));21238 bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type));
20721 // child: type21239 // child: type
20722 ensure_field_index(result->type, "child", 4);21240 ensure_field_index(result->type, "child", 4);
20723 fields[4].special = ConstValSpecialStatic;21241 fields[4]->special = ConstValSpecialStatic;
20724 fields[4].type = ira->codegen->builtin_types.entry_type;21242 fields[4]->type = ira->codegen->builtin_types.entry_type;
20725 fields[4].data.x_type = attrs_type->data.pointer.child_type;21243 fields[4]->data.x_type = attrs_type->data.pointer.child_type;
20726 // is_allowzero: bool21244 // is_allowzero: bool
20727 ensure_field_index(result->type, "is_allowzero", 5);21245 ensure_field_index(result->type, "is_allowzero", 5);
20728 fields[5].special = ConstValSpecialStatic;21246 fields[5]->special = ConstValSpecialStatic;
20729 fields[5].type = ira->codegen->builtin_types.entry_bool;21247 fields[5]->type = ira->codegen->builtin_types.entry_bool;
20730 fields[5].data.x_bool = attrs_type->data.pointer.allow_zero;21248 fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero;
2073121249
20732 return result;21250 return result;
20733};21251};
...@@ -20738,14 +21256,14 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val,...@@ -20738,14 +21256,14 @@ static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val,
20738 enum_field_val->special = ConstValSpecialStatic;21256 enum_field_val->special = ConstValSpecialStatic;
20739 enum_field_val->type = type_info_enum_field_type;21257 enum_field_val->type = type_info_enum_field_type;
2074021258
20741 ConstExprValue *inner_fields = create_const_vals(2);21259 ConstExprValue **inner_fields = alloc_const_vals_ptrs(2);
20742 inner_fields[1].special = ConstValSpecialStatic;21260 inner_fields[1]->special = ConstValSpecialStatic;
20743 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;21261 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
2074421262
20745 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name);21263 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name);
20746 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true);21264 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true);
2074721265
20748 bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value);21266 bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value);
2074921267
20750 enum_field_val->data.x_struct.fields = inner_fields;21268 enum_field_val->data.x_struct.fields = inner_fields;
20751}21269}
...@@ -20789,19 +21307,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20789,19 +21307,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20789 result->special = ConstValSpecialStatic;21307 result->special = ConstValSpecialStatic;
20790 result->type = ir_type_info_get_type(ira, "Int", nullptr);21308 result->type = ir_type_info_get_type(ira, "Int", nullptr);
2079121309
20792 ConstExprValue *fields = create_const_vals(2);21310 ConstExprValue **fields = alloc_const_vals_ptrs(2);
20793 result->data.x_struct.fields = fields;21311 result->data.x_struct.fields = fields;
2079421312
20795 // is_signed: bool21313 // is_signed: bool
20796 ensure_field_index(result->type, "is_signed", 0);21314 ensure_field_index(result->type, "is_signed", 0);
20797 fields[0].special = ConstValSpecialStatic;21315 fields[0]->special = ConstValSpecialStatic;
20798 fields[0].type = ira->codegen->builtin_types.entry_bool;21316 fields[0]->type = ira->codegen->builtin_types.entry_bool;
20799 fields[0].data.x_bool = type_entry->data.integral.is_signed;21317 fields[0]->data.x_bool = type_entry->data.integral.is_signed;
20800 // bits: u821318 // bits: u8
20801 ensure_field_index(result->type, "bits", 1);21319 ensure_field_index(result->type, "bits", 1);
20802 fields[1].special = ConstValSpecialStatic;21320 fields[1]->special = ConstValSpecialStatic;
20803 fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;21321 fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
20804 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count);21322 bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count);
2080521323
20806 break;21324 break;
20807 }21325 }
...@@ -20811,14 +21329,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20811,14 +21329,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20811 result->special = ConstValSpecialStatic;21329 result->special = ConstValSpecialStatic;
20812 result->type = ir_type_info_get_type(ira, "Float", nullptr);21330 result->type = ir_type_info_get_type(ira, "Float", nullptr);
2081321331
20814 ConstExprValue *fields = create_const_vals(1);21332 ConstExprValue **fields = alloc_const_vals_ptrs(1);
20815 result->data.x_struct.fields = fields;21333 result->data.x_struct.fields = fields;
2081621334
20817 // bits: u821335 // bits: u8
20818 ensure_field_index(result->type, "bits", 0);21336 ensure_field_index(result->type, "bits", 0);
20819 fields[0].special = ConstValSpecialStatic;21337 fields[0]->special = ConstValSpecialStatic;
20820 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;21338 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
20821 bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count);21339 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count);
2082221340
20823 break;21341 break;
20824 }21342 }
...@@ -20835,19 +21353,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20835,19 +21353,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20835 result->special = ConstValSpecialStatic;21353 result->special = ConstValSpecialStatic;
20836 result->type = ir_type_info_get_type(ira, "Array", nullptr);21354 result->type = ir_type_info_get_type(ira, "Array", nullptr);
2083721355
20838 ConstExprValue *fields = create_const_vals(2);21356 ConstExprValue **fields = alloc_const_vals_ptrs(2);
20839 result->data.x_struct.fields = fields;21357 result->data.x_struct.fields = fields;
2084021358
20841 // len: usize21359 // len: usize
20842 ensure_field_index(result->type, "len", 0);21360 ensure_field_index(result->type, "len", 0);
20843 fields[0].special = ConstValSpecialStatic;21361 fields[0]->special = ConstValSpecialStatic;
20844 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;21362 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
20845 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len);21363 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len);
20846 // child: type21364 // child: type
20847 ensure_field_index(result->type, "child", 1);21365 ensure_field_index(result->type, "child", 1);
20848 fields[1].special = ConstValSpecialStatic;21366 fields[1]->special = ConstValSpecialStatic;
20849 fields[1].type = ira->codegen->builtin_types.entry_type;21367 fields[1]->type = ira->codegen->builtin_types.entry_type;
20850 fields[1].data.x_type = type_entry->data.array.child_type;21368 fields[1]->data.x_type = type_entry->data.array.child_type;
2085121369
20852 break;21370 break;
20853 }21371 }
...@@ -20856,19 +21374,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20856,19 +21374,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20856 result->special = ConstValSpecialStatic;21374 result->special = ConstValSpecialStatic;
20857 result->type = ir_type_info_get_type(ira, "Vector", nullptr);21375 result->type = ir_type_info_get_type(ira, "Vector", nullptr);
2085821376
20859 ConstExprValue *fields = create_const_vals(2);21377 ConstExprValue **fields = alloc_const_vals_ptrs(2);
20860 result->data.x_struct.fields = fields;21378 result->data.x_struct.fields = fields;
2086121379
20862 // len: usize21380 // len: usize
20863 ensure_field_index(result->type, "len", 0);21381 ensure_field_index(result->type, "len", 0);
20864 fields[0].special = ConstValSpecialStatic;21382 fields[0]->special = ConstValSpecialStatic;
20865 fields[0].type = ira->codegen->builtin_types.entry_num_lit_int;21383 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int;
20866 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.vector.len);21384 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len);
20867 // child: type21385 // child: type
20868 ensure_field_index(result->type, "child", 1);21386 ensure_field_index(result->type, "child", 1);
20869 fields[1].special = ConstValSpecialStatic;21387 fields[1]->special = ConstValSpecialStatic;
20870 fields[1].type = ira->codegen->builtin_types.entry_type;21388 fields[1]->type = ira->codegen->builtin_types.entry_type;
20871 fields[1].data.x_type = type_entry->data.vector.elem_type;21389 fields[1]->data.x_type = type_entry->data.vector.elem_type;
2087221390
20873 break;21391 break;
20874 }21392 }
...@@ -20878,14 +21396,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20878,14 +21396,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20878 result->special = ConstValSpecialStatic;21396 result->special = ConstValSpecialStatic;
20879 result->type = ir_type_info_get_type(ira, "Optional", nullptr);21397 result->type = ir_type_info_get_type(ira, "Optional", nullptr);
2088021398
20881 ConstExprValue *fields = create_const_vals(1);21399 ConstExprValue **fields = alloc_const_vals_ptrs(1);
20882 result->data.x_struct.fields = fields;21400 result->data.x_struct.fields = fields;
2088321401
20884 // child: type21402 // child: type
20885 ensure_field_index(result->type, "child", 0);21403 ensure_field_index(result->type, "child", 0);
20886 fields[0].special = ConstValSpecialStatic;21404 fields[0]->special = ConstValSpecialStatic;
20887 fields[0].type = ira->codegen->builtin_types.entry_type;21405 fields[0]->type = ira->codegen->builtin_types.entry_type;
20888 fields[0].data.x_type = type_entry->data.maybe.child_type;21406 fields[0]->data.x_type = type_entry->data.maybe.child_type;
2088921407
20890 break;21408 break;
20891 }21409 }
...@@ -20894,14 +21412,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20894,14 +21412,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20894 result->special = ConstValSpecialStatic;21412 result->special = ConstValSpecialStatic;
20895 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);21413 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr);
2089621414
20897 ConstExprValue *fields = create_const_vals(1);21415 ConstExprValue **fields = alloc_const_vals_ptrs(1);
20898 result->data.x_struct.fields = fields;21416 result->data.x_struct.fields = fields;
2089921417
20900 // child: ?type21418 // child: ?type
20901 ensure_field_index(result->type, "child", 0);21419 ensure_field_index(result->type, "child", 0);
20902 fields[0].special = ConstValSpecialStatic;21420 fields[0]->special = ConstValSpecialStatic;
20903 fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);21421 fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
20904 fields[0].data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :21422 fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr :
20905 create_const_type(ira->codegen, type_entry->data.any_frame.result_type);21423 create_const_type(ira->codegen, type_entry->data.any_frame.result_type);
20906 break;21424 break;
20907 }21425 }
...@@ -20911,19 +21429,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20911,19 +21429,19 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20911 result->special = ConstValSpecialStatic;21429 result->special = ConstValSpecialStatic;
20912 result->type = ir_type_info_get_type(ira, "Enum", nullptr);21430 result->type = ir_type_info_get_type(ira, "Enum", nullptr);
2091321431
20914 ConstExprValue *fields = create_const_vals(4);21432 ConstExprValue **fields = alloc_const_vals_ptrs(4);
20915 result->data.x_struct.fields = fields;21433 result->data.x_struct.fields = fields;
2091621434
20917 // layout: ContainerLayout21435 // layout: ContainerLayout
20918 ensure_field_index(result->type, "layout", 0);21436 ensure_field_index(result->type, "layout", 0);
20919 fields[0].special = ConstValSpecialStatic;21437 fields[0]->special = ConstValSpecialStatic;
20920 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);21438 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
20921 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout);21439 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout);
20922 // tag_type: type21440 // tag_type: type
20923 ensure_field_index(result->type, "tag_type", 1);21441 ensure_field_index(result->type, "tag_type", 1);
20924 fields[1].special = ConstValSpecialStatic;21442 fields[1]->special = ConstValSpecialStatic;
20925 fields[1].type = ira->codegen->builtin_types.entry_type;21443 fields[1]->type = ira->codegen->builtin_types.entry_type;
20926 fields[1].data.x_type = type_entry->data.enumeration.tag_int_type;21444 fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type;
20927 // fields: []TypeInfo.EnumField21445 // fields: []TypeInfo.EnumField
20928 ensure_field_index(result->type, "fields", 2);21446 ensure_field_index(result->type, "fields", 2);
2092921447
...@@ -20939,7 +21457,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20939,7 +21457,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20939 enum_field_array->data.x_array.special = ConstArraySpecialNone;21457 enum_field_array->data.x_array.special = ConstArraySpecialNone;
20940 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);21458 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count);
2094121459
20942 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false);21460 init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false);
2094321461
20944 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)21462 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++)
20945 {21463 {
...@@ -20952,7 +21470,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20952,7 +21470,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20952 }21470 }
20953 // decls: []TypeInfo.Declaration21471 // decls: []TypeInfo.Declaration
20954 ensure_field_index(result->type, "decls", 3);21472 ensure_field_index(result->type, "decls", 3);
20955 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],21473 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
20956 type_entry->data.enumeration.decls_scope)))21474 type_entry->data.enumeration.decls_scope)))
20957 {21475 {
20958 return err;21476 return err;
...@@ -20995,17 +21513,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -20995,17 +21513,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
20995 error_val->special = ConstValSpecialStatic;21513 error_val->special = ConstValSpecialStatic;
20996 error_val->type = type_info_error_type;21514 error_val->type = type_info_error_type;
2099721515
20998 ConstExprValue *inner_fields = create_const_vals(2);21516 ConstExprValue **inner_fields = alloc_const_vals_ptrs(2);
20999 inner_fields[1].special = ConstValSpecialStatic;21517 inner_fields[1]->special = ConstValSpecialStatic;
21000 inner_fields[1].type = ira->codegen->builtin_types.entry_num_lit_int;21518 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
2100121519
21002 ConstExprValue *name = nullptr;21520 ConstExprValue *name = nullptr;
21003 if (error->cached_error_name_val != nullptr)21521 if (error->cached_error_name_val != nullptr)
21004 name = error->cached_error_name_val;21522 name = error->cached_error_name_val;
21005 if (name == nullptr)21523 if (name == nullptr)
21006 name = create_const_str_lit(ira->codegen, &error->name);21524 name = create_const_str_lit(ira->codegen, &error->name);
21007 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true);21525 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true);
21008 bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value);21526 bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value);
2100921527
21010 error_val->data.x_struct.fields = inner_fields;21528 error_val->data.x_struct.fields = inner_fields;
21011 error_val->parent.id = ConstParentIdArray;21529 error_val->parent.id = ConstParentIdArray;
...@@ -21021,20 +21539,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21021,20 +21539,20 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21021 result->special = ConstValSpecialStatic;21539 result->special = ConstValSpecialStatic;
21022 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr);21540 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr);
2102321541
21024 ConstExprValue *fields = create_const_vals(2);21542 ConstExprValue **fields = alloc_const_vals_ptrs(2);
21025 result->data.x_struct.fields = fields;21543 result->data.x_struct.fields = fields;
2102621544
21027 // error_set: type21545 // error_set: type
21028 ensure_field_index(result->type, "error_set", 0);21546 ensure_field_index(result->type, "error_set", 0);
21029 fields[0].special = ConstValSpecialStatic;21547 fields[0]->special = ConstValSpecialStatic;
21030 fields[0].type = ira->codegen->builtin_types.entry_type;21548 fields[0]->type = ira->codegen->builtin_types.entry_type;
21031 fields[0].data.x_type = type_entry->data.error_union.err_set_type;21549 fields[0]->data.x_type = type_entry->data.error_union.err_set_type;
2103221550
21033 // payload: type21551 // payload: type
21034 ensure_field_index(result->type, "payload", 1);21552 ensure_field_index(result->type, "payload", 1);
21035 fields[1].special = ConstValSpecialStatic;21553 fields[1]->special = ConstValSpecialStatic;
21036 fields[1].type = ira->codegen->builtin_types.entry_type;21554 fields[1]->type = ira->codegen->builtin_types.entry_type;
21037 fields[1].data.x_type = type_entry->data.error_union.payload_type;21555 fields[1]->data.x_type = type_entry->data.error_union.payload_type;
2103821556
21039 break;21557 break;
21040 }21558 }
...@@ -21044,18 +21562,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21044,18 +21562,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21044 result->special = ConstValSpecialStatic;21562 result->special = ConstValSpecialStatic;
21045 result->type = ir_type_info_get_type(ira, "Union", nullptr);21563 result->type = ir_type_info_get_type(ira, "Union", nullptr);
2104621564
21047 ConstExprValue *fields = create_const_vals(4);21565 ConstExprValue **fields = alloc_const_vals_ptrs(4);
21048 result->data.x_struct.fields = fields;21566 result->data.x_struct.fields = fields;
2104921567
21050 // layout: ContainerLayout21568 // layout: ContainerLayout
21051 ensure_field_index(result->type, "layout", 0);21569 ensure_field_index(result->type, "layout", 0);
21052 fields[0].special = ConstValSpecialStatic;21570 fields[0]->special = ConstValSpecialStatic;
21053 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);21571 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
21054 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout);21572 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout);
21055 // tag_type: ?type21573 // tag_type: ?type
21056 ensure_field_index(result->type, "tag_type", 1);21574 ensure_field_index(result->type, "tag_type", 1);
21057 fields[1].special = ConstValSpecialStatic;21575 fields[1]->special = ConstValSpecialStatic;
21058 fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);21576 fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
2105921577
21060 AstNode *union_decl_node = type_entry->data.unionation.decl_node;21578 AstNode *union_decl_node = type_entry->data.unionation.decl_node;
21061 if (union_decl_node->data.container_decl.auto_enum ||21579 if (union_decl_node->data.container_decl.auto_enum ||
...@@ -21065,9 +21583,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21065,9 +21583,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21065 tag_type->special = ConstValSpecialStatic;21583 tag_type->special = ConstValSpecialStatic;
21066 tag_type->type = ira->codegen->builtin_types.entry_type;21584 tag_type->type = ira->codegen->builtin_types.entry_type;
21067 tag_type->data.x_type = type_entry->data.unionation.tag_type;21585 tag_type->data.x_type = type_entry->data.unionation.tag_type;
21068 fields[1].data.x_optional = tag_type;21586 fields[1]->data.x_optional = tag_type;
21069 } else {21587 } else {
21070 fields[1].data.x_optional = nullptr;21588 fields[1]->data.x_optional = nullptr;
21071 }21589 }
21072 // fields: []TypeInfo.UnionField21590 // fields: []TypeInfo.UnionField
21073 ensure_field_index(result->type, "fields", 2);21591 ensure_field_index(result->type, "fields", 2);
...@@ -21083,7 +21601,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21083,7 +21601,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21083 union_field_array->data.x_array.special = ConstArraySpecialNone;21601 union_field_array->data.x_array.special = ConstArraySpecialNone;
21084 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);21602 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count);
2108521603
21086 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false);21604 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false);
2108721605
21088 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);21606 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr);
2108921607
...@@ -21094,23 +21612,23 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21094,23 +21612,23 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21094 union_field_val->special = ConstValSpecialStatic;21612 union_field_val->special = ConstValSpecialStatic;
21095 union_field_val->type = type_info_union_field_type;21613 union_field_val->type = type_info_union_field_type;
2109621614
21097 ConstExprValue *inner_fields = create_const_vals(3);21615 ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
21098 inner_fields[1].special = ConstValSpecialStatic;21616 inner_fields[1]->special = ConstValSpecialStatic;
21099 inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type);21617 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type);
2110021618
21101 if (fields[1].data.x_optional == nullptr) {21619 if (fields[1]->data.x_optional == nullptr) {
21102 inner_fields[1].data.x_optional = nullptr;21620 inner_fields[1]->data.x_optional = nullptr;
21103 } else {21621 } else {
21104 inner_fields[1].data.x_optional = create_const_vals(1);21622 inner_fields[1]->data.x_optional = create_const_vals(1);
21105 make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type);21623 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type);
21106 }21624 }
2110721625
21108 inner_fields[2].special = ConstValSpecialStatic;21626 inner_fields[2]->special = ConstValSpecialStatic;
21109 inner_fields[2].type = ira->codegen->builtin_types.entry_type;21627 inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
21110 inner_fields[2].data.x_type = union_field->type_entry;21628 inner_fields[2]->data.x_type = union_field->type_entry;
2111121629
21112 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name);21630 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name);
21113 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true);21631 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
2111421632
21115 union_field_val->data.x_struct.fields = inner_fields;21633 union_field_val->data.x_struct.fields = inner_fields;
21116 union_field_val->parent.id = ConstParentIdArray;21634 union_field_val->parent.id = ConstParentIdArray;
...@@ -21119,7 +21637,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21119,7 +21637,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21119 }21637 }
21120 // decls: []TypeInfo.Declaration21638 // decls: []TypeInfo.Declaration
21121 ensure_field_index(result->type, "decls", 3);21639 ensure_field_index(result->type, "decls", 3);
21122 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[3],21640 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
21123 type_entry->data.unionation.decls_scope)))21641 type_entry->data.unionation.decls_scope)))
21124 {21642 {
21125 return err;21643 return err;
...@@ -21140,14 +21658,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21140,14 +21658,14 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21140 result->special = ConstValSpecialStatic;21658 result->special = ConstValSpecialStatic;
21141 result->type = ir_type_info_get_type(ira, "Struct", nullptr);21659 result->type = ir_type_info_get_type(ira, "Struct", nullptr);
2114221660
21143 ConstExprValue *fields = create_const_vals(3);21661 ConstExprValue **fields = alloc_const_vals_ptrs(3);
21144 result->data.x_struct.fields = fields;21662 result->data.x_struct.fields = fields;
2114521663
21146 // layout: ContainerLayout21664 // layout: ContainerLayout
21147 ensure_field_index(result->type, "layout", 0);21665 ensure_field_index(result->type, "layout", 0);
21148 fields[0].special = ConstValSpecialStatic;21666 fields[0]->special = ConstValSpecialStatic;
21149 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);21667 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr);
21150 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout);21668 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout);
21151 // fields: []TypeInfo.StructField21669 // fields: []TypeInfo.StructField
21152 ensure_field_index(result->type, "fields", 1);21670 ensure_field_index(result->type, "fields", 1);
2115321671
...@@ -21163,18 +21681,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21163,18 +21681,18 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21163 struct_field_array->data.x_array.special = ConstArraySpecialNone;21681 struct_field_array->data.x_array.special = ConstArraySpecialNone;
21164 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);21682 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count);
2116521683
21166 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false);21684 init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false);
2116721685
21168 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {21686 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) {
21169 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index];21687 TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index];
21170 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];21688 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index];
2117121689
21172 struct_field_val->special = ConstValSpecialStatic;21690 struct_field_val->special = ConstValSpecialStatic;
21173 struct_field_val->type = type_info_struct_field_type;21691 struct_field_val->type = type_info_struct_field_type;
2117421692
21175 ConstExprValue *inner_fields = create_const_vals(3);21693 ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
21176 inner_fields[1].special = ConstValSpecialStatic;21694 inner_fields[1]->special = ConstValSpecialStatic;
21177 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);21695 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int);
2117821696
21179 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field);21697 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field);
21180 if (field_type == nullptr)21698 if (field_type == nullptr)
...@@ -21182,21 +21700,21 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21182,21 +21700,21 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21182 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))21700 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown)))
21183 return err;21701 return err;
21184 if (!type_has_bits(struct_field->type_entry)) {21702 if (!type_has_bits(struct_field->type_entry)) {
21185 inner_fields[1].data.x_optional = nullptr;21703 inner_fields[1]->data.x_optional = nullptr;
21186 } else {21704 } else {
21187 size_t byte_offset = struct_field->offset;21705 size_t byte_offset = struct_field->offset;
21188 inner_fields[1].data.x_optional = create_const_vals(1);21706 inner_fields[1]->data.x_optional = create_const_vals(1);
21189 inner_fields[1].data.x_optional->special = ConstValSpecialStatic;21707 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic;
21190 inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;21708 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int;
21191 bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset);21709 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset);
21192 }21710 }
2119321711
21194 inner_fields[2].special = ConstValSpecialStatic;21712 inner_fields[2]->special = ConstValSpecialStatic;
21195 inner_fields[2].type = ira->codegen->builtin_types.entry_type;21713 inner_fields[2]->type = ira->codegen->builtin_types.entry_type;
21196 inner_fields[2].data.x_type = struct_field->type_entry;21714 inner_fields[2]->data.x_type = struct_field->type_entry;
2119721715
21198 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name);21716 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name);
21199 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true);21717 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);
2120021718
21201 struct_field_val->data.x_struct.fields = inner_fields;21719 struct_field_val->data.x_struct.fields = inner_fields;
21202 struct_field_val->parent.id = ConstParentIdArray;21720 struct_field_val->parent.id = ConstParentIdArray;
...@@ -21205,7 +21723,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21205,7 +21723,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21205 }21723 }
21206 // decls: []TypeInfo.Declaration21724 // decls: []TypeInfo.Declaration
21207 ensure_field_index(result->type, "decls", 2);21725 ensure_field_index(result->type, "decls", 2);
21208 if ((err = ir_make_type_info_decls(ira, source_instr, &fields[2],21726 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
21209 type_entry->data.structure.decls_scope)))21727 type_entry->data.structure.decls_scope)))
21210 {21728 {
21211 return err;21729 return err;
...@@ -21219,38 +21737,38 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21219,38 +21737,38 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21219 result->special = ConstValSpecialStatic;21737 result->special = ConstValSpecialStatic;
21220 result->type = ir_type_info_get_type(ira, "Fn", nullptr);21738 result->type = ir_type_info_get_type(ira, "Fn", nullptr);
2122121739
21222 ConstExprValue *fields = create_const_vals(5);21740 ConstExprValue **fields = alloc_const_vals_ptrs(5);
21223 result->data.x_struct.fields = fields;21741 result->data.x_struct.fields = fields;
2122421742
21225 // calling_convention: TypeInfo.CallingConvention21743 // calling_convention: TypeInfo.CallingConvention
21226 ensure_field_index(result->type, "calling_convention", 0);21744 ensure_field_index(result->type, "calling_convention", 0);
21227 fields[0].special = ConstValSpecialStatic;21745 fields[0]->special = ConstValSpecialStatic;
21228 fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr);21746 fields[0]->type = ir_type_info_get_type(ira, "CallingConvention", nullptr);
21229 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);21747 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc);
21230 // is_generic: bool21748 // is_generic: bool
21231 ensure_field_index(result->type, "is_generic", 1);21749 ensure_field_index(result->type, "is_generic", 1);
21232 bool is_generic = type_entry->data.fn.is_generic;21750 bool is_generic = type_entry->data.fn.is_generic;
21233 fields[1].special = ConstValSpecialStatic;21751 fields[1]->special = ConstValSpecialStatic;
21234 fields[1].type = ira->codegen->builtin_types.entry_bool;21752 fields[1]->type = ira->codegen->builtin_types.entry_bool;
21235 fields[1].data.x_bool = is_generic;21753 fields[1]->data.x_bool = is_generic;
21236 // is_varargs: bool21754 // is_varargs: bool
21237 ensure_field_index(result->type, "is_var_args", 2);21755 ensure_field_index(result->type, "is_var_args", 2);
21238 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;21756 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;
21239 fields[2].special = ConstValSpecialStatic;21757 fields[2]->special = ConstValSpecialStatic;
21240 fields[2].type = ira->codegen->builtin_types.entry_bool;21758 fields[2]->type = ira->codegen->builtin_types.entry_bool;
21241 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;21759 fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args;
21242 // return_type: ?type21760 // return_type: ?type
21243 ensure_field_index(result->type, "return_type", 3);21761 ensure_field_index(result->type, "return_type", 3);
21244 fields[3].special = ConstValSpecialStatic;21762 fields[3]->special = ConstValSpecialStatic;
21245 fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);21763 fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
21246 if (type_entry->data.fn.fn_type_id.return_type == nullptr)21764 if (type_entry->data.fn.fn_type_id.return_type == nullptr)
21247 fields[3].data.x_optional = nullptr;21765 fields[3]->data.x_optional = nullptr;
21248 else {21766 else {
21249 ConstExprValue *return_type = create_const_vals(1);21767 ConstExprValue *return_type = create_const_vals(1);
21250 return_type->special = ConstValSpecialStatic;21768 return_type->special = ConstValSpecialStatic;
21251 return_type->type = ira->codegen->builtin_types.entry_type;21769 return_type->type = ira->codegen->builtin_types.entry_type;
21252 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;21770 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
21253 fields[3].data.x_optional = return_type;21771 fields[3]->data.x_optional = return_type;
21254 }21772 }
21255 // args: []TypeInfo.FnArg21773 // args: []TypeInfo.FnArg
21256 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);21774 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);
...@@ -21266,7 +21784,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21266,7 +21784,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21266 fn_arg_array->data.x_array.special = ConstArraySpecialNone;21784 fn_arg_array->data.x_array.special = ConstArraySpecialNone;
21267 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);21785 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count);
2126821786
21269 init_const_slice(ira->codegen, &fields[4], fn_arg_array, 0, fn_arg_count, false);21787 init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false);
2127021788
21271 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {21789 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
21272 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];21790 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
...@@ -21278,24 +21796,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr...@@ -21278,24 +21796,24 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
21278 bool arg_is_generic = fn_param_info->type == nullptr;21796 bool arg_is_generic = fn_param_info->type == nullptr;
21279 if (arg_is_generic) assert(is_generic);21797 if (arg_is_generic) assert(is_generic);
2128021798
21281 ConstExprValue *inner_fields = create_const_vals(3);21799 ConstExprValue **inner_fields = alloc_const_vals_ptrs(3);
21282 inner_fields[0].special = ConstValSpecialStatic;21800 inner_fields[0]->special = ConstValSpecialStatic;
21283 inner_fields[0].type = ira->codegen->builtin_types.entry_bool;21801 inner_fields[0]->type = ira->codegen->builtin_types.entry_bool;
21284 inner_fields[0].data.x_bool = arg_is_generic;21802 inner_fields[0]->data.x_bool = arg_is_generic;
21285 inner_fields[1].special = ConstValSpecialStatic;21803 inner_fields[1]->special = ConstValSpecialStatic;
21286 inner_fields[1].type = ira->codegen->builtin_types.entry_bool;21804 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool;
21287 inner_fields[1].data.x_bool = fn_param_info->is_noalias;21805 inner_fields[1]->data.x_bool = fn_param_info->is_noalias;
21288 inner_fields[2].special = ConstValSpecialStatic;21806 inner_fields[2]->special = ConstValSpecialStatic;
21289 inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);21807 inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
2129021808
21291 if (arg_is_generic)21809 if (arg_is_generic)
21292 inner_fields[2].data.x_optional = nullptr;21810 inner_fields[2]->data.x_optional = nullptr;
21293 else {21811 else {
21294 ConstExprValue *arg_type = create_const_vals(1);21812 ConstExprValue *arg_type = create_const_vals(1);
21295 arg_type->special = ConstValSpecialStatic;21813 arg_type->special = ConstValSpecialStatic;
21296 arg_type->type = ira->codegen->builtin_types.entry_type;21814 arg_type->type = ira->codegen->builtin_types.entry_type;
21297 arg_type->data.x_type = fn_param_info->type;21815 arg_type->data.x_type = fn_param_info->type;
21298 inner_fields[2].data.x_optional = arg_type;21816 inner_fields[2]->data.x_optional = arg_type;
21299 }21817 }
2130021818
21301 fn_arg_val->data.x_struct.fields = inner_fields;21819 fn_arg_val->data.x_struct.fields = inner_fields;
...@@ -21356,8 +21874,8 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira,...@@ -21356,8 +21874,8 @@ static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira,
21356static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)21874static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)
21357{21875{
21358 ensure_field_index(struct_value->type, name, field_index);21876 ensure_field_index(struct_value->type, name, field_index);
21359 assert(struct_value->data.x_struct.fields[field_index].special == ConstValSpecialStatic);21877 assert(struct_value->data.x_struct.fields[field_index]->special == ConstValSpecialStatic);
21360 return &struct_value->data.x_struct.fields[field_index];21878 return struct_value->data.x_struct.fields[field_index];
21361}21879}
2136221880
21363static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)21881static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index)
...@@ -21656,15 +22174,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct...@@ -21656,15 +22174,15 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
21656 }22174 }
21657 for (size_t i = 0; i < errors_len; i += 1) {22175 for (size_t i = 0; i < errors_len; i += 1) {
21658 Stage2ErrorMsg *clang_err = &errors_ptr[i];22176 Stage2ErrorMsg *clang_err = &errors_ptr[i];
21659 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null22177 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null
21660 if (clang_err->source && clang_err->filename_ptr) {22178 if (clang_err->source && clang_err->filename_ptr) {
21661 ErrorMsg *err_msg = err_msg_create_with_offset(22179 ErrorMsg *err_msg = err_msg_create_with_offset(
21662 clang_err->filename_ptr ?22180 clang_err->filename_ptr ?
21663 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),22181 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
21664 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,22182 clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
21665 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));22183 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
21666 err_msg_add_note(parent_err_msg, err_msg);22184 err_msg_add_note(parent_err_msg, err_msg);
21667 }22185 }
21668 }22186 }
2166922187
21670 return ira->codegen->invalid_instruction;22188 return ira->codegen->invalid_instruction;
...@@ -22122,7 +22640,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -22122,7 +22640,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
22122 if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align)))22640 if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align)))
22123 return ira->codegen->invalid_instruction;22641 return ira->codegen->invalid_instruction;
22124 } else if (is_slice(target->value.type)) {22642 } else if (is_slice(target->value.type)) {
22125 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;22643 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
22126 src_ptr_const = src_ptr_type->data.pointer.is_const;22644 src_ptr_const = src_ptr_type->data.pointer.is_const;
22127 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;22645 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
2212822646
...@@ -22165,7 +22683,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru...@@ -22165,7 +22683,7 @@ static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstru
22165 if (!val)22683 if (!val)
22166 return ira->codegen->invalid_instruction;22684 return ira->codegen->invalid_instruction;
2216722685
22168 ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index];22686 ConstExprValue *len_val = val->data.x_struct.fields[slice_len_index];
22169 if (value_is_comptime(len_val)) {22687 if (value_is_comptime(len_val)) {
22170 known_len = bigint_as_u64(&len_val->data.x_bigint);22688 known_len = bigint_as_u64(&len_val->data.x_bigint);
22171 have_known_len = true;22689 have_known_len = true;
...@@ -22215,7 +22733,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct...@@ -22215,7 +22733,7 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
22215 return ira->codegen->invalid_instruction;22733 return ira->codegen->invalid_instruction;
22216 }22734 }
2221722735
22218 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;22736 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
2221922737
22220 uint32_t alignment;22738 uint32_t alignment;
22221 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))22739 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
...@@ -22232,17 +22750,17 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct...@@ -22232,17 +22750,17 @@ static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstruct
22232 return ira->codegen->invalid_instruction;22750 return ira->codegen->invalid_instruction;
2223322751
22234 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type);22752 IrInstruction *result = ir_const(ira, &instruction->base, dest_slice_type);
22235 result->value.data.x_struct.fields = create_const_vals(2);22753 result->value.data.x_struct.fields = alloc_const_vals_ptrs(2);
2223622754
22237 ConstExprValue *ptr_val = &result->value.data.x_struct.fields[slice_ptr_index];22755 ConstExprValue *ptr_val = result->value.data.x_struct.fields[slice_ptr_index];
22238 ConstExprValue *target_ptr_val = &target_val->data.x_struct.fields[slice_ptr_index];22756 ConstExprValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
22239 copy_const_val(ptr_val, target_ptr_val, false);22757 copy_const_val(ptr_val, target_ptr_val, false);
22240 ptr_val->type = dest_ptr_type;22758 ptr_val->type = dest_ptr_type;
2224122759
22242 ConstExprValue *len_val = &result->value.data.x_struct.fields[slice_len_index];22760 ConstExprValue *len_val = result->value.data.x_struct.fields[slice_len_index];
22243 len_val->special = ConstValSpecialStatic;22761 len_val->special = ConstValSpecialStatic;
22244 len_val->type = ira->codegen->builtin_types.entry_usize;22762 len_val->type = ira->codegen->builtin_types.entry_usize;
22245 ConstExprValue *target_len_val = &target_val->data.x_struct.fields[slice_len_index];22763 ConstExprValue *target_len_val = target_val->data.x_struct.fields[slice_len_index];
22246 ZigType *elem_type = src_ptr_type->data.pointer.child_type;22764 ZigType *elem_type = src_ptr_type->data.pointer.child_type;
22247 BigInt elem_size_bigint;22765 BigInt elem_size_bigint;
22248 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));22766 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
...@@ -23023,7 +23541,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -23023,7 +23541,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
23023 }23541 }
23024 }23542 }
23025 } else if (is_slice(array_type)) {23543 } else if (is_slice(array_type)) {
23026 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;23544 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;
23027 return_type = get_slice_type(ira->codegen, ptr_type);23545 return_type = get_slice_type(ira->codegen, ptr_type);
23028 } else {23546 } else {
23029 ir_add_error(ira, &instruction->base,23547 ir_add_error(ira, &instruction->base,
...@@ -23131,13 +23649,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -23131,13 +23649,13 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
23131 return ira->codegen->invalid_instruction;23649 return ira->codegen->invalid_instruction;
23132 }23650 }
2313323651
23134 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index];23652 parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index];
23135 if (parent_ptr->special == ConstValSpecialUndef) {23653 if (parent_ptr->special == ConstValSpecialUndef) {
23136 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined"));23654 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined"));
23137 return ira->codegen->invalid_instruction;23655 return ira->codegen->invalid_instruction;
23138 }23656 }
2313923657
23140 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index];23658 ConstExprValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index];
2314123659
23142 switch (parent_ptr->data.x_ptr.special) {23660 switch (parent_ptr->data.x_ptr.special) {
23143 case ConstPtrSpecialInvalid:23661 case ConstPtrSpecialInvalid:
...@@ -23209,9 +23727,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -23209,9 +23727,9 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
2320923727
23210 IrInstruction *result = ir_const(ira, &instruction->base, return_type);23728 IrInstruction *result = ir_const(ira, &instruction->base, return_type);
23211 ConstExprValue *out_val = &result->value;23729 ConstExprValue *out_val = &result->value;
23212 out_val->data.x_struct.fields = create_const_vals(2);23730 out_val->data.x_struct.fields = alloc_const_vals_ptrs(2);
2321323731
23214 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index];23732 ConstExprValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index];
2321523733
23216 if (array_val) {23734 if (array_val) {
23217 size_t index = abs_offset + start_scalar;23735 size_t index = abs_offset + start_scalar;
...@@ -23258,7 +23776,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction...@@ -23258,7 +23776,7 @@ static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstruction
23258 zig_panic("TODO");23776 zig_panic("TODO");
23259 }23777 }
2326023778
23261 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];23779 ConstExprValue *len_val = out_val->data.x_struct.fields[slice_len_index];
23262 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);23780 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
2326323781
23264 return result;23782 return result;
...@@ -23332,7 +23850,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr...@@ -23332,7 +23850,7 @@ static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstr
23332 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));23850 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
23333 return ira->codegen->invalid_instruction;23851 return ira->codegen->invalid_instruction;
23334 }23852 }
23335 TypeStructField *field = &container_type->data.structure.fields[member_index];23853 TypeStructField *field = container_type->data.structure.fields[member_index];
2333623854
23337 return ir_const_type(ira, &instruction->base, field->type_entry);23855 return ir_const_type(ira, &instruction->base, field->type_entry);
23338 } else if (container_type->id == ZigTypeIdUnion) {23856 } else if (container_type->id == ZigTypeIdUnion) {
...@@ -23374,7 +23892,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr...@@ -23374,7 +23892,7 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr
23374 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));23892 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
23375 return ira->codegen->invalid_instruction;23893 return ira->codegen->invalid_instruction;
23376 }23894 }
23377 TypeStructField *field = &container_type->data.structure.fields[member_index];23895 TypeStructField *field = container_type->data.structure.fields[member_index];
2337823896
23379 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);23897 IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
23380 init_const_str_lit(ira->codegen, &result->value, field->name);23898 init_const_str_lit(ira->codegen, &result->value, field->name);
...@@ -24360,7 +24878,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3...@@ -24360,7 +24878,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
24360 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id);24878 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id);
24361 result_type = get_optional_type(ira->codegen, fn_type);24879 result_type = get_optional_type(ira->codegen, fn_type);
24362 } else if (is_slice(target_type)) {24880 } else if (is_slice(target_type)) {
24363 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry;24881 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry;
24364 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes)))24882 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes)))
24365 return ira->codegen->invalid_instruction;24883 return ira->codegen->invalid_instruction;
24366 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes);24884 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes);
...@@ -24409,6 +24927,10 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_...@@ -24409,6 +24927,10 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
24409 ZigType *src_type = ptr->value.type;24927 ZigType *src_type = ptr->value.type;
24410 assert(!type_is_invalid(src_type));24928 assert(!type_is_invalid(src_type));
2441124929
24930 if (src_type == dest_type) {
24931 return ptr;
24932 }
24933
24412 // We have a check for zero bits later so we use get_src_ptr_type to24934 // We have a check for zero bits later so we use get_src_ptr_type to
24413 // validate src_type and dest_type.24935 // validate src_type and dest_type.
2441424936
...@@ -24458,6 +24980,9 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_...@@ -24458,6 +24980,9 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
24458 IrInstruction *result;24980 IrInstruction *result;
24459 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {24981 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
24460 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);24982 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
24983
24984 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
24985 return ira->codegen->invalid_instruction;
24461 } else {24986 } else {
24462 result = ir_const(ira, source_instr, dest_type);24987 result = ir_const(ira, source_instr, dest_type);
24463 }24988 }
...@@ -24598,10 +25123,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -24598,10 +25123,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
24598 case ContainerLayoutExtern: {25123 case ContainerLayoutExtern: {
24599 size_t src_field_count = val->type->data.structure.src_field_count;25124 size_t src_field_count = val->type->data.structure.src_field_count;
24600 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {25125 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
24601 TypeStructField *struct_field = &val->type->data.structure.fields[field_i];25126 TypeStructField *struct_field = val->type->data.structure.fields[field_i];
24602 if (struct_field->gen_index == SIZE_MAX)25127 if (struct_field->gen_index == SIZE_MAX)
24603 continue;25128 continue;
24604 ConstExprValue *field_val = &val->data.x_struct.fields[field_i];25129 ConstExprValue *field_val = val->data.x_struct.fields[field_i];
24605 size_t offset = struct_field->offset;25130 size_t offset = struct_field->offset;
24606 buf_write_value_bytes(codegen, buf + offset, field_val);25131 buf_write_value_bytes(codegen, buf + offset, field_val);
24607 }25132 }
...@@ -24627,12 +25152,12 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -24627,12 +25152,12 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
24627 bigint_init_unsigned(&big_int, 0);25152 bigint_init_unsigned(&big_int, 0);
24628 size_t used_bits = 0;25153 size_t used_bits = 0;
24629 while (src_i < src_field_count) {25154 while (src_i < src_field_count) {
24630 TypeStructField *field = &val->type->data.structure.fields[src_i];25155 TypeStructField *field = val->type->data.structure.fields[src_i];
24631 assert(field->gen_index != SIZE_MAX);25156 assert(field->gen_index != SIZE_MAX);
24632 if (field->gen_index != gen_i)25157 if (field->gen_index != gen_i)
24633 break;25158 break;
24634 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);25159 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);
24635 buf_write_value_bytes(codegen, child_buf, &val->data.x_struct.fields[src_i]);25160 buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]);
24636 BigInt child_val;25161 BigInt child_val;
24637 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian,25162 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian,
24638 false);25163 false);
...@@ -24770,11 +25295,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -24770,11 +25295,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
24770 }25295 }
24771 case ContainerLayoutExtern: {25296 case ContainerLayoutExtern: {
24772 size_t src_field_count = val->type->data.structure.src_field_count;25297 size_t src_field_count = val->type->data.structure.src_field_count;
24773 val->data.x_struct.fields = create_const_vals(src_field_count);25298 val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
24774 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {25299 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
24775 ConstExprValue *field_val = &val->data.x_struct.fields[field_i];25300 ConstExprValue *field_val = val->data.x_struct.fields[field_i];
24776 field_val->special = ConstValSpecialStatic;25301 field_val->special = ConstValSpecialStatic;
24777 TypeStructField *struct_field = &val->type->data.structure.fields[field_i];25302 TypeStructField *struct_field = val->type->data.structure.fields[field_i];
24778 field_val->type = struct_field->type_entry;25303 field_val->type = struct_field->type_entry;
24779 if (struct_field->gen_index == SIZE_MAX)25304 if (struct_field->gen_index == SIZE_MAX)
24780 continue;25305 continue;
...@@ -24787,7 +25312,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -24787,7 +25312,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
24787 }25312 }
24788 case ContainerLayoutPacked: {25313 case ContainerLayoutPacked: {
24789 size_t src_field_count = val->type->data.structure.src_field_count;25314 size_t src_field_count = val->type->data.structure.src_field_count;
24790 val->data.x_struct.fields = create_const_vals(src_field_count);25315 val->data.x_struct.fields = alloc_const_vals_ptrs(src_field_count);
24791 size_t gen_field_count = val->type->data.structure.gen_field_count;25316 size_t gen_field_count = val->type->data.structure.gen_field_count;
24792 size_t gen_i = 0;25317 size_t gen_i = 0;
24793 size_t src_i = 0;25318 size_t src_i = 0;
...@@ -24805,11 +25330,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou...@@ -24805,11 +25330,11 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
24805 BigInt big_int;25330 BigInt big_int;
24806 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);25331 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
24807 while (src_i < src_field_count) {25332 while (src_i < src_field_count) {
24808 TypeStructField *field = &val->type->data.structure.fields[src_i];25333 TypeStructField *field = val->type->data.structure.fields[src_i];
24809 src_assert(field->gen_index != SIZE_MAX, source_node);25334 src_assert(field->gen_index != SIZE_MAX, source_node);
24810 if (field->gen_index != gen_i)25335 if (field->gen_index != gen_i)
24811 break;25336 break;
24812 ConstExprValue *field_val = &val->data.x_struct.fields[src_i];25337 ConstExprValue *field_val = val->data.x_struct.fields[src_i];
24813 field_val->special = ConstValSpecialStatic;25338 field_val->special = ConstValSpecialStatic;
24814 field_val->type = field->type_entry;25339 field_val->type = field->type_entry;
24815 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);25340 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry);
...@@ -24992,6 +25517,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,...@@ -24992,6 +25517,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
24992}25517}
2499325518
24994static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {25519static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) {
25520 Error err;
24995 IrInstruction *target = instruction->target->child;25521 IrInstruction *target = instruction->target->child;
24996 if (type_is_invalid(target->value.type))25522 if (type_is_invalid(target->value.type))
24997 return ira->codegen->invalid_instruction;25523 return ira->codegen->invalid_instruction;
...@@ -25005,6 +25531,8 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru...@@ -25005,6 +25531,8 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru
25005 return ira->codegen->invalid_instruction;25531 return ira->codegen->invalid_instruction;
25006 }25532 }
2500725533
25534 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown)))
25535 return ira->codegen->invalid_instruction;
25008 if (!type_has_bits(target->value.type)) {25536 if (!type_has_bits(target->value.type)) {
25009 ir_add_error(ira, target,25537 ir_add_error(ira, target,
25010 buf_sprintf("pointer to size 0 type has no address"));25538 buf_sprintf("pointer to size 0 type has no address"));
...@@ -25065,7 +25593,7 @@ static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstru...@@ -25065,7 +25593,7 @@ static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstru
2506525593
25066 ZigType *elem_type = nullptr;25594 ZigType *elem_type = nullptr;
25067 if (is_slice(target->value.type)) {25595 if (is_slice(target->value.type)) {
25068 ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry;25596 ZigType *slice_ptr_type = target->value.type->data.structure.fields[slice_ptr_index]->type_entry;
25069 elem_type = slice_ptr_type->data.pointer.child_type;25597 elem_type = slice_ptr_type->data.pointer.child_type;
25070 } else if (target->value.type->id == ZigTypeIdPointer) {25598 } else if (target->value.type->id == ZigTypeIdPointer) {
25071 elem_type = target->value.type->data.pointer.child_type;25599 elem_type = target->value.type->data.pointer.child_type;
...@@ -25142,6 +25670,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct...@@ -25142,6 +25670,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
25142 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index))25670 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index))
25143 return ira->codegen->invalid_instruction;25671 return ira->codegen->invalid_instruction;
2514425672
25673 if (fn_type->id == ZigTypeIdBoundFn) {
25674 fn_type = fn_type->data.bound_fn.fn_type;
25675 arg_index += 1;
25676 }
25145 if (fn_type->id != ZigTypeIdFn) {25677 if (fn_type->id != ZigTypeIdFn) {
25146 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name)));25678 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name)));
25147 return ira->codegen->invalid_instruction;25679 return ira->codegen->invalid_instruction;
...@@ -25149,6 +25681,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct...@@ -25149,6 +25681,10 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
2514925681
25150 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;25682 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
25151 if (arg_index >= fn_type_id->param_count) {25683 if (arg_index >= fn_type_id->param_count) {
25684 if (instruction->allow_var) {
25685 // TODO remove this with var args
25686 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var);
25687 }
25152 ir_add_error(ira, arg_index_inst,25688 ir_add_error(ira, arg_index_inst,
25153 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",25689 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments",
25154 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count));25690 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count));
...@@ -25160,10 +25696,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct...@@ -25160,10 +25696,14 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
25160 // Args are only unresolved if our function is generic.25696 // Args are only unresolved if our function is generic.
25161 ir_assert(fn_type->data.fn.is_generic, &instruction->base);25697 ir_assert(fn_type->data.fn.is_generic, &instruction->base);
2516225698
25163 ir_add_error(ira, arg_index_inst,25699 if (instruction->allow_var) {
25164 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",25700 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_var);
25165 arg_index, buf_ptr(&fn_type->name)));25701 } else {
25166 return ira->codegen->invalid_instruction;25702 ir_add_error(ira, arg_index_inst,
25703 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
25704 arg_index, buf_ptr(&fn_type->name)));
25705 return ira->codegen->invalid_instruction;
25706 }
25167 }25707 }
25168 return ir_const_type(ira, &instruction->base, result_type);25708 return ir_const_type(ira, &instruction->base, result_type);
25169}25709}
...@@ -25216,9 +25756,29 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op...@@ -25216,9 +25756,29 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
25216 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));25756 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));
25217 return ira->codegen->builtin_types.entry_invalid;25757 return ira->codegen->builtin_types.entry_invalid;
25218 }25758 }
25759 } else if (operand_type->id == ZigTypeIdEnum) {
25760 ZigType *int_type = operand_type->data.enumeration.tag_int_type;
25761 if (int_type->data.integral.bit_count < 8) {
25762 ir_add_error(ira, op,
25763 buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type",
25764 int_type->data.integral.bit_count));
25765 return ira->codegen->builtin_types.entry_invalid;
25766 }
25767 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
25768 if (int_type->data.integral.bit_count > max_atomic_bits) {
25769 ir_add_error(ira, op,
25770 buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type",
25771 max_atomic_bits, int_type->data.integral.bit_count));
25772 return ira->codegen->builtin_types.entry_invalid;
25773 }
25774 if (!is_power_of_2(int_type->data.integral.bit_count)) {
25775 ir_add_error(ira, op,
25776 buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count));
25777 return ira->codegen->builtin_types.entry_invalid;
25778 }
25219 } else if (get_codegen_ptr_type(operand_type) == nullptr) {25779 } else if (get_codegen_ptr_type(operand_type) == nullptr) {
25220 ir_add_error(ira, op,25780 ir_add_error(ira, op,
25221 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name)));25781 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name)));
25222 return ira->codegen->builtin_types.entry_invalid;25782 return ira->codegen->builtin_types.entry_invalid;
25223 }25783 }
2522425784
...@@ -25249,6 +25809,12 @@ static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstru...@@ -25249,6 +25809,12 @@ static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstru
25249 }25809 }
25250 }25810 }
2525125811
25812 if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) {
25813 ir_add_error(ira, instruction->op,
25814 buf_sprintf("@atomicRmw on enum only works with .Xchg"));
25815 return ira->codegen->invalid_instruction;
25816 }
25817
25252 IrInstruction *operand = instruction->operand->child;25818 IrInstruction *operand = instruction->operand->child;
25253 if (type_is_invalid(operand->value.type))25819 if (type_is_invalid(operand->value.type))
25254 return ira->codegen->invalid_instruction;25820 return ira->codegen->invalid_instruction;
...@@ -25323,6 +25889,56 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr...@@ -25323,6 +25889,56 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
25323 return result;25889 return result;
25324}25890}
2532525891
25892static IrInstruction *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstructionAtomicStore *instruction) {
25893 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child);
25894 if (type_is_invalid(operand_type))
25895 return ira->codegen->invalid_instruction;
25896
25897 IrInstruction *ptr_inst = instruction->ptr->child;
25898 if (type_is_invalid(ptr_inst->value.type))
25899 return ira->codegen->invalid_instruction;
25900
25901 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false);
25902 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type);
25903 if (type_is_invalid(casted_ptr->value.type))
25904 return ira->codegen->invalid_instruction;
25905
25906 IrInstruction *value = instruction->value->child;
25907 if (type_is_invalid(value->value.type))
25908 return ira->codegen->invalid_instruction;
25909
25910 IrInstruction *casted_value = ir_implicit_cast(ira, value, operand_type);
25911 if (type_is_invalid(casted_value->value.type))
25912 return ira->codegen->invalid_instruction;
25913
25914
25915 AtomicOrder ordering;
25916 if (instruction->ordering == nullptr) {
25917 ordering = instruction->resolved_ordering;
25918 } else {
25919 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering))
25920 return ira->codegen->invalid_instruction;
25921 }
25922
25923 if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) {
25924 ir_assert(instruction->ordering != nullptr, &instruction->base);
25925 ir_add_error(ira, instruction->ordering,
25926 buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel"));
25927 return ira->codegen->invalid_instruction;
25928 }
25929
25930 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) {
25931 IrInstruction *result = ir_analyze_store_ptr(ira, &instruction->base, casted_ptr, value, false);
25932 result->value.type = ira->codegen->builtin_types.entry_void;
25933 return result;
25934 }
25935
25936 IrInstruction *result = ir_build_atomic_store(&ira->new_irb, instruction->base.scope,
25937 instruction->base.source_node, nullptr, casted_ptr, casted_value, nullptr, ordering);
25938 result->value.type = ira->codegen->builtin_types.entry_void;
25939 return result;
25940}
25941
25326static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) {25942static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) {
25327 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope,25943 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope,
25328 instruction->base.source_node);25944 instruction->base.source_node);
...@@ -25854,6 +26470,26 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct...@@ -25854,6 +26470,26 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
25854 return ir_const_void(ira, &instruction->base);26470 return ir_const_void(ira, &instruction->base);
25855}26471}
2585626472
26473static IrInstruction *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstructionImplicitCast *instruction) {
26474 IrInstruction *operand = instruction->operand->child;
26475 if (type_is_invalid(operand->value.type))
26476 return operand;
26477
26478 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base,
26479 &instruction->result_loc_cast->base, operand->value.type, operand, false, false, true);
26480 if (result_loc != nullptr && (type_is_invalid(result_loc->value.type) || instr_is_unreachable(result_loc)))
26481 return result_loc;
26482
26483 if (instruction->result_loc_cast->parent->gen_instruction != nullptr) {
26484 return instruction->result_loc_cast->parent->gen_instruction;
26485 }
26486
26487 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child);
26488 if (type_is_invalid(dest_type))
26489 return ira->codegen->invalid_instruction;
26490 return ir_implicit_cast_with_result(ira, &instruction->base, operand, dest_type, nullptr);
26491}
26492
25857static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {26493static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstructionBitCastSrc *instruction) {
25858 IrInstruction *operand = instruction->operand->child;26494 IrInstruction *operand = instruction->operand->child;
25859 if (type_is_invalid(operand->value.type))26495 if (type_is_invalid(operand->value.type))
...@@ -26337,6 +26973,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -26337,6 +26973,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
26337 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction);26973 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction);
26338 case IrInstructionIdAtomicLoad:26974 case IrInstructionIdAtomicLoad:
26339 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction);26975 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction);
26976 case IrInstructionIdAtomicStore:
26977 return ir_analyze_instruction_atomic_store(ira, (IrInstructionAtomicStore *)instruction);
26340 case IrInstructionIdSaveErrRetAddr:26978 case IrInstructionIdSaveErrRetAddr:
26341 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction);26979 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction);
26342 case IrInstructionIdAddImplicitReturnType:26980 case IrInstructionIdAddImplicitReturnType:
...@@ -26517,6 +27155,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -26517,6 +27155,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
26517 case IrInstructionIdSaveErrRetAddr:27155 case IrInstructionIdSaveErrRetAddr:
26518 case IrInstructionIdAddImplicitReturnType:27156 case IrInstructionIdAddImplicitReturnType:
26519 case IrInstructionIdAtomicRmw:27157 case IrInstructionIdAtomicRmw:
27158 case IrInstructionIdAtomicStore:
26520 case IrInstructionIdCmpxchgGen:27159 case IrInstructionIdCmpxchgGen:
26521 case IrInstructionIdCmpxchgSrc:27160 case IrInstructionIdCmpxchgSrc:
26522 case IrInstructionIdAssertZero:27161 case IrInstructionIdAssertZero:
src/ir_print.cpp+60-12
...@@ -324,6 +324,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {...@@ -324,6 +324,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {
324 return "AtomicRmw";324 return "AtomicRmw";
325 case IrInstructionIdAtomicLoad:325 case IrInstructionIdAtomicLoad:
326 return "AtomicLoad";326 return "AtomicLoad";
327 case IrInstructionIdAtomicStore:
328 return "AtomicStore";
327 case IrInstructionIdSaveErrRetAddr:329 case IrInstructionIdSaveErrRetAddr:
328 return "SaveErrRetAddr";330 return "SaveErrRetAddr";
329 case IrInstructionIdAddImplicitReturnType:331 case IrInstructionIdAddImplicitReturnType:
...@@ -601,6 +603,12 @@ static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_...@@ -601,6 +603,12 @@ static void ir_print_result_loc_bit_cast(IrPrint *irp, ResultLocBitCast *result_
601 fprintf(irp->f, ")");603 fprintf(irp->f, ")");
602}604}
603605
606static void ir_print_result_loc_cast(IrPrint *irp, ResultLocCast *result_loc_cast) {
607 fprintf(irp->f, "cast(ty=");
608 ir_print_other_instruction(irp, result_loc_cast->base.source_instruction);
609 fprintf(irp->f, ")");
610}
611
604static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {612static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
605 switch (result_loc->id) {613 switch (result_loc->id) {
606 case ResultLocIdInvalid:614 case ResultLocIdInvalid:
...@@ -619,6 +627,8 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {...@@ -619,6 +627,8 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
619 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);627 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
620 case ResultLocIdBitCast:628 case ResultLocIdBitCast:
621 return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc);629 return ir_print_result_loc_bit_cast(irp, (ResultLocBitCast *)result_loc);
630 case ResultLocIdCast:
631 return ir_print_result_loc_cast(irp, (ResultLocCast *)result_loc);
622 case ResultLocIdPeerParent:632 case ResultLocIdPeerParent:
623 fprintf(irp->f, "peer_parent");633 fprintf(irp->f, "peer_parent");
624 return;634 return;
...@@ -723,7 +733,6 @@ static void ir_print_phi(IrPrint *irp, IrInstructionPhi *phi_instruction) {...@@ -723,7 +733,6 @@ static void ir_print_phi(IrPrint *irp, IrInstructionPhi *phi_instruction) {
723}733}
724734
725static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerInitList *instruction) {735static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerInitList *instruction) {
726 ir_print_other_instruction(irp, instruction->container_type);
727 fprintf(irp->f, "{");736 fprintf(irp->f, "{");
728 if (instruction->item_count > 50) {737 if (instruction->item_count > 50) {
729 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);738 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
...@@ -735,11 +744,11 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni...@@ -735,11 +744,11 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni
735 ir_print_other_instruction(irp, result_loc);744 ir_print_other_instruction(irp, result_loc);
736 }745 }
737 }746 }
738 fprintf(irp->f, "}");747 fprintf(irp->f, "}result=");
748 ir_print_other_instruction(irp, instruction->result_loc);
739}749}
740750
741static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerInitFields *instruction) {751static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerInitFields *instruction) {
742 ir_print_other_instruction(irp, instruction->container_type);
743 fprintf(irp->f, "{");752 fprintf(irp->f, "{");
744 for (size_t i = 0; i < instruction->field_count; i += 1) {753 for (size_t i = 0; i < instruction->field_count; i += 1) {
745 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];754 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
...@@ -747,7 +756,8 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI...@@ -747,7 +756,8 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
747 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));756 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
748 ir_print_other_instruction(irp, field->result_loc);757 ir_print_other_instruction(irp, field->result_loc);
749 }758 }
750 fprintf(irp->f, "} // container init");759 fprintf(irp->f, "}result=");
760 ir_print_other_instruction(irp, instruction->result_loc);
751}761}
752762
753static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {763static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
...@@ -1484,6 +1494,13 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc...@@ -1484,6 +1494,13 @@ static void ir_print_ptr_cast_gen(IrPrint *irp, IrInstructionPtrCastGen *instruc
1484 fprintf(irp->f, ")");1494 fprintf(irp->f, ")");
1485}1495}
14861496
1497static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
1498 fprintf(irp->f, "@implicitCast(");
1499 ir_print_other_instruction(irp, instruction->operand);
1500 fprintf(irp->f, ")result=");
1501 ir_print_result_loc(irp, &instruction->result_loc_cast->base);
1502}
1503
1487static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {1504static void ir_print_bit_cast_src(IrPrint *irp, IrInstructionBitCastSrc *instruction) {
1488 fprintf(irp->f, "@bitCast(");1505 fprintf(irp->f, "@bitCast(");
1489 ir_print_other_instruction(irp, instruction->operand);1506 ir_print_other_instruction(irp, instruction->operand);
...@@ -1739,14 +1756,6 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio...@@ -1739,14 +1756,6 @@ static void ir_print_align_cast(IrPrint *irp, IrInstructionAlignCast *instructio
1739 fprintf(irp->f, ")");1756 fprintf(irp->f, ")");
1740}1757}
17411758
1742static void ir_print_implicit_cast(IrPrint *irp, IrInstructionImplicitCast *instruction) {
1743 fprintf(irp->f, "@implicitCast(");
1744 ir_print_other_instruction(irp, instruction->dest_type);
1745 fprintf(irp->f, ",");
1746 ir_print_other_instruction(irp, instruction->target);
1747 fprintf(irp->f, ")");
1748}
1749
1750static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {1759static void ir_print_resolve_result(IrPrint *irp, IrInstructionResolveResult *instruction) {
1751 fprintf(irp->f, "ResolveResult(");1760 fprintf(irp->f, "ResolveResult(");
1752 ir_print_result_loc(irp, instruction->result_loc);1761 ir_print_result_loc(irp, instruction->result_loc);
...@@ -1864,6 +1873,27 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct...@@ -1864,6 +1873,27 @@ static void ir_print_atomic_load(IrPrint *irp, IrInstructionAtomicLoad *instruct
1864 fprintf(irp->f, ")");1873 fprintf(irp->f, ")");
1865}1874}
18661875
1876static void ir_print_atomic_store(IrPrint *irp, IrInstructionAtomicStore *instruction) {
1877 fprintf(irp->f, "@atomicStore(");
1878 if (instruction->operand_type != nullptr) {
1879 ir_print_other_instruction(irp, instruction->operand_type);
1880 } else {
1881 fprintf(irp->f, "[TODO print]");
1882 }
1883 fprintf(irp->f, ",");
1884 ir_print_other_instruction(irp, instruction->ptr);
1885 fprintf(irp->f, ",");
1886 ir_print_other_instruction(irp, instruction->value);
1887 fprintf(irp->f, ",");
1888 if (instruction->ordering != nullptr) {
1889 ir_print_other_instruction(irp, instruction->ordering);
1890 } else {
1891 fprintf(irp->f, "[TODO print]");
1892 }
1893 fprintf(irp->f, ")");
1894}
1895
1896
1867static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) {1897static void ir_print_save_err_ret_addr(IrPrint *irp, IrInstructionSaveErrRetAddr *instruction) {
1868 fprintf(irp->f, "@saveErrRetAddr()");1898 fprintf(irp->f, "@saveErrRetAddr()");
1869}1899}
...@@ -2424,6 +2454,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool...@@ -2424,6 +2454,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool
2424 case IrInstructionIdAtomicLoad:2454 case IrInstructionIdAtomicLoad:
2425 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);2455 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
2426 break;2456 break;
2457 case IrInstructionIdAtomicStore:
2458 ir_print_atomic_store(irp, (IrInstructionAtomicStore *)instruction);
2459 break;
2427 case IrInstructionIdEnumToInt:2460 case IrInstructionIdEnumToInt:
2428 ir_print_enum_to_int(irp, (IrInstructionEnumToInt *)instruction);2461 ir_print_enum_to_int(irp, (IrInstructionEnumToInt *)instruction);
2429 break;2462 break;
...@@ -2542,3 +2575,18 @@ void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction,...@@ -2542,3 +2575,18 @@ void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction,
25422575
2543 ir_print_instruction(irp, instruction, false);2576 ir_print_instruction(irp, instruction, false);
2544}2577}
2578
2579void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass) {
2580 IrPrint ir_print = {};
2581 IrPrint *irp = &ir_print;
2582 irp->pass = pass;
2583 irp->codegen = codegen;
2584 irp->f = f;
2585 irp->indent = indent_size;
2586 irp->indent_size = indent_size;
2587 irp->printed = {};
2588 irp->printed.init(4);
2589 irp->pending = {};
2590
2591 ir_print_const_value(irp, value);
2592}
src/ir_print.hpp+1
...@@ -14,6 +14,7 @@...@@ -14,6 +14,7 @@
1414
15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);15void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size, IrPass pass);
16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);16void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size, IrPass pass);
17void ir_print_const_expr(CodeGen *codegen, FILE *f, ConstExprValue *value, int indent_size, IrPass pass);
1718
18const char* ir_instruction_type_str(IrInstructionId id);19const char* ir_instruction_type_str(IrInstructionId id);
1920
src/parser.cpp+48-12
...@@ -81,7 +81,7 @@ static AstNode *ast_parse_for_type_expr(ParseContext *pc);...@@ -81,7 +81,7 @@ static AstNode *ast_parse_for_type_expr(ParseContext *pc);
81static AstNode *ast_parse_while_type_expr(ParseContext *pc);81static AstNode *ast_parse_while_type_expr(ParseContext *pc);
82static AstNode *ast_parse_switch_expr(ParseContext *pc);82static AstNode *ast_parse_switch_expr(ParseContext *pc);
83static AstNode *ast_parse_asm_expr(ParseContext *pc);83static AstNode *ast_parse_asm_expr(ParseContext *pc);
84static AstNode *ast_parse_enum_lit(ParseContext *pc);84static AstNode *ast_parse_anon_lit(ParseContext *pc);
85static AstNode *ast_parse_asm_output(ParseContext *pc);85static AstNode *ast_parse_asm_output(ParseContext *pc);
86static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);86static AsmOutput *ast_parse_asm_output_item(ParseContext *pc);
87static AstNode *ast_parse_asm_input(ParseContext *pc);87static AstNode *ast_parse_asm_input(ParseContext *pc);
...@@ -493,6 +493,9 @@ static AstNode *ast_parse_root(ParseContext *pc) {...@@ -493,6 +493,9 @@ static AstNode *ast_parse_root(ParseContext *pc) {
493 node->data.container_decl.layout = ContainerLayoutAuto;493 node->data.container_decl.layout = ContainerLayoutAuto;
494 node->data.container_decl.kind = ContainerKindStruct;494 node->data.container_decl.kind = ContainerKindStruct;
495 node->data.container_decl.is_root = true;495 node->data.container_decl.is_root = true;
496 if (buf_len(&members.doc_comments) != 0) {
497 node->data.container_decl.doc_comments = members.doc_comments;
498 }
496499
497 return node;500 return node;
498}501}
...@@ -514,6 +517,21 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {...@@ -514,6 +517,21 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
514 return first_doc_token;517 return first_doc_token;
515}518}
516519
520static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) {
521 if (buf_len(buf) != 0 && peek_token(pc)->id == TokenIdContainerDocComment) {
522 buf_append_char(buf, '\n');
523 }
524 Token *doc_token = nullptr;
525 while ((doc_token = eat_token_if(pc, TokenIdContainerDocComment))) {
526 if (buf->list.length == 0) {
527 buf_resize(buf, 0);
528 }
529 // chops off '//!' but leaves '\n'
530 buf_append_mem(buf, buf_ptr(pc->buf) + doc_token->start_pos + 3,
531 doc_token->end_pos - doc_token->start_pos - 3);
532 }
533}
534
517// ContainerMembers535// ContainerMembers
518// <- TestDecl ContainerMembers536// <- TestDecl ContainerMembers
519// / TopLevelComptime ContainerMembers537// / TopLevelComptime ContainerMembers
...@@ -523,7 +541,11 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {...@@ -523,7 +541,11 @@ static Token *ast_parse_doc_comments(ParseContext *pc, Buf *buf) {
523// /541// /
524static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {542static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
525 AstNodeContainerDecl res = {};543 AstNodeContainerDecl res = {};
544 Buf tld_doc_comment_buf = BUF_INIT;
545 buf_resize(&tld_doc_comment_buf, 0);
526 for (;;) {546 for (;;) {
547 ast_parse_container_doc_comments(pc, &tld_doc_comment_buf);
548
527 AstNode *test_decl = ast_parse_test_decl(pc);549 AstNode *test_decl = ast_parse_test_decl(pc);
528 if (test_decl != nullptr) {550 if (test_decl != nullptr) {
529 res.decls.append(test_decl);551 res.decls.append(test_decl);
...@@ -566,7 +588,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {...@@ -566,7 +588,7 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) {
566588
567 break;589 break;
568 }590 }
569591 res.doc_comments = tld_doc_comment_buf;
570 return res;592 return res;
571}593}
572594
...@@ -1600,9 +1622,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1600,9 +1622,9 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1600 if (container_decl != nullptr)1622 if (container_decl != nullptr)
1601 return container_decl;1623 return container_decl;
16021624
1603 AstNode *enum_lit = ast_parse_enum_lit(pc);1625 AstNode *anon_lit = ast_parse_anon_lit(pc);
1604 if (enum_lit != nullptr)1626 if (anon_lit != nullptr)
1605 return enum_lit;1627 return anon_lit;
16061628
1607 AstNode *error_set_decl = ast_parse_error_set_decl(pc);1629 AstNode *error_set_decl = ast_parse_error_set_decl(pc);
1608 if (error_set_decl != nullptr)1630 if (error_set_decl != nullptr)
...@@ -1876,16 +1898,22 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {...@@ -1876,16 +1898,22 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc) {
1876 return res;1898 return res;
1877}1899}
18781900
1879static AstNode *ast_parse_enum_lit(ParseContext *pc) {1901static AstNode *ast_parse_anon_lit(ParseContext *pc) {
1880 Token *period = eat_token_if(pc, TokenIdDot);1902 Token *period = eat_token_if(pc, TokenIdDot);
1881 if (period == nullptr)1903 if (period == nullptr)
1882 return nullptr;1904 return nullptr;
18831905
1884 Token *identifier = expect_token(pc, TokenIdSymbol);1906 // anon enum literal
1885 AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);1907 Token *identifier = eat_token_if(pc, TokenIdSymbol);
1886 res->data.enum_literal.period = period;1908 if (identifier != nullptr) {
1887 res->data.enum_literal.identifier = identifier;1909 AstNode *res = ast_create_node(pc, NodeTypeEnumLiteral, period);
1888 return res;1910 res->data.enum_literal.period = period;
1911 res->data.enum_literal.identifier = identifier;
1912 return res;
1913 }
1914
1915 // anon container literal
1916 return ast_parse_init_list(pc);
1889}1917}
18901918
1891// AsmOutput <- COLON AsmOutputList AsmInput?1919// AsmOutput <- COLON AsmOutputList AsmInput?
...@@ -2019,7 +2047,12 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {...@@ -2019,7 +2047,12 @@ static AstNode *ast_parse_field_init(ParseContext *pc) {
2019 if (first == nullptr)2047 if (first == nullptr)
2020 return nullptr;2048 return nullptr;
20212049
2022 Token *name = expect_token(pc, TokenIdSymbol);2050 Token *name = eat_token_if(pc, TokenIdSymbol);
2051 if (name == nullptr) {
2052 // Because of anon literals ".{" is also valid.
2053 put_back_token(pc);
2054 return nullptr;
2055 }
2023 if (eat_token_if(pc, TokenIdEq) == nullptr) {2056 if (eat_token_if(pc, TokenIdEq) == nullptr) {
2024 // Because ".Name" can also be intepreted as an enum literal, we should put back2057 // Because ".Name" can also be intepreted as an enum literal, we should put back
2025 // those two tokens again so that the parser can try to parse them as the enum2058 // those two tokens again so that the parser can try to parse them as the enum
...@@ -2791,6 +2824,9 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {...@@ -2791,6 +2824,9 @@ static AstNode *ast_parse_container_decl_auto(ParseContext *pc) {
27912824
2792 res->data.container_decl.fields = members.fields;2825 res->data.container_decl.fields = members.fields;
2793 res->data.container_decl.decls = members.decls;2826 res->data.container_decl.decls = members.decls;
2827 if (buf_len(&members.doc_comments) != 0) {
2828 res->data.container_decl.doc_comments = members.doc_comments;
2829 }
2794 return res;2830 return res;
2795}2831}
27962832
src/range_set.cpp+3
...@@ -40,6 +40,9 @@ void rangeset_sort(RangeSet *rs) {...@@ -40,6 +40,9 @@ void rangeset_sort(RangeSet *rs) {
40}40}
4141
42bool rangeset_spans(RangeSet *rs, BigInt *first, BigInt *last) {42bool rangeset_spans(RangeSet *rs, BigInt *first, BigInt *last) {
43 if (rs->src_range_list.length == 0)
44 return false;
45
43 rangeset_sort(rs);46 rangeset_sort(rs);
4447
45 const Range *first_range = &rs->src_range_list.at(0).range;48 const Range *first_range = &rs->src_range_list.at(0).range;
src/tokenizer.cpp+32-1
...@@ -153,7 +153,6 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -153,7 +153,6 @@ static const struct ZigKeyword zig_keywords[] = {
153 {"undefined", TokenIdKeywordUndefined},153 {"undefined", TokenIdKeywordUndefined},
154 {"union", TokenIdKeywordUnion},154 {"union", TokenIdKeywordUnion},
155 {"unreachable", TokenIdKeywordUnreachable},155 {"unreachable", TokenIdKeywordUnreachable},
156 {"use", TokenIdKeywordUsingNamespace},
157 {"usingnamespace", TokenIdKeywordUsingNamespace},156 {"usingnamespace", TokenIdKeywordUsingNamespace},
158 {"var", TokenIdKeywordVar},157 {"var", TokenIdKeywordVar},
159 {"volatile", TokenIdKeywordVolatile},158 {"volatile", TokenIdKeywordVolatile},
...@@ -199,6 +198,7 @@ enum TokenizeState {...@@ -199,6 +198,7 @@ enum TokenizeState {
199 TokenizeStateSawSlash,198 TokenizeStateSawSlash,
200 TokenizeStateSawSlash2,199 TokenizeStateSawSlash2,
201 TokenizeStateSawSlash3,200 TokenizeStateSawSlash3,
201 TokenizeStateSawSlashBang,
202 TokenizeStateSawBackslash,202 TokenizeStateSawBackslash,
203 TokenizeStateSawPercent,203 TokenizeStateSawPercent,
204 TokenizeStateSawPlus,204 TokenizeStateSawPlus,
...@@ -210,6 +210,7 @@ enum TokenizeState {...@@ -210,6 +210,7 @@ enum TokenizeState {
210 TokenizeStateSawBar,210 TokenizeStateSawBar,
211 TokenizeStateSawBarBar,211 TokenizeStateSawBarBar,
212 TokenizeStateDocComment,212 TokenizeStateDocComment,
213 TokenizeStateContainerDocComment,
213 TokenizeStateLineComment,214 TokenizeStateLineComment,
214 TokenizeStateLineString,215 TokenizeStateLineString,
215 TokenizeStateLineStringEnd,216 TokenizeStateLineStringEnd,
...@@ -939,6 +940,9 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -939,6 +940,9 @@ void tokenize(Buf *buf, Tokenization *out) {
939 case '/':940 case '/':
940 t.state = TokenizeStateSawSlash3;941 t.state = TokenizeStateSawSlash3;
941 break;942 break;
943 case '!':
944 t.state = TokenizeStateSawSlashBang;
945 break;
942 case '\n':946 case '\n':
943 cancel_token(&t);947 cancel_token(&t);
944 t.state = TokenizeStateStart;948 t.state = TokenizeStateStart;
...@@ -966,6 +970,19 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -966,6 +970,19 @@ void tokenize(Buf *buf, Tokenization *out) {
966 break;970 break;
967 }971 }
968 break;972 break;
973 case TokenizeStateSawSlashBang:
974 switch (c) {
975 case '\n':
976 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
977 end_token(&t);
978 t.state = TokenizeStateStart;
979 break;
980 default:
981 set_token_id(&t, t.cur_tok, TokenIdContainerDocComment);
982 t.state = TokenizeStateContainerDocComment;
983 break;
984 }
985 break;
969 case TokenizeStateSawBackslash:986 case TokenizeStateSawBackslash:
970 switch (c) {987 switch (c) {
971 case '\\':988 case '\\':
...@@ -1056,6 +1073,17 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1056,6 +1073,17 @@ void tokenize(Buf *buf, Tokenization *out) {
1056 break;1073 break;
1057 }1074 }
1058 break;1075 break;
1076 case TokenizeStateContainerDocComment:
1077 switch (c) {
1078 case '\n':
1079 end_token(&t);
1080 t.state = TokenizeStateStart;
1081 break;
1082 default:
1083 // do nothing
1084 break;
1085 }
1086 break;
1059 case TokenizeStateSymbolFirstC:1087 case TokenizeStateSymbolFirstC:
1060 switch (c) {1088 switch (c) {
1061 case '"':1089 case '"':
...@@ -1546,6 +1574,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1546,6 +1574,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1546 case TokenizeStateSawBarBar:1574 case TokenizeStateSawBarBar:
1547 case TokenizeStateLBracket:1575 case TokenizeStateLBracket:
1548 case TokenizeStateDocComment:1576 case TokenizeStateDocComment:
1577 case TokenizeStateContainerDocComment:
1549 end_token(&t);1578 end_token(&t);
1550 break;1579 break;
1551 case TokenizeStateSawDotDot:1580 case TokenizeStateSawDotDot:
...@@ -1560,6 +1589,7 @@ void tokenize(Buf *buf, Tokenization *out) {...@@ -1560,6 +1589,7 @@ void tokenize(Buf *buf, Tokenization *out) {
1560 case TokenizeStateLineComment:1589 case TokenizeStateLineComment:
1561 case TokenizeStateSawSlash2:1590 case TokenizeStateSawSlash2:
1562 case TokenizeStateSawSlash3:1591 case TokenizeStateSawSlash3:
1592 case TokenizeStateSawSlashBang:
1563 break;1593 break;
1564 }1594 }
1565 if (t.state != TokenizeStateError) {1595 if (t.state != TokenizeStateError) {
...@@ -1607,6 +1637,7 @@ const char * token_name(TokenId id) {...@@ -1607,6 +1637,7 @@ const char * token_name(TokenId id) {
1607 case TokenIdDash: return "-";1637 case TokenIdDash: return "-";
1608 case TokenIdDivEq: return "/=";1638 case TokenIdDivEq: return "/=";
1609 case TokenIdDocComment: return "DocComment";1639 case TokenIdDocComment: return "DocComment";
1640 case TokenIdContainerDocComment: return "ContainerDocComment";
1610 case TokenIdDot: return ".";1641 case TokenIdDot: return ".";
1611 case TokenIdDotStar: return ".*";1642 case TokenIdDotStar: return ".*";
1612 case TokenIdEllipsis2: return "..";1643 case TokenIdEllipsis2: return "..";
src/tokenizer.hpp+1
...@@ -43,6 +43,7 @@ enum TokenId {...@@ -43,6 +43,7 @@ enum TokenId {
43 TokenIdDash,43 TokenIdDash,
44 TokenIdDivEq,44 TokenIdDivEq,
45 TokenIdDocComment,45 TokenIdDocComment,
46 TokenIdContainerDocComment,
46 TokenIdDot,47 TokenIdDot,
47 TokenIdDotStar,48 TokenIdDotStar,
48 TokenIdEllipsis2,49 TokenIdEllipsis2,
src/translate_c.cpp+20-15
...@@ -221,6 +221,15 @@ static AstNode *trans_create_node_opaque(Context *c) {...@@ -221,6 +221,15 @@ static AstNode *trans_create_node_opaque(Context *c) {
221 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");221 return trans_create_node_builtin_fn_call_str(c, "OpaqueType");
222}222}
223223
224static AstNode *trans_create_node_cast(Context *c, AstNode *dest_type, AstNode *operand) {
225 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
226 node->data.fn_call_expr.fn_ref_expr = trans_create_node_symbol(c, buf_create_from_str("as"));
227 node->data.fn_call_expr.modifier = CallModifierBuiltin;
228 node->data.fn_call_expr.params.append(dest_type);
229 node->data.fn_call_expr.params.append(operand);
230 return node;
231}
232
224static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {233static AstNode *trans_create_node_fn_call_1(Context *c, AstNode *fn_ref_expr, AstNode *arg1) {
225 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);234 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
226 node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;235 node->data.fn_call_expr.fn_ref_expr = fn_ref_expr;
...@@ -337,14 +346,6 @@ static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {...@@ -337,14 +346,6 @@ static AstNode *trans_create_node_unsigned(Context *c, uint64_t x) {
337 return trans_create_node_unsigned_negative(c, x, false);346 return trans_create_node_unsigned_negative(c, x, false);
338}347}
339348
340static AstNode *trans_create_node_cast(Context *c, AstNode *dest, AstNode *src) {
341 AstNode *node = trans_create_node(c, NodeTypeFnCallExpr);
342 node->data.fn_call_expr.fn_ref_expr = dest;
343 node->data.fn_call_expr.params.resize(1);
344 node->data.fn_call_expr.params.items[0] = src;
345 return node;
346}
347
348static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,349static AstNode *trans_create_node_unsigned_negative_type(Context *c, uint64_t x, bool is_negative,
349 const char *type_name)350 const char *type_name)
350{351{
...@@ -701,7 +702,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,...@@ -701,7 +702,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
701 if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {702 if (c_is_unsigned_integer(c, dest_type) && qual_type_is_ptr(src_type)) {
702 AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");703 AstNode *addr_node = trans_create_node_builtin_fn_call_str(c, "ptrToInt");
703 addr_node->data.fn_call_expr.params.append(expr);704 addr_node->data.fn_call_expr.params.append(expr);
704 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), addr_node);705 return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), addr_node);
705 }706 }
706 if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {707 if (c_is_unsigned_integer(c, src_type) && qual_type_is_ptr(dest_type)) {
707 AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");708 AstNode *ptr_node = trans_create_node_builtin_fn_call_str(c, "intToPtr");
...@@ -712,7 +713,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,...@@ -712,7 +713,7 @@ static AstNode* trans_c_cast(Context *c, ZigClangSourceLocation source_location,
712 // TODO: maybe widen to increase size713 // TODO: maybe widen to increase size
713 // TODO: maybe bitcast to change sign714 // TODO: maybe bitcast to change sign
714 // TODO: maybe truncate to reduce size715 // TODO: maybe truncate to reduce size
715 return trans_create_node_fn_call_1(c, trans_qual_type(c, dest_type, source_location), expr);716 return trans_create_node_cast(c, trans_qual_type(c, dest_type, source_location), expr);
716}717}
717718
718static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {719static bool c_is_signed_integer(Context *c, ZigClangQualType qt) {
...@@ -1212,6 +1213,11 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc...@@ -1212,6 +1213,11 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc
1212 const ZigClangAttributedType *attributed_ty = reinterpret_cast<const ZigClangAttributedType *>(ty);1213 const ZigClangAttributedType *attributed_ty = reinterpret_cast<const ZigClangAttributedType *>(ty);
1213 return trans_qual_type(c, ZigClangAttributedType_getEquivalentType(attributed_ty), source_loc);1214 return trans_qual_type(c, ZigClangAttributedType_getEquivalentType(attributed_ty), source_loc);
1214 }1215 }
1216 case ZigClangType_MacroQualified:
1217 {
1218 const ZigClangMacroQualifiedType *macroqualified_ty = reinterpret_cast<const ZigClangMacroQualifiedType *>(ty);
1219 return trans_qual_type(c, ZigClangMacroQualifiedType_getModifiedType(macroqualified_ty), source_loc);
1220 }
1215 case ZigClangType_IncompleteArray:1221 case ZigClangType_IncompleteArray:
1216 {1222 {
1217 const ZigClangIncompleteArrayType *incomplete_array_ty = reinterpret_cast<const ZigClangIncompleteArrayType *>(ty);1223 const ZigClangIncompleteArrayType *incomplete_array_ty = reinterpret_cast<const ZigClangIncompleteArrayType *>(ty);
...@@ -1261,7 +1267,6 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc...@@ -1261,7 +1267,6 @@ static AstNode *trans_type(Context *c, const ZigClangType *ty, ZigClangSourceLoc
1261 case ZigClangType_DeducedTemplateSpecialization:1267 case ZigClangType_DeducedTemplateSpecialization:
1262 case ZigClangType_DependentAddressSpace:1268 case ZigClangType_DependentAddressSpace:
1263 case ZigClangType_DependentVector:1269 case ZigClangType_DependentVector:
1264 case ZigClangType_MacroQualified:
1265 emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty));1270 emit_warning(c, source_loc, "unsupported type: '%s'", ZigClangType_getTypeClassName(ty));
1266 return nullptr;1271 return nullptr;
1267 }1272 }
...@@ -1527,7 +1532,7 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQua...@@ -1527,7 +1532,7 @@ static AstNode *trans_create_shift_op(Context *c, TransScope *scope, ZigClangQua
15271532
1528 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);1533 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, rhs_expr, TransRValue);
1529 if (rhs == nullptr) return nullptr;1534 if (rhs == nullptr) return nullptr;
1530 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1535 AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
15311536
1532 return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);1537 return trans_create_node_bin_op(c, lhs, bin_op, coerced_rhs);
1533}1538}
...@@ -1702,7 +1707,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1702,7 +1707,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
17021707
1703 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);1708 AstNode *rhs = trans_expr(c, ResultUsedYes, scope, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
1704 if (rhs == nullptr) return nullptr;1709 if (rhs == nullptr) return nullptr;
1705 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1710 AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
17061711
1707 return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);1712 return trans_create_node_bin_op(c, lhs, assign_op, coerced_rhs);
1708 } else {1713 } else {
...@@ -1733,7 +1738,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result...@@ -1733,7 +1738,7 @@ static AstNode *trans_create_compound_assign_shift(Context *c, ResultUsed result
17331738
1734 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);1739 AstNode *rhs = trans_expr(c, ResultUsedYes, &child_scope->base, ZigClangCompoundAssignOperator_getRHS(stmt), TransRValue);
1735 if (rhs == nullptr) return nullptr;1740 if (rhs == nullptr) return nullptr;
1736 AstNode *coerced_rhs = trans_create_node_fn_call_1(c, rhs_type, rhs);1741 AstNode *coerced_rhs = trans_create_node_cast(c, rhs_type, rhs);
17371742
1738 // operation_type(*_ref)1743 // operation_type(*_ref)
1739 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,1744 AstNode *operation_type_cast = trans_c_cast(c, rhs_location,
...@@ -2684,7 +2689,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)...@@ -2684,7 +2689,7 @@ static AstNode *to_enum_zero_cmp(Context *c, AstNode *expr, AstNode *enum_type)
26842689
2685 // @TagType(Enum)(0)2690 // @TagType(Enum)(0)
2686 AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);2691 AstNode *zero = trans_create_node_unsigned_negative(c, 0, false);
2687 AstNode *casted_zero = trans_create_node_fn_call_1(c, tag_type, zero);2692 AstNode *casted_zero = trans_create_node_cast(c, tag_type, zero);
26882693
2689 // @bitCast(Enum, @TagType(Enum)(0))2694 // @bitCast(Enum, @TagType(Enum)(0))
2690 AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");2695 AstNode *bitcast = trans_create_node_builtin_fn_call_str(c, "bitCast");
src/zig_clang.cpp+5
...@@ -2214,6 +2214,11 @@ struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct Zi...@@ -2214,6 +2214,11 @@ struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct Zi
2214 return bitcast(casted->getEquivalentType());2214 return bitcast(casted->getEquivalentType());
2215}2215}
22162216
2217struct ZigClangQualType ZigClangMacroQualifiedType_getModifiedType(const struct ZigClangMacroQualifiedType *self) {
2218 auto casted = reinterpret_cast<const clang::MacroQualifiedType *>(self);
2219 return bitcast(casted->getModifiedType());
2220}
2221
2217struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *self) {2222struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *self) {
2218 auto casted = reinterpret_cast<const clang::ElaboratedType *>(self);2223 auto casted = reinterpret_cast<const clang::ElaboratedType *>(self);
2219 return bitcast(casted->getNamedType());2224 return bitcast(casted->getNamedType());
src/zig_clang.h+3
...@@ -112,6 +112,7 @@ struct ZigClangImplicitCastExpr;...@@ -112,6 +112,7 @@ struct ZigClangImplicitCastExpr;
112struct ZigClangIncompleteArrayType;112struct ZigClangIncompleteArrayType;
113struct ZigClangIntegerLiteral;113struct ZigClangIntegerLiteral;
114struct ZigClangMacroDefinitionRecord;114struct ZigClangMacroDefinitionRecord;
115struct ZigClangMacroQualifiedType;
115struct ZigClangMemberExpr;116struct ZigClangMemberExpr;
116struct ZigClangNamedDecl;117struct ZigClangNamedDecl;
117struct ZigClangNone;118struct ZigClangNone;
...@@ -1004,6 +1005,8 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangParenType_getInnerType(const struct...@@ -1004,6 +1005,8 @@ ZIG_EXTERN_C struct ZigClangQualType ZigClangParenType_getInnerType(const struct
10041005
1005ZIG_EXTERN_C struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *);1006ZIG_EXTERN_C struct ZigClangQualType ZigClangAttributedType_getEquivalentType(const struct ZigClangAttributedType *);
10061007
1008ZIG_EXTERN_C struct ZigClangQualType ZigClangMacroQualifiedType_getModifiedType(const struct ZigClangMacroQualifiedType *);
1009
1007ZIG_EXTERN_C struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *);1010ZIG_EXTERN_C struct ZigClangQualType ZigClangElaboratedType_getNamedType(const struct ZigClangElaboratedType *);
1008ZIG_EXTERN_C enum ZigClangElaboratedTypeKeyword ZigClangElaboratedType_getKeyword(const struct ZigClangElaboratedType *);1011ZIG_EXTERN_C enum ZigClangElaboratedTypeKeyword ZigClangElaboratedType_getKeyword(const struct ZigClangElaboratedType *);
10091012
test/compare_output.zig+61-61
...@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -14,12 +14,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
1414
15 cases.addCase(x: {15 cases.addCase(x: {
16 var tc = cases.create("multiple files with private function",16 var tc = cases.create("multiple files with private function",
17 \\use @import("std").io;17 \\usingnamespace @import("std").io;
18 \\use @import("foo.zig");18 \\usingnamespace @import("foo.zig");
19 \\19 \\
20 \\pub fn main() void {20 \\pub fn main() void {
21 \\ privateFunction();21 \\ privateFunction();
22 \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;22 \\ const stdout = &getStdOut().outStream().stream;
23 \\ stdout.print("OK 2\n") catch unreachable;23 \\ stdout.print("OK 2\n") catch unreachable;
24 \\}24 \\}
25 \\25 \\
...@@ -29,12 +29,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -29,12 +29,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
29 , "OK 1\nOK 2\n");29 , "OK 1\nOK 2\n");
3030
31 tc.addSourceFile("foo.zig",31 tc.addSourceFile("foo.zig",
32 \\use @import("std").io;32 \\usingnamespace @import("std").io;
33 \\33 \\
34 \\// purposefully conflicting function with main.zig34 \\// purposefully conflicting function with main.zig
35 \\// but it's private so it should be OK35 \\// but it's private so it should be OK
36 \\fn privateFunction() void {36 \\fn privateFunction() void {
37 \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;37 \\ const stdout = &getStdOut().outStream().stream;
38 \\ stdout.print("OK 1\n") catch unreachable;38 \\ stdout.print("OK 1\n") catch unreachable;
39 \\}39 \\}
40 \\40 \\
...@@ -48,8 +48,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -48,8 +48,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
4848
49 cases.addCase(x: {49 cases.addCase(x: {
50 var tc = cases.create("import segregation",50 var tc = cases.create("import segregation",
51 \\use @import("foo.zig");51 \\usingnamespace @import("foo.zig");
52 \\use @import("bar.zig");52 \\usingnamespace @import("bar.zig");
53 \\53 \\
54 \\pub fn main() void {54 \\pub fn main() void {
55 \\ foo_function();55 \\ foo_function();
...@@ -58,20 +58,20 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -58,20 +58,20 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
58 , "OK\nOK\n");58 , "OK\nOK\n");
5959
60 tc.addSourceFile("foo.zig",60 tc.addSourceFile("foo.zig",
61 \\use @import("std").io;61 \\usingnamespace @import("std").io;
62 \\pub fn foo_function() void {62 \\pub fn foo_function() void {
63 \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;63 \\ const stdout = &getStdOut().outStream().stream;
64 \\ stdout.print("OK\n") catch unreachable;64 \\ stdout.print("OK\n") catch unreachable;
65 \\}65 \\}
66 );66 );
6767
68 tc.addSourceFile("bar.zig",68 tc.addSourceFile("bar.zig",
69 \\use @import("other.zig");69 \\usingnamespace @import("other.zig");
70 \\use @import("std").io;70 \\usingnamespace @import("std").io;
71 \\71 \\
72 \\pub fn bar_function() void {72 \\pub fn bar_function() void {
73 \\ if (foo_function()) {73 \\ if (foo_function()) {
74 \\ const stdout = &(getStdOut() catch unreachable).outStream().stream;74 \\ const stdout = &getStdOut().outStream().stream;
75 \\ stdout.print("OK\n") catch unreachable;75 \\ stdout.print("OK\n") catch unreachable;
76 \\ }76 \\ }
77 \\}77 \\}
...@@ -88,8 +88,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -88,8 +88,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
88 });88 });
8989
90 cases.addCase(x: {90 cases.addCase(x: {
91 var tc = cases.create("two files use import each other",91 var tc = cases.create("two files usingnamespace import each other",
92 \\use @import("a.zig");92 \\usingnamespace @import("a.zig");
93 \\93 \\
94 \\pub fn main() void {94 \\pub fn main() void {
95 \\ ok();95 \\ ok();
...@@ -97,19 +97,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -97,19 +97,19 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
97 , "OK\n");97 , "OK\n");
9898
99 tc.addSourceFile("a.zig",99 tc.addSourceFile("a.zig",
100 \\use @import("b.zig");100 \\usingnamespace @import("b.zig");
101 \\const io = @import("std").io;101 \\const io = @import("std").io;
102 \\102 \\
103 \\pub const a_text = "OK\n";103 \\pub const a_text = "OK\n";
104 \\104 \\
105 \\pub fn ok() void {105 \\pub fn ok() void {
106 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;106 \\ const stdout = &io.getStdOut().outStream().stream;
107 \\ stdout.print(b_text) catch unreachable;107 \\ stdout.print(b_text) catch unreachable;
108 \\}108 \\}
109 );109 );
110110
111 tc.addSourceFile("b.zig",111 tc.addSourceFile("b.zig",
112 \\use @import("a.zig");112 \\usingnamespace @import("a.zig");
113 \\113 \\
114 \\pub const b_text = a_text;114 \\pub const b_text = a_text;
115 );115 );
...@@ -121,8 +121,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -121,8 +121,8 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
121 \\const io = @import("std").io;121 \\const io = @import("std").io;
122 \\122 \\
123 \\pub fn main() void {123 \\pub fn main() void {
124 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;124 \\ const stdout = &io.getStdOut().outStream().stream;
125 \\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;125 \\ stdout.print("Hello, world!\n{d:4} {x:3} {c}\n", @as(u32, 12), @as(u16, 0x12), @as(u8, 'a')) catch unreachable;
126 \\}126 \\}
127 , "Hello, world!\n 12 12 a\n");127 , "Hello, world!\n 12 12 a\n");
128128
...@@ -145,75 +145,75 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -145,75 +145,75 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
145 \\ _ = c._setmode(1, c._O_BINARY);145 \\ _ = c._setmode(1, c._O_BINARY);
146 \\ }146 \\ }
147 \\ _ = c.printf(c"0: %llu\n",147 \\ _ = c.printf(c"0: %llu\n",
148 \\ u64(0));148 \\ @as(u64, 0));
149 \\ _ = c.printf(c"320402575052271: %llu\n",149 \\ _ = c.printf(c"320402575052271: %llu\n",
150 \\ u64(320402575052271));150 \\ @as(u64, 320402575052271));
151 \\ _ = c.printf(c"0x01236789abcdef: %llu\n",151 \\ _ = c.printf(c"0x01236789abcdef: %llu\n",
152 \\ u64(0x01236789abcdef));152 \\ @as(u64, 0x01236789abcdef));
153 \\ _ = c.printf(c"0xffffffffffffffff: %llu\n",153 \\ _ = c.printf(c"0xffffffffffffffff: %llu\n",
154 \\ u64(0xffffffffffffffff));154 \\ @as(u64, 0xffffffffffffffff));
155 \\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n",155 \\ _ = c.printf(c"0x000000ffffffffffffffff: %llu\n",
156 \\ u64(0x000000ffffffffffffffff));156 \\ @as(u64, 0x000000ffffffffffffffff));
157 \\ _ = c.printf(c"0o1777777777777777777777: %llu\n",157 \\ _ = c.printf(c"0o1777777777777777777777: %llu\n",
158 \\ u64(0o1777777777777777777777));158 \\ @as(u64, 0o1777777777777777777777));
159 \\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n",159 \\ _ = c.printf(c"0o0000001777777777777777777777: %llu\n",
160 \\ u64(0o0000001777777777777777777777));160 \\ @as(u64, 0o0000001777777777777777777777));
161 \\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",161 \\ _ = c.printf(c"0b1111111111111111111111111111111111111111111111111111111111111111: %llu\n",
162 \\ u64(0b1111111111111111111111111111111111111111111111111111111111111111));162 \\ @as(u64, 0b1111111111111111111111111111111111111111111111111111111111111111));
163 \\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",163 \\ _ = c.printf(c"0b0000001111111111111111111111111111111111111111111111111111111111111111: %llu\n",
164 \\ u64(0b0000001111111111111111111111111111111111111111111111111111111111111111));164 \\ @as(u64, 0b0000001111111111111111111111111111111111111111111111111111111111111111));
165 \\165 \\
166 \\ _ = c.printf(c"\n");166 \\ _ = c.printf(c"\n");
167 \\167 \\
168 \\ _ = c.printf(c"0.0: %.013a\n",168 \\ _ = c.printf(c"0.0: %.013a\n",
169 \\ f64(0.0));169 \\ @as(f64, 0.0));
170 \\ _ = c.printf(c"0e0: %.013a\n",170 \\ _ = c.printf(c"0e0: %.013a\n",
171 \\ f64(0e0));171 \\ @as(f64, 0e0));
172 \\ _ = c.printf(c"0.0e0: %.013a\n",172 \\ _ = c.printf(c"0.0e0: %.013a\n",
173 \\ f64(0.0e0));173 \\ @as(f64, 0.0e0));
174 \\ _ = c.printf(c"000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",174 \\ _ = c.printf(c"000000000000000000000000000000000000000000000000000000000.0e0: %.013a\n",
175 \\ f64(000000000000000000000000000000000000000000000000000000000.0e0));175 \\ @as(f64, 000000000000000000000000000000000000000000000000000000000.0e0));
176 \\ _ = c.printf(c"0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",176 \\ _ = c.printf(c"0.000000000000000000000000000000000000000000000000000000000e0: %.013a\n",
177 \\ f64(0.000000000000000000000000000000000000000000000000000000000e0));177 \\ @as(f64, 0.000000000000000000000000000000000000000000000000000000000e0));
178 \\ _ = c.printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",178 \\ _ = c.printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %.013a\n",
179 \\ f64(0.0e000000000000000000000000000000000000000000000000000000000));179 \\ @as(f64, 0.0e000000000000000000000000000000000000000000000000000000000));
180 \\ _ = c.printf(c"1.0: %.013a\n",180 \\ _ = c.printf(c"1.0: %.013a\n",
181 \\ f64(1.0));181 \\ @as(f64, 1.0));
182 \\ _ = c.printf(c"10.0: %.013a\n",182 \\ _ = c.printf(c"10.0: %.013a\n",
183 \\ f64(10.0));183 \\ @as(f64, 10.0));
184 \\ _ = c.printf(c"10.5: %.013a\n",184 \\ _ = c.printf(c"10.5: %.013a\n",
185 \\ f64(10.5));185 \\ @as(f64, 10.5));
186 \\ _ = c.printf(c"10.5e5: %.013a\n",186 \\ _ = c.printf(c"10.5e5: %.013a\n",
187 \\ f64(10.5e5));187 \\ @as(f64, 10.5e5));
188 \\ _ = c.printf(c"10.5e+5: %.013a\n",188 \\ _ = c.printf(c"10.5e+5: %.013a\n",
189 \\ f64(10.5e+5));189 \\ @as(f64, 10.5e+5));
190 \\ _ = c.printf(c"50.0e-2: %.013a\n",190 \\ _ = c.printf(c"50.0e-2: %.013a\n",
191 \\ f64(50.0e-2));191 \\ @as(f64, 50.0e-2));
192 \\ _ = c.printf(c"50e-2: %.013a\n",192 \\ _ = c.printf(c"50e-2: %.013a\n",
193 \\ f64(50e-2));193 \\ @as(f64, 50e-2));
194 \\194 \\
195 \\ _ = c.printf(c"\n");195 \\ _ = c.printf(c"\n");
196 \\196 \\
197 \\ _ = c.printf(c"0x1.0: %.013a\n",197 \\ _ = c.printf(c"0x1.0: %.013a\n",
198 \\ f64(0x1.0));198 \\ @as(f64, 0x1.0));
199 \\ _ = c.printf(c"0x10.0: %.013a\n",199 \\ _ = c.printf(c"0x10.0: %.013a\n",
200 \\ f64(0x10.0));200 \\ @as(f64, 0x10.0));
201 \\ _ = c.printf(c"0x100.0: %.013a\n",201 \\ _ = c.printf(c"0x100.0: %.013a\n",
202 \\ f64(0x100.0));202 \\ @as(f64, 0x100.0));
203 \\ _ = c.printf(c"0x103.0: %.013a\n",203 \\ _ = c.printf(c"0x103.0: %.013a\n",
204 \\ f64(0x103.0));204 \\ @as(f64, 0x103.0));
205 \\ _ = c.printf(c"0x103.7: %.013a\n",205 \\ _ = c.printf(c"0x103.7: %.013a\n",
206 \\ f64(0x103.7));206 \\ @as(f64, 0x103.7));
207 \\ _ = c.printf(c"0x103.70: %.013a\n",207 \\ _ = c.printf(c"0x103.70: %.013a\n",
208 \\ f64(0x103.70));208 \\ @as(f64, 0x103.70));
209 \\ _ = c.printf(c"0x103.70p4: %.013a\n",209 \\ _ = c.printf(c"0x103.70p4: %.013a\n",
210 \\ f64(0x103.70p4));210 \\ @as(f64, 0x103.70p4));
211 \\ _ = c.printf(c"0x103.70p5: %.013a\n",211 \\ _ = c.printf(c"0x103.70p5: %.013a\n",
212 \\ f64(0x103.70p5));212 \\ @as(f64, 0x103.70p5));
213 \\ _ = c.printf(c"0x103.70p+5: %.013a\n",213 \\ _ = c.printf(c"0x103.70p+5: %.013a\n",
214 \\ f64(0x103.70p+5));214 \\ @as(f64, 0x103.70p+5));
215 \\ _ = c.printf(c"0x103.70p-5: %.013a\n",215 \\ _ = c.printf(c"0x103.70p-5: %.013a\n",
216 \\ f64(0x103.70p-5));216 \\ @as(f64, 0x103.70p-5));
217 \\217 \\
218 \\ return 0;218 \\ return 0;
219 \\}219 \\}
...@@ -264,7 +264,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -264,7 +264,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
264 \\ var x_local : i32 = print_ok(x);264 \\ var x_local : i32 = print_ok(x);
265 \\}265 \\}
266 \\fn print_ok(val: @typeOf(x)) @typeOf(foo) {266 \\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
267 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;267 \\ const stdout = &io.getStdOut().outStream().stream;
268 \\ stdout.print("OK\n") catch unreachable;268 \\ stdout.print("OK\n") catch unreachable;
269 \\ return 0;269 \\ return 0;
270 \\}270 \\}
...@@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
323 \\ const x: f64 = small;323 \\ const x: f64 = small;
324 \\ const y = @floatToInt(i32, x);324 \\ const y = @floatToInt(i32, x);
325 \\ const z = @intToFloat(f64, y);325 \\ const z = @intToFloat(f64, y);
326 \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4));326 \\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, @as(f64, -0.4));
327 \\ return 0;327 \\ return 0;
328 \\}328 \\}
329 , "3.25\n3\n3.00\n-0.40\n");329 , "3.25\n3\n3.00\n-0.40\n");
...@@ -346,7 +346,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -346,7 +346,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
346 \\pub fn main() void {346 \\pub fn main() void {
347 \\ const bar = Bar {.field2 = 13,};347 \\ const bar = Bar {.field2 = 13,};
348 \\ const foo = Foo {.field1 = bar,};348 \\ const foo = Foo {.field1 = bar,};
349 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;349 \\ const stdout = &io.getStdOut().outStream().stream;
350 \\ if (!foo.method()) {350 \\ if (!foo.method()) {
351 \\ stdout.print("BAD\n") catch unreachable;351 \\ stdout.print("BAD\n") catch unreachable;
352 \\ }352 \\ }
...@@ -360,7 +360,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -360,7 +360,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
360 cases.add("defer with only fallthrough",360 cases.add("defer with only fallthrough",
361 \\const io = @import("std").io;361 \\const io = @import("std").io;
362 \\pub fn main() void {362 \\pub fn main() void {
363 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;363 \\ const stdout = &io.getStdOut().outStream().stream;
364 \\ stdout.print("before\n") catch unreachable;364 \\ stdout.print("before\n") catch unreachable;
365 \\ defer stdout.print("defer1\n") catch unreachable;365 \\ defer stdout.print("defer1\n") catch unreachable;
366 \\ defer stdout.print("defer2\n") catch unreachable;366 \\ defer stdout.print("defer2\n") catch unreachable;
...@@ -373,7 +373,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -373,7 +373,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
373 \\const io = @import("std").io;373 \\const io = @import("std").io;
374 \\const os = @import("std").os;374 \\const os = @import("std").os;
375 \\pub fn main() void {375 \\pub fn main() void {
376 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;376 \\ const stdout = &io.getStdOut().outStream().stream;
377 \\ stdout.print("before\n") catch unreachable;377 \\ stdout.print("before\n") catch unreachable;
378 \\ defer stdout.print("defer1\n") catch unreachable;378 \\ defer stdout.print("defer1\n") catch unreachable;
379 \\ defer stdout.print("defer2\n") catch unreachable;379 \\ defer stdout.print("defer2\n") catch unreachable;
...@@ -390,7 +390,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -390,7 +390,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
390 \\ do_test() catch return;390 \\ do_test() catch return;
391 \\}391 \\}
392 \\fn do_test() !void {392 \\fn do_test() !void {
393 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;393 \\ const stdout = &io.getStdOut().outStream().stream;
394 \\ stdout.print("before\n") catch unreachable;394 \\ stdout.print("before\n") catch unreachable;
395 \\ defer stdout.print("defer1\n") catch unreachable;395 \\ defer stdout.print("defer1\n") catch unreachable;
396 \\ errdefer stdout.print("deferErr\n") catch unreachable;396 \\ errdefer stdout.print("deferErr\n") catch unreachable;
...@@ -409,7 +409,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -409,7 +409,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
409 \\ do_test() catch return;409 \\ do_test() catch return;
410 \\}410 \\}
411 \\fn do_test() !void {411 \\fn do_test() !void {
412 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;412 \\ const stdout = &io.getStdOut().outStream().stream;
413 \\ stdout.print("before\n") catch unreachable;413 \\ stdout.print("before\n") catch unreachable;
414 \\ defer stdout.print("defer1\n") catch unreachable;414 \\ defer stdout.print("defer1\n") catch unreachable;
415 \\ errdefer stdout.print("deferErr\n") catch unreachable;415 \\ errdefer stdout.print("deferErr\n") catch unreachable;
...@@ -426,7 +426,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -426,7 +426,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
426 \\const io = @import("std").io;426 \\const io = @import("std").io;
427 \\427 \\
428 \\pub fn main() void {428 \\pub fn main() void {
429 \\ const stdout = &(io.getStdOut() catch unreachable).outStream().stream;429 \\ const stdout = &io.getStdOut().outStream().stream;
430 \\ stdout.print(foo_txt) catch unreachable;430 \\ stdout.print(foo_txt) catch unreachable;
431 \\}431 \\}
432 , "1234\nabcd\n");432 , "1234\nabcd\n");
...@@ -445,7 +445,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -445,7 +445,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
445 \\445 \\
446 \\pub fn main() !void {446 \\pub fn main() !void {
447 \\ var args_it = std.process.args();447 \\ var args_it = std.process.args();
448 \\ var stdout_file = try io.getStdOut();448 \\ var stdout_file = io.getStdOut();
449 \\ var stdout_adapter = stdout_file.outStream();449 \\ var stdout_adapter = stdout_file.outStream();
450 \\ const stdout = &stdout_adapter.stream;450 \\ const stdout = &stdout_adapter.stream;
451 \\ var index: usize = 0;451 \\ var index: usize = 0;
...@@ -486,7 +486,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -486,7 +486,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
486 \\486 \\
487 \\pub fn main() !void {487 \\pub fn main() !void {
488 \\ var args_it = std.process.args();488 \\ var args_it = std.process.args();
489 \\ var stdout_file = try io.getStdOut();489 \\ var stdout_file = io.getStdOut();
490 \\ var stdout_adapter = stdout_file.outStream();490 \\ var stdout_adapter = stdout_file.outStream();
491 \\ const stdout = &stdout_adapter.stream;491 \\ const stdout = &stdout_adapter.stream;
492 \\ var index: usize = 0;492 \\ var index: usize = 0;
test/compile_errors.zig+196-74
...@@ -2,6 +2,130 @@ const tests = @import("tests.zig");...@@ -2,6 +2,130 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "empty switch on an integer",
7 \\export fn entry() void {
8 \\ var x: u32 = 0;
9 \\ switch(x) {}
10 \\}
11 ,
12 "tmp.zig:3:5: error: switch must handle all possibilities",
13 );
14
15 cases.add(
16 "incorrect return type",
17 \\ pub export fn entry() void{
18 \\ _ = foo();
19 \\ }
20 \\ const A = struct {
21 \\ a: u32,
22 \\ };
23 \\ fn foo() A {
24 \\ return bar();
25 \\ }
26 \\ const B = struct {
27 \\ a: u32,
28 \\ };
29 \\ fn bar() B {
30 \\ unreachable;
31 \\ }
32 ,
33 "tmp.zig:8:16: error: expected type 'A', found 'B'",
34 );
35
36 cases.add(
37 "regression test #2980: base type u32 is not type checked properly when assigning a value within a struct",
38 \\const Foo = struct {
39 \\ ptr: ?*usize,
40 \\ uval: u32,
41 \\};
42 \\fn get_uval(x: u32) !u32 {
43 \\ return error.NotFound;
44 \\}
45 \\export fn entry() void {
46 \\ const afoo = Foo{
47 \\ .ptr = null,
48 \\ .uval = get_uval(42),
49 \\ };
50 \\}
51 ,
52 "tmp.zig:11:25: error: expected type 'u32', found '@typeOf(get_uval).ReturnType.ErrorSet!u32'",
53 );
54
55 cases.add(
56 "asigning to struct or union fields that are not optionals with a function that returns an optional",
57 \\fn maybe(is: bool) ?u8 {
58 \\ if (is) return @as(u8, 10) else return null;
59 \\}
60 \\const U = union {
61 \\ Ye: u8,
62 \\};
63 \\const S = struct {
64 \\ num: u8,
65 \\};
66 \\export fn entry() void {
67 \\ var u = U{ .Ye = maybe(false) };
68 \\ var s = S{ .num = maybe(false) };
69 \\}
70 ,
71 "tmp.zig:11:27: error: expected type 'u8', found '?u8'",
72 );
73
74 cases.add(
75 "missing result type for phi node",
76 \\fn foo() !void {
77 \\ return anyerror.Foo;
78 \\}
79 \\export fn entry() void {
80 \\ foo() catch 0;
81 \\}
82 ,
83 "tmp.zig:5:17: error: integer value 0 cannot be coerced to type 'void'",
84 );
85
86 cases.add(
87 "atomicrmw with enum op not .Xchg",
88 \\export fn entry() void {
89 \\ const E = enum(u8) {
90 \\ a,
91 \\ b,
92 \\ c,
93 \\ d,
94 \\ };
95 \\ var x: E = .a;
96 \\ _ = @atomicRmw(E, &x, .Add, .b, .SeqCst);
97 \\}
98 ,
99 "tmp.zig:9:27: error: @atomicRmw on enum only works with .Xchg",
100 );
101
102 cases.add(
103 "atomic orderings of atomicStore Acquire or AcqRel",
104 \\export fn entry() void {
105 \\ var x: u32 = 0;
106 \\ @atomicStore(u32, &x, 1, .Acquire);
107 \\}
108 ,
109 "tmp.zig:3:30: error: @atomicStore atomic ordering must not be Acquire or AcqRel",
110 );
111
112 cases.add(
113 "missing const in slice with nested array type",
114 \\const Geo3DTex2D = struct { vertices: [][2]f32 };
115 \\pub fn getGeo3DTex2D() Geo3DTex2D {
116 \\ return Geo3DTex2D{
117 \\ .vertices = [_][2]f32{
118 \\ [_]f32{ -0.5, -0.5},
119 \\ },
120 \\ };
121 \\}
122 \\export fn entry() void {
123 \\ var geo_data = getGeo3DTex2D();
124 \\}
125 ,
126 "tmp.zig:4:30: error: expected type '[][2]f32', found '[1][2]f32'",
127 );
128
5 cases.add(129 cases.add(
6 "slicing of global undefined pointer",130 "slicing of global undefined pointer",
7 \\var buf: *[1]u8 = undefined;131 \\var buf: *[1]u8 = undefined;
...@@ -186,21 +310,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -186,21 +310,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
186 cases.add(310 cases.add(
187 "shift amount has to be an integer type",311 "shift amount has to be an integer type",
188 \\export fn entry() void {312 \\export fn entry() void {
189 \\ const x = 1 << &u8(10);313 \\ const x = 1 << &@as(u8, 10);
190 \\}314 \\}
191 ,315 ,
192 "tmp.zig:2:23: error: shift amount has to be an integer type, but found '*u8'",316 "tmp.zig:2:21: error: shift amount has to be an integer type, but found '*u8'",
193 "tmp.zig:2:17: note: referenced here",317 "tmp.zig:2:17: note: referenced here",
194 );318 );
195319
196 cases.add(320 cases.add(
197 "bit shifting only works on integer types",321 "bit shifting only works on integer types",
198 \\export fn entry() void {322 \\export fn entry() void {
199 \\ const x = &u8(1) << 10;323 \\ const x = &@as(u8, 1) << 10;
200 \\}324 \\}
201 ,325 ,
202 "tmp.zig:2:18: error: bit shifting operation expected integer type, found '*u8'",326 "tmp.zig:2:16: error: bit shifting operation expected integer type, found '*u8'",
203 "tmp.zig:2:22: note: referenced here",327 "tmp.zig:2:27: note: referenced here",
204 );328 );
205329
206 cases.add(330 cases.add(
...@@ -216,9 +340,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -216,9 +340,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
216 \\ const obj = AstObject{ .lhsExpr = lhsExpr };340 \\ const obj = AstObject{ .lhsExpr = lhsExpr };
217 \\}341 \\}
218 ,342 ,
219 "tmp.zig:4:19: error: union 'AstObject' depends on itself",343 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
220 "tmp.zig:2:5: note: while checking this field",
221 "tmp.zig:5:5: note: while checking this field",344 "tmp.zig:5:5: note: while checking this field",
345 "tmp.zig:2:5: note: while checking this field",
222 );346 );
223347
224 cases.add(348 cases.add(
...@@ -241,11 +365,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -241,11 +365,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
241 \\ var x: []align(true) i32 = undefined;365 \\ var x: []align(true) i32 = undefined;
242 \\}366 \\}
243 \\export fn entry2() void {367 \\export fn entry2() void {
244 \\ var x: *align(f64(12.34)) i32 = undefined;368 \\ var x: *align(@as(f64, 12.34)) i32 = undefined;
245 \\}369 \\}
246 ,370 ,
247 "tmp.zig:2:20: error: expected type 'u29', found 'bool'",371 "tmp.zig:2:20: error: expected type 'u29', found 'bool'",
248 "tmp.zig:5:22: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",372 "tmp.zig:5:19: error: fractional component prevents float value 12.340000 from being casted to type 'u29'",
249 );373 );
250374
251 cases.addCase(x: {375 cases.addCase(x: {
...@@ -1243,7 +1367,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1243,7 +1367,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1243 \\ var ptr: [*c]u8 = x;1367 \\ var ptr: [*c]u8 = x;
1244 \\}1368 \\}
1245 ,1369 ,
1246 "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be implicitly casted to type 'usize'",1370 "tmp.zig:2:33: error: integer value 18446744073709551617 cannot be coerced to type 'usize'",
1247 "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",1371 "tmp.zig:6:23: error: integer type 'u65' too big for implicit @intToPtr to type '[*c]u8'",
1248 );1372 );
12491373
...@@ -1297,17 +1421,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1297,17 +1421,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1297 cases.add(1421 cases.add(
1298 "@truncate undefined value",1422 "@truncate undefined value",
1299 \\export fn entry() void {1423 \\export fn entry() void {
1300 \\ var z = @truncate(u8, u16(undefined));1424 \\ var z = @truncate(u8, @as(u16, undefined));
1301 \\}1425 \\}
1302 ,1426 ,
1303 "tmp.zig:2:30: error: use of undefined value here causes undefined behavior",1427 "tmp.zig:2:27: error: use of undefined value here causes undefined behavior",
1304 );1428 );
13051429
1306 cases.addTest(1430 cases.addTest(
1307 "return invalid type from test",1431 "return invalid type from test",
1308 \\test "example" { return 1; }1432 \\test "example" { return 1; }
1309 ,1433 ,
1310 "tmp.zig:1:25: error: integer value 1 cannot be implicitly casted to type 'void'",1434 "tmp.zig:1:25: error: integer value 1 cannot be coerced to type 'void'",
1311 );1435 );
13121436
1313 cases.add(1437 cases.add(
...@@ -1332,7 +1456,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1332,7 +1456,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1332 cases.add(1456 cases.add(
1333 "@bitCast with different sizes inside an expression",1457 "@bitCast with different sizes inside an expression",
1334 \\export fn entry() void {1458 \\export fn entry() void {
1335 \\ var foo = (@bitCast(u8, f32(1.0)) == 0xf);1459 \\ var foo = (@bitCast(u8, @as(f32, 1.0)) == 0xf);
1336 \\}1460 \\}
1337 ,1461 ,
1338 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",1462 "tmp.zig:2:25: error: destination type 'u8' has size 1 but source type 'f32' has size 4",
...@@ -1464,8 +1588,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1464,8 +1588,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1464 \\ var byte: u8 = spartan_count;1588 \\ var byte: u8 = spartan_count;
1465 \\}1589 \\}
1466 ,1590 ,
1467 "tmp.zig:3:31: error: integer value 300 cannot be implicitly casted to type 'u8'",1591 "tmp.zig:3:31: error: integer value 300 cannot be coerced to type 'u8'",
1468 "tmp.zig:7:22: error: integer value 300 cannot be implicitly casted to type 'u8'",1592 "tmp.zig:7:22: error: integer value 300 cannot be coerced to type 'u8'",
1469 "tmp.zig:11:20: error: expected type 'u8', found 'u16'",1593 "tmp.zig:11:20: error: expected type 'u8', found 'u16'",
1470 );1594 );
14711595
...@@ -1498,7 +1622,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1498,7 +1622,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1498 \\ var x: i65536 = 1;1622 \\ var x: i65536 = 1;
1499 \\}1623 \\}
1500 ,1624 ,
1501 "tmp.zig:2:31: error: integer value 65536 cannot be implicitly casted to type 'u16'",1625 "tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'",
1502 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",1626 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
1503 );1627 );
15041628
...@@ -1686,10 +1810,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1686,10 +1810,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1686 cases.add(1810 cases.add(
1687 "non float passed to @floatToInt",1811 "non float passed to @floatToInt",
1688 \\export fn entry() void {1812 \\export fn entry() void {
1689 \\ const x = @floatToInt(i32, i32(54));1813 \\ const x = @floatToInt(i32, @as(i32, 54));
1690 \\}1814 \\}
1691 ,1815 ,
1692 "tmp.zig:2:35: error: expected float type, found 'i32'",1816 "tmp.zig:2:32: error: expected float type, found 'i32'",
1693 );1817 );
16941818
1695 cases.add(1819 cases.add(
...@@ -1698,7 +1822,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1698,7 +1822,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1698 \\ const x = @floatToInt(i8, 200);1822 \\ const x = @floatToInt(i8, 200);
1699 \\}1823 \\}
1700 ,1824 ,
1701 "tmp.zig:2:31: error: integer value 200 cannot be implicitly casted to type 'i8'",1825 "tmp.zig:2:31: error: integer value 200 cannot be coerced to type 'i8'",
1702 );1826 );
17031827
1704 cases.add(1828 cases.add(
...@@ -2096,8 +2220,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2096,8 +2220,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2096 \\2220 \\
2097 \\fn bar(x: *b.Foo) void {}2221 \\fn bar(x: *b.Foo) void {}
2098 ,2222 ,
2099 "tmp.zig:6:10: error: expected type '*b.Foo', found '*a.Foo'",2223 "tmp.zig:6:9: error: expected type '*b.Foo', found '*a.Foo'",
2100 "tmp.zig:6:10: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",2224 "tmp.zig:6:9: note: pointer type child 'a.Foo' cannot cast into pointer type child 'b.Foo'",
2101 "a.zig:1:17: note: a.Foo declared here",2225 "a.zig:1:17: note: a.Foo declared here",
2102 "b.zig:1:17: note: b.Foo declared here",2226 "b.zig:1:17: note: b.Foo declared here",
2103 );2227 );
...@@ -2120,13 +2244,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2120,13 +2244,13 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2120 cases.add(2244 cases.add(
2121 "@floatToInt comptime safety",2245 "@floatToInt comptime safety",
2122 \\comptime {2246 \\comptime {
2123 \\ _ = @floatToInt(i8, f32(-129.1));2247 \\ _ = @floatToInt(i8, @as(f32, -129.1));
2124 \\}2248 \\}
2125 \\comptime {2249 \\comptime {
2126 \\ _ = @floatToInt(u8, f32(-1.1));2250 \\ _ = @floatToInt(u8, @as(f32, -1.1));
2127 \\}2251 \\}
2128 \\comptime {2252 \\comptime {
2129 \\ _ = @floatToInt(u8, f32(256.1));2253 \\ _ = @floatToInt(u8, @as(f32, 256.1));
2130 \\}2254 \\}
2131 ,2255 ,
2132 "tmp.zig:2:9: error: integer value '-129' cannot be stored in type 'i8'",2256 "tmp.zig:2:9: error: integer value '-129' cannot be stored in type 'i8'",
...@@ -2197,7 +2321,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2197,7 +2321,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2197 cases.add(2321 cases.add(
2198 "error when evaluating return type",2322 "error when evaluating return type",
2199 \\const Foo = struct {2323 \\const Foo = struct {
2200 \\ map: i32(i32),2324 \\ map: @as(i32, i32),
2201 \\2325 \\
2202 \\ fn init() Foo {2326 \\ fn init() Foo {
2203 \\ return undefined;2327 \\ return undefined;
...@@ -2207,7 +2331,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2207,7 +2331,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2207 \\ var rule_set = try Foo.init();2331 \\ var rule_set = try Foo.init();
2208 \\}2332 \\}
2209 ,2333 ,
2210 "tmp.zig:2:13: error: expected type 'i32', found 'type'",2334 "tmp.zig:2:10: error: expected type 'i32', found 'type'",
2211 );2335 );
22122336
2213 cases.add(2337 cases.add(
...@@ -2338,7 +2462,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2338,7 +2462,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2338 cases.add(2462 cases.add(
2339 "var not allowed in structs",2463 "var not allowed in structs",
2340 \\export fn entry() void {2464 \\export fn entry() void {
2341 \\ var s = (struct{v: var}){.v=i32(10)};2465 \\ var s = (struct{v: var}){.v=@as(i32, 10)};
2342 \\}2466 \\}
2343 ,2467 ,
2344 "tmp.zig:2:23: error: invalid token: 'var'",2468 "tmp.zig:2:23: error: invalid token: 'var'",
...@@ -2357,10 +2481,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2357,10 +2481,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2357 cases.add(2481 cases.add(
2358 "comptime slice of undefined pointer non-zero len",2482 "comptime slice of undefined pointer non-zero len",
2359 \\export fn entry() void {2483 \\export fn entry() void {
2360 \\ const slice = ([*]i32)(undefined)[0..1];2484 \\ const slice = @as([*]i32, undefined)[0..1];
2361 \\}2485 \\}
2362 ,2486 ,
2363 "tmp.zig:2:38: error: non-zero length slice of undefined pointer",2487 "tmp.zig:2:41: error: non-zero length slice of undefined pointer",
2364 );2488 );
23652489
2366 cases.add(2490 cases.add(
...@@ -2657,10 +2781,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2657,10 +2781,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2657 cases.add(2781 cases.add(
2658 "cast negative integer literal to usize",2782 "cast negative integer literal to usize",
2659 \\export fn entry() void {2783 \\export fn entry() void {
2660 \\ const x = usize(-10);2784 \\ const x = @as(usize, -10);
2661 \\}2785 \\}
2662 ,2786 ,
2663 "tmp.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",2787 "tmp.zig:2:26: error: cannot cast negative value -10 to unsigned integer type 'usize'",
2664 );2788 );
26652789
2666 cases.add(2790 cases.add(
...@@ -3384,11 +3508,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3384,11 +3508,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3384 \\ const x : i32 = if (b) h: { break :h 1; };3508 \\ const x : i32 = if (b) h: { break :h 1; };
3385 \\}3509 \\}
3386 \\fn g(b: bool) void {3510 \\fn g(b: bool) void {
3387 \\ const y = if (b) h: { break :h i32(1); };3511 \\ const y = if (b) h: { break :h @as(i32, 1); };
3388 \\}3512 \\}
3389 \\export fn entry() void { f(true); g(true); }3513 \\export fn entry() void { f(true); g(true); }
3390 ,3514 ,
3391 "tmp.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",3515 "tmp.zig:2:21: error: expected type 'i32', found 'void'",
3392 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",3516 "tmp.zig:5:15: error: incompatible types: 'i32' and 'void'",
3393 );3517 );
33943518
...@@ -3520,11 +3644,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3520,11 +3644,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3520 cases.add(3644 cases.add(
3521 "cast unreachable",3645 "cast unreachable",
3522 \\fn f() i32 {3646 \\fn f() i32 {
3523 \\ return i32(return 1);3647 \\ return @as(i32, return 1);
3524 \\}3648 \\}
3525 \\export fn entry() void { _ = f(); }3649 \\export fn entry() void { _ = f(); }
3526 ,3650 ,
3527 "tmp.zig:2:15: error: unreachable code",3651 "tmp.zig:2:12: error: unreachable code",
3528 );3652 );
35293653
3530 cases.add(3654 cases.add(
...@@ -3595,7 +3719,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3595,7 +3719,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3595 \\ switch (n) {3719 \\ switch (n) {
3596 \\ Number.One => 1,3720 \\ Number.One => 1,
3597 \\ Number.Two => 2,3721 \\ Number.Two => 2,
3598 \\ Number.Three => i32(3),3722 \\ Number.Three => @as(i32, 3),
3599 \\ }3723 \\ }
3600 \\}3724 \\}
3601 \\3725 \\
...@@ -3616,7 +3740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3616,7 +3740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3616 \\ switch (n) {3740 \\ switch (n) {
3617 \\ Number.One => 1,3741 \\ Number.One => 1,
3618 \\ Number.Two => 2,3742 \\ Number.Two => 2,
3619 \\ Number.Three => i32(3),3743 \\ Number.Three => @as(i32, 3),
3620 \\ Number.Four => 4,3744 \\ Number.Four => 4,
3621 \\ Number.Two => 2,3745 \\ Number.Two => 2,
3622 \\ }3746 \\ }
...@@ -3640,7 +3764,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3640,7 +3764,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3640 \\ switch (n) {3764 \\ switch (n) {
3641 \\ Number.One => 1,3765 \\ Number.One => 1,
3642 \\ Number.Two => 2,3766 \\ Number.Two => 2,
3643 \\ Number.Three => i32(3),3767 \\ Number.Three => @as(i32, 3),
3644 \\ Number.Four => 4,3768 \\ Number.Four => 4,
3645 \\ Number.Two => 2,3769 \\ Number.Two => 2,
3646 \\ else => 10,3770 \\ else => 10,
...@@ -3685,7 +3809,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3685,7 +3809,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3685 "switch expression - duplicate or overlapping integer value",3809 "switch expression - duplicate or overlapping integer value",
3686 \\fn foo(x: u8) u8 {3810 \\fn foo(x: u8) u8 {
3687 \\ return switch (x) {3811 \\ return switch (x) {
3688 \\ 0 ... 100 => u8(0),3812 \\ 0 ... 100 => @as(u8, 0),
3689 \\ 101 ... 200 => 1,3813 \\ 101 ... 200 => 1,
3690 \\ 201, 203 ... 207 => 2,3814 \\ 201, 203 ... 207 => 2,
3691 \\ 206 ... 255 => 3,3815 \\ 206 ... 255 => 3,
...@@ -3722,7 +3846,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3722,7 +3846,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3722 cases.add(3846 cases.add(
3723 "array concatenation with wrong type",3847 "array concatenation with wrong type",
3724 \\const src = "aoeu";3848 \\const src = "aoeu";
3725 \\const derp = usize(1234);3849 \\const derp = @as(usize, 1234);
3726 \\const a = derp ++ "foo";3850 \\const a = derp ++ "foo";
3727 \\3851 \\
3728 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }3852 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
...@@ -3765,7 +3889,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3765,7 +3889,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3765 \\const x : u8 = 300;3889 \\const x : u8 = 300;
3766 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }3890 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
3767 ,3891 ,
3768 "tmp.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",3892 "tmp.zig:1:16: error: integer value 300 cannot be coerced to type 'u8'",
3769 );3893 );
37703894
3771 cases.add(3895 cases.add(
...@@ -3887,8 +4011,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3887,8 +4011,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3887 "division by zero",4011 "division by zero",
3888 \\const lit_int_x = 1 / 0;4012 \\const lit_int_x = 1 / 0;
3889 \\const lit_float_x = 1.0 / 0.0;4013 \\const lit_float_x = 1.0 / 0.0;
3890 \\const int_x = u32(1) / u32(0);4014 \\const int_x = @as(u32, 1) / @as(u32, 0);
3891 \\const float_x = f32(1.0) / f32(0.0);4015 \\const float_x = @as(f32, 1.0) / @as(f32, 0.0);
3892 \\4016 \\
3893 \\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }4017 \\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }
3894 \\export fn entry2() usize { return @sizeOf(@typeOf(lit_float_x)); }4018 \\export fn entry2() usize { return @sizeOf(@typeOf(lit_float_x)); }
...@@ -3897,8 +4021,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3897,8 +4021,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3897 ,4021 ,
3898 "tmp.zig:1:21: error: division by zero",4022 "tmp.zig:1:21: error: division by zero",
3899 "tmp.zig:2:25: error: division by zero",4023 "tmp.zig:2:25: error: division by zero",
3900 "tmp.zig:3:22: error: division by zero",4024 "tmp.zig:3:27: error: division by zero",
3901 "tmp.zig:4:26: error: division by zero",4025 "tmp.zig:4:31: error: division by zero",
3902 );4026 );
39034027
3904 cases.add(4028 cases.add(
...@@ -4590,7 +4714,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4590,7 +4714,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4590 \\var bytes: [ext()]u8 = undefined;4714 \\var bytes: [ext()]u8 = undefined;
4591 \\export fn f() void {4715 \\export fn f() void {
4592 \\ for (bytes) |*b, i| {4716 \\ for (bytes) |*b, i| {
4593 \\ b.* = u8(i);4717 \\ b.* = @as(u8, i);
4594 \\ }4718 \\ }
4595 \\}4719 \\}
4596 ,4720 ,
...@@ -4874,7 +4998,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4874,7 +4998,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4874 \\}4998 \\}
4875 \\4999 \\
4876 \\fn foo() i32 {5000 \\fn foo() i32 {
4877 \\ return add(i32(1234));5001 \\ return add(@as(i32, 1234));
4878 \\}5002 \\}
4879 \\5003 \\
4880 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }5004 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
...@@ -4886,7 +5010,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4886,7 +5010,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4886 cases.add(5010 cases.add(
4887 "pass integer literal to var args",5011 "pass integer literal to var args",
4888 \\fn add(args: ...) i32 {5012 \\fn add(args: ...) i32 {
4889 \\ var sum = i32(0);5013 \\ var sum = @as(i32, 0);
4890 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {5014 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
4891 \\ sum += args[i];5015 \\ sum += args[i];
4892 \\ }}5016 \\ }}
...@@ -4908,7 +5032,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4908,7 +5032,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4908 \\ var vga_mem: u16 = 0xB8000;5032 \\ var vga_mem: u16 = 0xB8000;
4909 \\}5033 \\}
4910 ,5034 ,
4911 "tmp.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'",5035 "tmp.zig:2:24: error: integer value 753664 cannot be coerced to type 'u16'",
4912 );5036 );
49135037
4914 cases.add(5038 cases.add(
...@@ -4961,7 +5085,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4961,7 +5085,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4961 \\5085 \\
4962 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }5086 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
4963 ,5087 ,
4964 "tmp.zig:8:26: error: expected type '*const u3', found '*align(:3:1) const u3'",5088 "tmp.zig:8:16: error: expected type '*const u3', found '*align(:3:1) const u3'",
4965 );5089 );
49665090
4967 cases.add(5091 cases.add(
...@@ -5080,7 +5204,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5080,7 +5204,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5080 cases.add(5204 cases.add(
5081 "pass const ptr to mutable ptr fn",5205 "pass const ptr to mutable ptr fn",
5082 \\fn foo() bool {5206 \\fn foo() bool {
5083 \\ const a = ([]const u8)("a",);5207 \\ const a = @as([]const u8, "a",);
5084 \\ const b = &a;5208 \\ const b = &a;
5085 \\ return ptrEql(b, b);5209 \\ return ptrEql(b, b);
5086 \\}5210 \\}
...@@ -5581,10 +5705,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5581,10 +5705,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5581 cases.add(5705 cases.add(
5582 "explicit cast float literal to integer when there is a fraction component",5706 "explicit cast float literal to integer when there is a fraction component",
5583 \\export fn entry() i32 {5707 \\export fn entry() i32 {
5584 \\ return i32(12.34);5708 \\ return @as(i32, 12.34);
5585 \\}5709 \\}
5586 ,5710 ,
5587 "tmp.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",5711 "tmp.zig:2:21: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
5588 );5712 );
55895713
5590 cases.add(5714 cases.add(
...@@ -5599,7 +5723,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5599,7 +5723,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5599 cases.add(5723 cases.add(
5600 "@shlExact shifts out 1 bits",5724 "@shlExact shifts out 1 bits",
5601 \\comptime {5725 \\comptime {
5602 \\ const x = @shlExact(u8(0b01010101), 2);5726 \\ const x = @shlExact(@as(u8, 0b01010101), 2);
5603 \\}5727 \\}
5604 ,5728 ,
5605 "tmp.zig:2:15: error: operation caused overflow",5729 "tmp.zig:2:15: error: operation caused overflow",
...@@ -5608,7 +5732,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5608,7 +5732,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5608 cases.add(5732 cases.add(
5609 "@shrExact shifts out 1 bits",5733 "@shrExact shifts out 1 bits",
5610 \\comptime {5734 \\comptime {
5611 \\ const x = @shrExact(u8(0b10101010), 2);5735 \\ const x = @shrExact(@as(u8, 0b10101010), 2);
5612 \\}5736 \\}
5613 ,5737 ,
5614 "tmp.zig:2:15: error: exact shift shifted out 1 bits",5738 "tmp.zig:2:15: error: exact shift shifted out 1 bits",
...@@ -5658,7 +5782,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5658,7 +5782,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5658 \\ x.* += 1;5782 \\ x.* += 1;
5659 \\}5783 \\}
5660 ,5784 ,
5661 "tmp.zig:8:13: error: expected type '*u32', found '*align(1) u32'",5785 "tmp.zig:8:9: error: expected type '*u32', found '*align(1) u32'",
5662 );5786 );
56635787
5664 cases.add(5788 cases.add(
...@@ -5671,16 +5795,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5671,16 +5795,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5671 \\export fn entry() void {5795 \\export fn entry() void {
5672 \\ var foo = Foo { .a = 1, .b = 10 };5796 \\ var foo = Foo { .a = 1, .b = 10 };
5673 \\ foo.b += 1;5797 \\ foo.b += 1;
5674 \\ bar((*[1]u32)(&foo.b)[0..]);5798 \\ bar(@as(*[1]u32, &foo.b)[0..]);
5675 \\}5799 \\}
5676 \\5800 \\
5677 \\fn bar(x: []u32) void {5801 \\fn bar(x: []u32) void {
5678 \\ x[0] += 1;5802 \\ x[0] += 1;
5679 \\}5803 \\}
5680 ,5804 ,
5681 "tmp.zig:9:18: error: cast increases pointer alignment",5805 "tmp.zig:9:9: error: cast increases pointer alignment",
5682 "tmp.zig:9:23: note: '*align(1) u32' has alignment 1",5806 "tmp.zig:9:26: note: '*align(1) u32' has alignment 1",
5683 "tmp.zig:9:18: note: '*[1]u32' has alignment 4",5807 "tmp.zig:9:9: note: '*[1]u32' has alignment 4",
5684 );5808 );
56855809
5686 cases.add(5810 cases.add(
...@@ -5699,10 +5823,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5699,10 +5823,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5699 cases.add(5823 cases.add(
5700 "@alignCast expects pointer or slice",5824 "@alignCast expects pointer or slice",
5701 \\export fn entry() void {5825 \\export fn entry() void {
5702 \\ @alignCast(4, u32(3));5826 \\ @alignCast(4, @as(u32, 3));
5703 \\}5827 \\}
5704 ,5828 ,
5705 "tmp.zig:2:22: error: expected pointer or slice, found 'u32'",5829 "tmp.zig:2:19: error: expected pointer or slice, found 'u32'",
5706 );5830 );
57075831
5708 cases.add(5832 cases.add(
...@@ -5740,11 +5864,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5740,11 +5864,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5740 );5864 );
57415865
5742 cases.add(5866 cases.add(
5743 "wrong pointer implicitly casted to pointer to @OpaqueType()",5867 "wrong pointer coerced to pointer to @OpaqueType()",
5744 \\const Derp = @OpaqueType();5868 \\const Derp = @OpaqueType();
5745 \\extern fn bar(d: *Derp) void;5869 \\extern fn bar(d: *Derp) void;
5746 \\export fn foo() void {5870 \\export fn foo() void {
5747 \\ var x = u8(1);5871 \\ var x = @as(u8, 1);
5748 \\ bar(@ptrCast(*c_void, &x));5872 \\ bar(@ptrCast(*c_void, &x));
5749 \\}5873 \\}
5750 ,5874 ,
...@@ -5793,27 +5917,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5793,27 +5917,27 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5793 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",5917 "tmp.zig:17:4: error: variable of type 'Opaque' not allowed",
5794 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime",5918 "tmp.zig:20:4: error: variable of type 'type' must be const or comptime",
5795 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",5919 "tmp.zig:23:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
5796 "tmp.zig:26:4: error: unreachable code",5920 "tmp.zig:26:22: error: unreachable code",
5797 );5921 );
57985922
5799 cases.add(5923 cases.add(
5800 "wrong types given to atomic order args in cmpxchg",5924 "wrong types given to atomic order args in cmpxchg",
5801 \\export fn entry() void {5925 \\export fn entry() void {
5802 \\ var x: i32 = 1234;5926 \\ var x: i32 = 1234;
5803 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}5927 \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, @as(u32, 1234), @as(u32, 1234))) {}
5804 \\}5928 \\}
5805 ,5929 ,
5806 "tmp.zig:3:50: error: expected type 'std.builtin.AtomicOrder', found 'u32'",5930 "tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'",
5807 );5931 );
58085932
5809 cases.add(5933 cases.add(
5810 "wrong types given to @export",5934 "wrong types given to @export",
5811 \\extern fn entry() void { }5935 \\extern fn entry() void { }
5812 \\comptime {5936 \\comptime {
5813 \\ @export("entry", entry, u32(1234));5937 \\ @export("entry", entry, @as(u32, 1234));
5814 \\}5938 \\}
5815 ,5939 ,
5816 "tmp.zig:3:32: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",5940 "tmp.zig:3:29: error: expected type 'std.builtin.GlobalLinkage', found 'u32'",
5817 );5941 );
58185942
5819 cases.add(5943 cases.add(
...@@ -6185,7 +6309,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6185,7 +6309,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6185 \\};6309 \\};
6186 \\6310 \\
6187 \\export fn entry() void {6311 \\export fn entry() void {
6188 \\ var y = u3(3);6312 \\ var y = @as(u3, 3);
6189 \\ var x = @intToEnum(Small, y);6313 \\ var x = @intToEnum(Small, y);
6190 \\}6314 \\}
6191 ,6315 ,
...@@ -6722,8 +6846,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6722,8 +6846,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6722 "tmp.zig:1:1: note: declared here",6846 "tmp.zig:1:1: note: declared here",
6723 );6847 );
67246848
6725 // fixed bug #20326849 cases.add( // fixed bug #2032
6726 cases.add(
6727 "compile diagnostic string for top level decl type",6850 "compile diagnostic string for top level decl type",
6728 \\export fn entry() void {6851 \\export fn entry() void {
6729 \\ var foo: u32 = @This(){};6852 \\ var foo: u32 = @This(){};
...@@ -6731,6 +6854,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6731,6 +6854,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6731 ,6854 ,
6732 "tmp.zig:2:27: error: expected type 'u32', found '(root)'",6855 "tmp.zig:2:27: error: expected type 'u32', found '(root)'",
6733 "tmp.zig:1:1: note: (root) declared here",6856 "tmp.zig:1:1: note: (root) declared here",
6734 "tmp.zig:2:5: note: referenced here",
6735 );6857 );
6736}6858}
test/stage1/behavior.zig+2
...@@ -32,6 +32,8 @@ comptime {...@@ -32,6 +32,8 @@ comptime {
32 _ = @import("behavior/bugs/2346.zig");32 _ = @import("behavior/bugs/2346.zig");
33 _ = @import("behavior/bugs/2578.zig");33 _ = @import("behavior/bugs/2578.zig");
34 _ = @import("behavior/bugs/2692.zig");34 _ = @import("behavior/bugs/2692.zig");
35 _ = @import("behavior/bugs/2889.zig");
36 _ = @import("behavior/bugs/3007.zig");
35 _ = @import("behavior/bugs/3046.zig");37 _ = @import("behavior/bugs/3046.zig");
36 _ = @import("behavior/bugs/3112.zig");38 _ = @import("behavior/bugs/3112.zig");
37 _ = @import("behavior/bugs/3367.zig");39 _ = @import("behavior/bugs/3367.zig");
test/stage1/behavior/align.zig+2-2
...@@ -7,7 +7,7 @@ var foo: u8 align(4) = 100;...@@ -7,7 +7,7 @@ var foo: u8 align(4) = 100;
7test "global variable alignment" {7test "global variable alignment" {
8 expect(@typeOf(&foo).alignment == 4);8 expect(@typeOf(&foo).alignment == 4);
9 expect(@typeOf(&foo) == *align(4) u8);9 expect(@typeOf(&foo) == *align(4) u8);
10 const slice = (*[1]u8)(&foo)[0..];10 const slice = @as(*[1]u8, &foo)[0..];
11 expect(@typeOf(slice) == []align(4) u8);11 expect(@typeOf(slice) == []align(4) u8);
12}12}
1313
...@@ -61,7 +61,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {...@@ -61,7 +61,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
61test "implicitly decreasing slice alignment" {61test "implicitly decreasing slice alignment" {
62 const a: u32 align(4) = 3;62 const a: u32 align(4) = 3;
63 const b: u32 align(8) = 4;63 const b: u32 align(8) = 4;
64 expect(addUnalignedSlice((*const [1]u32)(&a)[0..], (*const [1]u32)(&b)[0..]) == 7);64 expect(addUnalignedSlice(@as(*const [1]u32, &a)[0..], @as(*const [1]u32, &b)[0..]) == 7);
65}65}
66fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {66fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
67 return a[0] + b[0];67 return a[0] + b[0];
test/stage1/behavior/array.zig+37-2
...@@ -12,7 +12,7 @@ test "arrays" {...@@ -12,7 +12,7 @@ test "arrays" {
12 }12 }
1313
14 i = 0;14 i = 0;
15 var accumulator = u32(0);15 var accumulator = @as(u32, 0);
16 while (i < 5) {16 while (i < 5) {
17 accumulator += array[i];17 accumulator += array[i];
1818
...@@ -149,7 +149,7 @@ test "implicit cast single-item pointer" {...@@ -149,7 +149,7 @@ test "implicit cast single-item pointer" {
149149
150fn testImplicitCastSingleItemPtr() void {150fn testImplicitCastSingleItemPtr() void {
151 var byte: u8 = 100;151 var byte: u8 = 100;
152 const slice = (*[1]u8)(&byte)[0..];152 const slice = @as(*[1]u8, &byte)[0..];
153 slice[0] += 1;153 slice[0] += 1;
154 expect(byte == 101);154 expect(byte == 101);
155}155}
...@@ -298,3 +298,38 @@ test "implicit cast zero sized array ptr to slice" {...@@ -298,3 +298,38 @@ test "implicit cast zero sized array ptr to slice" {
298 const c: []const u8 = &b;298 const c: []const u8 = &b;
299 expect(c.len == 0);299 expect(c.len == 0);
300}300}
301
302test "anonymous list literal syntax" {
303 const S = struct {
304 fn doTheTest() void {
305 var array: [4]u8 = .{1, 2, 3, 4};
306 expect(array[0] == 1);
307 expect(array[1] == 2);
308 expect(array[2] == 3);
309 expect(array[3] == 4);
310 }
311 };
312 S.doTheTest();
313 comptime S.doTheTest();
314}
315
316test "anonymous literal in array" {
317 const S = struct {
318 const Foo = struct {
319 a: usize = 2,
320 b: usize = 4,
321 };
322 fn doTheTest() void {
323 var array: [2]Foo = .{
324 .{.a = 3},
325 .{.b = 3},
326 };
327 expect(array[0].a == 3);
328 expect(array[0].b == 4);
329 expect(array[1].a == 2);
330 expect(array[1].b == 3);
331 }
332 };
333 S.doTheTest();
334 comptime S.doTheTest();
335}
test/stage1/behavior/asm.zig+8-8
...@@ -45,42 +45,42 @@ test "alternative constraints" {...@@ -45,42 +45,42 @@ test "alternative constraints" {
45test "sized integer/float in asm input" {45test "sized integer/float in asm input" {
46 asm volatile (""46 asm volatile (""
47 :47 :
48 : [_] "m" (usize(3))48 : [_] "m" (@as(usize, 3))
49 : ""49 : ""
50 );50 );
51 asm volatile (""51 asm volatile (""
52 :52 :
53 : [_] "m" (i15(-3))53 : [_] "m" (@as(i15, -3))
54 : ""54 : ""
55 );55 );
56 asm volatile (""56 asm volatile (""
57 :57 :
58 : [_] "m" (u3(3))58 : [_] "m" (@as(u3, 3))
59 : ""59 : ""
60 );60 );
61 asm volatile (""61 asm volatile (""
62 :62 :
63 : [_] "m" (i3(3))63 : [_] "m" (@as(i3, 3))
64 : ""64 : ""
65 );65 );
66 asm volatile (""66 asm volatile (""
67 :67 :
68 : [_] "m" (u121(3))68 : [_] "m" (@as(u121, 3))
69 : ""69 : ""
70 );70 );
71 asm volatile (""71 asm volatile (""
72 :72 :
73 : [_] "m" (i121(3))73 : [_] "m" (@as(i121, 3))
74 : ""74 : ""
75 );75 );
76 asm volatile (""76 asm volatile (""
77 :77 :
78 : [_] "m" (f32(3.17))78 : [_] "m" (@as(f32, 3.17))
79 : ""79 : ""
80 );80 );
81 asm volatile (""81 asm volatile (""
82 :82 :
83 : [_] "m" (f64(3.17))83 : [_] "m" (@as(f64, 3.17))
84 : ""84 : ""
85 );85 );
86}86}
test/stage1/behavior/async_fn.zig+7-7
...@@ -191,7 +191,7 @@ async fn testSuspendBlock() void {...@@ -191,7 +191,7 @@ async fn testSuspendBlock() void {
191191
192 // Test to make sure that @frame() works as advertised (issue #1296)192 // Test to make sure that @frame() works as advertised (issue #1296)
193 // var our_handle: anyframe = @frame();193 // var our_handle: anyframe = @frame();
194 expect(a_promise == anyframe(@frame()));194 expect(a_promise == @as(anyframe, @frame()));
195195
196 global_result = true;196 global_result = true;
197}197}
...@@ -543,7 +543,7 @@ test "pass string literal to async function" {...@@ -543,7 +543,7 @@ test "pass string literal to async function" {
543 fn hello(msg: []const u8) void {543 fn hello(msg: []const u8) void {
544 frame = @frame();544 frame = @frame();
545 suspend;545 suspend;
546 expectEqual(([]const u8)("hello"), msg);546 expectEqual(@as([]const u8, "hello"), msg);
547 ok = true;547 ok = true;
548 }548 }
549 };549 };
...@@ -1048,7 +1048,7 @@ test "using @typeOf on a generic function call" {...@@ -1048,7 +1048,7 @@ test "using @typeOf on a generic function call" {
1048 return await @asyncCall(frame, {}, amain, x - 1);1048 return await @asyncCall(frame, {}, amain, x - 1);
1049 }1049 }
1050 };1050 };
1051 _ = async S.amain(u32(1));1051 _ = async S.amain(@as(u32, 1));
1052 resume S.global_frame;1052 resume S.global_frame;
1053 expect(S.global_ok);1053 expect(S.global_ok);
1054}1054}
...@@ -1080,8 +1080,8 @@ test "recursive call of await @asyncCall with struct return type" {...@@ -1080,8 +1080,8 @@ test "recursive call of await @asyncCall with struct return type" {
1080 };1080 };
1081 };1081 };
1082 var res: S.Foo = undefined;1082 var res: S.Foo = undefined;
1083 var frame: @typeOf(async S.amain(u32(1))) = undefined;1083 var frame: @typeOf(async S.amain(@as(u32, 1))) = undefined;
1084 _ = @asyncCall(&frame, &res, S.amain, u32(1));1084 _ = @asyncCall(&frame, &res, S.amain, @as(u32, 1));
1085 resume S.global_frame;1085 resume S.global_frame;
1086 expect(S.global_ok);1086 expect(S.global_ok);
1087 expect(res.x == 1);1087 expect(res.x == 1);
...@@ -1214,7 +1214,7 @@ test "spill target expr in a for loop" {...@@ -1214,7 +1214,7 @@ test "spill target expr in a for loop" {
1214 }1214 }
12151215
1216 const Foo = struct {1216 const Foo = struct {
1217 slice: []i32,1217 slice: []const i32,
1218 };1218 };
12191219
1220 fn atest(foo: *Foo) i32 {1220 fn atest(foo: *Foo) i32 {
...@@ -1245,7 +1245,7 @@ test "spill target expr in a for loop, with a var decl in the loop body" {...@@ -1245,7 +1245,7 @@ test "spill target expr in a for loop, with a var decl in the loop body" {
1245 }1245 }
12461246
1247 const Foo = struct {1247 const Foo = struct {
1248 slice: []i32,1248 slice: []const i32,
1249 };1249 };
12501250
1251 fn atest(foo: *Foo) i32 {1251 fn atest(foo: *Foo) i32 {
test/stage1/behavior/atomics.zig+40-3
...@@ -98,12 +98,49 @@ test "cmpxchg with ignored result" {...@@ -98,12 +98,49 @@ test "cmpxchg with ignored result" {
9898
99 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);99 _ = @cmpxchgStrong(i32, &x, 1234, 5678, .Monotonic, .Monotonic);
100100
101 expectEqual(i32(5678), x);101 expectEqual(@as(i32, 5678), x);
102}102}
103103
104var a_global_variable = u32(1234);104var a_global_variable = @as(u32, 1234);
105105
106test "cmpxchg on a global variable" {106test "cmpxchg on a global variable" {
107 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);107 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
108 expectEqual(u32(42), a_global_variable);108 expectEqual(@as(u32, 42), a_global_variable);
109}109}
110
111test "atomic load and rmw with enum" {
112 const Value = enum(u8) {
113 a,
114 b,
115 c,
116 };
117 var x = Value.a;
118
119 expect(@atomicLoad(Value, &x, .SeqCst) != .b);
120
121 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
122 expect(@atomicLoad(Value, &x, .SeqCst) == .c);
123 expect(@atomicLoad(Value, &x, .SeqCst) != .a);
124 expect(@atomicLoad(Value, &x, .SeqCst) != .b);
125}
126
127test "atomic store" {
128 var x: u32 = 0;
129 @atomicStore(u32, &x, 1, .SeqCst);
130 expect(@atomicLoad(u32, &x, .SeqCst) == 1);
131 @atomicStore(u32, &x, 12345678, .SeqCst);
132 expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
133}
134
135test "atomic store comptime" {
136 comptime testAtomicStore();
137 testAtomicStore();
138}
139
140fn testAtomicStore() void {
141 var x: u32 = 0;
142 @atomicStore(u32, &x, 1, .SeqCst);
143 expect(@atomicLoad(u32, &x, .SeqCst) == 1);
144 @atomicStore(u32, &x, 12345678, .SeqCst);
145 expect(@atomicLoad(u32, &x, .SeqCst) == 12345678);
146}
\ No newline at end of file
test/stage1/behavior/bitreverse.zig+14-14
...@@ -46,24 +46,24 @@ fn testBitReverse() void {...@@ -46,24 +46,24 @@ fn testBitReverse() void {
46 expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);46 expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
4747
48 // using comptime_ints, signed, positive48 // using comptime_ints, signed, positive
49 expect(@bitReverse(u8, u8(0)) == 0);49 expect(@bitReverse(u8, @as(u8, 0)) == 0);
50 expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));50 expect(@bitReverse(i8, @bitCast(i8, @as(u8, 0x92))) == @bitCast(i8, @as(u8, 0x49)));
51 expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));51 expect(@bitReverse(i16, @bitCast(i16, @as(u16, 0x1234))) == @bitCast(i16, @as(u16, 0x2c48)));
52 expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));52 expect(@bitReverse(i24, @bitCast(i24, @as(u24, 0x123456))) == @bitCast(i24, @as(u24, 0x6a2c48)));
53 expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));53 expect(@bitReverse(i32, @bitCast(i32, @as(u32, 0x12345678))) == @bitCast(i32, @as(u32, 0x1e6a2c48)));
54 expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));54 expect(@bitReverse(i40, @bitCast(i40, @as(u40, 0x123456789a))) == @bitCast(i40, @as(u40, 0x591e6a2c48)));
55 expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));55 expect(@bitReverse(i48, @bitCast(i48, @as(u48, 0x123456789abc))) == @bitCast(i48, @as(u48, 0x3d591e6a2c48)));
56 expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));56 expect(@bitReverse(i56, @bitCast(i56, @as(u56, 0x123456789abcde))) == @bitCast(i56, @as(u56, 0x7b3d591e6a2c48)));
57 expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));57 expect(@bitReverse(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1))) == @bitCast(i64, @as(u64, 0x8f7b3d591e6a2c48)));
58 expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));58 expect(@bitReverse(i128, @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181))) == @bitCast(i128, @as(u128, 0x818e868a828c84888f7b3d591e6a2c48)));
5959
60 // using signed, negative. Compare to runtime ints returned from llvm.60 // using signed, negative. Compare to runtime ints returned from llvm.
61 var neg8: i8 = -18;61 var neg8: i8 = -18;
62 expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8));62 expect(@bitReverse(i8, @as(i8, -18)) == @bitReverse(i8, neg8));
63 var neg16: i16 = -32694;63 var neg16: i16 = -32694;
64 expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16));64 expect(@bitReverse(i16, @as(i16, -32694)) == @bitReverse(i16, neg16));
65 var neg24: i24 = -6773785;65 var neg24: i24 = -6773785;
66 expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24));66 expect(@bitReverse(i24, @as(i24, -6773785)) == @bitReverse(i24, neg24));
67 var neg32: i32 = -16773785;67 var neg32: i32 = -16773785;
68 expect(@bitReverse(i32, i32(-16773785)) == @bitReverse(i32, neg32));68 expect(@bitReverse(i32, @as(i32, -16773785)) == @bitReverse(i32, neg32));
69}69}
test/stage1/behavior/bool.zig+4-4
...@@ -8,14 +8,14 @@ test "bool literals" {...@@ -8,14 +8,14 @@ test "bool literals" {
8test "cast bool to int" {8test "cast bool to int" {
9 const t = true;9 const t = true;
10 const f = false;10 const f = false;
11 expect(@boolToInt(t) == u32(1));11 expect(@boolToInt(t) == @as(u32, 1));
12 expect(@boolToInt(f) == u32(0));12 expect(@boolToInt(f) == @as(u32, 0));
13 nonConstCastBoolToInt(t, f);13 nonConstCastBoolToInt(t, f);
14}14}
1515
16fn nonConstCastBoolToInt(t: bool, f: bool) void {16fn nonConstCastBoolToInt(t: bool, f: bool) void {
17 expect(@boolToInt(t) == u32(1));17 expect(@boolToInt(t) == @as(u32, 1));
18 expect(@boolToInt(f) == u32(0));18 expect(@boolToInt(f) == @as(u32, 0));
19}19}
2020
21test "bool cmp" {21test "bool cmp" {
test/stage1/behavior/bugs/1322.zig+2-2
...@@ -13,7 +13,7 @@ const C = struct {};...@@ -13,7 +13,7 @@ const C = struct {};
1313
14test "tagged union with all void fields but a meaningful tag" {14test "tagged union with all void fields but a meaningful tag" {
15 var a: A = A{ .b = B{ .c = C{} } };15 var a: A = A{ .b = B{ .c = C{} } };
16 std.testing.expect(@TagType(B)(a.b) == @TagType(B).c);16 std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).c);
17 a = A{ .b = B.None };17 a = A{ .b = B.None };
18 std.testing.expect(@TagType(B)(a.b) == @TagType(B).None);18 std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).None);
19}19}
test/stage1/behavior/bugs/1421.zig+1-1
...@@ -10,5 +10,5 @@ const S = struct {...@@ -10,5 +10,5 @@ const S = struct {
1010
11test "functions with return type required to be comptime are generic" {11test "functions with return type required to be comptime are generic" {
12 const ti = S.method();12 const ti = S.method();
13 expect(builtin.TypeId(ti) == builtin.TypeId.Struct);13 expect(@as(builtin.TypeId, ti) == builtin.TypeId.Struct);
14}14}
test/stage1/behavior/bugs/2114.zig+4-4
...@@ -12,8 +12,8 @@ test "fixed" {...@@ -12,8 +12,8 @@ test "fixed" {
12}12}
1313
14fn testClz() void {14fn testClz() void {
15 expect(ctz(u128(0x40000000000000000000000000000000)) == 126);15 expect(ctz(@as(u128, 0x40000000000000000000000000000000)) == 126);
16 expect(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1)) == u128(0x80000000000000000000000000000000));16 expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000));
17 expect(ctz(u128(0x80000000000000000000000000000000)) == 127);17 expect(ctz(@as(u128, 0x80000000000000000000000000000000)) == 127);
18 expect(ctz(math.rotl(u128, u128(0x40000000000000000000000000000000), u8(1))) == 127);18 expect(ctz(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127);
19}19}
test/stage1/behavior/bugs/2889.zig created+31
...@@ -0,0 +1,31 @@
1const std = @import("std");
2
3const source = "A-";
4
5fn parseNote() ?i32 {
6 const letter = source[0];
7 const modifier = source[1];
8
9 const semitone = blk: {
10 if (letter == 'C' and modifier == '-') break :blk @as(i32, 0);
11 if (letter == 'C' and modifier == '#') break :blk @as(i32, 1);
12 if (letter == 'D' and modifier == '-') break :blk @as(i32, 2);
13 if (letter == 'D' and modifier == '#') break :blk @as(i32, 3);
14 if (letter == 'E' and modifier == '-') break :blk @as(i32, 4);
15 if (letter == 'F' and modifier == '-') break :blk @as(i32, 5);
16 if (letter == 'F' and modifier == '#') break :blk @as(i32, 6);
17 if (letter == 'G' and modifier == '-') break :blk @as(i32, 7);
18 if (letter == 'G' and modifier == '#') break :blk @as(i32, 8);
19 if (letter == 'A' and modifier == '-') break :blk @as(i32, 9);
20 if (letter == 'A' and modifier == '#') break :blk @as(i32, 10);
21 if (letter == 'B' and modifier == '-') break :blk @as(i32, 11);
22 return null;
23 };
24
25 return semitone;
26}
27
28test "fixed" {
29 const result = parseNote();
30 std.testing.expect(result.? == 9);
31}
test/stage1/behavior/bugs/3007.zig created+23
...@@ -0,0 +1,23 @@
1const std = @import("std");
2
3const Foo = struct {
4 free: bool,
5
6 pub const FooError = error{NotFree};
7};
8
9var foo = Foo{ .free = true };
10var default_foo: ?*Foo = null;
11
12fn get_foo() Foo.FooError!*Foo {
13 if (foo.free) {
14 foo.free = false;
15 return &foo;
16 }
17 return error.NotFree;
18}
19
20test "fixed" {
21 default_foo = get_foo() catch null; // This Line
22 std.testing.expect(!default_foo.?.free);
23}
test/stage1/behavior/bugs/3046.zig+1-1
...@@ -13,7 +13,7 @@ var some_struct: SomeStruct = undefined;...@@ -13,7 +13,7 @@ var some_struct: SomeStruct = undefined;
1313
14test "fixed" {14test "fixed" {
15 some_struct = SomeStruct{15 some_struct = SomeStruct{
16 .field = couldFail() catch |_| i32(0),16 .field = couldFail() catch |_| @as(i32, 0),
17 };17 };
18 expect(some_struct.field == 1);18 expect(some_struct.field == 1);
19}19}
test/stage1/behavior/byteswap.zig+12-12
...@@ -11,24 +11,24 @@ test "@byteSwap integers" {...@@ -11,24 +11,24 @@ test "@byteSwap integers" {
11 t(u24, 0x123456, 0x563412);11 t(u24, 0x123456, 0x563412);
12 t(u32, 0x12345678, 0x78563412);12 t(u32, 0x12345678, 0x78563412);
13 t(u40, 0x123456789a, 0x9a78563412);13 t(u40, 0x123456789a, 0x9a78563412);
14 t(i48, 0x123456789abc, @bitCast(i48, u48(0xbc9a78563412)));14 t(i48, 0x123456789abc, @bitCast(i48, @as(u48, 0xbc9a78563412)));
15 t(u56, 0x123456789abcde, 0xdebc9a78563412);15 t(u56, 0x123456789abcde, 0xdebc9a78563412);
16 t(u64, 0x123456789abcdef1, 0xf1debc9a78563412);16 t(u64, 0x123456789abcdef1, 0xf1debc9a78563412);
17 t(u128, 0x123456789abcdef11121314151617181, 0x8171615141312111f1debc9a78563412);17 t(u128, 0x123456789abcdef11121314151617181, 0x8171615141312111f1debc9a78563412);
1818
19 t(u0, u0(0), 0);19 t(u0, @as(u0, 0), 0);
20 t(i8, i8(-50), -50);20 t(i8, @as(i8, -50), -50);
21 t(i16, @bitCast(i16, u16(0x1234)), @bitCast(i16, u16(0x3412)));21 t(i16, @bitCast(i16, @as(u16, 0x1234)), @bitCast(i16, @as(u16, 0x3412)));
22 t(i24, @bitCast(i24, u24(0x123456)), @bitCast(i24, u24(0x563412)));22 t(i24, @bitCast(i24, @as(u24, 0x123456)), @bitCast(i24, @as(u24, 0x563412)));
23 t(i32, @bitCast(i32, u32(0x12345678)), @bitCast(i32, u32(0x78563412)));23 t(i32, @bitCast(i32, @as(u32, 0x12345678)), @bitCast(i32, @as(u32, 0x78563412)));
24 t(u40, @bitCast(i40, u40(0x123456789a)), u40(0x9a78563412));24 t(u40, @bitCast(i40, @as(u40, 0x123456789a)), @as(u40, 0x9a78563412));
25 t(i48, @bitCast(i48, u48(0x123456789abc)), @bitCast(i48, u48(0xbc9a78563412)));25 t(i48, @bitCast(i48, @as(u48, 0x123456789abc)), @bitCast(i48, @as(u48, 0xbc9a78563412)));
26 t(i56, @bitCast(i56, u56(0x123456789abcde)), @bitCast(i56, u56(0xdebc9a78563412)));26 t(i56, @bitCast(i56, @as(u56, 0x123456789abcde)), @bitCast(i56, @as(u56, 0xdebc9a78563412)));
27 t(i64, @bitCast(i64, u64(0x123456789abcdef1)), @bitCast(i64, u64(0xf1debc9a78563412)));27 t(i64, @bitCast(i64, @as(u64, 0x123456789abcdef1)), @bitCast(i64, @as(u64, 0xf1debc9a78563412)));
28 t(28 t(
29 i128,29 i128,
30 @bitCast(i128, u128(0x123456789abcdef11121314151617181)),30 @bitCast(i128, @as(u128, 0x123456789abcdef11121314151617181)),
31 @bitCast(i128, u128(0x8171615141312111f1debc9a78563412)),31 @bitCast(i128, @as(u128, 0x8171615141312111f1debc9a78563412)),
32 );32 );
33 }33 }
34 fn t(comptime I: type, input: I, expected_output: I) void {34 fn t(comptime I: type, input: I, expected_output: I) void {
test/stage1/behavior/cast.zig+38-11
...@@ -4,7 +4,7 @@ const mem = std.mem;...@@ -4,7 +4,7 @@ const mem = std.mem;
4const maxInt = std.math.maxInt;4const maxInt = std.math.maxInt;
55
6test "int to ptr cast" {6test "int to ptr cast" {
7 const x = usize(13);7 const x = @as(usize, 13);
8 const y = @intToPtr(*u8, x);8 const y = @intToPtr(*u8, x);
9 const z = @ptrToInt(y);9 const z = @ptrToInt(y);
10 expect(z == 13);10 expect(z == 13);
...@@ -75,8 +75,8 @@ test "peer resolve array and const slice" {...@@ -75,8 +75,8 @@ test "peer resolve array and const slice" {
75 comptime testPeerResolveArrayConstSlice(true);75 comptime testPeerResolveArrayConstSlice(true);
76}76}
77fn testPeerResolveArrayConstSlice(b: bool) void {77fn testPeerResolveArrayConstSlice(b: bool) void {
78 const value1 = if (b) "aoeu" else ([]const u8)("zz");78 const value1 = if (b) "aoeu" else @as([]const u8, "zz");
79 const value2 = if (b) ([]const u8)("zz") else "aoeu";79 const value2 = if (b) @as([]const u8, "zz") else "aoeu";
80 expect(mem.eql(u8, value1, "aoeu"));80 expect(mem.eql(u8, value1, "aoeu"));
81 expect(mem.eql(u8, value2, "zz"));81 expect(mem.eql(u8, value2, "zz"));
82}82}
...@@ -90,7 +90,7 @@ const A = struct {...@@ -90,7 +90,7 @@ const A = struct {
90 a: i32,90 a: i32,
91};91};
92fn castToOptionalTypeError(z: i32) void {92fn castToOptionalTypeError(z: i32) void {
93 const x = i32(1);93 const x = @as(i32, 1);
94 const y: anyerror!?i32 = x;94 const y: anyerror!?i32 = x;
95 expect((try y).? == 1);95 expect((try y).? == 1);
9696
...@@ -134,10 +134,10 @@ test "peer type resolution: ?T and T" {...@@ -134,10 +134,10 @@ test "peer type resolution: ?T and T" {
134}134}
135fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {135fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
136 if (c) {136 if (c) {
137 return if (b) null else usize(0);137 return if (b) null else @as(usize, 0);
138 }138 }
139139
140 return usize(3);140 return @as(usize, 3);
141}141}
142142
143test "peer type resolution: [0]u8 and []const u8" {143test "peer type resolution: [0]u8 and []const u8" {
...@@ -256,9 +256,9 @@ test "@floatToInt" {...@@ -256,9 +256,9 @@ test "@floatToInt" {
256}256}
257257
258fn testFloatToInts() void {258fn testFloatToInts() void {
259 const x = i32(1e4);259 const x = @as(i32, 1e4);
260 expect(x == 10000);260 expect(x == 10000);
261 const y = @floatToInt(i32, f32(1e4));261 const y = @floatToInt(i32, @as(f32, 1e4));
262 expect(y == 10000);262 expect(y == 10000);
263 expectFloatToInt(f16, 255.1, u8, 255);263 expectFloatToInt(f16, 255.1, u8, 255);
264 expectFloatToInt(f16, 127.2, i8, 127);264 expectFloatToInt(f16, 127.2, i8, 127);
...@@ -392,7 +392,7 @@ fn MakeType(comptime T: type) type {...@@ -392,7 +392,7 @@ fn MakeType(comptime T: type) type {
392 }392 }
393393
394 fn getNonNull() ?T {394 fn getNonNull() ?T {
395 return T(undefined);395 return @as(T, undefined);
396 }396 }
397 };397 };
398}398}
...@@ -442,7 +442,7 @@ fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {...@@ -442,7 +442,7 @@ fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
442}442}
443443
444test "*usize to *void" {444test "*usize to *void" {
445 var i = usize(0);445 var i = @as(usize, 0);
446 var v = @ptrCast(*void, &i);446 var v = @ptrCast(*void, &i);
447 v.* = {};447 v.* = {};
448}448}
...@@ -535,6 +535,33 @@ test "peer type resolution: unreachable, error set, unreachable" {...@@ -535,6 +535,33 @@ test "peer type resolution: unreachable, error set, unreachable" {
535}535}
536536
537test "implicit cast comptime_int to comptime_float" {537test "implicit cast comptime_int to comptime_float" {
538 comptime expect(comptime_float(10) == f32(10));538 comptime expect(@as(comptime_float, 10) == @as(f32, 10));
539 expect(2 == 2.0);539 expect(2 == 2.0);
540}540}
541
542test "implicit cast *[0]T to E![]const u8" {
543 var x = @as(anyerror![]const u8, &[0]u8{});
544 expect((x catch unreachable).len == 0);
545}
546
547test "peer cast *[0]T to E![]const T" {
548 var buffer: [5]u8 = "abcde";
549 var buf: anyerror![]const u8 = buffer[0..];
550 var b = false;
551 var y = if (b) &[0]u8{} else buf;
552 expect(mem.eql(u8, "abcde", y catch unreachable));
553}
554
555test "peer cast *[0]T to []const T" {
556 var buffer: [5]u8 = "abcde";
557 var buf: []const u8 = buffer[0..];
558 var b = false;
559 var y = if (b) &[0]u8{} else buf;
560 expect(mem.eql(u8, "abcde", y));
561}
562
563var global_array: [4]u8 = undefined;
564test "cast from array reference to fn" {
565 const f = @ptrCast(extern fn () void, &global_array);
566 expect(@ptrToInt(f) == @ptrToInt(&global_array));
567}
test/stage1/behavior/defer.zig+1-1
...@@ -52,7 +52,7 @@ fn testBreakContInDefer(x: usize) void {...@@ -52,7 +52,7 @@ fn testBreakContInDefer(x: usize) void {
52}52}
5353
54test "defer and labeled break" {54test "defer and labeled break" {
55 var i = usize(0);55 var i = @as(usize, 0);
5656
57 blk: {57 blk: {
58 defer i += 1;58 defer i += 1;
test/stage1/behavior/enum.zig+2-2
...@@ -788,7 +788,7 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {...@@ -788,7 +788,7 @@ fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
788 expect(1234 == switch (x) {788 expect(1234 == switch (x) {
789 MultipleChoice.A => 1,789 MultipleChoice.A => 1,
790 MultipleChoice.B => 2,790 MultipleChoice.B => 2,
791 MultipleChoice.C => u32(1234),791 MultipleChoice.C => @as(u32, 1234),
792 MultipleChoice.D => 4,792 MultipleChoice.D => 4,
793 });793 });
794}794}
...@@ -816,7 +816,7 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {...@@ -816,7 +816,7 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
816 MultipleChoice2.A => 1,816 MultipleChoice2.A => 1,
817 MultipleChoice2.B => 2,817 MultipleChoice2.B => 2,
818 MultipleChoice2.C => 3,818 MultipleChoice2.C => 3,
819 MultipleChoice2.D => u32(1234),819 MultipleChoice2.D => @as(u32, 1234),
820 MultipleChoice2.Unspecified1 => 5,820 MultipleChoice2.Unspecified1 => 5,
821 MultipleChoice2.Unspecified2 => 6,821 MultipleChoice2.Unspecified2 => 6,
822 MultipleChoice2.Unspecified3 => 7,822 MultipleChoice2.Unspecified3 => 7,
test/stage1/behavior/error.zig+6-2
...@@ -51,7 +51,7 @@ test "error binary operator" {...@@ -51,7 +51,7 @@ test "error binary operator" {
51 expect(b == 10);51 expect(b == 10);
52}52}
53fn errBinaryOperatorG(x: bool) anyerror!isize {53fn errBinaryOperatorG(x: bool) anyerror!isize {
54 return if (x) error.ItBroke else isize(10);54 return if (x) error.ItBroke else @as(isize, 10);
55}55}
5656
57test "unwrap simple value from error" {57test "unwrap simple value from error" {
...@@ -160,6 +160,10 @@ fn testErrToIntWithOnePossibleValue(...@@ -160,6 +160,10 @@ fn testErrToIntWithOnePossibleValue(
160 }160 }
161}161}
162162
163test "empty error union" {
164 const x = error{} || error{};
165}
166
163test "error union peer type resolution" {167test "error union peer type resolution" {
164 testErrorUnionPeerTypeResolution(1);168 testErrorUnionPeerTypeResolution(1);
165}169}
...@@ -295,7 +299,7 @@ test "nested error union function call in optional unwrap" {...@@ -295,7 +299,7 @@ test "nested error union function call in optional unwrap" {
295test "widen cast integer payload of error union function call" {299test "widen cast integer payload of error union function call" {
296 const S = struct {300 const S = struct {
297 fn errorable() !u64 {301 fn errorable() !u64 {
298 var x = u64(try number());302 var x = @as(u64, try number());
299 return x;303 return x;
300 }304 }
301305
test/stage1/behavior/eval.zig+18-18
...@@ -405,19 +405,19 @@ test "float literal at compile time not lossy" {...@@ -405,19 +405,19 @@ test "float literal at compile time not lossy" {
405}405}
406406
407test "f32 at compile time is lossy" {407test "f32 at compile time is lossy" {
408 expect(f32(1 << 24) + 1 == 1 << 24);408 expect(@as(f32, 1 << 24) + 1 == 1 << 24);
409}409}
410410
411test "f64 at compile time is lossy" {411test "f64 at compile time is lossy" {
412 expect(f64(1 << 53) + 1 == 1 << 53);412 expect(@as(f64, 1 << 53) + 1 == 1 << 53);
413}413}
414414
415test "f128 at compile time is lossy" {415test "f128 at compile time is lossy" {
416 expect(f128(10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);416 expect(@as(f128, 10384593717069655257060992658440192.0) + 1 == 10384593717069655257060992658440192.0);
417}417}
418418
419comptime {419comptime {
420 expect(f128(1 << 113) == 10384593717069655257060992658440192);420 expect(@as(f128, 1 << 113) == 10384593717069655257060992658440192);
421}421}
422422
423pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {423pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
...@@ -434,9 +434,9 @@ test "string literal used as comptime slice is memoized" {...@@ -434,9 +434,9 @@ test "string literal used as comptime slice is memoized" {
434}434}
435435
436test "comptime slice of undefined pointer of length 0" {436test "comptime slice of undefined pointer of length 0" {
437 const slice1 = ([*]i32)(undefined)[0..0];437 const slice1 = @as([*]i32, undefined)[0..0];
438 expect(slice1.len == 0);438 expect(slice1.len == 0);
439 const slice2 = ([*]i32)(undefined)[100..100];439 const slice2 = @as([*]i32, undefined)[100..100];
440 expect(slice2.len == 0);440 expect(slice2.len == 0);
441}441}
442442
...@@ -444,10 +444,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {...@@ -444,10 +444,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {
444 comptime var i: usize = 0;444 comptime var i: usize = 0;
445 inline while (i < 4) : (i += 1) {445 inline while (i < 4) : (i += 1) {
446 s[i] = 0;446 s[i] = 0;
447 s[i] |= u32(b[i * 4 + 0]) << 24;447 s[i] |= @as(u32, b[i * 4 + 0]) << 24;
448 s[i] |= u32(b[i * 4 + 1]) << 16;448 s[i] |= @as(u32, b[i * 4 + 1]) << 16;
449 s[i] |= u32(b[i * 4 + 2]) << 8;449 s[i] |= @as(u32, b[i * 4 + 2]) << 8;
450 s[i] |= u32(b[i * 4 + 3]) << 0;450 s[i] |= @as(u32, b[i * 4 + 3]) << 0;
451 }451 }
452}452}
453453
...@@ -557,14 +557,14 @@ test "array concat of slices gives slice" {...@@ -557,14 +557,14 @@ test "array concat of slices gives slice" {
557557
558test "comptime shlWithOverflow" {558test "comptime shlWithOverflow" {
559 const ct_shifted: u64 = comptime amt: {559 const ct_shifted: u64 = comptime amt: {
560 var amt = u64(0);560 var amt = @as(u64, 0);
561 _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);561 _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt);
562 break :amt amt;562 break :amt amt;
563 };563 };
564564
565 const rt_shifted: u64 = amt: {565 const rt_shifted: u64 = amt: {
566 var amt = u64(0);566 var amt = @as(u64, 0);
567 _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);567 _ = @shlWithOverflow(u64, ~@as(u64, 0), 16, &amt);
568 break :amt amt;568 break :amt amt;
569 };569 };
570570
...@@ -670,7 +670,7 @@ fn loopNTimes(comptime n: usize) void {...@@ -670,7 +670,7 @@ fn loopNTimes(comptime n: usize) void {
670}670}
671671
672test "variable inside inline loop that has different types on different iterations" {672test "variable inside inline loop that has different types on different iterations" {
673 testVarInsideInlineLoop(true, u32(42));673 testVarInsideInlineLoop(true, @as(u32, 42));
674}674}
675675
676fn testVarInsideInlineLoop(args: ...) void {676fn testVarInsideInlineLoop(args: ...) void {
...@@ -757,11 +757,11 @@ test "comptime bitwise operators" {...@@ -757,11 +757,11 @@ test "comptime bitwise operators" {
757 expect(-3 | -1 == -1);757 expect(-3 | -1 == -1);
758 expect(3 ^ -1 == -4);758 expect(3 ^ -1 == -4);
759 expect(-3 ^ -1 == 2);759 expect(-3 ^ -1 == 2);
760 expect(~i8(-1) == 0);760 expect(~@as(i8, -1) == 0);
761 expect(~i128(-1) == 0);761 expect(~@as(i128, -1) == 0);
762 expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611);762 expect(18446744073709551615 & 18446744073709551611 == 18446744073709551611);
763 expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);763 expect(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);
764 expect(~u128(0) == 0xffffffffffffffffffffffffffffffff);764 expect(~@as(u128, 0) == 0xffffffffffffffffffffffffffffffff);
765 }765 }
766}766}
767767
test/stage1/behavior/floatop.zig+2-2
...@@ -117,11 +117,11 @@ test "@ln" {...@@ -117,11 +117,11 @@ test "@ln" {
117fn testLn() void {117fn testLn() void {
118 {118 {
119 var a: f32 = e;119 var a: f32 = e;
120 expect(@ln(f32, a) == 1 or @ln(f32, a) == @bitCast(f32, u32(0x3f7fffff)));120 expect(@ln(f32, a) == 1 or @ln(f32, a) == @bitCast(f32, @as(u32, 0x3f7fffff)));
121 }121 }
122 {122 {
123 var a: f64 = e;123 var a: f64 = e;
124 expect(@ln(f64, a) == 1 or @ln(f64, a) == @bitCast(f64, u64(0x3ff0000000000000)));124 expect(@ln(f64, a) == 1 or @ln(f64, a) == @bitCast(f64, @as(u64, 0x3ff0000000000000)));
125 }125 }
126}126}
127127
test/stage1/behavior/fn.zig+18-2
...@@ -29,7 +29,7 @@ test "mutable local variables" {...@@ -29,7 +29,7 @@ test "mutable local variables" {
29 var zero: i32 = 0;29 var zero: i32 = 0;
30 expect(zero == 0);30 expect(zero == 0);
3131
32 var i = i32(0);32 var i = @as(i32, 0);
33 while (i != 3) {33 while (i != 3) {
34 i += 1;34 i += 1;
35 }35 }
...@@ -43,7 +43,7 @@ test "separate block scopes" {...@@ -43,7 +43,7 @@ test "separate block scopes" {
43 }43 }
4444
45 const c = x: {45 const c = x: {
46 const no_conflict = i32(10);46 const no_conflict = @as(i32, 10);
47 break :x no_conflict;47 break :x no_conflict;
48 };48 };
49 expect(c == 10);49 expect(c == 10);
...@@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" {...@@ -247,3 +247,19 @@ test "discard the result of a function that returns a struct" {
247 S.entry();247 S.entry();
248 comptime S.entry();248 comptime S.entry();
249}249}
250
251test "function call with anon list literal" {
252 const S = struct {
253 fn doTheTest() void {
254 consumeVec(.{9, 8, 7});
255 }
256
257 fn consumeVec(vec: [3]f32) void {
258 expect(vec[0] == 9);
259 expect(vec[1] == 8);
260 expect(vec[2] == 7);
261 }
262 };
263 S.doTheTest();
264 comptime S.doTheTest();
265}
test/stage1/behavior/if.zig+2-2
...@@ -32,7 +32,7 @@ fn elseIfExpressionF(c: u8) u8 {...@@ -32,7 +32,7 @@ fn elseIfExpressionF(c: u8) u8 {
32 } else if (c == 1) {32 } else if (c == 1) {
33 return 1;33 return 1;
34 } else {34 } else {
35 return u8(2);35 return @as(u8, 2);
36 }36 }
37}37}
3838
...@@ -58,7 +58,7 @@ test "labeled break inside comptime if inside runtime if" {...@@ -58,7 +58,7 @@ test "labeled break inside comptime if inside runtime if" {
58 var c = true;58 var c = true;
59 if (c) {59 if (c) {
60 answer = if (true) blk: {60 answer = if (true) blk: {
61 break :blk i32(42);61 break :blk @as(i32, 42);
62 };62 };
63 }63 }
64 expect(answer == 42);64 expect(answer == 42);
test/stage1/behavior/import.zig+2-2
...@@ -3,7 +3,7 @@ const expectEqual = @import("std").testing.expectEqual;...@@ -3,7 +3,7 @@ const expectEqual = @import("std").testing.expectEqual;
3const a_namespace = @import("import/a_namespace.zig");3const a_namespace = @import("import/a_namespace.zig");
44
5test "call fn via namespace lookup" {5test "call fn via namespace lookup" {
6 expectEqual(i32(1234), a_namespace.foo());6 expectEqual(@as(i32, 1234), a_namespace.foo());
7}7}
88
9test "importing the same thing gives the same import" {9test "importing the same thing gives the same import" {
...@@ -14,5 +14,5 @@ test "import in non-toplevel scope" {...@@ -14,5 +14,5 @@ test "import in non-toplevel scope" {
14 const S = struct {14 const S = struct {
15 usingnamespace @import("import/a_namespace.zig");15 usingnamespace @import("import/a_namespace.zig");
16 };16 };
17 expectEqual(i32(1234), S.foo());17 expectEqual(@as(i32, 1234), S.foo());
18}18}
test/stage1/behavior/math.zig+12-12
...@@ -186,9 +186,9 @@ fn testThreeExprInARow(f: bool, t: bool) void {...@@ -186,9 +186,9 @@ fn testThreeExprInARow(f: bool, t: bool) void {
186 assertFalse(90 >> 1 >> 2 != 90 >> 3);186 assertFalse(90 >> 1 >> 2 != 90 >> 3);
187 assertFalse(100 - 1 + 1000 != 1099);187 assertFalse(100 - 1 + 1000 != 1099);
188 assertFalse(5 * 4 / 2 % 3 != 1);188 assertFalse(5 * 4 / 2 % 3 != 1);
189 assertFalse(i32(i32(5)) != 5);189 assertFalse(@as(i32, @as(i32, 5)) != 5);
190 assertFalse(!!false);190 assertFalse(!!false);
191 assertFalse(i32(7) != --(i32(7)));191 assertFalse(@as(i32, 7) != --(@as(i32, 7)));
192}192}
193fn assertFalse(b: bool) void {193fn assertFalse(b: bool) void {
194 expect(!b);194 expect(!b);
...@@ -256,10 +256,10 @@ const DivResult = struct {...@@ -256,10 +256,10 @@ const DivResult = struct {
256256
257test "binary not" {257test "binary not" {
258 expect(comptime x: {258 expect(comptime x: {
259 break :x ~u16(0b1010101010101010) == 0b0101010101010101;259 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
260 });260 });
261 expect(comptime x: {261 expect(comptime x: {
262 break :x ~u64(2147483647) == 18446744071562067968;262 break :x ~@as(u64, 2147483647) == 18446744071562067968;
263 });263 });
264 testBinaryNot(0b1010101010101010);264 testBinaryNot(0b1010101010101010);
265}265}
...@@ -472,7 +472,7 @@ test "comptime_int multiplication" {...@@ -472,7 +472,7 @@ test "comptime_int multiplication" {
472472
473test "comptime_int shifting" {473test "comptime_int shifting" {
474 comptime {474 comptime {
475 expect((u128(1) << 127) == 0x80000000000000000000000000000000);475 expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000);
476 }476 }
477}477}
478478
...@@ -480,13 +480,13 @@ test "comptime_int multi-limb shift and mask" {...@@ -480,13 +480,13 @@ test "comptime_int multi-limb shift and mask" {
480 comptime {480 comptime {
481 var a = 0xefffffffa0000001eeeeeeefaaaaaaab;481 var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
482482
483 expect(u32(a & 0xffffffff) == 0xaaaaaaab);483 expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab);
484 a >>= 32;484 a >>= 32;
485 expect(u32(a & 0xffffffff) == 0xeeeeeeef);485 expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef);
486 a >>= 32;486 a >>= 32;
487 expect(u32(a & 0xffffffff) == 0xa0000001);487 expect(@as(u32, a & 0xffffffff) == 0xa0000001);
488 a >>= 32;488 a >>= 32;
489 expect(u32(a & 0xffffffff) == 0xefffffff);489 expect(@as(u32, a & 0xffffffff) == 0xefffffff);
490 a >>= 32;490 a >>= 32;
491491
492 expect(a == 0);492 expect(a == 0);
...@@ -552,7 +552,7 @@ fn should_not_be_zero(x: f128) void {...@@ -552,7 +552,7 @@ fn should_not_be_zero(x: f128) void {
552552
553test "comptime float rem int" {553test "comptime float rem int" {
554 comptime {554 comptime {
555 var x = f32(1) % 2;555 var x = @as(f32, 1) % 2;
556 expect(x == 1.0);556 expect(x == 1.0);
557 }557 }
558}558}
...@@ -568,8 +568,8 @@ test "remainder division" {...@@ -568,8 +568,8 @@ test "remainder division" {
568}568}
569569
570fn remdiv(comptime T: type) void {570fn remdiv(comptime T: type) void {
571 expect(T(1) == T(1) % T(2));571 expect(@as(T, 1) == @as(T, 1) % @as(T, 2));
572 expect(T(1) == T(7) % T(3));572 expect(@as(T, 1) == @as(T, 7) % @as(T, 3));
573}573}
574574
575test "@sqrt" {575test "@sqrt" {
test/stage1/behavior/misc.zig+8-8
...@@ -241,14 +241,14 @@ fn memFree(comptime T: type, memory: []T) void {}...@@ -241,14 +241,14 @@ fn memFree(comptime T: type, memory: []T) void {}
241241
242test "cast undefined" {242test "cast undefined" {
243 const array: [100]u8 = undefined;243 const array: [100]u8 = undefined;
244 const slice = ([]const u8)(array);244 const slice = @as([]const u8, array);
245 testCastUndefined(slice);245 testCastUndefined(slice);
246}246}
247fn testCastUndefined(x: []const u8) void {}247fn testCastUndefined(x: []const u8) void {}
248248
249test "cast small unsigned to larger signed" {249test "cast small unsigned to larger signed" {
250 expect(castSmallUnsignedToLargerSigned1(200) == i16(200));250 expect(castSmallUnsignedToLargerSigned1(200) == @as(i16, 200));
251 expect(castSmallUnsignedToLargerSigned2(9999) == i64(9999));251 expect(castSmallUnsignedToLargerSigned2(9999) == @as(i64, 9999));
252}252}
253fn castSmallUnsignedToLargerSigned1(x: u8) i16 {253fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
254 return x;254 return x;
...@@ -268,7 +268,7 @@ fn outer() i64 {...@@ -268,7 +268,7 @@ fn outer() i64 {
268}268}
269269
270test "pointer dereferencing" {270test "pointer dereferencing" {
271 var x = i32(3);271 var x = @as(i32, 3);
272 const y = &x;272 const y = &x;
273273
274 y.* += 1;274 y.* += 1;
...@@ -350,7 +350,7 @@ fn testTakeAddressOfParameter(f: f32) void {...@@ -350,7 +350,7 @@ fn testTakeAddressOfParameter(f: f32) void {
350}350}
351351
352test "pointer comparison" {352test "pointer comparison" {
353 const a = ([]const u8)("a");353 const a = @as([]const u8, "a");
354 const b = &a;354 const b = &a;
355 expect(ptrEql(b, b));355 expect(ptrEql(b, b));
356}356}
...@@ -500,7 +500,7 @@ fn TypeFromFn(comptime T: type) type {...@@ -500,7 +500,7 @@ fn TypeFromFn(comptime T: type) type {
500}500}
501501
502test "double implicit cast in same expression" {502test "double implicit cast in same expression" {
503 var x = i32(u16(nine()));503 var x = @as(i32, @as(u16, nine()));
504 expect(x == 9);504 expect(x == 9);
505}505}
506fn nine() u8 {506fn nine() u8 {
...@@ -642,7 +642,7 @@ test "self reference through fn ptr field" {...@@ -642,7 +642,7 @@ test "self reference through fn ptr field" {
642642
643test "volatile load and store" {643test "volatile load and store" {
644 var number: i32 = 1234;644 var number: i32 = 1234;
645 const ptr = (*volatile i32)(&number);645 const ptr = @as(*volatile i32, &number);
646 ptr.* += 1;646 ptr.* += 1;
647 expect(ptr.* == 1235);647 expect(ptr.* == 1235);
648}648}
...@@ -761,7 +761,7 @@ test "nested optional field in struct" {...@@ -761,7 +761,7 @@ test "nested optional field in struct" {
761761
762fn maybe(x: bool) anyerror!?u32 {762fn maybe(x: bool) anyerror!?u32 {
763 return switch (x) {763 return switch (x) {
764 true => u32(42),764 true => @as(u32, 42),
765 else => null,765 else => null,
766 };766 };
767}767}
test/stage1/behavior/popcount.zig+1-1
...@@ -35,7 +35,7 @@ fn testPopCount() void {...@@ -35,7 +35,7 @@ fn testPopCount() void {
35 expect(@popCount(i8, x) == 2);35 expect(@popCount(i8, x) == 2);
36 }36 }
37 comptime {37 comptime {
38 expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2);38 expect(@popCount(u8, @bitCast(u8, @as(i8, -120))) == 2);
39 }39 }
40 comptime {40 comptime {
41 expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);41 expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
test/stage1/behavior/pub_enum.zig+1-1
...@@ -9,5 +9,5 @@ fn pubEnumTest(foo: other.APubEnum) void {...@@ -9,5 +9,5 @@ fn pubEnumTest(foo: other.APubEnum) void {
9}9}
1010
11test "cast with imported symbol" {11test "cast with imported symbol" {
12 expect(other.size_t(42) == 42);12 expect(@as(other.size_t, 42) == 42);
13}13}
test/stage1/behavior/shuffle.zig+13-13
...@@ -7,39 +7,39 @@ test "@shuffle" {...@@ -7,39 +7,39 @@ test "@shuffle" {
7 fn doTheTest() void {7 fn doTheTest() void {
8 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };8 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
9 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };9 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
10 const mask: @Vector(4, i32) = [4]i32{ 0, ~i32(2), 3, ~i32(3) };10 const mask: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) };
11 var res = @shuffle(i32, v, x, mask);11 var res = @shuffle(i32, v, x, mask);
12 expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 40, 4 }));12 expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 }));
1313
14 // Implicit cast from array (of mask)14 // Implicit cast from array (of mask)
15 res = @shuffle(i32, v, x, [4]i32{ 0, ~i32(2), 3, ~i32(3) });15 res = @shuffle(i32, v, x, [4]i32{ 0, ~@as(i32, 2), 3, ~@as(i32, 3) });
16 expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 40, 4 }));16 expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 40, 4 }));
1717
18 // Undefined18 // Undefined
19 const mask2: @Vector(4, i32) = [4]i32{ 3, 1, 2, 0 };19 const mask2: @Vector(4, i32) = [4]i32{ 3, 1, 2, 0 };
20 res = @shuffle(i32, v, undefined, mask2);20 res = @shuffle(i32, v, undefined, mask2);
21 expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 40, -2, 30, 2147483647 }));21 expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 40, -2, 30, 2147483647 }));
2222
23 // Upcasting of b23 // Upcasting of b
24 var v2: @Vector(2, i32) = [2]i32{ 2147483647, undefined };24 var v2: @Vector(2, i32) = [2]i32{ 2147483647, undefined };
25 const mask3: @Vector(4, i32) = [4]i32{ ~i32(0), 2, ~i32(0), 3 };25 const mask3: @Vector(4, i32) = [4]i32{ ~@as(i32, 0), 2, ~@as(i32, 0), 3 };
26 res = @shuffle(i32, x, v2, mask3);26 res = @shuffle(i32, x, v2, mask3);
27 expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, 2147483647, 4 }));27 expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, 2147483647, 4 }));
2828
29 // Upcasting of a29 // Upcasting of a
30 var v3: @Vector(2, i32) = [2]i32{ 2147483647, -2 };30 var v3: @Vector(2, i32) = [2]i32{ 2147483647, -2 };
31 const mask4: @Vector(4, i32) = [4]i32{ 0, ~i32(2), 1, ~i32(3) };31 const mask4: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 2), 1, ~@as(i32, 3) };
32 res = @shuffle(i32, v3, x, mask4);32 res = @shuffle(i32, v3, x, mask4);
33 expect(mem.eql(i32, ([4]i32)(res), [4]i32{ 2147483647, 3, -2, 4 }));33 expect(mem.eql(i32, @as([4]i32,res), [4]i32{ 2147483647, 3, -2, 4 }));
3434
35 // bool35 // bool
36 // Disabled because of #331736 // Disabled because of #3317
37 if (@import("builtin").arch != .mipsel) {37 if (@import("builtin").arch != .mipsel) {
38 var x2: @Vector(4, bool) = [4]bool{ false, true, false, true };38 var x2: @Vector(4, bool) = [4]bool{ false, true, false, true };
39 var v4: @Vector(2, bool) = [2]bool{ true, false };39 var v4: @Vector(2, bool) = [2]bool{ true, false };
40 const mask5: @Vector(4, i32) = [4]i32{ 0, ~i32(1), 1, 2 };40 const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
41 var res2 = @shuffle(bool, x2, v4, mask5);41 var res2 = @shuffle(bool, x2, v4, mask5);
42 expect(mem.eql(bool, ([4]bool)(res2), [4]bool{ false, false, true, false }));42 expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false }));
43 }43 }
4444
45 // TODO re-enable when LLVM codegen is fixed45 // TODO re-enable when LLVM codegen is fixed
...@@ -47,9 +47,9 @@ test "@shuffle" {...@@ -47,9 +47,9 @@ test "@shuffle" {
47 if (false) {47 if (false) {
48 var x2: @Vector(3, bool) = [3]bool{ false, true, false };48 var x2: @Vector(3, bool) = [3]bool{ false, true, false };
49 var v4: @Vector(2, bool) = [2]bool{ true, false };49 var v4: @Vector(2, bool) = [2]bool{ true, false };
50 const mask5: @Vector(4, i32) = [4]i32{ 0, ~i32(1), 1, 2 };50 const mask5: @Vector(4, i32) = [4]i32{ 0, ~@as(i32, 1), 1, 2 };
51 var res2 = @shuffle(bool, x2, v4, mask5);51 var res2 = @shuffle(bool, x2, v4, mask5);
52 expect(mem.eql(bool, ([4]bool)(res2), [4]bool{ false, false, true, false }));52 expect(mem.eql(bool, @as([4]bool,res2), [4]bool{ false, false, true, false }));
53 }53 }
54 }54 }
55 };55 };
test/stage1/behavior/slicetobytes.zig+1-1
...@@ -10,7 +10,7 @@ test "@sliceToBytes packed struct at runtime and comptime" {...@@ -10,7 +10,7 @@ test "@sliceToBytes packed struct at runtime and comptime" {
10 const S = struct {10 const S = struct {
11 fn doTheTest() void {11 fn doTheTest() void {
12 var foo: Foo = undefined;12 var foo: Foo = undefined;
13 var slice = @sliceToBytes(((*[1]Foo)(&foo))[0..1]);13 var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]);
14 slice[0] = 0x13;14 slice[0] = 0x13;
15 switch (builtin.endian) {15 switch (builtin.endian) {
16 builtin.Endian.Big => {16 builtin.Endian.Big => {
test/stage1/behavior/struct.zig+76-8
...@@ -388,8 +388,8 @@ test "runtime struct initialization of bitfield" {...@@ -388,8 +388,8 @@ test "runtime struct initialization of bitfield" {
388 expect(s2.y == @intCast(u4, x2));388 expect(s2.y == @intCast(u4, x2));
389}389}
390390
391var x1 = u4(1);391var x1 = @as(u4, 1);
392var x2 = u8(2);392var x2 = @as(u8, 2);
393393
394const Nibbles = packed struct {394const Nibbles = packed struct {
395 x: u4,395 x: u4,
...@@ -545,9 +545,9 @@ test "packed struct with fp fields" {...@@ -545,9 +545,9 @@ test "packed struct with fp fields" {
545 s.data[1] = 2.0;545 s.data[1] = 2.0;
546 s.data[2] = 3.0;546 s.data[2] = 3.0;
547 s.frob();547 s.frob();
548 expectEqual(f32(6.0), s.data[0]);548 expectEqual(@as(f32, 6.0), s.data[0]);
549 expectEqual(f32(11.0), s.data[1]);549 expectEqual(@as(f32, 11.0), s.data[1]);
550 expectEqual(f32(20.0), s.data[2]);550 expectEqual(@as(f32, 20.0), s.data[2]);
551}551}
552552
553test "use within struct scope" {553test "use within struct scope" {
...@@ -558,7 +558,7 @@ test "use within struct scope" {...@@ -558,7 +558,7 @@ test "use within struct scope" {
558 }558 }
559 };559 };
560 };560 };
561 expectEqual(i32(42), S.inner());561 expectEqual(@as(i32, 42), S.inner());
562}562}
563563
564test "default struct initialization fields" {564test "default struct initialization fields" {
...@@ -583,7 +583,7 @@ test "extern fn returns struct by value" {...@@ -583,7 +583,7 @@ test "extern fn returns struct by value" {
583 const S = struct {583 const S = struct {
584 fn entry() void {584 fn entry() void {
585 var x = makeBar(10);585 var x = makeBar(10);
586 expectEqual(i32(10), x.handle);586 expectEqual(@as(i32, 10), x.handle);
587 }587 }
588588
589 const ExternBar = extern struct {589 const ExternBar = extern struct {
...@@ -614,7 +614,7 @@ test "for loop over pointers to struct, getting field from struct pointer" {...@@ -614,7 +614,7 @@ test "for loop over pointers to struct, getting field from struct pointer" {
614614
615 const ArrayList = struct {615 const ArrayList = struct {
616 fn toSlice(self: *ArrayList) []*Foo {616 fn toSlice(self: *ArrayList) []*Foo {
617 return ([*]*Foo)(undefined)[0..0];617 return @as([*]*Foo, undefined)[0..0];
618 }618 }
619 };619 };
620620
...@@ -709,3 +709,71 @@ test "packed struct field passed to generic function" {...@@ -709,3 +709,71 @@ test "packed struct field passed to generic function" {
709 var loaded = S.genericReadPackedField(&p.b);709 var loaded = S.genericReadPackedField(&p.b);
710 expect(loaded == 29);710 expect(loaded == 29);
711}711}
712
713test "anonymous struct literal syntax" {
714 const S = struct {
715 const Point = struct {
716 x: i32,
717 y: i32,
718 };
719
720 fn doTheTest() void {
721 var p: Point = .{
722 .x = 1,
723 .y = 2,
724 };
725 expect(p.x == 1);
726 expect(p.y == 2);
727 }
728 };
729 S.doTheTest();
730 comptime S.doTheTest();
731}
732
733test "fully anonymous struct" {
734 const S = struct {
735 fn doTheTest() void {
736 dump(.{
737 .int = @as(u32, 1234),
738 .float = @as(f64, 12.34),
739 .b = true,
740 .s = "hi",
741 });
742 }
743 fn dump(args: var) void {
744 expect(args.int == 1234);
745 expect(args.float == 12.34);
746 expect(args.b);
747 expect(args.s[0] == 'h');
748 expect(args.s[1] == 'i');
749 }
750 };
751 S.doTheTest();
752 comptime S.doTheTest();
753}
754
755test "fully anonymous list literal" {
756 const S = struct {
757 fn doTheTest() void {
758 dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
759 }
760 fn dump(args: var) void {
761 expect(args.@"0" == 1234);
762 expect(args.@"1" == 12.34);
763 expect(args.@"2");
764 expect(args.@"3"[0] == 'h');
765 expect(args.@"3"[1] == 'i');
766 }
767 };
768 S.doTheTest();
769 comptime S.doTheTest();
770}
771
772test "anonymous struct literal assigned to variable" {
773 var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
774 expect(vec.@"0" == 22);
775 expect(vec.@"1" == 55);
776 expect(vec.@"2" == 99);
777 vec.@"1" += 1;
778 expect(vec.@"1" == 56);
779}
test/stage1/behavior/switch.zig+4-4
...@@ -68,7 +68,7 @@ test "switch statement" {...@@ -68,7 +68,7 @@ test "switch statement" {
68}68}
69fn nonConstSwitch(foo: SwitchStatmentFoo) void {69fn nonConstSwitch(foo: SwitchStatmentFoo) void {
70 const val = switch (foo) {70 const val = switch (foo) {
71 SwitchStatmentFoo.A => i32(1),71 SwitchStatmentFoo.A => @as(i32, 1),
72 SwitchStatmentFoo.B => 2,72 SwitchStatmentFoo.B => 2,
73 SwitchStatmentFoo.C => 3,73 SwitchStatmentFoo.C => 3,
74 SwitchStatmentFoo.D => 4,74 SwitchStatmentFoo.D => 4,
...@@ -127,7 +127,7 @@ test "switch with multiple expressions" {...@@ -127,7 +127,7 @@ test "switch with multiple expressions" {
127 const x = switch (returnsFive()) {127 const x = switch (returnsFive()) {
128 1, 2, 3 => 1,128 1, 2, 3 => 1,
129 4, 5, 6 => 2,129 4, 5, 6 => 2,
130 else => i32(3),130 else => @as(i32, 3),
131 };131 };
132 expect(x == 2);132 expect(x == 2);
133}133}
...@@ -186,7 +186,7 @@ fn testSwitchHandleAllCases() void {...@@ -186,7 +186,7 @@ fn testSwitchHandleAllCases() void {
186186
187fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {187fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
188 return switch (x) {188 return switch (x) {
189 0 => u2(3),189 0 => @as(u2, 3),
190 1 => 2,190 1 => 2,
191 2 => 1,191 2 => 1,
192 3 => 0,192 3 => 0,
...@@ -195,7 +195,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {...@@ -195,7 +195,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
195195
196fn testSwitchHandleAllCasesRange(x: u8) u8 {196fn testSwitchHandleAllCasesRange(x: u8) u8 {
197 return switch (x) {197 return switch (x) {
198 0...100 => u8(0),198 0...100 => @as(u8, 0),
199 101...200 => 1,199 101...200 => 1,
200 201, 203 => 2,200 201, 203 => 2,
201 202 => 4,201 202 => 4,
test/stage1/behavior/try.zig+3-3
...@@ -8,7 +8,7 @@ test "try on error union" {...@@ -8,7 +8,7 @@ test "try on error union" {
8fn tryOnErrorUnionImpl() void {8fn tryOnErrorUnionImpl() void {
9 const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {9 const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
10 error.ItBroke, error.NoMem => 1,10 error.ItBroke, error.NoMem => 1,
11 error.CrappedOut => i32(2),11 error.CrappedOut => @as(i32, 2),
12 else => unreachable,12 else => unreachable,
13 };13 };
14 expect(x == 11);14 expect(x == 11);
...@@ -19,10 +19,10 @@ fn returnsTen() anyerror!i32 {...@@ -19,10 +19,10 @@ fn returnsTen() anyerror!i32 {
19}19}
2020
21test "try without vars" {21test "try without vars" {
22 const result1 = if (failIfTrue(true)) 1 else |_| i32(2);22 const result1 = if (failIfTrue(true)) 1 else |_| @as(i32, 2);
23 expect(result1 == 2);23 expect(result1 == 2);
2424
25 const result2 = if (failIfTrue(false)) 1 else |_| i32(2);25 const result2 = if (failIfTrue(false)) 1 else |_| @as(i32, 2);
26 expect(result2 == 1);26 expect(result2 == 1);
27}27}
2828
test/stage1/behavior/type_info.zig+23-23
...@@ -13,7 +13,7 @@ test "type info: tag type, void info" {...@@ -13,7 +13,7 @@ test "type info: tag type, void info" {
13fn testBasic() void {13fn testBasic() void {
14 expect(@TagType(TypeInfo) == TypeId);14 expect(@TagType(TypeInfo) == TypeId);
15 const void_info = @typeInfo(void);15 const void_info = @typeInfo(void);
16 expect(TypeId(void_info) == TypeId.Void);16 expect(@as(TypeId, void_info) == TypeId.Void);
17 expect(void_info.Void == {});17 expect(void_info.Void == {});
18}18}
1919
...@@ -24,12 +24,12 @@ test "type info: integer, floating point type info" {...@@ -24,12 +24,12 @@ test "type info: integer, floating point type info" {
2424
25fn testIntFloat() void {25fn testIntFloat() void {
26 const u8_info = @typeInfo(u8);26 const u8_info = @typeInfo(u8);
27 expect(TypeId(u8_info) == TypeId.Int);27 expect(@as(TypeId, u8_info) == TypeId.Int);
28 expect(!u8_info.Int.is_signed);28 expect(!u8_info.Int.is_signed);
29 expect(u8_info.Int.bits == 8);29 expect(u8_info.Int.bits == 8);
3030
31 const f64_info = @typeInfo(f64);31 const f64_info = @typeInfo(f64);
32 expect(TypeId(f64_info) == TypeId.Float);32 expect(@as(TypeId, f64_info) == TypeId.Float);
33 expect(f64_info.Float.bits == 64);33 expect(f64_info.Float.bits == 64);
34}34}
3535
...@@ -40,7 +40,7 @@ test "type info: pointer type info" {...@@ -40,7 +40,7 @@ test "type info: pointer type info" {
4040
41fn testPointer() void {41fn testPointer() void {
42 const u32_ptr_info = @typeInfo(*u32);42 const u32_ptr_info = @typeInfo(*u32);
43 expect(TypeId(u32_ptr_info) == TypeId.Pointer);43 expect(@as(TypeId, u32_ptr_info) == TypeId.Pointer);
44 expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);44 expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
45 expect(u32_ptr_info.Pointer.is_const == false);45 expect(u32_ptr_info.Pointer.is_const == false);
46 expect(u32_ptr_info.Pointer.is_volatile == false);46 expect(u32_ptr_info.Pointer.is_volatile == false);
...@@ -55,7 +55,7 @@ test "type info: unknown length pointer type info" {...@@ -55,7 +55,7 @@ test "type info: unknown length pointer type info" {
5555
56fn testUnknownLenPtr() void {56fn testUnknownLenPtr() void {
57 const u32_ptr_info = @typeInfo([*]const volatile f64);57 const u32_ptr_info = @typeInfo([*]const volatile f64);
58 expect(TypeId(u32_ptr_info) == TypeId.Pointer);58 expect(@as(TypeId,u32_ptr_info) == TypeId.Pointer);
59 expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);59 expect(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
60 expect(u32_ptr_info.Pointer.is_const == true);60 expect(u32_ptr_info.Pointer.is_const == true);
61 expect(u32_ptr_info.Pointer.is_volatile == true);61 expect(u32_ptr_info.Pointer.is_volatile == true);
...@@ -70,7 +70,7 @@ test "type info: C pointer type info" {...@@ -70,7 +70,7 @@ test "type info: C pointer type info" {
7070
71fn testCPtr() void {71fn testCPtr() void {
72 const ptr_info = @typeInfo([*c]align(4) const i8);72 const ptr_info = @typeInfo([*c]align(4) const i8);
73 expect(TypeId(ptr_info) == TypeId.Pointer);73 expect(@as(TypeId,ptr_info) == TypeId.Pointer);
74 expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);74 expect(ptr_info.Pointer.size == TypeInfo.Pointer.Size.C);
75 expect(ptr_info.Pointer.is_const);75 expect(ptr_info.Pointer.is_const);
76 expect(!ptr_info.Pointer.is_volatile);76 expect(!ptr_info.Pointer.is_volatile);
...@@ -85,7 +85,7 @@ test "type info: slice type info" {...@@ -85,7 +85,7 @@ test "type info: slice type info" {
8585
86fn testSlice() void {86fn testSlice() void {
87 const u32_slice_info = @typeInfo([]u32);87 const u32_slice_info = @typeInfo([]u32);
88 expect(TypeId(u32_slice_info) == TypeId.Pointer);88 expect(@as(TypeId, u32_slice_info) == TypeId.Pointer);
89 expect(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);89 expect(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
90 expect(u32_slice_info.Pointer.is_const == false);90 expect(u32_slice_info.Pointer.is_const == false);
91 expect(u32_slice_info.Pointer.is_volatile == false);91 expect(u32_slice_info.Pointer.is_volatile == false);
...@@ -100,7 +100,7 @@ test "type info: array type info" {...@@ -100,7 +100,7 @@ test "type info: array type info" {
100100
101fn testArray() void {101fn testArray() void {
102 const arr_info = @typeInfo([42]bool);102 const arr_info = @typeInfo([42]bool);
103 expect(TypeId(arr_info) == TypeId.Array);103 expect(@as(TypeId, arr_info) == TypeId.Array);
104 expect(arr_info.Array.len == 42);104 expect(arr_info.Array.len == 42);
105 expect(arr_info.Array.child == bool);105 expect(arr_info.Array.child == bool);
106}106}
...@@ -112,7 +112,7 @@ test "type info: optional type info" {...@@ -112,7 +112,7 @@ test "type info: optional type info" {
112112
113fn testOptional() void {113fn testOptional() void {
114 const null_info = @typeInfo(?void);114 const null_info = @typeInfo(?void);
115 expect(TypeId(null_info) == TypeId.Optional);115 expect(@as(TypeId, null_info) == TypeId.Optional);
116 expect(null_info.Optional.child == void);116 expect(null_info.Optional.child == void);
117}117}
118118
...@@ -129,18 +129,18 @@ fn testErrorSet() void {...@@ -129,18 +129,18 @@ fn testErrorSet() void {
129 };129 };
130130
131 const error_set_info = @typeInfo(TestErrorSet);131 const error_set_info = @typeInfo(TestErrorSet);
132 expect(TypeId(error_set_info) == TypeId.ErrorSet);132 expect(@as(TypeId, error_set_info) == TypeId.ErrorSet);
133 expect(error_set_info.ErrorSet.?.len == 3);133 expect(error_set_info.ErrorSet.?.len == 3);
134 expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "First"));134 expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "First"));
135 expect(error_set_info.ErrorSet.?[2].value == @errorToInt(TestErrorSet.Third));135 expect(error_set_info.ErrorSet.?[2].value == @errorToInt(TestErrorSet.Third));
136136
137 const error_union_info = @typeInfo(TestErrorSet!usize);137 const error_union_info = @typeInfo(TestErrorSet!usize);
138 expect(TypeId(error_union_info) == TypeId.ErrorUnion);138 expect(@as(TypeId, error_union_info) == TypeId.ErrorUnion);
139 expect(error_union_info.ErrorUnion.error_set == TestErrorSet);139 expect(error_union_info.ErrorUnion.error_set == TestErrorSet);
140 expect(error_union_info.ErrorUnion.payload == usize);140 expect(error_union_info.ErrorUnion.payload == usize);
141141
142 const global_info = @typeInfo(anyerror);142 const global_info = @typeInfo(anyerror);
143 expect(TypeId(global_info) == TypeId.ErrorSet);143 expect(@as(TypeId, global_info) == TypeId.ErrorSet);
144 expect(global_info.ErrorSet == null);144 expect(global_info.ErrorSet == null);
145}145}
146146
...@@ -158,7 +158,7 @@ fn testEnum() void {...@@ -158,7 +158,7 @@ fn testEnum() void {
158 };158 };
159159
160 const os_info = @typeInfo(Os);160 const os_info = @typeInfo(Os);
161 expect(TypeId(os_info) == TypeId.Enum);161 expect(@as(TypeId, os_info) == TypeId.Enum);
162 expect(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);162 expect(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
163 expect(os_info.Enum.fields.len == 4);163 expect(os_info.Enum.fields.len == 4);
164 expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));164 expect(mem.eql(u8, os_info.Enum.fields[1].name, "Macos"));
...@@ -174,7 +174,7 @@ test "type info: union info" {...@@ -174,7 +174,7 @@ test "type info: union info" {
174174
175fn testUnion() void {175fn testUnion() void {
176 const typeinfo_info = @typeInfo(TypeInfo);176 const typeinfo_info = @typeInfo(TypeInfo);
177 expect(TypeId(typeinfo_info) == TypeId.Union);177 expect(@as(TypeId, typeinfo_info) == TypeId.Union);
178 expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);178 expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
179 expect(typeinfo_info.Union.tag_type.? == TypeId);179 expect(typeinfo_info.Union.tag_type.? == TypeId);
180 expect(typeinfo_info.Union.fields.len == 26);180 expect(typeinfo_info.Union.fields.len == 26);
...@@ -189,7 +189,7 @@ fn testUnion() void {...@@ -189,7 +189,7 @@ fn testUnion() void {
189 };189 };
190190
191 const notag_union_info = @typeInfo(TestNoTagUnion);191 const notag_union_info = @typeInfo(TestNoTagUnion);
192 expect(TypeId(notag_union_info) == TypeId.Union);192 expect(@as(TypeId, notag_union_info) == TypeId.Union);
193 expect(notag_union_info.Union.tag_type == null);193 expect(notag_union_info.Union.tag_type == null);
194 expect(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);194 expect(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
195 expect(notag_union_info.Union.fields.len == 2);195 expect(notag_union_info.Union.fields.len == 2);
...@@ -214,7 +214,7 @@ test "type info: struct info" {...@@ -214,7 +214,7 @@ test "type info: struct info" {
214214
215fn testStruct() void {215fn testStruct() void {
216 const struct_info = @typeInfo(TestStruct);216 const struct_info = @typeInfo(TestStruct);
217 expect(TypeId(struct_info) == TypeId.Struct);217 expect(@as(TypeId, struct_info) == TypeId.Struct);
218 expect(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);218 expect(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
219 expect(struct_info.Struct.fields.len == 3);219 expect(struct_info.Struct.fields.len == 3);
220 expect(struct_info.Struct.fields[1].offset == null);220 expect(struct_info.Struct.fields[1].offset == null);
...@@ -244,7 +244,7 @@ test "type info: function type info" {...@@ -244,7 +244,7 @@ test "type info: function type info" {
244244
245fn testFunction() void {245fn testFunction() void {
246 const fn_info = @typeInfo(@typeOf(foo));246 const fn_info = @typeInfo(@typeOf(foo));
247 expect(TypeId(fn_info) == TypeId.Fn);247 expect(@as(TypeId, fn_info) == TypeId.Fn);
248 expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);248 expect(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
249 expect(fn_info.Fn.is_generic);249 expect(fn_info.Fn.is_generic);
250 expect(fn_info.Fn.args.len == 2);250 expect(fn_info.Fn.args.len == 2);
...@@ -253,7 +253,7 @@ fn testFunction() void {...@@ -253,7 +253,7 @@ fn testFunction() void {
253253
254 const test_instance: TestStruct = undefined;254 const test_instance: TestStruct = undefined;
255 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));255 const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
256 expect(TypeId(bound_fn_info) == TypeId.BoundFn);256 expect(@as(TypeId, bound_fn_info) == TypeId.BoundFn);
257 expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);257 expect(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
258}258}
259259
...@@ -275,7 +275,7 @@ test "type info: vectors" {...@@ -275,7 +275,7 @@ test "type info: vectors" {
275275
276fn testVector() void {276fn testVector() void {
277 const vec_info = @typeInfo(@Vector(4, i32));277 const vec_info = @typeInfo(@Vector(4, i32));
278 expect(TypeId(vec_info) == TypeId.Vector);278 expect(@as(TypeId, vec_info) == TypeId.Vector);
279 expect(vec_info.Vector.len == 4);279 expect(vec_info.Vector.len == 4);
280 expect(vec_info.Vector.child == i32);280 expect(vec_info.Vector.child == i32);
281}281}
...@@ -288,13 +288,13 @@ test "type info: anyframe and anyframe->T" {...@@ -288,13 +288,13 @@ test "type info: anyframe and anyframe->T" {
288fn testAnyFrame() void {288fn testAnyFrame() void {
289 {289 {
290 const anyframe_info = @typeInfo(anyframe->i32);290 const anyframe_info = @typeInfo(anyframe->i32);
291 expect(TypeId(anyframe_info) == .AnyFrame);291 expect(@as(TypeId,anyframe_info) == .AnyFrame);
292 expect(anyframe_info.AnyFrame.child.? == i32);292 expect(anyframe_info.AnyFrame.child.? == i32);
293 }293 }
294294
295 {295 {
296 const anyframe_info = @typeInfo(anyframe);296 const anyframe_info = @typeInfo(anyframe);
297 expect(TypeId(anyframe_info) == .AnyFrame);297 expect(@as(TypeId,anyframe_info) == .AnyFrame);
298 expect(anyframe_info.AnyFrame.child == null);298 expect(anyframe_info.AnyFrame.child == null);
299 }299 }
300}300}
...@@ -334,7 +334,7 @@ test "type info: extern fns with and without lib names" {...@@ -334,7 +334,7 @@ test "type info: extern fns with and without lib names" {
334 if (std.mem.eql(u8, decl.name, "bar1")) {334 if (std.mem.eql(u8, decl.name, "bar1")) {
335 expect(decl.data.Fn.lib_name == null);335 expect(decl.data.Fn.lib_name == null);
336 } else {336 } else {
337 std.testing.expectEqual(([]const u8)("cool"), decl.data.Fn.lib_name.?);337 std.testing.expectEqual(@as([]const u8,"cool"), decl.data.Fn.lib_name.?);
338 }338 }
339 }339 }
340 }340 }
...@@ -342,7 +342,7 @@ test "type info: extern fns with and without lib names" {...@@ -342,7 +342,7 @@ test "type info: extern fns with and without lib names" {
342342
343test "data field is a compile-time value" {343test "data field is a compile-time value" {
344 const S = struct {344 const S = struct {
345 const Bar = isize(-1);345 const Bar = @as(isize, -1);
346 };346 };
347 comptime expect(@typeInfo(S).Struct.decls[0].data.Var == isize);347 comptime expect(@typeInfo(S).Struct.decls[0].data.Var == isize);
348}348}
test/stage1/behavior/union.zig+59-12
...@@ -14,7 +14,7 @@ const Agg = struct {...@@ -14,7 +14,7 @@ const Agg = struct {
14const v1 = Value{ .Int = 1234 };14const v1 = Value{ .Int = 1234 };
15const v2 = Value{ .Array = [_]u8{3} ** 9 };15const v2 = Value{ .Array = [_]u8{3} ** 9 };
1616
17const err = (anyerror!Agg)(Agg{17const err = @as(anyerror!Agg, Agg{
18 .val1 = v1,18 .val1 = v1,
19 .val2 = v2,19 .val2 = v2,
20});20});
...@@ -110,11 +110,11 @@ fn doTest() void {...@@ -110,11 +110,11 @@ fn doTest() void {
110}110}
111111
112fn bar(value: Payload) i32 {112fn bar(value: Payload) i32 {
113 expect(Letter(value) == Letter.A);113 expect(@as(Letter, value) == Letter.A);
114 return switch (value) {114 return switch (value) {
115 Payload.A => |x| return x - 1244,115 Payload.A => |x| return x - 1244,
116 Payload.B => |x| if (x == 12.34) i32(20) else 21,116 Payload.B => |x| if (x == 12.34) @as(i32, 20) else 21,
117 Payload.C => |x| if (x) i32(30) else 31,117 Payload.C => |x| if (x) @as(i32, 30) else 31,
118 };118 };
119}119}
120120
...@@ -127,7 +127,7 @@ const MultipleChoice = union(enum(u32)) {...@@ -127,7 +127,7 @@ const MultipleChoice = union(enum(u32)) {
127test "simple union(enum(u32))" {127test "simple union(enum(u32))" {
128 var x = MultipleChoice.C;128 var x = MultipleChoice.C;
129 expect(x == MultipleChoice.C);129 expect(x == MultipleChoice.C);
130 expect(@enumToInt(@TagType(MultipleChoice)(x)) == 60);130 expect(@enumToInt(@as(@TagType(MultipleChoice), x)) == 60);
131}131}
132132
133const MultipleChoice2 = union(enum(u32)) {133const MultipleChoice2 = union(enum(u32)) {
...@@ -149,11 +149,11 @@ test "union(enum(u32)) with specified and unspecified tag values" {...@@ -149,11 +149,11 @@ test "union(enum(u32)) with specified and unspecified tag values" {
149}149}
150150
151fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {151fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
152 expect(@enumToInt(@TagType(MultipleChoice2)(x)) == 60);152 expect(@enumToInt(@as(@TagType(MultipleChoice2), x)) == 60);
153 expect(1123 == switch (x) {153 expect(1123 == switch (x) {
154 MultipleChoice2.A => 1,154 MultipleChoice2.A => 1,
155 MultipleChoice2.B => 2,155 MultipleChoice2.B => 2,
156 MultipleChoice2.C => |v| i32(1000) + v,156 MultipleChoice2.C => |v| @as(i32, 1000) + v,
157 MultipleChoice2.D => 4,157 MultipleChoice2.D => 4,
158 MultipleChoice2.Unspecified1 => 5,158 MultipleChoice2.Unspecified1 => 5,
159 MultipleChoice2.Unspecified2 => 6,159 MultipleChoice2.Unspecified2 => 6,
...@@ -208,12 +208,12 @@ test "cast union to tag type of union" {...@@ -208,12 +208,12 @@ test "cast union to tag type of union" {
208}208}
209209
210fn testCastUnionToTagType(x: TheUnion) void {210fn testCastUnionToTagType(x: TheUnion) void {
211 expect(TheTag(x) == TheTag.B);211 expect(@as(TheTag, x) == TheTag.B);
212}212}
213213
214test "cast tag type of union to union" {214test "cast tag type of union to union" {
215 var x: Value2 = Letter2.B;215 var x: Value2 = Letter2.B;
216 expect(Letter2(x) == Letter2.B);216 expect(@as(Letter2, x) == Letter2.B);
217}217}
218const Letter2 = enum {218const Letter2 = enum {
219 A,219 A,
...@@ -297,7 +297,7 @@ const TaggedUnionWithAVoid = union(enum) {...@@ -297,7 +297,7 @@ const TaggedUnionWithAVoid = union(enum) {
297297
298fn testTaggedUnionInit(x: var) bool {298fn testTaggedUnionInit(x: var) bool {
299 const y = TaggedUnionWithAVoid{ .A = x };299 const y = TaggedUnionWithAVoid{ .A = x };
300 return @TagType(TaggedUnionWithAVoid)(y) == TaggedUnionWithAVoid.A;300 return @as(@TagType(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A;
301}301}
302302
303pub const UnionEnumNoPayloads = union(enum) {303pub const UnionEnumNoPayloads = union(enum) {
...@@ -326,7 +326,7 @@ test "union with only 1 field casted to its enum type" {...@@ -326,7 +326,7 @@ test "union with only 1 field casted to its enum type" {
326 var e = Expr{ .Literal = Literal{ .Bool = true } };326 var e = Expr{ .Literal = Literal{ .Bool = true } };
327 const Tag = @TagType(Expr);327 const Tag = @TagType(Expr);
328 comptime expect(@TagType(Tag) == u0);328 comptime expect(@TagType(Tag) == u0);
329 var t = Tag(e);329 var t = @as(Tag, e);
330 expect(t == Expr.Literal);330 expect(t == Expr.Literal);
331}331}
332332
...@@ -346,7 +346,7 @@ test "union with only 1 field casted to its enum type which has enum value speci...@@ -346,7 +346,7 @@ test "union with only 1 field casted to its enum type which has enum value speci
346346
347 var e = Expr{ .Literal = Literal{ .Bool = true } };347 var e = Expr{ .Literal = Literal{ .Bool = true } };
348 comptime expect(@TagType(Tag) == comptime_int);348 comptime expect(@TagType(Tag) == comptime_int);
349 var t = Tag(e);349 var t = @as(Tag, e);
350 expect(t == Expr.Literal);350 expect(t == Expr.Literal);
351 expect(@enumToInt(t) == 33);351 expect(@enumToInt(t) == 33);
352 comptime expect(@enumToInt(t) == 33);352 comptime expect(@enumToInt(t) == 33);
...@@ -535,3 +535,50 @@ test "global union with single field is correctly initialized" {...@@ -535,3 +535,50 @@ test "global union with single field is correctly initialized" {
535 };535 };
536 expect(glbl.f.x == 123);536 expect(glbl.f.x == 123);
537}537}
538
539pub const FooUnion = union(enum) {
540 U0: usize,
541 U1: u8,
542};
543
544var glbl_array: [2]FooUnion = undefined;
545
546test "initialize global array of union" {
547 glbl_array[1] = FooUnion{ .U1 = 2 };
548 glbl_array[0] = FooUnion{ .U0 = 1 };
549 expect(glbl_array[0].U0 == 1);
550 expect(glbl_array[1].U1 == 2);
551}
552
553test "anonymous union literal syntax" {
554 const S = struct {
555 const Number = union {
556 int: i32,
557 float: f64,
558 };
559
560 fn doTheTest() void {
561 var i: Number = .{ .int = 42 };
562 var f = makeNumber();
563 expect(i.int == 42);
564 expect(f.float == 12.34);
565 }
566
567 fn makeNumber() Number {
568 return .{ .float = 12.34 };
569 }
570 };
571 S.doTheTest();
572 comptime S.doTheTest();
573}
574
575test "update the tag value for zero-sized unions" {
576 const S = union(enum) {
577 U0: void,
578 U1: void,
579 };
580 var x = S{ .U0 = {} };
581 expect(x == .U0);
582 x = S{ .U1 = {} };
583 expect(x == .U1);
584}
test/stage1/behavior/var_args.zig+5-5
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const expect = @import("std").testing.expect;1const expect = @import("std").testing.expect;
22
3fn add(args: ...) i32 {3fn add(args: ...) i32 {
4 var sum = i32(0);4 var sum = @as(i32, 0);
5 {5 {
6 comptime var i: usize = 0;6 comptime var i: usize = 0;
7 inline while (i < args.len) : (i += 1) {7 inline while (i < args.len) : (i += 1) {
...@@ -12,8 +12,8 @@ fn add(args: ...) i32 {...@@ -12,8 +12,8 @@ fn add(args: ...) i32 {
12}12}
1313
14test "add arbitrary args" {14test "add arbitrary args" {
15 expect(add(i32(1), i32(2), i32(3), i32(4)) == 10);15 expect(add(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
16 expect(add(i32(1234)) == 1234);16 expect(add(@as(i32, 1234)) == 1234);
17 expect(add() == 0);17 expect(add() == 0);
18}18}
1919
...@@ -26,8 +26,8 @@ test "send void arg to var args" {...@@ -26,8 +26,8 @@ test "send void arg to var args" {
26}26}
2727
28test "pass args directly" {28test "pass args directly" {
29 expect(addSomeStuff(i32(1), i32(2), i32(3), i32(4)) == 10);29 expect(addSomeStuff(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
30 expect(addSomeStuff(i32(1234)) == 1234);30 expect(addSomeStuff(@as(i32, 1234)) == 1234);
31 expect(addSomeStuff() == 0);31 expect(addSomeStuff() == 0);
32}32}
3333
test/stage1/behavior/vector.zig+25-25
...@@ -20,11 +20,11 @@ test "vector wrap operators" {...@@ -20,11 +20,11 @@ test "vector wrap operators" {
20 fn doTheTest() void {20 fn doTheTest() void {
21 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };21 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
22 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };22 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 3, 4 };
23 expect(mem.eql(i32, ([4]i32)(v +% x), [4]i32{ -2147483648, 2147483645, 33, 44 }));23 expect(mem.eql(i32, @as([4]i32, v +% x), [4]i32{ -2147483648, 2147483645, 33, 44 }));
24 expect(mem.eql(i32, ([4]i32)(v -% x), [4]i32{ 2147483646, 2147483647, 27, 36 }));24 expect(mem.eql(i32, @as([4]i32, v -% x), [4]i32{ 2147483646, 2147483647, 27, 36 }));
25 expect(mem.eql(i32, ([4]i32)(v *% x), [4]i32{ 2147483647, 2, 90, 160 }));25 expect(mem.eql(i32, @as([4]i32, v *% x), [4]i32{ 2147483647, 2, 90, 160 }));
26 var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };26 var z: @Vector(4, i32) = [4]i32{ 1, 2, 3, -2147483648 };
27 expect(mem.eql(i32, ([4]i32)(-%z), [4]i32{ -1, -2, -3, -2147483648 }));27 expect(mem.eql(i32, @as([4]i32, -%z), [4]i32{ -1, -2, -3, -2147483648 }));
28 }28 }
29 };29 };
30 S.doTheTest();30 S.doTheTest();
...@@ -36,12 +36,12 @@ test "vector bin compares with mem.eql" {...@@ -36,12 +36,12 @@ test "vector bin compares with mem.eql" {
36 fn doTheTest() void {36 fn doTheTest() void {
37 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };37 var v: @Vector(4, i32) = [4]i32{ 2147483647, -2, 30, 40 };
38 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };38 var x: @Vector(4, i32) = [4]i32{ 1, 2147483647, 30, 4 };
39 expect(mem.eql(bool, ([4]bool)(v == x), [4]bool{ false, false, true, false }));39 expect(mem.eql(bool, @as([4]bool, v == x), [4]bool{ false, false, true, false }));
40 expect(mem.eql(bool, ([4]bool)(v != x), [4]bool{ true, true, false, true }));40 expect(mem.eql(bool, @as([4]bool, v != x), [4]bool{ true, true, false, true }));
41 expect(mem.eql(bool, ([4]bool)(v < x), [4]bool{ false, true, false, false }));41 expect(mem.eql(bool, @as([4]bool, v < x), [4]bool{ false, true, false, false }));
42 expect(mem.eql(bool, ([4]bool)(v > x), [4]bool{ true, false, false, true }));42 expect(mem.eql(bool, @as([4]bool, v > x), [4]bool{ true, false, false, true }));
43 expect(mem.eql(bool, ([4]bool)(v <= x), [4]bool{ false, true, true, false }));43 expect(mem.eql(bool, @as([4]bool, v <= x), [4]bool{ false, true, true, false }));
44 expect(mem.eql(bool, ([4]bool)(v >= x), [4]bool{ true, false, true, true }));44 expect(mem.eql(bool, @as([4]bool, v >= x), [4]bool{ true, false, true, true }));
45 }45 }
46 };46 };
47 S.doTheTest();47 S.doTheTest();
...@@ -53,10 +53,10 @@ test "vector int operators" {...@@ -53,10 +53,10 @@ test "vector int operators" {
53 fn doTheTest() void {53 fn doTheTest() void {
54 var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };54 var v: @Vector(4, i32) = [4]i32{ 10, 20, 30, 40 };
55 var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };55 var x: @Vector(4, i32) = [4]i32{ 1, 2, 3, 4 };
56 expect(mem.eql(i32, ([4]i32)(v + x), [4]i32{ 11, 22, 33, 44 }));56 expect(mem.eql(i32, @as([4]i32, v + x), [4]i32{ 11, 22, 33, 44 }));
57 expect(mem.eql(i32, ([4]i32)(v - x), [4]i32{ 9, 18, 27, 36 }));57 expect(mem.eql(i32, @as([4]i32, v - x), [4]i32{ 9, 18, 27, 36 }));
58 expect(mem.eql(i32, ([4]i32)(v * x), [4]i32{ 10, 40, 90, 160 }));58 expect(mem.eql(i32, @as([4]i32, v * x), [4]i32{ 10, 40, 90, 160 }));
59 expect(mem.eql(i32, ([4]i32)(-v), [4]i32{ -10, -20, -30, -40 }));59 expect(mem.eql(i32, @as([4]i32, -v), [4]i32{ -10, -20, -30, -40 }));
60 }60 }
61 };61 };
62 S.doTheTest();62 S.doTheTest();
...@@ -68,10 +68,10 @@ test "vector float operators" {...@@ -68,10 +68,10 @@ test "vector float operators" {
68 fn doTheTest() void {68 fn doTheTest() void {
69 var v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 };69 var v: @Vector(4, f32) = [4]f32{ 10, 20, 30, 40 };
70 var x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 };70 var x: @Vector(4, f32) = [4]f32{ 1, 2, 3, 4 };
71 expect(mem.eql(f32, ([4]f32)(v + x), [4]f32{ 11, 22, 33, 44 }));71 expect(mem.eql(f32, @as([4]f32, v + x), [4]f32{ 11, 22, 33, 44 }));
72 expect(mem.eql(f32, ([4]f32)(v - x), [4]f32{ 9, 18, 27, 36 }));72 expect(mem.eql(f32, @as([4]f32, v - x), [4]f32{ 9, 18, 27, 36 }));
73 expect(mem.eql(f32, ([4]f32)(v * x), [4]f32{ 10, 40, 90, 160 }));73 expect(mem.eql(f32, @as([4]f32, v * x), [4]f32{ 10, 40, 90, 160 }));
74 expect(mem.eql(f32, ([4]f32)(-x), [4]f32{ -1, -2, -3, -4 }));74 expect(mem.eql(f32, @as([4]f32, -x), [4]f32{ -1, -2, -3, -4 }));
75 }75 }
76 };76 };
77 S.doTheTest();77 S.doTheTest();
...@@ -83,9 +83,9 @@ test "vector bit operators" {...@@ -83,9 +83,9 @@ test "vector bit operators" {
83 fn doTheTest() void {83 fn doTheTest() void {
84 var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };84 var v: @Vector(4, u8) = [4]u8{ 0b10101010, 0b10101010, 0b10101010, 0b10101010 };
85 var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };85 var x: @Vector(4, u8) = [4]u8{ 0b11110000, 0b00001111, 0b10101010, 0b01010101 };
86 expect(mem.eql(u8, ([4]u8)(v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));86 expect(mem.eql(u8, @as([4]u8, v ^ x), [4]u8{ 0b01011010, 0b10100101, 0b00000000, 0b11111111 }));
87 expect(mem.eql(u8, ([4]u8)(v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));87 expect(mem.eql(u8, @as([4]u8, v | x), [4]u8{ 0b11111010, 0b10101111, 0b10101010, 0b11111111 }));
88 expect(mem.eql(u8, ([4]u8)(v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));88 expect(mem.eql(u8, @as([4]u8, v & x), [4]u8{ 0b10100000, 0b00001010, 0b10101010, 0b00000000 }));
89 }89 }
90 };90 };
91 S.doTheTest();91 S.doTheTest();
...@@ -120,22 +120,22 @@ test "vector casts of sizes not divisable by 8" {...@@ -120,22 +120,22 @@ test "vector casts of sizes not divisable by 8" {
120 {120 {
121 var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };121 var v: @Vector(4, u3) = [4]u3{ 5, 2, 3, 0 };
122 var x: [4]u3 = v;122 var x: [4]u3 = v;
123 expect(mem.eql(u3, x, ([4]u3)(v)));123 expect(mem.eql(u3, x, @as([4]u3, v)));
124 }124 }
125 {125 {
126 var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };126 var v: @Vector(4, u2) = [4]u2{ 1, 2, 3, 0 };
127 var x: [4]u2 = v;127 var x: [4]u2 = v;
128 expect(mem.eql(u2, x, ([4]u2)(v)));128 expect(mem.eql(u2, x, @as([4]u2, v)));
129 }129 }
130 {130 {
131 var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };131 var v: @Vector(4, u1) = [4]u1{ 1, 0, 1, 0 };
132 var x: [4]u1 = v;132 var x: [4]u1 = v;
133 expect(mem.eql(u1, x, ([4]u1)(v)));133 expect(mem.eql(u1, x, @as([4]u1, v)));
134 }134 }
135 {135 {
136 var v: @Vector(4, bool) = [4]bool{ false, false, true, false };136 var v: @Vector(4, bool) = [4]bool{ false, false, true, false };
137 var x: [4]bool = v;137 var x: [4]bool = v;
138 expect(mem.eql(bool, x, ([4]bool)(v)));138 expect(mem.eql(bool, x, @as([4]bool, v)));
139 }139 }
140 }140 }
141 };141 };
test/stage1/behavior/void.zig+1-1
...@@ -26,7 +26,7 @@ test "iterate over a void slice" {...@@ -26,7 +26,7 @@ test "iterate over a void slice" {
26}26}
2727
28fn times(n: usize) []const void {28fn times(n: usize) []const void {
29 return ([*]void)(undefined)[0..n];29 return @as([*]void, undefined)[0..n];
30}30}
3131
32test "void optional" {32test "void optional" {
test/stage1/behavior/while.zig+8-8
...@@ -137,7 +137,7 @@ test "while on optional with else result follow else prong" {...@@ -137,7 +137,7 @@ test "while on optional with else result follow else prong" {
137 const result = while (returnNull()) |value| {137 const result = while (returnNull()) |value| {
138 break value;138 break value;
139 } else139 } else
140 i32(2);140 @as(i32, 2);
141 expect(result == 2);141 expect(result == 2);
142}142}
143143
...@@ -145,7 +145,7 @@ test "while on optional with else result follow break prong" {...@@ -145,7 +145,7 @@ test "while on optional with else result follow break prong" {
145 const result = while (returnOptional(10)) |value| {145 const result = while (returnOptional(10)) |value| {
146 break value;146 break value;
147 } else147 } else
148 i32(2);148 @as(i32, 2);
149 expect(result == 10);149 expect(result == 10);
150}150}
151151
...@@ -153,7 +153,7 @@ test "while on error union with else result follow else prong" {...@@ -153,7 +153,7 @@ test "while on error union with else result follow else prong" {
153 const result = while (returnError()) |value| {153 const result = while (returnError()) |value| {
154 break value;154 break value;
155 } else |err|155 } else |err|
156 i32(2);156 @as(i32, 2);
157 expect(result == 2);157 expect(result == 2);
158}158}
159159
...@@ -161,23 +161,23 @@ test "while on error union with else result follow break prong" {...@@ -161,23 +161,23 @@ test "while on error union with else result follow break prong" {
161 const result = while (returnSuccess(10)) |value| {161 const result = while (returnSuccess(10)) |value| {
162 break value;162 break value;
163 } else |err|163 } else |err|
164 i32(2);164 @as(i32, 2);
165 expect(result == 10);165 expect(result == 10);
166}166}
167167
168test "while on bool with else result follow else prong" {168test "while on bool with else result follow else prong" {
169 const result = while (returnFalse()) {169 const result = while (returnFalse()) {
170 break i32(10);170 break @as(i32, 10);
171 } else171 } else
172 i32(2);172 @as(i32, 2);
173 expect(result == 2);173 expect(result == 2);
174}174}
175175
176test "while on bool with else result follow break prong" {176test "while on bool with else result follow break prong" {
177 const result = while (returnTrue()) {177 const result = while (returnTrue()) {
178 break i32(10);178 break @as(i32, 10);
179 } else179 } else
180 i32(2);180 @as(i32, 2);
181 expect(result == 10);181 expect(result == 10);
182}182}
183183
test/standalone/brace_expansion/main.zig+2-2
...@@ -179,8 +179,8 @@ fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {...@@ -179,8 +179,8 @@ fn expandNode(node: Node, output: *ArrayList(Buffer)) ExpandNodeError!void {
179}179}
180180
181pub fn main() !void {181pub fn main() !void {
182 var stdin_file = try io.getStdIn();182 const stdin_file = io.getStdIn();
183 var stdout_file = try io.getStdOut();183 const stdout_file = io.getStdOut();
184184
185 var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator);185 var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator);
186 defer arena.deinit();186 defer arena.deinit();
test/standalone/cat/main.zig+6-8
...@@ -10,30 +10,28 @@ pub fn main() !void {...@@ -10,30 +10,28 @@ pub fn main() !void {
10 var args_it = process.args();10 var args_it = process.args();
11 const exe = try unwrapArg(args_it.next(allocator).?);11 const exe = try unwrapArg(args_it.next(allocator).?);
12 var catted_anything = false;12 var catted_anything = false;
13 var stdout_file = try io.getStdOut();13 const stdout_file = io.getStdOut();
1414
15 while (args_it.next(allocator)) |arg_or_err| {15 while (args_it.next(allocator)) |arg_or_err| {
16 const arg = try unwrapArg(arg_or_err);16 const arg = try unwrapArg(arg_or_err);
17 if (mem.eql(u8, arg, "-")) {17 if (mem.eql(u8, arg, "-")) {
18 catted_anything = true;18 catted_anything = true;
19 var stdin_file = try io.getStdIn();19 try cat_file(stdout_file, io.getStdIn());
20 try cat_file(&stdout_file, &stdin_file);
21 } else if (arg[0] == '-') {20 } else if (arg[0] == '-') {
22 return usage(exe);21 return usage(exe);
23 } else {22 } else {
24 var file = File.openRead(arg) catch |err| {23 const file = File.openRead(arg) catch |err| {
25 warn("Unable to open file: {}\n", @errorName(err));24 warn("Unable to open file: {}\n", @errorName(err));
26 return err;25 return err;
27 };26 };
28 defer file.close();27 defer file.close();
2928
30 catted_anything = true;29 catted_anything = true;
31 try cat_file(&stdout_file, &file);30 try cat_file(stdout_file, file);
32 }31 }
33 }32 }
34 if (!catted_anything) {33 if (!catted_anything) {
35 var stdin_file = try io.getStdIn();34 try cat_file(stdout_file, io.getStdIn());
36 try cat_file(&stdout_file, &stdin_file);
37 }35 }
38}36}
3937
...@@ -42,7 +40,7 @@ fn usage(exe: []const u8) !void {...@@ -42,7 +40,7 @@ fn usage(exe: []const u8) !void {
42 return error.Invalid;40 return error.Invalid;
43}41}
4442
45fn cat_file(stdout: *File, file: *File) !void {43fn cat_file(stdout: File, file: File) !void {
46 var buf: [1024 * 4]u8 = undefined;44 var buf: [1024 * 4]u8 = undefined;
4745
48 while (true) {46 while (true) {
test/standalone/guess_number/main.zig+1-2
...@@ -4,8 +4,7 @@ const io = std.io;...@@ -4,8 +4,7 @@ const io = std.io;
4const fmt = std.fmt;4const fmt = std.fmt;
55
6pub fn main() !void {6pub fn main() !void {
7 var stdout_file = try io.getStdOut();7 const stdout = &io.getStdOut().outStream().stream;
8 const stdout = &stdout_file.outStream().stream;
98
10 try stdout.print("Welcome to the Guess Number Game in Zig.\n");9 try stdout.print("Welcome to the Guess Number Game in Zig.\n");
1110
test/standalone/hello_world/hello.zig+1-2
...@@ -1,8 +1,7 @@...@@ -1,8 +1,7 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() !void {3pub fn main() !void {
4 // If this program is run without stdout attached, exit with an error.4 const stdout_file = std.io.getStdOut();
5 const stdout_file = try std.io.getStdOut();
6 // If this program encounters pipe failure when printing to stdout, exit5 // If this program encounters pipe failure when printing to stdout, exit
7 // with an error.6 // with an error.
8 try stdout_file.write("Hello, world!\n");7 try stdout_file.write("Hello, world!\n");
test/tests.zig+2-2
...@@ -411,7 +411,7 @@ pub fn addPkgTests(...@@ -411,7 +411,7 @@ pub fn addPkgTests(
411 const ArchTag = @TagType(builtin.Arch);411 const ArchTag = @TagType(builtin.Arch);
412 if (test_target.disable_native and412 if (test_target.disable_native and
413 test_target.target.getOs() == builtin.os and413 test_target.target.getOs() == builtin.os and
414 ArchTag(test_target.target.getArch()) == ArchTag(builtin.arch))414 @as(ArchTag,test_target.target.getArch()) == @as(ArchTag,builtin.arch))
415 {415 {
416 continue;416 continue;
417 }417 }
...@@ -429,7 +429,7 @@ pub fn addPkgTests(...@@ -429,7 +429,7 @@ pub fn addPkgTests(
429 "bare";429 "bare";
430430
431 const triple_prefix = if (test_target.target == .Native)431 const triple_prefix = if (test_target.target == .Native)
432 ([]const u8)("native")432 @as([]const u8,"native")
433 else433 else
434 test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;434 test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;
435435
test/translate_c.zig+66-57
...@@ -28,9 +28,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -28,9 +28,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
28 ,28 ,
29 \\pub fn foo() void {29 \\pub fn foo() void {
30 \\ var a: c_int = undefined;30 \\ var a: c_int = undefined;
31 \\ var b: u8 = u8(123);31 \\ var b: u8 = @as(u8, 123);
32 \\ const c: c_int = undefined;32 \\ const c: c_int = undefined;
33 \\ const d: c_uint = c_uint(440);33 \\ const d: c_uint = @as(c_uint, 440);
34 \\}34 \\}
35 );35 );
3636
...@@ -144,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -144,7 +144,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
144 \\pub extern fn foo() void;144 \\pub extern fn foo() void;
145 \\pub fn bar() void {145 \\pub fn bar() void {
146 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);146 \\ var func_ptr: ?*c_void = @ptrCast(?*c_void, foo);
147 \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, c_ulong(@ptrToInt(func_ptr)));147 \\ var typed_func_ptr: ?extern fn () void = @intToPtr(?extern fn () void, @as(c_ulong, @ptrToInt(func_ptr)));
148 \\}148 \\}
149 );149 );
150150
...@@ -561,43 +561,43 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -561,43 +561,43 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
561 cases.add("u integer suffix after hex literal",561 cases.add("u integer suffix after hex literal",
562 \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */562 \\#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
563 ,563 ,
564 \\pub const SDL_INIT_VIDEO = c_uint(32);564 \\pub const SDL_INIT_VIDEO = @as(c_uint, 32);
565 );565 );
566566
567 cases.add("l integer suffix after hex literal",567 cases.add("l integer suffix after hex literal",
568 \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */568 \\#define SDL_INIT_VIDEO 0x00000020l /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
569 ,569 ,
570 \\pub const SDL_INIT_VIDEO = c_long(32);570 \\pub const SDL_INIT_VIDEO = @as(c_long, 32);
571 );571 );
572572
573 cases.add("ul integer suffix after hex literal",573 cases.add("ul integer suffix after hex literal",
574 \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */574 \\#define SDL_INIT_VIDEO 0x00000020ul /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
575 ,575 ,
576 \\pub const SDL_INIT_VIDEO = c_ulong(32);576 \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
577 );577 );
578578
579 cases.add("lu integer suffix after hex literal",579 cases.add("lu integer suffix after hex literal",
580 \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */580 \\#define SDL_INIT_VIDEO 0x00000020lu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
581 ,581 ,
582 \\pub const SDL_INIT_VIDEO = c_ulong(32);582 \\pub const SDL_INIT_VIDEO = @as(c_ulong, 32);
583 );583 );
584584
585 cases.add("ll integer suffix after hex literal",585 cases.add("ll integer suffix after hex literal",
586 \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */586 \\#define SDL_INIT_VIDEO 0x00000020ll /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
587 ,587 ,
588 \\pub const SDL_INIT_VIDEO = c_longlong(32);588 \\pub const SDL_INIT_VIDEO = @as(c_longlong, 32);
589 );589 );
590590
591 cases.add("ull integer suffix after hex literal",591 cases.add("ull integer suffix after hex literal",
592 \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */592 \\#define SDL_INIT_VIDEO 0x00000020ull /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
593 ,593 ,
594 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);594 \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
595 );595 );
596596
597 cases.add("llu integer suffix after hex literal",597 cases.add("llu integer suffix after hex literal",
598 \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */598 \\#define SDL_INIT_VIDEO 0x00000020llu /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
599 ,599 ,
600 \\pub const SDL_INIT_VIDEO = c_ulonglong(32);600 \\pub const SDL_INIT_VIDEO = @as(c_ulonglong, 32);
601 );601 );
602602
603 cases.add("zig keywords in C code",603 cases.add("zig keywords in C code",
...@@ -676,8 +676,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -676,8 +676,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
676 \\pub export fn log2(_arg_a: c_uint) c_int {676 \\pub export fn log2(_arg_a: c_uint) c_int {
677 \\ var a = _arg_a;677 \\ var a = _arg_a;
678 \\ var i: c_int = 0;678 \\ var i: c_int = 0;
679 \\ while (a > c_uint(0)) {679 \\ while (a > @as(c_uint, 0)) {
680 \\ a >>= @import("std").math.Log2Int(c_uint)(1);680 \\ a >>= @as(@import("std").math.Log2Int(c_uint), 1);
681 \\ }681 \\ }
682 \\ return i;682 \\ return i;
683 \\}683 \\}
...@@ -848,8 +848,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -848,8 +848,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
848 \\pub export fn log2(_arg_a: u32) c_int {848 \\pub export fn log2(_arg_a: u32) c_int {
849 \\ var a = _arg_a;849 \\ var a = _arg_a;
850 \\ var i: c_int = 0;850 \\ var i: c_int = 0;
851 \\ while (a > c_uint(0)) {851 \\ while (a > @as(c_uint, 0)) {
852 \\ a >>= u5(1);852 \\ a >>= @as(u5, 1);
853 \\ }853 \\ }
854 \\ return i;854 \\ return i;
855 \\}855 \\}
...@@ -937,7 +937,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -937,7 +937,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
937 \\}937 \\}
938 ,938 ,
939 \\pub export fn float_to_int(a: f32) c_int {939 \\pub export fn float_to_int(a: f32) c_int {
940 \\ return c_int(a);940 \\ return @as(c_int, a);
941 \\}941 \\}
942 );942 );
943943
...@@ -1027,7 +1027,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1027,7 +1027,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1027 \\}1027 \\}
1028 ,1028 ,
1029 \\pub export fn foo() c_int {1029 \\pub export fn foo() c_int {
1030 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);1030 \\ return (1 << @as(@import("std").math.Log2Int(c_int), 2)) >> @as(@import("std").math.Log2Int(c_int), 1);
1031 \\}1031 \\}
1032 );1032 );
10331033
...@@ -1076,14 +1076,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1076,14 +1076,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1076 \\ _ref.* = (_ref.* ^ 1);1076 \\ _ref.* = (_ref.* ^ 1);
1077 \\ break :x _ref.*;1077 \\ break :x _ref.*;
1078 \\ });1078 \\ });
1079 \\ a >>= @import("std").math.Log2Int(c_int)((x: {1079 \\ a >>= @as(@import("std").math.Log2Int(c_int), (x: {
1080 \\ const _ref = &a;1080 \\ const _ref = &a;
1081 \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));1081 \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_int), 1));
1082 \\ break :x _ref.*;1082 \\ break :x _ref.*;
1083 \\ }));1083 \\ }));
1084 \\ a <<= @import("std").math.Log2Int(c_int)((x: {1084 \\ a <<= @as(@import("std").math.Log2Int(c_int), (x: {
1085 \\ const _ref = &a;1085 \\ const _ref = &a;
1086 \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));1086 \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_int), 1));
1087 \\ break :x _ref.*;1087 \\ break :x _ref.*;
1088 \\ }));1088 \\ }));
1089 \\}1089 \\}
...@@ -1103,45 +1103,45 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1103,45 +1103,45 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1103 \\}1103 \\}
1104 ,1104 ,
1105 \\pub export fn foo() void {1105 \\pub export fn foo() void {
1106 \\ var a: c_uint = c_uint(0);1106 \\ var a: c_uint = @as(c_uint, 0);
1107 \\ a +%= (x: {1107 \\ a +%= (x: {
1108 \\ const _ref = &a;1108 \\ const _ref = &a;
1109 \\ _ref.* = (_ref.* +% c_uint(1));1109 \\ _ref.* = (_ref.* +% @as(c_uint, 1));
1110 \\ break :x _ref.*;1110 \\ break :x _ref.*;
1111 \\ });1111 \\ });
1112 \\ a -%= (x: {1112 \\ a -%= (x: {
1113 \\ const _ref = &a;1113 \\ const _ref = &a;
1114 \\ _ref.* = (_ref.* -% c_uint(1));1114 \\ _ref.* = (_ref.* -% @as(c_uint, 1));
1115 \\ break :x _ref.*;1115 \\ break :x _ref.*;
1116 \\ });1116 \\ });
1117 \\ a *%= (x: {1117 \\ a *%= (x: {
1118 \\ const _ref = &a;1118 \\ const _ref = &a;
1119 \\ _ref.* = (_ref.* *% c_uint(1));1119 \\ _ref.* = (_ref.* *% @as(c_uint, 1));
1120 \\ break :x _ref.*;1120 \\ break :x _ref.*;
1121 \\ });1121 \\ });
1122 \\ a &= (x: {1122 \\ a &= (x: {
1123 \\ const _ref = &a;1123 \\ const _ref = &a;
1124 \\ _ref.* = (_ref.* & c_uint(1));1124 \\ _ref.* = (_ref.* & @as(c_uint, 1));
1125 \\ break :x _ref.*;1125 \\ break :x _ref.*;
1126 \\ });1126 \\ });
1127 \\ a |= (x: {1127 \\ a |= (x: {
1128 \\ const _ref = &a;1128 \\ const _ref = &a;
1129 \\ _ref.* = (_ref.* | c_uint(1));1129 \\ _ref.* = (_ref.* | @as(c_uint, 1));
1130 \\ break :x _ref.*;1130 \\ break :x _ref.*;
1131 \\ });1131 \\ });
1132 \\ a ^= (x: {1132 \\ a ^= (x: {
1133 \\ const _ref = &a;1133 \\ const _ref = &a;
1134 \\ _ref.* = (_ref.* ^ c_uint(1));1134 \\ _ref.* = (_ref.* ^ @as(c_uint, 1));
1135 \\ break :x _ref.*;1135 \\ break :x _ref.*;
1136 \\ });1136 \\ });
1137 \\ a >>= @import("std").math.Log2Int(c_uint)((x: {1137 \\ a >>= @as(@import("std").math.Log2Int(c_uint), (x: {
1138 \\ const _ref = &a;1138 \\ const _ref = &a;
1139 \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));1139 \\ _ref.* = (_ref.* >> @as(@import("std").math.Log2Int(c_uint), 1));
1140 \\ break :x _ref.*;1140 \\ break :x _ref.*;
1141 \\ }));1141 \\ }));
1142 \\ a <<= @import("std").math.Log2Int(c_uint)((x: {1142 \\ a <<= @as(@import("std").math.Log2Int(c_uint), (x: {
1143 \\ const _ref = &a;1143 \\ const _ref = &a;
1144 \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));1144 \\ _ref.* = (_ref.* << @as(@import("std").math.Log2Int(c_uint), 1));
1145 \\ break :x _ref.*;1145 \\ break :x _ref.*;
1146 \\ }));1146 \\ }));
1147 \\}1147 \\}
...@@ -1174,7 +1174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1174,7 +1174,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1174 ,1174 ,
1175 \\pub export fn foo() void {1175 \\pub export fn foo() void {
1176 \\ var i: c_int = 0;1176 \\ var i: c_int = 0;
1177 \\ var u: c_uint = c_uint(0);1177 \\ var u: c_uint = @as(c_uint, 0);
1178 \\ i += 1;1178 \\ i += 1;
1179 \\ i -= 1;1179 \\ i -= 1;
1180 \\ u +%= 1;1180 \\ u +%= 1;
...@@ -1222,7 +1222,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1222,7 +1222,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1222 ,1222 ,
1223 \\pub export fn foo() void {1223 \\pub export fn foo() void {
1224 \\ var i: c_int = 0;1224 \\ var i: c_int = 0;
1225 \\ var u: c_uint = c_uint(0);1225 \\ var u: c_uint = @as(c_uint, 0);
1226 \\ i += 1;1226 \\ i += 1;
1227 \\ i -= 1;1227 \\ i -= 1;
1228 \\ u +%= 1;1228 \\ u +%= 1;
...@@ -1539,7 +1539,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1539,7 +1539,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1539 cases.add("macro pointer cast",1539 cases.add("macro pointer cast",
1540 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1540 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1541 ,1541 ,
1542 \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*c]NRF_GPIO_Type)(NRF_GPIO_BASE);1542 \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
1543 );1543 );
15441544
1545 cases.add("if on non-bool",1545 cases.add("if on non-bool",
...@@ -1564,7 +1564,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1564,7 +1564,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1564 \\ if (a != 0) return 0;1564 \\ if (a != 0) return 0;
1565 \\ if (b != 0) return 1;1565 \\ if (b != 0) return 1;
1566 \\ if (c != null) return 2;1566 \\ if (c != null) return 2;
1567 \\ if (d != @bitCast(enum_SomeEnum, @TagType(enum_SomeEnum)(0))) return 3;1567 \\ if (d != @bitCast(enum_SomeEnum, @as(@TagType(enum_SomeEnum), 0))) return 3;
1568 \\ return 4;1568 \\ return 4;
1569 \\}1569 \\}
1570 );1570 );
...@@ -1646,49 +1646,49 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1646,49 +1646,49 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1646 cases.addC(1646 cases.addC(
1647 "u integer suffix after 0 (zero) in macro definition",1647 "u integer suffix after 0 (zero) in macro definition",
1648 "#define ZERO 0U",1648 "#define ZERO 0U",
1649 "pub const ZERO = c_uint(0);",1649 "pub const ZERO = @as(c_uint, 0);",
1650 );1650 );
16511651
1652 cases.addC(1652 cases.addC(
1653 "l integer suffix after 0 (zero) in macro definition",1653 "l integer suffix after 0 (zero) in macro definition",
1654 "#define ZERO 0L",1654 "#define ZERO 0L",
1655 "pub const ZERO = c_long(0);",1655 "pub const ZERO = @as(c_long, 0);",
1656 );1656 );
16571657
1658 cases.addC(1658 cases.addC(
1659 "ul integer suffix after 0 (zero) in macro definition",1659 "ul integer suffix after 0 (zero) in macro definition",
1660 "#define ZERO 0UL",1660 "#define ZERO 0UL",
1661 "pub const ZERO = c_ulong(0);",1661 "pub const ZERO = @as(c_ulong, 0);",
1662 );1662 );
16631663
1664 cases.addC(1664 cases.addC(
1665 "lu integer suffix after 0 (zero) in macro definition",1665 "lu integer suffix after 0 (zero) in macro definition",
1666 "#define ZERO 0LU",1666 "#define ZERO 0LU",
1667 "pub const ZERO = c_ulong(0);",1667 "pub const ZERO = @as(c_ulong, 0);",
1668 );1668 );
16691669
1670 cases.addC(1670 cases.addC(
1671 "ll integer suffix after 0 (zero) in macro definition",1671 "ll integer suffix after 0 (zero) in macro definition",
1672 "#define ZERO 0LL",1672 "#define ZERO 0LL",
1673 "pub const ZERO = c_longlong(0);",1673 "pub const ZERO = @as(c_longlong, 0);",
1674 );1674 );
16751675
1676 cases.addC(1676 cases.addC(
1677 "ull integer suffix after 0 (zero) in macro definition",1677 "ull integer suffix after 0 (zero) in macro definition",
1678 "#define ZERO 0ULL",1678 "#define ZERO 0ULL",
1679 "pub const ZERO = c_ulonglong(0);",1679 "pub const ZERO = @as(c_ulonglong, 0);",
1680 );1680 );
16811681
1682 cases.addC(1682 cases.addC(
1683 "llu integer suffix after 0 (zero) in macro definition",1683 "llu integer suffix after 0 (zero) in macro definition",
1684 "#define ZERO 0LLU",1684 "#define ZERO 0LLU",
1685 "pub const ZERO = c_ulonglong(0);",1685 "pub const ZERO = @as(c_ulonglong, 0);",
1686 );1686 );
16871687
1688 cases.addC(1688 cases.addC(
1689 "bitwise not on u-suffixed 0 (zero) in macro definition",1689 "bitwise not on u-suffixed 0 (zero) in macro definition",
1690 "#define NOT_ZERO (~0U)",1690 "#define NOT_ZERO (~0U)",
1691 "pub const NOT_ZERO = ~c_uint(0);",1691 "pub const NOT_ZERO = ~@as(c_uint, 0);",
1692 );1692 );
16931693
1694 cases.addC("implicit casts",1694 cases.addC("implicit casts",
...@@ -1733,9 +1733,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1733,9 +1733,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1733 \\ fn_int(1094861636);1733 \\ fn_int(1094861636);
1734 \\ fn_f32(@intToFloat(f32, 3));1734 \\ fn_f32(@intToFloat(f32, 3));
1735 \\ fn_f64(@intToFloat(f64, 3));1735 \\ fn_f64(@intToFloat(f64, 3));
1736 \\ fn_char(u8('3'));1736 \\ fn_char(@as(u8, '3'));
1737 \\ fn_char(u8('\x01'));1737 \\ fn_char(@as(u8, '\x01'));
1738 \\ fn_char(u8(0));1738 \\ fn_char(@as(u8, 0));
1739 \\ fn_f32(3.000000);1739 \\ fn_f32(3.000000);
1740 \\ fn_f64(3.000000);1740 \\ fn_f64(3.000000);
1741 \\ fn_bool(true);1741 \\ fn_bool(true);
...@@ -1798,22 +1798,31 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1798,22 +1798,31 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1798 \\1798 \\
1799 ,1799 ,
1800 \\pub export fn escapes() [*c]const u8 {1800 \\pub export fn escapes() [*c]const u8 {
1801 \\ var a: u8 = u8('\'');1801 \\ var a: u8 = @as(u8, '\'');
1802 \\ var b: u8 = u8('\\');1802 \\ var b: u8 = @as(u8, '\\');
1803 \\ var c: u8 = u8('\x07');1803 \\ var c: u8 = @as(u8, '\x07');
1804 \\ var d: u8 = u8('\x08');1804 \\ var d: u8 = @as(u8, '\x08');
1805 \\ var e: u8 = u8('\x0c');1805 \\ var e: u8 = @as(u8, '\x0c');
1806 \\ var f: u8 = u8('\n');1806 \\ var f: u8 = @as(u8, '\n');
1807 \\ var g: u8 = u8('\r');1807 \\ var g: u8 = @as(u8, '\r');
1808 \\ var h: u8 = u8('\t');1808 \\ var h: u8 = @as(u8, '\t');
1809 \\ var i: u8 = u8('\x0b');1809 \\ var i: u8 = @as(u8, '\x0b');
1810 \\ var j: u8 = u8('\x00');1810 \\ var j: u8 = @as(u8, '\x00');
1811 \\ var k: u8 = u8('\"');1811 \\ var k: u8 = @as(u8, '\"');
1812 \\ return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";1812 \\ return c"\'\\\x07\x08\x0c\n\r\t\x0b\x00\"";
1813 \\}1813 \\}
1814 \\1814 \\
1815 );1815 );
18161816
1817 if (builtin.os != builtin.Os.windows) {
1818 // sysv_abi not currently supported on windows
1819 cases.add("Macro qualified functions",
1820 \\void __attribute__((sysv_abi)) foo(void);
1821 ,
1822 \\pub extern fn foo() void;
1823 );
1824 }
1825
1817 /////////////// Cases for only stage1 because stage2 behavior is better ////////////////1826 /////////////// Cases for only stage1 because stage2 behavior is better ////////////////
1818 cases.addC("Parameterless function prototypes",1827 cases.addC("Parameterless function prototypes",
1819 \\void foo() {}1828 \\void foo() {}