authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-16 01:26:18-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-16 01:26:18-04:00
log69a5f0d7973f2a3fefb69bc30c7dc1f0b430bba2
treee3e8fad5e67b66f5b51b53c421187221d1cab1e5
parenta286b5de38617809db58f918a81a650b41fbdd49
parentf8b99331a2ca98f0e938c8caaf1cd232ad1e9fa3

Merge remote-tracking branch 'origin/master' into self-hosted-incremental-compilation


107 files changed, 1930 insertions(+), 1335 deletions(-)

doc/docgen.zig+1-3
...@@ -800,10 +800,9 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -800,10 +800,9 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
800 .Keyword_for,800 .Keyword_for,
801 .Keyword_if,801 .Keyword_if,
802 .Keyword_inline,802 .Keyword_inline,
803 .Keyword_nakedcc,
804 .Keyword_noalias,803 .Keyword_noalias,
805 .Keyword_noasync,
806 .Keyword_noinline,804 .Keyword_noinline,
805 .Keyword_nosuspend,
807 .Keyword_or,806 .Keyword_or,
808 .Keyword_orelse,807 .Keyword_orelse,
809 .Keyword_packed,808 .Keyword_packed,
...@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok...@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
813 .Keyword_return,812 .Keyword_return,
814 .Keyword_linksection,813 .Keyword_linksection,
815 .Keyword_callconv,814 .Keyword_callconv,
816 .Keyword_stdcallcc,
817 .Keyword_struct,815 .Keyword_struct,
818 .Keyword_suspend,816 .Keyword_suspend,
819 .Keyword_switch,817 .Keyword_switch,
doc/langref.html.in+16-12
...@@ -1565,7 +1565,7 @@ value == null{#endsyntax#}</pre>...@@ -1565,7 +1565,7 @@ value == null{#endsyntax#}</pre>
1565const array1 = [_]u32{1,2};1565const array1 = [_]u32{1,2};
1566const array2 = [_]u32{3,4};1566const array2 = [_]u32{3,4};
1567const together = array1 ++ array2;1567const together = array1 ++ array2;
1568mem.eql(u32, together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>1568mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
1569 </td>1569 </td>
1570 </tr>1570 </tr>
1571 <tr>1571 <tr>
...@@ -6713,7 +6713,7 @@ const assert = std.debug.assert;...@@ -6713,7 +6713,7 @@ const assert = std.debug.assert;
6713test "async fn pointer in a struct field" {6713test "async fn pointer in a struct field" {
6714 var data: i32 = 1;6714 var data: i32 = 1;
6715 const Foo = struct {6715 const Foo = struct {
6716 bar: async fn (*i32) void,6716 bar: fn (*i32) callconv(.Async) void,
6717 };6717 };
6718 var foo = Foo{ .bar = func };6718 var foo = Foo{ .bar = func };
6719 var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;6719 var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
...@@ -6723,7 +6723,7 @@ test "async fn pointer in a struct field" {...@@ -6723,7 +6723,7 @@ test "async fn pointer in a struct field" {
6723 assert(data == 4);6723 assert(data == 4);
6724}6724}
67256725
6726async fn func(y: *i32) void {6726fn func(y: *i32) void {
6727 defer y.* += 2;6727 defer y.* += 2;
6728 y.* += 1;6728 y.* += 1;
6729 suspend;6729 suspend;
...@@ -8189,9 +8189,7 @@ fn List(comptime T: type) type {...@@ -8189,9 +8189,7 @@ fn List(comptime T: type) type {
8189 {#code_end#}8189 {#code_end#}
8190 <p>8190 <p>
8191 When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the8191 When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the
8192 current import. There is a proposal to remove the import type and use an empty struct8192 struct that corresponds to the current file.
8193 type instead. See
8194 <a href="https://github.com/ziglang/zig/issues/1047">#1047</a> for details.
8195 </p>8193 </p>
8196 {#header_close#}8194 {#header_close#}
81978195
...@@ -9990,6 +9988,13 @@ coding style....@@ -9990,6 +9988,13 @@ coding style.
9990 conventions.9988 conventions.
9991 </p>9989 </p>
9992 <p>9990 <p>
9991 File names fall into two categories: types and namespaces. If the file
9992 (implicity a struct) has top level fields, it should be named like any
9993 other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise,
9994 it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be
9995 {#syntax#}snake_case{#endsyntax#}.
9996 </p>
9997 <p>
9993 These are general rules of thumb; if it makes sense to do something different,9998 These are general rules of thumb; if it makes sense to do something different,
9994 do what makes sense. For example, if there is an established convention such as9999 do what makes sense. For example, if there is an established convention such as
9995 {#syntax#}ENOENT{#endsyntax#}, follow the established convention.10000 {#syntax#}ENOENT{#endsyntax#}, follow the established convention.
...@@ -9998,6 +10003,7 @@ coding style....@@ -9998,6 +10003,7 @@ coding style.
9998 {#header_open|Examples#}10003 {#header_open|Examples#}
9999 {#code_begin|syntax#}10004 {#code_begin|syntax#}
10000const namespace_name = @import("dir_name/file_name.zig");10005const namespace_name = @import("dir_name/file_name.zig");
10006const TypeName = @import("dir_name/TypeName.zig");
10001var global_var: i32 = undefined;10007var global_var: i32 = undefined;
10002const const_name = 42;10008const const_name = 42;
10003const primitive_type_alias = f32;10009const primitive_type_alias = f32;
...@@ -10088,7 +10094,7 @@ TopLevelDecl...@@ -10088,7 +10094,7 @@ TopLevelDecl
10088 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl10094 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
10089 / KEYWORD_usingnamespace Expr SEMICOLON10095 / KEYWORD_usingnamespace Expr SEMICOLON
1009010096
10091FnProto &lt;- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)10097FnProto &lt;- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
1009210098
10093VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON10099VarDecl &lt;- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
1009410100
...@@ -10098,6 +10104,7 @@ ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?...@@ -10098,6 +10104,7 @@ ContainerField &lt;- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
10098Statement10104Statement
10099 &lt;- KEYWORD_comptime? VarDecl10105 &lt;- KEYWORD_comptime? VarDecl
10100 / KEYWORD_comptime BlockExprStatement10106 / KEYWORD_comptime BlockExprStatement
10107 / KEYWORD_nosuspend BlockExprStatement
10101 / KEYWORD_suspend (SEMICOLON / BlockExprStatement)10108 / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
10102 / KEYWORD_defer BlockExprStatement10109 / KEYWORD_defer BlockExprStatement
10103 / KEYWORD_errdefer BlockExprStatement10110 / KEYWORD_errdefer BlockExprStatement
...@@ -10154,6 +10161,7 @@ PrimaryExpr...@@ -10154,6 +10161,7 @@ PrimaryExpr
10154 / IfExpr10161 / IfExpr
10155 / KEYWORD_break BreakLabel? Expr?10162 / KEYWORD_break BreakLabel? Expr?
10156 / KEYWORD_comptime Expr10163 / KEYWORD_comptime Expr
10164 / KEYWORD_nosuspend Expr
10157 / KEYWORD_continue BreakLabel?10165 / KEYWORD_continue BreakLabel?
10158 / KEYWORD_resume Expr10166 / KEYWORD_resume Expr
10159 / KEYWORD_return Expr?10167 / KEYWORD_return Expr?
...@@ -10255,11 +10263,6 @@ WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN...@@ -10255,11 +10263,6 @@ WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN
1025510263
10256LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN10264LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN
1025710265
10258# Fn specific
10259FnCC
10260 &lt;- KEYWORD_extern
10261 / KEYWORD_async
10262
10263ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType10266ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
1026410267
10265ParamType10268ParamType
...@@ -10521,6 +10524,7 @@ KEYWORD_for &lt;- 'for' end_of_word...@@ -10521,6 +10524,7 @@ KEYWORD_for &lt;- 'for' end_of_word
10521KEYWORD_if &lt;- 'if' end_of_word10524KEYWORD_if &lt;- 'if' end_of_word
10522KEYWORD_inline &lt;- 'inline' end_of_word10525KEYWORD_inline &lt;- 'inline' end_of_word
10523KEYWORD_noalias &lt;- 'noalias' end_of_word10526KEYWORD_noalias &lt;- 'noalias' end_of_word
10527KEYWORD_nosuspend &lt;- 'nosuspend' end_of_word
10524KEYWORD_null &lt;- 'null' end_of_word10528KEYWORD_null &lt;- 'null' end_of_word
10525KEYWORD_or &lt;- 'or' end_of_word10529KEYWORD_or &lt;- 'or' end_of_word
10526KEYWORD_orelse &lt;- 'orelse' end_of_word10530KEYWORD_orelse &lt;- 'orelse' end_of_word
lib/std/ascii.zig+21-2
...@@ -227,6 +227,8 @@ test "ascii character classes" {...@@ -227,6 +227,8 @@ test "ascii character classes" {
227 testing.expect(isSpace(' '));227 testing.expect(isSpace(' '));
228}228}
229229
230/// Allocates a lower case copy of `ascii_string`.
231/// Caller owns returned string and must free with `allocator`.
230pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {232pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {
231 const result = try allocator.alloc(u8, ascii_string.len);233 const result = try allocator.alloc(u8, ascii_string.len);
232 for (result) |*c, i| {234 for (result) |*c, i| {
...@@ -241,6 +243,23 @@ test "allocLowerString" {...@@ -241,6 +243,23 @@ test "allocLowerString" {
241 std.testing.expect(std.mem.eql(u8, "abcdefghijklmnopqrst0234+💩!", result));243 std.testing.expect(std.mem.eql(u8, "abcdefghijklmnopqrst0234+💩!", result));
242}244}
243245
246/// Allocates an upper case copy of `ascii_string`.
247/// Caller owns returned string and must free with `allocator`.
248pub fn allocUpperString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {
249 const result = try allocator.alloc(u8, ascii_string.len);
250 for (result) |*c, i| {
251 c.* = toUpper(ascii_string[i]);
252 }
253 return result;
254}
255
256test "allocUpperString" {
257 const result = try allocUpperString(std.testing.allocator, "aBcDeFgHiJkLmNOPqrst0234+💩!");
258 defer std.testing.allocator.free(result);
259 std.testing.expect(std.mem.eql(u8, "ABCDEFGHIJKLMNOPQRST0234+💩!", result));
260}
261
262/// Compares strings `a` and `b` case insensitively and returns whether they are equal.
244pub fn eqlIgnoreCase(a: []const u8, b: []const u8) bool {263pub fn eqlIgnoreCase(a: []const u8, b: []const u8) bool {
245 if (a.len != b.len) return false;264 if (a.len != b.len) return false;
246 for (a) |a_c, i| {265 for (a) |a_c, i| {
...@@ -255,7 +274,7 @@ test "eqlIgnoreCase" {...@@ -255,7 +274,7 @@ test "eqlIgnoreCase" {
255 std.testing.expect(!eqlIgnoreCase("hElLo!", "helro!"));274 std.testing.expect(!eqlIgnoreCase("hElLo!", "helro!"));
256}275}
257276
258/// Finds `substr` in `container`, starting at `start_index`.277/// Finds `substr` in `container`, ignoring case, starting at `start_index`.
259/// TODO boyer-moore algorithm278/// TODO boyer-moore algorithm
260pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {279pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
261 if (substr.len > container.len) return null;280 if (substr.len > container.len) return null;
...@@ -268,7 +287,7 @@ pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: [...@@ -268,7 +287,7 @@ pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: [
268 return null;287 return null;
269}288}
270289
271/// Finds `substr` in `container`, starting at `start_index`.290/// Finds `substr` in `container`, ignoring case, starting at index 0.
272pub fn indexOfIgnoreCase(container: []const u8, substr: []const u8) ?usize {291pub fn indexOfIgnoreCase(container: []const u8, substr: []const u8) ?usize {
273 return indexOfIgnoreCasePos(container, 0, substr);292 return indexOfIgnoreCasePos(container, 0, substr);
274}293}
lib/std/build.zig+11-6
...@@ -284,11 +284,11 @@ pub const Builder = struct {...@@ -284,11 +284,11 @@ pub const Builder = struct {
284 return run_step;284 return run_step;
285 }285 }
286286
287 fn dupe(self: *Builder, bytes: []const u8) []u8 {287 pub fn dupe(self: *Builder, bytes: []const u8) []u8 {
288 return mem.dupe(self.allocator, u8, bytes) catch unreachable;288 return mem.dupe(self.allocator, u8, bytes) catch unreachable;
289 }289 }
290290
291 fn dupePath(self: *Builder, bytes: []const u8) []u8 {291 pub fn dupePath(self: *Builder, bytes: []const u8) []u8 {
292 const the_copy = self.dupe(bytes);292 const the_copy = self.dupe(bytes);
293 for (the_copy) |*byte| {293 for (the_copy) |*byte| {
294 switch (byte.*) {294 switch (byte.*) {
...@@ -717,7 +717,7 @@ pub const Builder = struct {...@@ -717,7 +717,7 @@ pub const Builder = struct {
717 return self.invalid_user_input;717 return self.invalid_user_input;
718 }718 }
719719
720 fn spawnChild(self: *Builder, argv: []const []const u8) !void {720 pub fn spawnChild(self: *Builder, argv: []const []const u8) !void {
721 return self.spawnChildEnvMap(null, self.env_map, argv);721 return self.spawnChildEnvMap(null, self.env_map, argv);
722 }722 }
723723
...@@ -843,7 +843,7 @@ pub const Builder = struct {...@@ -843,7 +843,7 @@ pub const Builder = struct {
843 }) catch unreachable;843 }) catch unreachable;
844 }844 }
845845
846 fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {846 pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
847 if (self.verbose) {847 if (self.verbose) {
848 warn("cp {} {} ", .{ source_path, dest_path });848 warn("cp {} {} ", .{ source_path, dest_path });
849 }849 }
...@@ -855,7 +855,7 @@ pub const Builder = struct {...@@ -855,7 +855,7 @@ pub const Builder = struct {
855 };855 };
856 }856 }
857857
858 fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {858 pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
859 return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;859 return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;
860 }860 }
861861
...@@ -985,7 +985,7 @@ pub const Builder = struct {...@@ -985,7 +985,7 @@ pub const Builder = struct {
985 self.search_prefixes.append(search_prefix) catch unreachable;985 self.search_prefixes.append(search_prefix) catch unreachable;
986 }986 }
987987
988 fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {988 pub fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
989 const base_dir = switch (dir) {989 const base_dir = switch (dir) {
990 .Prefix => self.install_path,990 .Prefix => self.install_path,
991 .Bin => self.exe_dir,991 .Bin => self.exe_dir,
...@@ -1132,6 +1132,7 @@ pub const LibExeObjStep = struct {...@@ -1132,6 +1132,7 @@ pub const LibExeObjStep = struct {
1132 name_prefix: []const u8,1132 name_prefix: []const u8,
1133 filter: ?[]const u8,1133 filter: ?[]const u8,
1134 single_threaded: bool,1134 single_threaded: bool,
1135 test_evented_io: bool = false,
1135 code_model: builtin.CodeModel = .default,1136 code_model: builtin.CodeModel = .default,
11361137
1137 root_src: ?FileSource,1138 root_src: ?FileSource,
...@@ -1864,6 +1865,10 @@ pub const LibExeObjStep = struct {...@@ -1864,6 +1865,10 @@ pub const LibExeObjStep = struct {
1864 try zig_args.append(filter);1865 try zig_args.append(filter);
1865 }1866 }
18661867
1868 if (self.test_evented_io) {
1869 try zig_args.append("--test-evented-io");
1870 }
1871
1867 if (self.name_prefix.len != 0) {1872 if (self.name_prefix.len != 0) {
1868 try zig_args.append("--test-name-prefix");1873 try zig_args.append("--test-name-prefix");
1869 try zig_args.append(self.name_prefix);1874 try zig_args.append(self.name_prefix);
lib/std/c.zig+1-1
...@@ -217,7 +217,7 @@ pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]timeval) c_int;...@@ -217,7 +217,7 @@ pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]timeval) c_int;
217pub extern "c" fn utimensat(dirfd: fd_t, pathname: [*:0]const u8, times: *[2]timespec, flags: u32) c_int;217pub extern "c" fn utimensat(dirfd: fd_t, pathname: [*:0]const u8, times: *[2]timespec, flags: u32) c_int;
218pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;218pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;
219219
220pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;220pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: fn (?*c_void) callconv(.C) ?*c_void, noalias arg: ?*c_void) c_int;
221pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;221pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
222pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;222pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
223pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int;223pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int;
lib/std/c/dragonfly.zig+1-1
...@@ -9,7 +9,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;...@@ -9,7 +9,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
9pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;9pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
10pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;10pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
1111
12pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;12pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
13pub 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;
1414
15pub const pthread_mutex_t = extern struct {15pub const pthread_mutex_t = extern struct {
lib/std/c/freebsd.zig+1-1
...@@ -24,7 +24,7 @@ pub extern "c" fn sendfile(...@@ -24,7 +24,7 @@ pub extern "c" fn sendfile(
24 flags: u32,24 flags: u32,
25) c_int;25) c_int;
2626
27pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;27pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
28pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;28pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
2929
30pub const pthread_mutex_t = extern struct {30pub const pthread_mutex_t = extern struct {
lib/std/c/linux.zig+1-1
...@@ -75,7 +75,7 @@ pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32)...@@ -75,7 +75,7 @@ pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32)
75/// See std.elf for constants for this75/// See std.elf for constants for this
76pub extern "c" fn getauxval(__type: c_ulong) c_ulong;76pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
7777
78pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;78pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
79pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;79pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
8080
81pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;81pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
lib/std/c/netbsd.zig+1-1
...@@ -6,7 +6,7 @@ usingnamespace std.c;...@@ -6,7 +6,7 @@ usingnamespace std.c;
6extern "c" fn __errno() *c_int;6extern "c" fn __errno() *c_int;
7pub const _errno = __errno;7pub const _errno = __errno;
88
9pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;9pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
10pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;10pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
1111
12pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;12pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
lib/std/crypto/blake3.zig+2-1
...@@ -338,7 +338,7 @@ pub const Blake3 = struct {...@@ -338,7 +338,7 @@ pub const Blake3 = struct {
338 }338 }
339339
340 // Section 5.1.2 of the BLAKE3 spec explains this algorithm in more detail.340 // Section 5.1.2 of the BLAKE3 spec explains this algorithm in more detail.
341 fn add_chunk_chaining_value(self: *Blake3, new_cv: [8]u32, total_chunks: u64) void {341 fn add_chunk_chaining_value(self: *Blake3, first_cv: [8]u32, total_chunks: u64) void {
342 // This chunk might complete some subtrees. For each completed subtree,342 // This chunk might complete some subtrees. For each completed subtree,
343 // its left child will be the current top entry in the CV stack, and343 // its left child will be the current top entry in the CV stack, and
344 // its right child will be the current value of `new_cv`. Pop each left344 // its right child will be the current value of `new_cv`. Pop each left
...@@ -346,6 +346,7 @@ pub const Blake3 = struct {...@@ -346,6 +346,7 @@ pub const Blake3 = struct {
346 // with the result. After all these merges, push the final value of346 // with the result. After all these merges, push the final value of
347 // `new_cv` onto the stack. The number of completed subtrees is given347 // `new_cv` onto the stack. The number of completed subtrees is given
348 // by the number of trailing 0-bits in the new total number of chunks.348 // by the number of trailing 0-bits in the new total number of chunks.
349 var new_cv = first_cv;
349 var chunk_counter = total_chunks;350 var chunk_counter = total_chunks;
350 while (chunk_counter & 1 == 0) {351 while (chunk_counter & 1 == 0) {
351 new_cv = parent_cv(self.pop_cv(), new_cv, self.key, self.flags);352 new_cv = parent_cv(self.pop_cv(), new_cv, self.key, self.flags);
lib/std/debug.zig+16-16
...@@ -62,7 +62,7 @@ pub fn warn(comptime fmt: []const u8, args: var) void {...@@ -62,7 +62,7 @@ pub fn warn(comptime fmt: []const u8, args: var) void {
62 const held = stderr_mutex.acquire();62 const held = stderr_mutex.acquire();
63 defer held.release();63 defer held.release();
64 const stderr = getStderrStream();64 const stderr = getStderrStream();
65 noasync stderr.print(fmt, args) catch return;65 nosuspend stderr.print(fmt, args) catch return;
66}66}
6767
68pub fn getStderrStream() *File.OutStream {68pub fn getStderrStream() *File.OutStream {
...@@ -112,7 +112,7 @@ pub fn detectTTYConfig() TTY.Config {...@@ -112,7 +112,7 @@ pub fn detectTTYConfig() TTY.Config {
112/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.112/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
113/// TODO multithreaded awareness113/// TODO multithreaded awareness
114pub fn dumpCurrentStackTrace(start_addr: ?usize) void {114pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
115 noasync {115 nosuspend {
116 const stderr = getStderrStream();116 const stderr = getStderrStream();
117 if (builtin.strip_debug_info) {117 if (builtin.strip_debug_info) {
118 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;118 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
...@@ -133,7 +133,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {...@@ -133,7 +133,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
133/// unbuffered, and ignores any error returned.133/// unbuffered, and ignores any error returned.
134/// TODO multithreaded awareness134/// TODO multithreaded awareness
135pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {135pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
136 noasync {136 nosuspend {
137 const stderr = getStderrStream();137 const stderr = getStderrStream();
138 if (builtin.strip_debug_info) {138 if (builtin.strip_debug_info) {
139 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;139 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
...@@ -203,7 +203,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace...@@ -203,7 +203,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace
203/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.203/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
204/// TODO multithreaded awareness204/// TODO multithreaded awareness
205pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {205pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
206 noasync {206 nosuspend {
207 const stderr = getStderrStream();207 const stderr = getStderrStream();
208 if (builtin.strip_debug_info) {208 if (builtin.strip_debug_info) {
209 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;209 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
...@@ -261,7 +261,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c...@@ -261,7 +261,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
261 resetSegfaultHandler();261 resetSegfaultHandler();
262 }262 }
263263
264 noasync switch (panic_stage) {264 nosuspend switch (panic_stage) {
265 0 => {265 0 => {
266 panic_stage = 1;266 panic_stage = 1;
267267
...@@ -357,7 +357,7 @@ pub const StackIterator = struct {...@@ -357,7 +357,7 @@ pub const StackIterator = struct {
357 else357 else
358 0;358 0;
359359
360 fn next(self: *StackIterator) ?usize {360 pub fn next(self: *StackIterator) ?usize {
361 var address = self.next_internal() orelse return null;361 var address = self.next_internal() orelse return null;
362362
363 if (self.first_address) |first_address| {363 if (self.first_address) |first_address| {
...@@ -447,7 +447,7 @@ pub const TTY = struct {...@@ -447,7 +447,7 @@ pub const TTY = struct {
447 windows_api,447 windows_api,
448448
449 fn setColor(conf: Config, out_stream: var, color: Color) void {449 fn setColor(conf: Config, out_stream: var, color: Color) void {
450 noasync switch (conf) {450 nosuspend switch (conf) {
451 .no_color => return,451 .no_color => return,
452 .escape_codes => switch (color) {452 .escape_codes => switch (color) {
453 .Red => out_stream.writeAll(RED) catch return,453 .Red => out_stream.writeAll(RED) catch return,
...@@ -604,7 +604,7 @@ fn printLineInfo(...@@ -604,7 +604,7 @@ fn printLineInfo(
604 tty_config: TTY.Config,604 tty_config: TTY.Config,
605 comptime printLineFromFile: var,605 comptime printLineFromFile: var,
606) !void {606) !void {
607 noasync {607 nosuspend {
608 tty_config.setColor(out_stream, .White);608 tty_config.setColor(out_stream, .White);
609609
610 if (line_info) |*li| {610 if (line_info) |*li| {
...@@ -651,7 +651,7 @@ pub const OpenSelfDebugInfoError = error{...@@ -651,7 +651,7 @@ pub const OpenSelfDebugInfoError = error{
651651
652/// TODO resources https://github.com/ziglang/zig/issues/4353652/// TODO resources https://github.com/ziglang/zig/issues/4353
653pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {653pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
654 noasync {654 nosuspend {
655 if (builtin.strip_debug_info)655 if (builtin.strip_debug_info)
656 return error.MissingDebugInfo;656 return error.MissingDebugInfo;
657 if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {657 if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) {
...@@ -672,7 +672,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {...@@ -672,7 +672,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
672672
673/// TODO resources https://github.com/ziglang/zig/issues/4353673/// TODO resources https://github.com/ziglang/zig/issues/4353
674fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {674fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {
675 noasync {675 nosuspend {
676 const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });676 const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
677 errdefer coff_file.close();677 errdefer coff_file.close();
678678
...@@ -853,7 +853,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {...@@ -853,7 +853,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
853853
854/// TODO resources https://github.com/ziglang/zig/issues/4353854/// TODO resources https://github.com/ziglang/zig/issues/4353
855pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {855pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {
856 noasync {856 nosuspend {
857 const mapped_mem = try mapWholeFile(elf_file_path);857 const mapped_mem = try mapWholeFile(elf_file_path);
858 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);858 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
859 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;859 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
...@@ -1056,7 +1056,7 @@ const MachoSymbol = struct {...@@ -1056,7 +1056,7 @@ const MachoSymbol = struct {
1056};1056};
10571057
1058fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {1058fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
1059 noasync {1059 nosuspend {
1060 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });1060 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
1061 defer file.close();1061 defer file.close();
10621062
...@@ -1418,7 +1418,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {...@@ -1418,7 +1418,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
1418 }1418 }
14191419
1420 fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {1420 fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
1421 noasync {1421 nosuspend {
1422 // Translate the VA into an address into this object1422 // Translate the VA into an address into this object
1423 const relocated_address = address - self.base_address;1423 const relocated_address = address - self.base_address;
1424 assert(relocated_address >= 0x100000000);1424 assert(relocated_address >= 0x100000000);
...@@ -1643,14 +1643,14 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {...@@ -1643,14 +1643,14 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
1643 // Translate the VA into an address into this object1643 // Translate the VA into an address into this object
1644 const relocated_address = address - self.base_address;1644 const relocated_address = address - self.base_address;
16451645
1646 if (noasync self.dwarf.findCompileUnit(relocated_address)) |compile_unit| {1646 if (nosuspend self.dwarf.findCompileUnit(relocated_address)) |compile_unit| {
1647 return SymbolInfo{1647 return SymbolInfo{
1648 .symbol_name = noasync self.dwarf.getSymbolName(relocated_address) orelse "???",1648 .symbol_name = nosuspend self.dwarf.getSymbolName(relocated_address) orelse "???",
1649 .compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) {1649 .compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) {
1650 error.MissingDebugInfo, error.InvalidDebugInfo => "???",1650 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
1651 else => return err,1651 else => return err,
1652 },1652 },
1653 .line_info = noasync self.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) {1653 .line_info = nosuspend self.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) {
1654 error.MissingDebugInfo, error.InvalidDebugInfo => null,1654 error.MissingDebugInfo, error.InvalidDebugInfo => null,
1655 else => return err,1655 else => return err,
1656 },1656 },
lib/std/dwarf.zig+29-29
...@@ -121,7 +121,7 @@ const Die = struct {...@@ -121,7 +121,7 @@ const Die = struct {
121 };121 };
122 }122 }
123123
124 fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {124 pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
125 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;125 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
126 return switch (form_value.*) {126 return switch (form_value.*) {
127 FormValue.String => |value| value,127 FormValue.String => |value| value,
...@@ -248,17 +248,17 @@ fn readUnitLength(in_stream: var, endian: builtin.Endian, is_64: *bool) !u64 {...@@ -248,17 +248,17 @@ fn readUnitLength(in_stream: var, endian: builtin.Endian, is_64: *bool) !u64 {
248 }248 }
249}249}
250250
251// TODO the noasyncs here are workarounds251// TODO the nosuspends here are workarounds
252fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {252fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
253 const buf = try allocator.alloc(u8, size);253 const buf = try allocator.alloc(u8, size);
254 errdefer allocator.free(buf);254 errdefer allocator.free(buf);
255 if ((try noasync in_stream.read(buf)) < size) return error.EndOfFile;255 if ((try nosuspend in_stream.read(buf)) < size) return error.EndOfFile;
256 return buf;256 return buf;
257}257}
258258
259// TODO the noasyncs here are workarounds259// TODO the nosuspends here are workarounds
260fn readAddress(in_stream: var, endian: builtin.Endian, is_64: bool) !u64 {260fn readAddress(in_stream: var, endian: builtin.Endian, is_64: bool) !u64 {
261 return noasync if (is_64)261 return nosuspend if (is_64)
262 try in_stream.readInt(u64, endian)262 try in_stream.readInt(u64, endian)
263 else263 else
264 @as(u64, try in_stream.readInt(u32, endian));264 @as(u64, try in_stream.readInt(u32, endian));
...@@ -269,29 +269,29 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize...@@ -269,29 +269,29 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
269 return FormValue{ .Block = buf };269 return FormValue{ .Block = buf };
270}270}
271271
272// TODO the noasyncs here are workarounds272// TODO the nosuspends here are workarounds
273fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: usize) !FormValue {273fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: usize) !FormValue {
274 const block_len = try noasync in_stream.readVarInt(usize, endian, size);274 const block_len = try nosuspend in_stream.readVarInt(usize, endian, size);
275 return parseFormValueBlockLen(allocator, in_stream, block_len);275 return parseFormValueBlockLen(allocator, in_stream, block_len);
276}276}
277277
278fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, endian: builtin.Endian, comptime size: i32) !FormValue {278fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, endian: builtin.Endian, comptime size: i32) !FormValue {
279 // TODO: Please forgive me, I've worked around zig not properly spilling some intermediate values here.279 // TODO: Please forgive me, I've worked around zig not properly spilling some intermediate values here.
280 // `noasync` should be removed from all the function calls once it is fixed.280 // `nosuspend` should be removed from all the function calls once it is fixed.
281 return FormValue{281 return FormValue{
282 .Const = Constant{282 .Const = Constant{
283 .signed = signed,283 .signed = signed,
284 .payload = switch (size) {284 .payload = switch (size) {
285 1 => try noasync in_stream.readInt(u8, endian),285 1 => try nosuspend in_stream.readInt(u8, endian),
286 2 => try noasync in_stream.readInt(u16, endian),286 2 => try nosuspend in_stream.readInt(u16, endian),
287 4 => try noasync in_stream.readInt(u32, endian),287 4 => try nosuspend in_stream.readInt(u32, endian),
288 8 => try noasync in_stream.readInt(u64, endian),288 8 => try nosuspend in_stream.readInt(u64, endian),
289 -1 => blk: {289 -1 => blk: {
290 if (signed) {290 if (signed) {
291 const x = try noasync leb.readILEB128(i64, in_stream);291 const x = try nosuspend leb.readILEB128(i64, in_stream);
292 break :blk @bitCast(u64, x);292 break :blk @bitCast(u64, x);
293 } else {293 } else {
294 const x = try noasync leb.readULEB128(u64, in_stream);294 const x = try nosuspend leb.readULEB128(u64, in_stream);
295 break :blk x;295 break :blk x;
296 }296 }
297 },297 },
...@@ -301,21 +301,21 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo...@@ -301,21 +301,21 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
301 };301 };
302}302}
303303
304// TODO the noasyncs here are workarounds304// TODO the nosuspends here are workarounds
305fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {305fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {
306 return FormValue{306 return FormValue{
307 .Ref = switch (size) {307 .Ref = switch (size) {
308 1 => try noasync in_stream.readInt(u8, endian),308 1 => try nosuspend in_stream.readInt(u8, endian),
309 2 => try noasync in_stream.readInt(u16, endian),309 2 => try nosuspend in_stream.readInt(u16, endian),
310 4 => try noasync in_stream.readInt(u32, endian),310 4 => try nosuspend in_stream.readInt(u32, endian),
311 8 => try noasync in_stream.readInt(u64, endian),311 8 => try nosuspend in_stream.readInt(u64, endian),
312 -1 => try noasync leb.readULEB128(u64, in_stream),312 -1 => try nosuspend leb.readULEB128(u64, in_stream),
313 else => unreachable,313 else => unreachable,
314 },314 },
315 };315 };
316}316}
317317
318// TODO the noasyncs here are workarounds318// TODO the nosuspends here are workarounds
319fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {319fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {
320 return switch (form_id) {320 return switch (form_id) {
321 FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },321 FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },
...@@ -323,7 +323,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia...@@ -323,7 +323,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
323 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),323 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
324 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),324 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
325 FORM_block => x: {325 FORM_block => x: {
326 const block_len = try noasync leb.readULEB128(usize, in_stream);326 const block_len = try nosuspend leb.readULEB128(usize, in_stream);
327 return parseFormValueBlockLen(allocator, in_stream, block_len);327 return parseFormValueBlockLen(allocator, in_stream, block_len);
328 },328 },
329 FORM_data1 => parseFormValueConstant(allocator, in_stream, false, endian, 1),329 FORM_data1 => parseFormValueConstant(allocator, in_stream, false, endian, 1),
...@@ -335,11 +335,11 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia...@@ -335,11 +335,11 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
335 return parseFormValueConstant(allocator, in_stream, signed, endian, -1);335 return parseFormValueConstant(allocator, in_stream, signed, endian, -1);
336 },336 },
337 FORM_exprloc => {337 FORM_exprloc => {
338 const size = try noasync leb.readULEB128(usize, in_stream);338 const size = try nosuspend leb.readULEB128(usize, in_stream);
339 const buf = try readAllocBytes(allocator, in_stream, size);339 const buf = try readAllocBytes(allocator, in_stream, size);
340 return FormValue{ .ExprLoc = buf };340 return FormValue{ .ExprLoc = buf };
341 },341 },
342 FORM_flag => FormValue{ .Flag = (try noasync in_stream.readByte()) != 0 },342 FORM_flag => FormValue{ .Flag = (try nosuspend in_stream.readByte()) != 0 },
343 FORM_flag_present => FormValue{ .Flag = true },343 FORM_flag_present => FormValue{ .Flag = true },
344 FORM_sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) },344 FORM_sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) },
345345
...@@ -350,12 +350,12 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia...@@ -350,12 +350,12 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
350 FORM_ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),350 FORM_ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),
351351
352 FORM_ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) },352 FORM_ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) },
353 FORM_ref_sig8 => FormValue{ .Ref = try noasync in_stream.readInt(u64, endian) },353 FORM_ref_sig8 => FormValue{ .Ref = try nosuspend in_stream.readInt(u64, endian) },
354354
355 FORM_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },355 FORM_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
356 FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },356 FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
357 FORM_indirect => {357 FORM_indirect => {
358 const child_form_id = try noasync leb.readULEB128(u64, in_stream);358 const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
359 const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));359 const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
360 var frame = try allocator.create(F);360 var frame = try allocator.create(F);
361 defer allocator.destroy(frame);361 defer allocator.destroy(frame);
...@@ -389,7 +389,7 @@ pub const DwarfInfo = struct {...@@ -389,7 +389,7 @@ pub const DwarfInfo = struct {
389 return self.abbrev_table_list.allocator;389 return self.abbrev_table_list.allocator;
390 }390 }
391391
392 fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {392 pub fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {
393 for (di.func_list.span()) |*func| {393 for (di.func_list.span()) |*func| {
394 if (func.pc_range) |range| {394 if (func.pc_range) |range| {
395 if (address >= range.start and address < range.end) {395 if (address >= range.start and address < range.end) {
...@@ -578,7 +578,7 @@ pub const DwarfInfo = struct {...@@ -578,7 +578,7 @@ pub const DwarfInfo = struct {
578 }578 }
579 }579 }
580580
581 fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {581 pub fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
582 for (di.compile_unit_list.span()) |*compile_unit| {582 for (di.compile_unit_list.span()) |*compile_unit| {
583 if (compile_unit.pc_range) |range| {583 if (compile_unit.pc_range) |range| {
584 if (target_address >= range.start and target_address < range.end) return compile_unit;584 if (target_address >= range.start and target_address < range.end) return compile_unit;
...@@ -690,7 +690,7 @@ pub const DwarfInfo = struct {...@@ -690,7 +690,7 @@ pub const DwarfInfo = struct {
690 return result;690 return result;
691 }691 }
692692
693 fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo {693 pub fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo {
694 var stream = io.fixedBufferStream(di.debug_line);694 var stream = io.fixedBufferStream(di.debug_line);
695 const in = &stream.inStream();695 const in = &stream.inStream();
696 const seekable = &stream.seekableStream();696 const seekable = &stream.seekableStream();
lib/std/dynamic_library.zig+2-2
...@@ -33,11 +33,11 @@ const LinkMap = extern struct {...@@ -33,11 +33,11 @@ const LinkMap = extern struct {
33 pub const Iterator = struct {33 pub const Iterator = struct {
34 current: ?*LinkMap,34 current: ?*LinkMap,
3535
36 fn end(self: *Iterator) bool {36 pub fn end(self: *Iterator) bool {
37 return self.current == null;37 return self.current == null;
38 }38 }
3939
40 fn next(self: *Iterator) ?*LinkMap {40 pub fn next(self: *Iterator) ?*LinkMap {
41 if (self.current) |it| {41 if (self.current) |it| {
42 self.current = it.l_next;42 self.current = it.l_next;
43 return it;43 return it;
lib/std/elf.zig+1
...@@ -548,6 +548,7 @@ fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void {...@@ -548,6 +548,7 @@ fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void {
548 error.BrokenPipe => return error.UnableToReadElfFile,548 error.BrokenPipe => return error.UnableToReadElfFile,
549 error.Unseekable => return error.UnableToReadElfFile,549 error.Unseekable => return error.UnableToReadElfFile,
550 error.ConnectionResetByPeer => return error.UnableToReadElfFile,550 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
551 error.ConnectionTimedOut => return error.UnableToReadElfFile,
551 error.InputOutput => return error.FileSystem,552 error.InputOutput => return error.FileSystem,
552 error.Unexpected => return error.Unexpected,553 error.Unexpected => return error.Unexpected,
553 error.WouldBlock => return error.Unexpected,554 error.WouldBlock => return error.Unexpected,
lib/std/event/batch.zig+3-3
...@@ -21,7 +21,7 @@ pub fn Batch(...@@ -21,7 +21,7 @@ pub fn Batch(
21 /// usual recommended option for this parameter.21 /// usual recommended option for this parameter.
22 auto_async,22 auto_async,
2323
24 /// Always uses the `noasync` keyword when using `await` on the jobs,24 /// Always uses the `nosuspend` keyword when using `await` on the jobs,
25 /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.25 /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
26 never_async,26 never_async,
2727
...@@ -75,7 +75,7 @@ pub fn Batch(...@@ -75,7 +75,7 @@ pub fn Batch(
75 const job = &self.jobs[self.next_job_index];75 const job = &self.jobs[self.next_job_index];
76 self.next_job_index = (self.next_job_index + 1) % max_jobs;76 self.next_job_index = (self.next_job_index + 1) % max_jobs;
77 if (job.frame) |existing| {77 if (job.frame) |existing| {
78 job.result = if (async_ok) await existing else noasync await existing;78 job.result = if (async_ok) await existing else nosuspend await existing;
79 if (CollectedResult != void) {79 if (CollectedResult != void) {
80 job.result catch |err| {80 job.result catch |err| {
81 self.collected_result = err;81 self.collected_result = err;
...@@ -94,7 +94,7 @@ pub fn Batch(...@@ -94,7 +94,7 @@ pub fn Batch(
94 /// a time, however, it need not be the same thread.94 /// a time, however, it need not be the same thread.
95 pub fn wait(self: *Self) CollectedResult {95 pub fn wait(self: *Self) CollectedResult {
96 for (self.jobs) |*job| if (job.frame) |f| {96 for (self.jobs) |*job| if (job.frame) |f| {
97 job.result = if (async_ok) await f else noasync await f;97 job.result = if (async_ok) await f else nosuspend await f;
98 if (CollectedResult != void) {98 if (CollectedResult != void) {
99 job.result catch |err| {99 job.result catch |err| {
100 self.collected_result = err;100 self.collected_result = err;
lib/std/event/channel.zig+4-7
...@@ -105,7 +105,7 @@ pub fn Channel(comptime T: type) type {...@@ -105,7 +105,7 @@ pub fn Channel(comptime T: type) type {
105105
106 /// await this function to get an item from the channel. If the buffer is empty, the frame will106 /// await this function to get an item from the channel. If the buffer is empty, the frame will
107 /// complete when the next item is put in the channel.107 /// complete when the next item is put in the channel.
108 pub async fn get(self: *SelfChannel) T {108 pub fn get(self: *SelfChannel) callconv(.Async) T {
109 // TODO https://github.com/ziglang/zig/issues/2765109 // TODO https://github.com/ziglang/zig/issues/2765
110 var result: T = undefined;110 var result: T = undefined;
111 var my_tick_node = Loop.NextTickNode.init(@frame());111 var my_tick_node = Loop.NextTickNode.init(@frame());
...@@ -305,8 +305,7 @@ test "std.event.Channel wraparound" {...@@ -305,8 +305,7 @@ test "std.event.Channel wraparound" {
305 channel.put(7);305 channel.put(7);
306 testing.expectEqual(@as(i32, 7), channel.get());306 testing.expectEqual(@as(i32, 7), channel.get());
307}307}
308308fn testChannelGetter(channel: *Channel(i32)) callconv(.Async) void {
309async fn testChannelGetter(channel: *Channel(i32)) void {
310 const value1 = channel.get();309 const value1 = channel.get();
311 testing.expect(value1 == 1234);310 testing.expect(value1 == 1234);
312311
...@@ -321,12 +320,10 @@ async fn testChannelGetter(channel: *Channel(i32)) void {...@@ -321,12 +320,10 @@ async fn testChannelGetter(channel: *Channel(i32)) void {
321 testing.expect(value4.? == 4444);320 testing.expect(value4.? == 4444);
322 await last_put;321 await last_put;
323}322}
324323fn testChannelPutter(channel: *Channel(i32)) callconv(.Async) void {
325async fn testChannelPutter(channel: *Channel(i32)) void {
326 channel.put(1234);324 channel.put(1234);
327 channel.put(4567);325 channel.put(4567);
328}326}
329327fn testPut(channel: *Channel(i32), value: i32) callconv(.Async) void {
330async fn testPut(channel: *Channel(i32), value: i32) void {
331 channel.put(value);328 channel.put(value);
332}329}
lib/std/event/future.zig+2-2
...@@ -34,7 +34,7 @@ pub fn Future(comptime T: type) type {...@@ -34,7 +34,7 @@ pub fn Future(comptime T: type) type {
34 /// Obtain the value. If it's not available, wait until it becomes34 /// Obtain the value. If it's not available, wait until it becomes
35 /// available.35 /// available.
36 /// Thread-safe.36 /// Thread-safe.
37 pub async fn get(self: *Self) *T {37 pub fn get(self: *Self) callconv(.Async) *T {
38 if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {38 if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
39 return &self.data;39 return &self.data;
40 }40 }
...@@ -59,7 +59,7 @@ pub fn Future(comptime T: type) type {...@@ -59,7 +59,7 @@ pub fn Future(comptime T: type) type {
59 /// should start working on the data.59 /// should start working on the data.
60 /// 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
61 /// this method is thread-safe.61 /// this method is thread-safe.
62 pub async fn start(self: *Self) ?*T {62 pub fn start(self: *Self) callconv(.Async) ?*T {
63 const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;63 const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
64 switch (state) {64 switch (state) {
65 .Started => {65 .Started => {
lib/std/event/group.zig+6-10
...@@ -84,7 +84,7 @@ pub fn Group(comptime ReturnType: type) type {...@@ -84,7 +84,7 @@ pub fn Group(comptime ReturnType: type) type {
84 /// Wait for all the calls and promises of the group to complete.84 /// Wait for all the calls and promises of the group to complete.
85 /// Thread-safe.85 /// Thread-safe.
86 /// Safe to call any number of times.86 /// Safe to call any number of times.
87 pub async fn wait(self: *Self) ReturnType {87 pub fn wait(self: *Self) callconv(.Async) ReturnType {
88 const held = self.lock.acquire();88 const held = self.lock.acquire();
89 defer held.release();89 defer held.release();
9090
...@@ -127,8 +127,7 @@ test "std.event.Group" {...@@ -127,8 +127,7 @@ test "std.event.Group" {
127127
128 const handle = async testGroup(std.heap.page_allocator);128 const handle = async testGroup(std.heap.page_allocator);
129}129}
130130fn testGroup(allocator: *Allocator) callconv(.Async) void {
131async fn testGroup(allocator: *Allocator) void {
132 var count: usize = 0;131 var count: usize = 0;
133 var group = Group(void).init(allocator);132 var group = Group(void).init(allocator);
134 var sleep_a_little_frame = async sleepALittle(&count);133 var sleep_a_little_frame = async sleepALittle(&count);
...@@ -145,20 +144,17 @@ async fn testGroup(allocator: *Allocator) void {...@@ -145,20 +144,17 @@ async fn testGroup(allocator: *Allocator) void {
145 another.add(&something_that_fails_frame) catch @panic("memory");144 another.add(&something_that_fails_frame) catch @panic("memory");
146 testing.expectError(error.ItBroke, another.wait());145 testing.expectError(error.ItBroke, another.wait());
147}146}
148147fn sleepALittle(count: *usize) callconv(.Async) void {
149async fn sleepALittle(count: *usize) void {
150 std.time.sleep(1 * std.time.millisecond);148 std.time.sleep(1 * std.time.millisecond);
151 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);149 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
152}150}
153151fn increaseByTen(count: *usize) callconv(.Async) void {
154async fn increaseByTen(count: *usize) void {
155 var i: usize = 0;152 var i: usize = 0;
156 while (i < 10) : (i += 1) {153 while (i < 10) : (i += 1) {
157 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);154 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
158 }155 }
159}156}
160157fn doSomethingThatFails() callconv(.Async) anyerror!void {}
161async fn doSomethingThatFails() anyerror!void {}158fn somethingElse() callconv(.Async) anyerror!void {
162async fn somethingElse() anyerror!void {
163 return error.ItBroke;159 return error.ItBroke;
164}160}
lib/std/event/lock.zig+3-5
...@@ -89,7 +89,7 @@ pub const Lock = struct {...@@ -89,7 +89,7 @@ pub const Lock = struct {
89 while (self.queue.get()) |node| resume node.data;89 while (self.queue.get()) |node| resume node.data;
90 }90 }
9191
92 pub async fn acquire(self: *Lock) Held {92 pub fn acquire(self: *Lock) callconv(.Async) Held {
93 var my_tick_node = Loop.NextTickNode.init(@frame());93 var my_tick_node = Loop.NextTickNode.init(@frame());
9494
95 errdefer _ = self.queue.remove(&my_tick_node); // TODO test canceling an acquire95 errdefer _ = self.queue.remove(&my_tick_node); // TODO test canceling an acquire
...@@ -134,8 +134,7 @@ test "std.event.Lock" {...@@ -134,8 +134,7 @@ test "std.event.Lock" {
134 const expected_result = [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;134 const expected_result = [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
135 testing.expectEqualSlices(i32, &expected_result, &shared_test_data);135 testing.expectEqualSlices(i32, &expected_result, &shared_test_data);
136}136}
137137fn testLock(lock: *Lock) callconv(.Async) void {
138async fn testLock(lock: *Lock) void {
139 var handle1 = async lockRunner(lock);138 var handle1 = async lockRunner(lock);
140 var tick_node1 = Loop.NextTickNode{139 var tick_node1 = Loop.NextTickNode{
141 .prev = undefined,140 .prev = undefined,
...@@ -167,8 +166,7 @@ async fn testLock(lock: *Lock) void {...@@ -167,8 +166,7 @@ async fn testLock(lock: *Lock) void {
167166
168var shared_test_data = [1]i32{0} ** 10;167var shared_test_data = [1]i32{0} ** 10;
169var shared_test_index: usize = 0;168var shared_test_index: usize = 0;
170169fn lockRunner(lock: *Lock) callconv(.Async) void {
171async fn lockRunner(lock: *Lock) void {
172 suspend; // resumed by onNextTick170 suspend; // resumed by onNextTick
173171
174 var i: usize = 0;172 var i: usize = 0;
lib/std/event/locked.zig+1-1
...@@ -31,7 +31,7 @@ pub fn Locked(comptime T: type) type {...@@ -31,7 +31,7 @@ pub fn Locked(comptime T: type) type {
31 self.lock.deinit();31 self.lock.deinit();
32 }32 }
3333
34 pub async fn acquire(self: *Self) HeldLock {34 pub fn acquire(self: *Self) callconv(.Async) HeldLock {
35 return HeldLock{35 return HeldLock{
36 // TODO guaranteed allocation elision36 // TODO guaranteed allocation elision
37 .held = self.lock.acquire(),37 .held = self.lock.acquire(),
lib/std/event/loop.zig+28-19
...@@ -195,7 +195,7 @@ pub const Loop = struct {...@@ -195,7 +195,7 @@ pub const Loop = struct {
195 const wakeup_bytes = [_]u8{0x1} ** 8;195 const wakeup_bytes = [_]u8{0x1} ** 8;
196196
197 fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {197 fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {
198 noasync switch (builtin.os.tag) {198 nosuspend switch (builtin.os.tag) {
199 .linux => {199 .linux => {
200 errdefer {200 errdefer {
201 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);201 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
...@@ -371,7 +371,7 @@ pub const Loop = struct {...@@ -371,7 +371,7 @@ pub const Loop = struct {
371 }371 }
372372
373 fn deinitOsData(self: *Loop) void {373 fn deinitOsData(self: *Loop) void {
374 noasync switch (builtin.os.tag) {374 nosuspend switch (builtin.os.tag) {
375 .linux => {375 .linux => {
376 os.close(self.os_data.final_eventfd);376 os.close(self.os_data.final_eventfd);
377 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);377 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
...@@ -493,7 +493,7 @@ pub const Loop = struct {...@@ -493,7 +493,7 @@ pub const Loop = struct {
493 pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {493 pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {
494 switch (builtin.os.tag) {494 switch (builtin.os.tag) {
495 .linux => {495 .linux => {
496 self.linuxWaitFd(@intCast(usize, fd), os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);496 self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
497 },497 },
498 .macosx, .freebsd, .netbsd, .dragonfly => {498 .macosx, .freebsd, .netbsd, .dragonfly => {
499 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);499 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
...@@ -503,7 +503,7 @@ pub const Loop = struct {...@@ -503,7 +503,7 @@ pub const Loop = struct {
503 }503 }
504 }504 }
505505
506 pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) void {506 pub fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, flags: u16) void {
507 var resume_node = ResumeNode.Basic{507 var resume_node = ResumeNode.Basic{
508 .base = ResumeNode{508 .base = ResumeNode{
509 .id = ResumeNode.Id.Basic,509 .id = ResumeNode.Id.Basic,
...@@ -512,21 +512,28 @@ pub const Loop = struct {...@@ -512,21 +512,28 @@ pub const Loop = struct {
512 },512 },
513 .kev = undefined,513 .kev = undefined,
514 };514 };
515 defer self.bsdRemoveKev(ident, filter);515
516 defer {
517 // If the kevent was set to be ONESHOT, it doesn't need to be deleted manually.
518 if (flags & os.EV_ONESHOT != 0) {
519 self.bsdRemoveKev(ident, filter);
520 }
521 }
522
516 suspend {523 suspend {
517 self.bsdAddKev(&resume_node, ident, filter, fflags) catch unreachable;524 self.bsdAddKev(&resume_node, ident, filter, flags) catch unreachable;
518 }525 }
519 }526 }
520527
521 /// resume_node must live longer than the anyframe that it holds a reference to.528 /// resume_node must live longer than the anyframe that it holds a reference to.
522 pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, fflags: u32) !void {529 pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, flags: u16) !void {
523 self.beginOneEvent();530 self.beginOneEvent();
524 errdefer self.finishOneEvent();531 errdefer self.finishOneEvent();
525 var kev = [1]os.Kevent{os.Kevent{532 var kev = [1]os.Kevent{os.Kevent{
526 .ident = ident,533 .ident = ident,
527 .filter = filter,534 .filter = filter,
528 .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR,535 .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR | flags,
529 .fflags = fflags,536 .fflags = 0,
530 .data = 0,537 .data = 0,
531 .udata = @ptrToInt(&resume_node.base),538 .udata = @ptrToInt(&resume_node.base),
532 }};539 }};
...@@ -616,14 +623,16 @@ pub const Loop = struct {...@@ -616,14 +623,16 @@ pub const Loop = struct {
616623
617 self.workerRun();624 self.workerRun();
618625
619 switch (builtin.os.tag) {626 if (!builtin.single_threaded) {
620 .linux,627 switch (builtin.os.tag) {
621 .macosx,628 .linux,
622 .freebsd,629 .macosx,
623 .netbsd,630 .freebsd,
624 .dragonfly,631 .netbsd,
625 => self.fs_thread.wait(),632 .dragonfly,
626 else => {},633 => self.fs_thread.wait(),
634 else => {},
635 }
627 }636 }
628637
629 for (self.extra_threads) |extra_thread| {638 for (self.extra_threads) |extra_thread| {
...@@ -663,7 +672,7 @@ pub const Loop = struct {...@@ -663,7 +672,7 @@ pub const Loop = struct {
663 }672 }
664673
665 pub fn finishOneEvent(self: *Loop) void {674 pub fn finishOneEvent(self: *Loop) void {
666 noasync {675 nosuspend {
667 const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst);676 const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst);
668 if (prev != 1) return;677 if (prev != 1) return;
669678
...@@ -1041,7 +1050,7 @@ pub const Loop = struct {...@@ -1041,7 +1050,7 @@ pub const Loop = struct {
1041 }1050 }
10421051
1043 fn posixFsRun(self: *Loop) void {1052 fn posixFsRun(self: *Loop) void {
1044 noasync while (true) {1053 nosuspend while (true) {
1045 self.fs_thread_wakeup.reset();1054 self.fs_thread_wakeup.reset();
1046 while (self.fs_queue.get()) |node| {1055 while (self.fs_queue.get()) |node| {
1047 switch (node.data.msg) {1056 switch (node.data.msg) {
lib/std/event/rwlock.zig+5-8
...@@ -97,7 +97,7 @@ pub const RwLock = struct {...@@ -97,7 +97,7 @@ pub const RwLock = struct {
97 while (self.reader_queue.get()) |node| resume node.data;97 while (self.reader_queue.get()) |node| resume node.data;
98 }98 }
9999
100 pub async fn acquireRead(self: *RwLock) HeldRead {100 pub fn acquireRead(self: *RwLock) callconv(.Async) HeldRead {
101 _ = @atomicRmw(usize, &self.reader_lock_count, .Add, 1, .SeqCst);101 _ = @atomicRmw(usize, &self.reader_lock_count, .Add, 1, .SeqCst);
102102
103 suspend {103 suspend {
...@@ -130,7 +130,7 @@ pub const RwLock = struct {...@@ -130,7 +130,7 @@ pub const RwLock = struct {
130 return HeldRead{ .lock = self };130 return HeldRead{ .lock = self };
131 }131 }
132132
133 pub async fn acquireWrite(self: *RwLock) HeldWrite {133 pub fn acquireWrite(self: *RwLock) callconv(.Async) HeldWrite {
134 suspend {134 suspend {
135 var my_tick_node = Loop.NextTickNode{135 var my_tick_node = Loop.NextTickNode{
136 .data = @frame(),136 .data = @frame(),
...@@ -225,8 +225,7 @@ test "std.event.RwLock" {...@@ -225,8 +225,7 @@ test "std.event.RwLock" {
225 const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;225 const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
226 testing.expectEqualSlices(i32, expected_result, shared_test_data);226 testing.expectEqualSlices(i32, expected_result, shared_test_data);
227}227}
228228fn testLock(allocator: *Allocator, lock: *RwLock) callconv(.Async) void {
229async fn testLock(allocator: *Allocator, lock: *RwLock) void {
230 var read_nodes: [100]Loop.NextTickNode = undefined;229 var read_nodes: [100]Loop.NextTickNode = undefined;
231 for (read_nodes) |*read_node| {230 for (read_nodes) |*read_node| {
232 const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");231 const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");
...@@ -259,8 +258,7 @@ const shared_it_count = 10;...@@ -259,8 +258,7 @@ const shared_it_count = 10;
259var shared_test_data = [1]i32{0} ** 10;258var shared_test_data = [1]i32{0} ** 10;
260var shared_test_index: usize = 0;259var shared_test_index: usize = 0;
261var shared_count: usize = 0;260var shared_count: usize = 0;
262261fn writeRunner(lock: *RwLock) callconv(.Async) void {
263async fn writeRunner(lock: *RwLock) void {
264 suspend; // resumed by onNextTick262 suspend; // resumed by onNextTick
265263
266 var i: usize = 0;264 var i: usize = 0;
...@@ -277,8 +275,7 @@ async fn writeRunner(lock: *RwLock) void {...@@ -277,8 +275,7 @@ async fn writeRunner(lock: *RwLock) void {
277 shared_test_index = 0;275 shared_test_index = 0;
278 }276 }
279}277}
280278fn readRunner(lock: *RwLock) callconv(.Async) void {
281async fn readRunner(lock: *RwLock) void {
282 suspend; // resumed by onNextTick279 suspend; // resumed by onNextTick
283 std.time.sleep(1);280 std.time.sleep(1);
284281
lib/std/event/rwlocked.zig+2-2
...@@ -40,14 +40,14 @@ pub fn RwLocked(comptime T: type) type {...@@ -40,14 +40,14 @@ pub fn RwLocked(comptime T: type) type {
40 self.lock.deinit();40 self.lock.deinit();
41 }41 }
4242
43 pub async fn acquireRead(self: *Self) HeldReadLock {43 pub fn acquireRead(self: *Self) callconv(.Async) HeldReadLock {
44 return HeldReadLock{44 return HeldReadLock{
45 .held = self.lock.acquireRead(),45 .held = self.lock.acquireRead(),
46 .value = &self.locked_data,46 .value = &self.locked_data,
47 };47 };
48 }48 }
4949
50 pub async fn acquireWrite(self: *Self) HeldWriteLock {50 pub fn acquireWrite(self: *Self) callconv(.Async) HeldWriteLock {
51 return HeldWriteLock{51 return HeldWriteLock{
52 .held = self.lock.acquireWrite(),52 .held = self.lock.acquireWrite(),
53 .value = &self.locked_data,53 .value = &self.locked_data,
lib/std/fs/file.zig+2-2
...@@ -66,7 +66,7 @@ pub const File = struct {...@@ -66,7 +66,7 @@ pub const File = struct {
66 lock_nonblocking: bool = false,66 lock_nonblocking: bool = false,
6767
68 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even68 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even
69 /// if `std.io.is_async`. It allows the use of `noasync` when calling functions69 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
70 /// related to opening the file, reading, writing, and locking.70 /// related to opening the file, reading, writing, and locking.
71 intended_io_mode: io.ModeOverride = io.default_mode,71 intended_io_mode: io.ModeOverride = io.default_mode,
72 };72 };
...@@ -112,7 +112,7 @@ pub const File = struct {...@@ -112,7 +112,7 @@ pub const File = struct {
112 mode: Mode = default_mode,112 mode: Mode = default_mode,
113113
114 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even114 /// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even
115 /// if `std.io.is_async`. It allows the use of `noasync` when calling functions115 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
116 /// related to opening the file, reading, writing, and locking.116 /// related to opening the file, reading, writing, and locking.
117 intended_io_mode: io.ModeOverride = io.default_mode,117 intended_io_mode: io.ModeOverride = io.default_mode,
118 };118 };
lib/std/hash/auto_hash.zig+1-3
...@@ -113,11 +113,9 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {...@@ -113,11 +113,9 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
113 hasher.update(mem.asBytes(&key));113 hasher.update(mem.asBytes(&key));
114 } else {114 } else {
115 // Otherwise, hash every element.115 // Otherwise, hash every element.
116 // TODO remove the copy to an array once field access is done.
117 const array: [info.len]info.child = key;
118 comptime var i = 0;116 comptime var i = 0;
119 inline while (i < info.len) : (i += 1) {117 inline while (i < info.len) : (i += 1) {
120 hash(hasher, array[i], strat);118 hash(hasher, key[i], strat);
121 }119 }
122 }120 }
123 },121 },
lib/std/json.zig+4-4
...@@ -136,7 +136,7 @@ pub const Token = union(enum) {...@@ -136,7 +136,7 @@ pub const Token = union(enum) {
136/// they are encountered. No copies or allocations are performed during parsing and the entire136/// they are encountered. No copies or allocations are performed during parsing and the entire
137/// parsing state requires ~40-50 bytes of stack space.137/// parsing state requires ~40-50 bytes of stack space.
138///138///
139/// Conforms strictly to RFC8529.139/// Conforms strictly to RFC8259.
140///140///
141/// For a non-byte based wrapper, consider using TokenStream instead.141/// For a non-byte based wrapper, consider using TokenStream instead.
142pub const StreamingParser = struct {142pub const StreamingParser = struct {
...@@ -2194,7 +2194,7 @@ test "write json then parse it" {...@@ -2194,7 +2194,7 @@ test "write json then parse it" {
2194 try jw.emitBool(true);2194 try jw.emitBool(true);
21952195
2196 try jw.objectField("int");2196 try jw.objectField("int");
2197 try jw.emitNumber(@as(i32, 1234));2197 try jw.emitNumber(1234);
21982198
2199 try jw.objectField("array");2199 try jw.objectField("array");
2200 try jw.beginArray();2200 try jw.beginArray();
...@@ -2203,7 +2203,7 @@ test "write json then parse it" {...@@ -2203,7 +2203,7 @@ test "write json then parse it" {
2203 try jw.emitNull();2203 try jw.emitNull();
22042204
2205 try jw.arrayElem();2205 try jw.arrayElem();
2206 try jw.emitNumber(@as(f64, 12.34));2206 try jw.emitNumber(12.34);
22072207
2208 try jw.endArray();2208 try jw.endArray();
22092209
...@@ -2336,7 +2336,7 @@ pub const StringifyOptions = struct {...@@ -2336,7 +2336,7 @@ pub const StringifyOptions = struct {
2336 /// After a colon, should whitespace be inserted?2336 /// After a colon, should whitespace be inserted?
2337 separator: bool = true,2337 separator: bool = true,
23382338
2339 fn outputIndent(2339 pub fn outputIndent(
2340 whitespace: @This(),2340 whitespace: @This(),
2341 out_stream: var,2341 out_stream: var,
2342 ) @TypeOf(out_stream).Error!void {2342 ) @TypeOf(out_stream).Error!void {
lib/std/json/write_stream.zig+36-25
...@@ -168,8 +168,11 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {...@@ -168,8 +168,11 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
168 return;168 return;
169 }169 }
170 },170 },
171 .Float => if (@floatCast(f64, value) == value) {171 .ComptimeInt => {
172 try self.stream.print("{}", .{value});172 return self.emitNumber(@as(std.math.IntFittingRange(value, value), value));
173 },
174 .Float, .ComptimeFloat => if (@floatCast(f64, value) == value) {
175 try self.stream.print("{}", .{@floatCast(f64, value)});
173 self.popState();176 self.popState();
174 return;177 return;
175 },178 },
...@@ -180,6 +183,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {...@@ -180,6 +183,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
180 }183 }
181184
182 pub fn emitString(self: *Self, string: []const u8) !void {185 pub fn emitString(self: *Self, string: []const u8) !void {
186 assert(self.state[self.state_index] == State.Value);
183 try self.writeEscapedString(string);187 try self.writeEscapedString(string);
184 self.popState();188 self.popState();
185 }189 }
...@@ -191,7 +195,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {...@@ -191,7 +195,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
191195
192 /// Writes the complete json into the output stream196 /// Writes the complete json into the output stream
193 pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void {197 pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void {
198 assert(self.state[self.state_index] == State.Value);
194 try self.stringify(json);199 try self.stringify(json);
200 self.popState();
195 }201 }
196202
197 fn indent(self: *Self) !void {203 fn indent(self: *Self) !void {
...@@ -233,7 +239,32 @@ test "json write stream" {...@@ -233,7 +239,32 @@ test "json write stream" {
233 defer arena_allocator.deinit();239 defer arena_allocator.deinit();
234240
235 var w = std.json.writeStream(out, 10);241 var w = std.json.writeStream(out, 10);
236 try w.emitJson(try getJson(&arena_allocator.allocator));242
243 try w.beginObject();
244
245 try w.objectField("object");
246 try w.emitJson(try getJsonObject(&arena_allocator.allocator));
247
248 try w.objectField("string");
249 try w.emitString("This is a string");
250
251 try w.objectField("array");
252 try w.beginArray();
253 try w.arrayElem();
254 try w.emitString("Another string");
255 try w.arrayElem();
256 try w.emitNumber(@as(i32, 1));
257 try w.arrayElem();
258 try w.emitNumber(@as(f32, 3.5));
259 try w.endArray();
260
261 try w.objectField("int");
262 try w.emitNumber(@as(i32, 10));
263
264 try w.objectField("float");
265 try w.emitNumber(@as(f32, 3.5));
266
267 try w.endObject();
237268
238 const result = slice_stream.getWritten();269 const result = slice_stream.getWritten();
239 const expected =270 const expected =
...@@ -246,38 +277,18 @@ test "json write stream" {...@@ -246,38 +277,18 @@ test "json write stream" {
246 \\ "array": [277 \\ "array": [
247 \\ "Another string",278 \\ "Another string",
248 \\ 1,279 \\ 1,
249 \\ 3.14e+00280 \\ 3.5e+00
250 \\ ],281 \\ ],
251 \\ "int": 10,282 \\ "int": 10,
252 \\ "float": 3.14e+00283 \\ "float": 3.5e+00
253 \\}284 \\}
254 ;285 ;
255 std.testing.expect(std.mem.eql(u8, expected, result));286 std.testing.expect(std.mem.eql(u8, expected, result));
256}287}
257288
258fn getJson(allocator: *std.mem.Allocator) !std.json.Value {
259 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
260 _ = try value.Object.put("string", std.json.Value{ .String = "This is a string" });
261 _ = try value.Object.put("int", std.json.Value{ .Integer = @intCast(i64, 10) });
262 _ = try value.Object.put("float", std.json.Value{ .Float = 3.14 });
263 _ = try value.Object.put("array", try getJsonArray(allocator));
264 _ = try value.Object.put("object", try getJsonObject(allocator));
265 return value;
266}
267
268fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {289fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {
269 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };290 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
270 _ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });291 _ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });
271 _ = try value.Object.put("two", std.json.Value{ .Float = 2.0 });292 _ = try value.Object.put("two", std.json.Value{ .Float = 2.0 });
272 return value;293 return value;
273}294}
274
275fn getJsonArray(allocator: *std.mem.Allocator) !std.json.Value {
276 var value = std.json.Value{ .Array = std.json.Array.init(allocator) };
277 var array = &value.Array;
278 _ = try array.append(std.json.Value{ .String = "Another string" });
279 _ = try array.append(std.json.Value{ .Integer = @intCast(i64, 1) });
280 _ = try array.append(std.json.Value{ .Float = 3.14 });
281
282 return value;
283}
lib/std/mem.zig+25-2
...@@ -124,9 +124,9 @@ pub const Allocator = struct {...@@ -124,9 +124,9 @@ pub const Allocator = struct {
124124
125 fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, comptime sentinel: ?Elem) type {125 fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, comptime sentinel: ?Elem) type {
126 if (sentinel) |s| {126 if (sentinel) |s| {
127 return [:s]align(alignment orelse @alignOf(T)) Elem;127 return [:s]align(alignment orelse @alignOf(Elem)) Elem;
128 } else {128 } else {
129 return []align(alignment orelse @alignOf(T)) Elem;129 return []align(alignment orelse @alignOf(Elem)) Elem;
130 }130 }
131 }131 }
132132
...@@ -296,6 +296,22 @@ pub const Allocator = struct {...@@ -296,6 +296,22 @@ pub const Allocator = struct {
296 }296 }
297};297};
298298
299var failAllocator = Allocator {
300 .reallocFn = failAllocatorRealloc,
301 .shrinkFn = failAllocatorShrink,
302};
303fn failAllocatorRealloc(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
304 return error.OutOfMemory;
305}
306fn failAllocatorShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
307 @panic("failAllocatorShrink should never be called because it cannot allocate");
308}
309
310test "mem.Allocator basics" {
311 testing.expectError(error.OutOfMemory, failAllocator.alloc(u8, 1));
312 testing.expectError(error.OutOfMemory, failAllocator.allocSentinel(u8, 1, 0));
313}
314
299/// Copy all of source into dest at position 0.315/// Copy all of source into dest at position 0.
300/// dest.len must be >= source.len.316/// dest.len must be >= source.len.
301/// dest.ptr must be <= src.ptr.317/// dest.ptr must be <= src.ptr.
...@@ -381,6 +397,9 @@ pub fn zeroes(comptime T: type) T {...@@ -381,6 +397,9 @@ pub fn zeroes(comptime T: type) T {
381 }397 }
382 },398 },
383 .Array => |info| {399 .Array => |info| {
400 if (info.sentinel) |sentinel| {
401 return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
402 }
384 return [_]info.child{zeroes(info.child)} ** info.len;403 return [_]info.child{zeroes(info.child)} ** info.len;
385 },404 },
386 .Vector,405 .Vector,
...@@ -441,6 +460,7 @@ test "mem.zeroes" {...@@ -441,6 +460,7 @@ test "mem.zeroes" {
441 array: [2]u32,460 array: [2]u32,
442 optional_int: ?u8,461 optional_int: ?u8,
443 empty: void,462 empty: void,
463 sentinel: [3:0]u8,
444 };464 };
445465
446 const b = zeroes(ZigStruct);466 const b = zeroes(ZigStruct);
...@@ -465,6 +485,9 @@ test "mem.zeroes" {...@@ -465,6 +485,9 @@ test "mem.zeroes" {
465 testing.expectEqual(@as(u32, 0), e);485 testing.expectEqual(@as(u32, 0), e);
466 }486 }
467 testing.expectEqual(@as(?u8, null), b.optional_int);487 testing.expectEqual(@as(?u8, null), b.optional_int);
488 for (b.sentinel) |e| {
489 testing.expectEqual(@as(u8, 0), e);
490 }
468}491}
469492
470pub fn secureZero(comptime T: type, s: []T) void {493pub fn secureZero(comptime T: type, s: []T) void {
lib/std/net.zig+6-3
...@@ -341,7 +341,7 @@ pub const Address = extern union {...@@ -341,7 +341,7 @@ pub const Address = extern union {
341 return mem.eql(u8, a_bytes, b_bytes);341 return mem.eql(u8, a_bytes, b_bytes);
342 }342 }
343343
344 fn getOsSockLen(self: Address) os.socklen_t {344 pub fn getOsSockLen(self: Address) os.socklen_t {
345 switch (self.any.family) {345 switch (self.any.family) {
346 os.AF_INET => return @sizeOf(os.sockaddr_in),346 os.AF_INET => return @sizeOf(os.sockaddr_in),
347 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),347 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
...@@ -377,7 +377,6 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {...@@ -377,7 +377,6 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
377377
378 return fs.File{378 return fs.File{
379 .handle = sockfd,379 .handle = sockfd,
380 .io_mode = std.io.mode,
381 };380 };
382}381}
383382
...@@ -386,7 +385,7 @@ pub const AddressList = struct {...@@ -386,7 +385,7 @@ pub const AddressList = struct {
386 addrs: []Address,385 addrs: []Address,
387 canon_name: ?[]u8,386 canon_name: ?[]u8,
388387
389 fn deinit(self: *AddressList) void {388 pub fn deinit(self: *AddressList) void {
390 // Here we copy the arena allocator into stack memory, because389 // Here we copy the arena allocator into stack memory, because
391 // otherwise it would destroy itself while it was still working.390 // otherwise it would destroy itself while it was still working.
392 var arena = self.arena;391 var arena = self.arena;
...@@ -1366,6 +1365,10 @@ pub const StreamServer = struct {...@@ -1366,6 +1365,10 @@ pub const StreamServer = struct {
13661365
1367 /// Firewall rules forbid connection.1366 /// Firewall rules forbid connection.
1368 BlockedByFirewall,1367 BlockedByFirewall,
1368
1369 /// Permission to create a socket of the specified type and/or
1370 /// protocol is denied.
1371 PermissionDenied,
1369 } || os.UnexpectedError;1372 } || os.UnexpectedError;
13701373
1371 pub const Connection = struct {1374 pub const Connection = struct {
lib/std/net/test.zig+1-1
...@@ -81,7 +81,7 @@ test "resolve DNS" {...@@ -81,7 +81,7 @@ test "resolve DNS" {
81test "listen on a port, send bytes, receive bytes" {81test "listen on a port, send bytes, receive bytes" {
82 if (!std.io.is_async) return error.SkipZigTest;82 if (!std.io.is_async) return error.SkipZigTest;
8383
84 if (std.builtin.os.tag != .linux) {84 if (std.builtin.os.tag != .linux and !std.builtin.os.tag.isDarwin()) {
85 // TODO build abstractions for other operating systems85 // TODO build abstractions for other operating systems
86 return error.SkipZigTest;86 return error.SkipZigTest;
87 }87 }
lib/std/os.zig+18-8
...@@ -292,6 +292,7 @@ pub const ReadError = error{...@@ -292,6 +292,7 @@ pub const ReadError = error{
292 OperationAborted,292 OperationAborted,
293 BrokenPipe,293 BrokenPipe,
294 ConnectionResetByPeer,294 ConnectionResetByPeer,
295 ConnectionTimedOut,
295296
296 /// This error occurs when no global event loop is configured,297 /// This error occurs when no global event loop is configured,
297 /// and reading from the file descriptor would block.298 /// and reading from the file descriptor would block.
...@@ -351,6 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -351,6 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
351 ENOBUFS => return error.SystemResources,352 ENOBUFS => return error.SystemResources,
352 ENOMEM => return error.SystemResources,353 ENOMEM => return error.SystemResources,
353 ECONNRESET => return error.ConnectionResetByPeer,354 ECONNRESET => return error.ConnectionResetByPeer,
355 ETIMEDOUT => return error.ConnectionTimedOut,
354 else => |err| return unexpectedErrno(err),356 else => |err| return unexpectedErrno(err),
355 }357 }
356 }358 }
...@@ -2156,6 +2158,9 @@ pub const SocketError = error{...@@ -2156,6 +2158,9 @@ pub const SocketError = error{
21562158
2157 /// The protocol type or the specified protocol is not supported within this domain.2159 /// The protocol type or the specified protocol is not supported within this domain.
2158 ProtocolNotSupported,2160 ProtocolNotSupported,
2161
2162 /// The socket type is not supported by the protocol.
2163 SocketTypeNotSupported,
2159} || UnexpectedError;2164} || UnexpectedError;
21602165
2161pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {2166pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
...@@ -2164,11 +2169,11 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {...@@ -2164,11 +2169,11 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
2164 socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC)2169 socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC)
2165 else2170 else
2166 socket_type;2171 socket_type;
2167 const rc = system.socket(domain, socket_type, protocol);2172 const rc = system.socket(domain, filtered_sock_type, protocol);
2168 switch (errno(rc)) {2173 switch (errno(rc)) {
2169 0 => {2174 0 => {
2170 const fd = @intCast(fd_t, rc);2175 const fd = @intCast(fd_t, rc);
2171 if (!have_sock_flags and filtered_sock_type != socket_type) {2176 if (!have_sock_flags) {
2172 try setSockFlags(fd, socket_type);2177 try setSockFlags(fd, socket_type);
2173 }2178 }
2174 return fd;2179 return fd;
...@@ -2181,6 +2186,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {...@@ -2181,6 +2186,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
2181 ENOBUFS => return error.SystemResources,2186 ENOBUFS => return error.SystemResources,
2182 ENOMEM => return error.SystemResources,2187 ENOMEM => return error.SystemResources,
2183 EPROTONOSUPPORT => return error.ProtocolNotSupported,2188 EPROTONOSUPPORT => return error.ProtocolNotSupported,
2189 EPROTOTYPE => return error.SocketTypeNotSupported,
2184 else => |err| return unexpectedErrno(err),2190 else => |err| return unexpectedErrno(err),
2185 }2191 }
2186}2192}
...@@ -2290,6 +2296,10 @@ pub const AcceptError = error{...@@ -2290,6 +2296,10 @@ pub const AcceptError = error{
2290 /// This error occurs when no global event loop is configured,2296 /// This error occurs when no global event loop is configured,
2291 /// and accepting from the socket would block.2297 /// and accepting from the socket would block.
2292 WouldBlock,2298 WouldBlock,
2299
2300 /// Permission to create a socket of the specified type and/or
2301 /// protocol is denied.
2302 PermissionDenied,
2293} || UnexpectedError;2303} || UnexpectedError;
22942304
2295/// Accept a connection on a socket.2305/// Accept a connection on a socket.
...@@ -2331,7 +2341,7 @@ pub fn accept(...@@ -2331,7 +2341,7 @@ pub fn accept(
2331 switch (errno(rc)) {2341 switch (errno(rc)) {
2332 0 => {2342 0 => {
2333 const fd = @intCast(fd_t, rc);2343 const fd = @intCast(fd_t, rc);
2334 if (!have_accept4 and flags != 0) {2344 if (!have_accept4) {
2335 try setSockFlags(fd, flags);2345 try setSockFlags(fd, flags);
2336 }2346 }
2337 return fd;2347 return fd;
...@@ -2539,7 +2549,7 @@ pub fn connect(sockfd: fd_t, sock_addr: *const sockaddr, len: socklen_t) Connect...@@ -2539,7 +2549,7 @@ pub fn connect(sockfd: fd_t, sock_addr: *const sockaddr, len: socklen_t) Connect
2539 EAFNOSUPPORT => return error.AddressFamilyNotSupported,2549 EAFNOSUPPORT => return error.AddressFamilyNotSupported,
2540 EAGAIN, EINPROGRESS => {2550 EAGAIN, EINPROGRESS => {
2541 const loop = std.event.Loop.instance orelse return error.WouldBlock;2551 const loop = std.event.Loop.instance orelse return error.WouldBlock;
2542 loop.waitUntilFdWritableOrReadable(sockfd);2552 loop.waitUntilFdWritable(sockfd);
2543 return getsockoptError(sockfd);2553 return getsockoptError(sockfd);
2544 },2554 },
2545 EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.2555 EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.
...@@ -3267,26 +3277,26 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {...@@ -3267,26 +3277,26 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
3267}3277}
32683278
3269fn setSockFlags(fd: fd_t, flags: u32) !void {3279fn setSockFlags(fd: fd_t, flags: u32) !void {
3270 {3280 if ((flags & SOCK_CLOEXEC) != 0) {
3271 var fd_flags = fcntl(fd, F_GETFD, 0) catch |err| switch (err) {3281 var fd_flags = fcntl(fd, F_GETFD, 0) catch |err| switch (err) {
3272 error.FileBusy => unreachable,3282 error.FileBusy => unreachable,
3273 error.Locked => unreachable,3283 error.Locked => unreachable,
3274 else => |e| return e,3284 else => |e| return e,
3275 };3285 };
3276 if ((flags & SOCK_NONBLOCK) != 0) fd_flags |= FD_CLOEXEC;3286 fd_flags |= FD_CLOEXEC;
3277 _ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {3287 _ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {
3278 error.FileBusy => unreachable,3288 error.FileBusy => unreachable,
3279 error.Locked => unreachable,3289 error.Locked => unreachable,
3280 else => |e| return e,3290 else => |e| return e,
3281 };3291 };
3282 }3292 }
3283 {3293 if ((flags & SOCK_NONBLOCK) != 0) {
3284 var fl_flags = fcntl(fd, F_GETFL, 0) catch |err| switch (err) {3294 var fl_flags = fcntl(fd, F_GETFL, 0) catch |err| switch (err) {
3285 error.FileBusy => unreachable,3295 error.FileBusy => unreachable,
3286 error.Locked => unreachable,3296 error.Locked => unreachable,
3287 else => |e| return e,3297 else => |e| return e,
3288 };3298 };
3289 if ((flags & SOCK_CLOEXEC) != 0) fl_flags |= O_NONBLOCK;3299 fl_flags |= O_NONBLOCK;
3290 _ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {3300 _ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {
3291 error.FileBusy => unreachable,3301 error.FileBusy => unreachable,
3292 error.Locked => unreachable,3302 error.Locked => unreachable,
lib/std/os/bits/darwin.zig+5-5
...@@ -125,7 +125,7 @@ pub const empty_sigset = sigset_t(0);...@@ -125,7 +125,7 @@ pub const empty_sigset = sigset_t(0);
125125
126/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.126/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
127pub const Sigaction = extern struct {127pub const Sigaction = extern struct {
128 handler: extern fn (c_int) void,128 handler: fn (c_int) callconv(.C) void,
129 sa_mask: sigset_t,129 sa_mask: sigset_t,
130 sa_flags: c_int,130 sa_flags: c_int,
131};131};
...@@ -1263,10 +1263,10 @@ pub const RTLD_NOLOAD = 0x10;...@@ -1263,10 +1263,10 @@ pub const RTLD_NOLOAD = 0x10;
1263pub const RTLD_NODELETE = 0x80;1263pub const RTLD_NODELETE = 0x80;
1264pub const RTLD_FIRST = 0x100;1264pub const RTLD_FIRST = 0x100;
12651265
1266pub const RTLD_NEXT = @intToPtr(*c_void, ~maxInt(usize));1266pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
1267pub const RTLD_DEFAULT = @intToPtr(*c_void, ~maxInt(usize) - 1);1267pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
1268pub const RTLD_SELF = @intToPtr(*c_void, ~maxInt(usize) - 2);1268pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
1269pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, ~maxInt(usize) - 4);1269pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, @bitCast(usize, @as(isize, -5)));
12701270
1271/// duplicate file descriptor1271/// duplicate file descriptor
1272pub const F_DUPFD = 0;1272pub const F_DUPFD = 0;
lib/std/os/bits/dragonfly.zig+6-6
...@@ -458,9 +458,9 @@ pub const S_IFSOCK = 49152;...@@ -458,9 +458,9 @@ pub const S_IFSOCK = 49152;
458pub const S_IFWHT = 57344;458pub const S_IFWHT = 57344;
459pub const S_IFMT = 61440;459pub const S_IFMT = 61440;
460460
461pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));461pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
462pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);462pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
463pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);463pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
464pub const BADSIG = SIG_ERR;464pub const BADSIG = SIG_ERR;
465pub const SIG_BLOCK = 1;465pub const SIG_BLOCK = 1;
466pub const SIG_UNBLOCK = 2;466pub const SIG_UNBLOCK = 2;
...@@ -519,13 +519,13 @@ pub const sigset_t = extern struct {...@@ -519,13 +519,13 @@ pub const sigset_t = extern struct {
519pub const sig_atomic_t = c_int;519pub const sig_atomic_t = c_int;
520pub const Sigaction = extern struct {520pub const Sigaction = extern struct {
521 __sigaction_u: extern union {521 __sigaction_u: extern union {
522 __sa_handler: ?extern fn (c_int) void,522 __sa_handler: ?fn (c_int) callconv(.C) void,
523 __sa_sigaction: ?extern fn (c_int, [*c]siginfo_t, ?*c_void) void,523 __sa_sigaction: ?fn (c_int, [*c]siginfo_t, ?*c_void) callconv(.C) void,
524 },524 },
525 sa_flags: c_int,525 sa_flags: c_int,
526 sa_mask: sigset_t,526 sa_mask: sigset_t,
527};527};
528pub const sig_t = [*c]extern fn (c_int) void;528pub const sig_t = [*c]fn (c_int) callconv(.C) void;
529529
530pub const sigvec = extern struct {530pub const sigvec = extern struct {
531 sv_handler: [*c]__sighandler_t,531 sv_handler: [*c]__sighandler_t,
lib/std/os/bits/freebsd.zig+5-5
...@@ -725,16 +725,16 @@ pub const winsize = extern struct {...@@ -725,16 +725,16 @@ pub const winsize = extern struct {
725725
726const NSIG = 32;726const NSIG = 32;
727727
728pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));728pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
729pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);729pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
730pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);730pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
731731
732/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.732/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
733pub const Sigaction = extern struct {733pub const Sigaction = extern struct {
734 /// signal handler734 /// signal handler
735 __sigaction_u: extern union {735 __sigaction_u: extern union {
736 __sa_handler: extern fn (i32) void,736 __sa_handler: fn (i32) callconv(.C) void,
737 __sa_sigaction: extern fn (i32, *__siginfo, usize) void,737 __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
738 },738 },
739739
740 /// see signal options740 /// see signal options
lib/std/os/bits/linux.zig+5-5
...@@ -813,15 +813,15 @@ pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffff...@@ -813,15 +813,15 @@ pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffff
813pub const k_sigaction = if (is_mips)813pub const k_sigaction = if (is_mips)
814 extern struct {814 extern struct {
815 flags: usize,815 flags: usize,
816 sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,816 sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
817 mask: [4]u32,817 mask: [4]u32,
818 restorer: extern fn () void,818 restorer: fn () callconv(.C) void,
819 }819 }
820else820else
821 extern struct {821 extern struct {
822 sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,822 sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
823 flags: usize,823 flags: usize,
824 restorer: extern fn () void,824 restorer: fn () callconv(.C) void,
825 mask: [2]u32,825 mask: [2]u32,
826 };826 };
827827
...@@ -831,7 +831,7 @@ pub const Sigaction = extern struct {...@@ -831,7 +831,7 @@ pub const Sigaction = extern struct {
831 sigaction: ?sigaction_fn,831 sigaction: ?sigaction_fn,
832 mask: sigset_t,832 mask: sigset_t,
833 flags: u32,833 flags: u32,
834 restorer: ?extern fn () void = null,834 restorer: ?fn () callconv(.C) void = null,
835};835};
836836
837pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));837pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
lib/std/os/linux.zig+2-2
...@@ -599,7 +599,7 @@ pub fn flock(fd: fd_t, operation: i32) usize {...@@ -599,7 +599,7 @@ pub fn flock(fd: fd_t, operation: i32) usize {
599var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);599var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
600600
601// We must follow the C calling convention when we call into the VDSO601// We must follow the C calling convention when we call into the VDSO
602const vdso_clock_gettime_ty = extern fn (i32, *timespec) usize;602const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;
603603
604pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {604pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
605 if (@hasDecl(@This(), "VDSO_CGT_SYM")) {605 if (@hasDecl(@This(), "VDSO_CGT_SYM")) {
...@@ -791,7 +791,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti...@@ -791,7 +791,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
791 .sigaction = act.sigaction,791 .sigaction = act.sigaction,
792 .flags = act.flags | SA_RESTORER,792 .flags = act.flags | SA_RESTORER,
793 .mask = undefined,793 .mask = undefined,
794 .restorer = @ptrCast(extern fn () void, restorer_fn),794 .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
795 };795 };
796 var ksa_old: k_sigaction = undefined;796 var ksa_old: k_sigaction = undefined;
797 const ksa_mask_size = @sizeOf(@TypeOf(ksa_old.mask));797 const ksa_mask_size = @sizeOf(@TypeOf(ksa_old.mask));
lib/std/os/linux/arm-eabi.zig+1-1
...@@ -86,7 +86,7 @@ pub fn syscall6(...@@ -86,7 +86,7 @@ pub fn syscall6(
86}86}
8787
88/// This matches the libc clone function.88/// This matches the libc clone function.
89pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;89pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
9090
91pub fn restore() callconv(.Naked) void {91pub fn restore() callconv(.Naked) void {
92 return asm volatile ("svc #0"92 return asm volatile ("svc #0"
lib/std/os/linux/arm64.zig+1-1
...@@ -86,7 +86,7 @@ pub fn syscall6(...@@ -86,7 +86,7 @@ pub fn syscall6(
86}86}
8787
88/// This matches the libc clone function.88/// This matches the libc clone function.
89pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;89pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
9090
91pub const restore = restore_rt;91pub const restore = restore_rt;
9292
lib/std/os/linux/i386.zig+1-1
...@@ -106,7 +106,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize {...@@ -106,7 +106,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
106}106}
107107
108/// This matches the libc clone function.108/// This matches the libc clone function.
109pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;109pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
110110
111pub fn restore() callconv(.Naked) void {111pub fn restore() callconv(.Naked) void {
112 return asm volatile ("int $0x80"112 return asm volatile ("int $0x80"
lib/std/os/linux/mips.zig+1-1
...@@ -142,7 +142,7 @@ pub fn syscall6(...@@ -142,7 +142,7 @@ pub fn syscall6(
142}142}
143143
144/// This matches the libc clone function.144/// This matches the libc clone function.
145pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;145pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
146146
147pub fn restore() callconv(.Naked) void {147pub fn restore() callconv(.Naked) void {
148 return asm volatile ("syscall"148 return asm volatile ("syscall"
lib/std/os/linux/riscv64.zig+1-1
...@@ -85,7 +85,7 @@ pub fn syscall6(...@@ -85,7 +85,7 @@ pub fn syscall6(
85 );85 );
86}86}
8787
88pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;88pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
8989
90pub const restore = restore_rt;90pub const restore = restore_rt;
9191
lib/std/os/linux/x86_64.zig+1-1
...@@ -86,7 +86,7 @@ pub fn syscall6(...@@ -86,7 +86,7 @@ pub fn syscall6(
86}86}
8787
88/// This matches the libc clone function.88/// This matches the libc clone function.
89pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;89pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
9090
91pub const restore = restore_rt;91pub const restore = restore_rt;
9292
lib/std/os/uefi/protocols/absolute_pointer_protocol.zig+2-2
...@@ -5,8 +5,8 @@ const Status = uefi.Status;...@@ -5,8 +5,8 @@ const Status = uefi.Status;
55
6/// Protocol for touchscreens6/// Protocol for touchscreens
7pub const AbsolutePointerProtocol = extern struct {7pub const AbsolutePointerProtocol = extern struct {
8 _reset: extern fn (*const AbsolutePointerProtocol, bool) Status,8 _reset: fn (*const AbsolutePointerProtocol, bool) callconv(.C) Status,
9 _get_state: extern fn (*const AbsolutePointerProtocol, *AbsolutePointerState) Status,9 _get_state: fn (*const AbsolutePointerProtocol, *AbsolutePointerState) callconv(.C) Status,
10 wait_for_input: Event,10 wait_for_input: Event,
11 mode: *AbsolutePointerMode,11 mode: *AbsolutePointerMode,
1212
lib/std/os/uefi/protocols/edid_override_protocol.zig+1-1
...@@ -5,7 +5,7 @@ const Status = uefi.Status;...@@ -5,7 +5,7 @@ const Status = uefi.Status;
55
6/// Override EDID information6/// Override EDID information
7pub const EdidOverrideProtocol = extern struct {7pub const EdidOverrideProtocol = extern struct {
8 _get_edid: extern fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) Status,8 _get_edid: fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) callconv(.C) Status,
99
10 /// Returns policy information and potentially a replacement EDID for the specified video output device.10 /// Returns policy information and potentially a replacement EDID for the specified video output device.
11 /// attributes must be align(4)11 /// attributes must be align(4)
lib/std/os/uefi/protocols/file_protocol.zig+10-10
...@@ -5,16 +5,16 @@ const Status = uefi.Status;...@@ -5,16 +5,16 @@ const Status = uefi.Status;
55
6pub const FileProtocol = extern struct {6pub const FileProtocol = extern struct {
7 revision: u64,7 revision: u64,
8 _open: extern fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) Status,8 _open: fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) callconv(.C) Status,
9 _close: extern fn (*const FileProtocol) Status,9 _close: fn (*const FileProtocol) callconv(.C) Status,
10 _delete: extern fn (*const FileProtocol) Status,10 _delete: fn (*const FileProtocol) callconv(.C) Status,
11 _read: extern fn (*const FileProtocol, *usize, [*]u8) Status,11 _read: fn (*const FileProtocol, *usize, [*]u8) callconv(.C) Status,
12 _write: extern fn (*const FileProtocol, *usize, [*]const u8) Status,12 _write: fn (*const FileProtocol, *usize, [*]const u8) callconv(.C) Status,
13 _get_position: extern fn (*const FileProtocol, *u64) Status,13 _get_position: fn (*const FileProtocol, *u64) callconv(.C) Status,
14 _set_position: extern fn (*const FileProtocol, *const u64) Status,14 _set_position: fn (*const FileProtocol, *const u64) callconv(.C) Status,
15 _get_info: extern fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) Status,15 _get_info: fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) callconv(.C) Status,
16 _set_info: extern fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) Status,16 _set_info: fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) callconv(.C) Status,
17 _flush: extern fn (*const FileProtocol) Status,17 _flush: fn (*const FileProtocol) callconv(.C) Status,
1818
19 pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {19 pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {
20 return self._open(self, new_handle, file_name, open_mode, attributes);20 return self._open(self, new_handle, file_name, open_mode, attributes);
lib/std/os/uefi/protocols/graphics_output_protocol.zig+3-3
...@@ -4,9 +4,9 @@ const Status = uefi.Status;...@@ -4,9 +4,9 @@ const Status = uefi.Status;
44
5/// Graphics output5/// Graphics output
6pub const GraphicsOutputProtocol = extern struct {6pub const GraphicsOutputProtocol = extern struct {
7 _query_mode: extern fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) Status,7 _query_mode: fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) callconv(.C) Status,
8 _set_mode: extern fn (*const GraphicsOutputProtocol, u32) Status,8 _set_mode: fn (*const GraphicsOutputProtocol, u32) callconv(.C) Status,
9 _blt: extern fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) Status,9 _blt: fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) callconv(.C) Status,
10 mode: *GraphicsOutputProtocolMode,10 mode: *GraphicsOutputProtocolMode,
1111
12 /// Returns information for an available graphics mode that the graphics device and the set of active video output devices supports.12 /// Returns information for an available graphics mode that the graphics device and the set of active video output devices supports.
lib/std/os/uefi/protocols/hii_database_protocol.zig+4-4
...@@ -6,10 +6,10 @@ const hii = uefi.protocols.hii;...@@ -6,10 +6,10 @@ const hii = uefi.protocols.hii;
6/// Database manager for HII-related data structures.6/// Database manager for HII-related data structures.
7pub const HIIDatabaseProtocol = extern struct {7pub const HIIDatabaseProtocol = extern struct {
8 _new_package_list: Status, // TODO8 _new_package_list: Status, // TODO
9 _remove_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle) Status,9 _remove_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle) callconv(.C) Status,
10 _update_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) Status,10 _update_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) callconv(.C) Status,
11 _list_package_lists: extern fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) Status,11 _list_package_lists: fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) callconv(.C) Status,
12 _export_package_lists: extern fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) Status,12 _export_package_lists: fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) callconv(.C) Status,
13 _register_package_notify: Status, // TODO13 _register_package_notify: Status, // TODO
14 _unregister_package_notify: Status, // TODO14 _unregister_package_notify: Status, // TODO
15 _find_keyboard_layouts: Status, // TODO15 _find_keyboard_layouts: Status, // TODO
lib/std/os/uefi/protocols/hii_popup_protocol.zig+1-1
...@@ -6,7 +6,7 @@ const hii = uefi.protocols.hii;...@@ -6,7 +6,7 @@ const hii = uefi.protocols.hii;
6/// Display a popup window6/// Display a popup window
7pub const HIIPopupProtocol = extern struct {7pub const HIIPopupProtocol = extern struct {
8 revision: u64,8 revision: u64,
9 _create_popup: extern fn (*const HIIPopupProtocol, HIIPopupStyle, HIIPopupType, hii.HIIHandle, u16, ?*HIIPopupSelection) Status,9 _create_popup: fn (*const HIIPopupProtocol, HIIPopupStyle, HIIPopupType, hii.HIIHandle, u16, ?*HIIPopupSelection) callconv(.C) Status,
1010
11 /// Displays a popup window.11 /// Displays a popup window.
12 pub fn createPopup(self: *const HIIPopupProtocol, style: HIIPopupStyle, popup_type: HIIPopupType, handle: hii.HIIHandle, msg: u16, user_selection: ?*HIIPopupSelection) Status {12 pub fn createPopup(self: *const HIIPopupProtocol, style: HIIPopupStyle, popup_type: HIIPopupType, handle: hii.HIIHandle, msg: u16, user_selection: ?*HIIPopupSelection) Status {
lib/std/os/uefi/protocols/ip6_config_protocol.zig+4-4
...@@ -4,10 +4,10 @@ const Event = uefi.Event;...@@ -4,10 +4,10 @@ const Event = uefi.Event;
4const Status = uefi.Status;4const Status = uefi.Status;
55
6pub const Ip6ConfigProtocol = extern struct {6pub const Ip6ConfigProtocol = extern struct {
7 _set_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) Status,7 _set_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) callconv(.C) Status,
8 _get_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) Status,8 _get_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) callconv(.C) Status,
9 _register_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,9 _register_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
10 _unregister_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,10 _unregister_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
1111
12 pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) Status {12 pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) Status {
13 return self._set_data(self, data_type, data_size, data);13 return self._set_data(self, data_type, data_size, data);
lib/std/os/uefi/protocols/ip6_protocol.zig+9-9
...@@ -7,15 +7,15 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;...@@ -7,15 +7,15 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
7const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;7const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
88
9pub const Ip6Protocol = extern struct {9pub const Ip6Protocol = extern struct {
10 _get_mode_data: extern fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,10 _get_mode_data: fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
11 _configure: extern fn (*const Ip6Protocol, ?*const Ip6ConfigData) Status,11 _configure: fn (*const Ip6Protocol, ?*const Ip6ConfigData) callconv(.C) Status,
12 _groups: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address) Status,12 _groups: fn (*const Ip6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
13 _routes: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) Status,13 _routes: fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) callconv(.C) Status,
14 _neighbors: extern fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) Status,14 _neighbors: fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) callconv(.C) Status,
15 _transmit: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,15 _transmit: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
16 _receive: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,16 _receive: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
17 _cancel: extern fn (*const Ip6Protocol, ?*Ip6CompletionToken) Status,17 _cancel: fn (*const Ip6Protocol, ?*Ip6CompletionToken) callconv(.C) Status,
18 _poll: extern fn (*const Ip6Protocol) Status,18 _poll: fn (*const Ip6Protocol) callconv(.C) Status,
1919
20 /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.20 /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
21 pub fn getModeData(self: *const Ip6Protocol, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {21 pub fn getModeData(self: *const Ip6Protocol, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {
lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig+2-2
...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
4const Status = uefi.Status;4const Status = uefi.Status;
55
6pub const Ip6ServiceBindingProtocol = extern struct {6pub const Ip6ServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const Ip6ServiceBindingProtocol, *?Handle) Status,7 _create_child: fn (*const Ip6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: extern fn (*const Ip6ServiceBindingProtocol, Handle) Status,8 _destroy_child: fn (*const Ip6ServiceBindingProtocol, Handle) callconv(.C) Status,
99
10 pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) Status {10 pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) Status {
11 return self._create_child(self, handle);11 return self._create_child(self, handle);
lib/std/os/uefi/protocols/loaded_image_protocol.zig+1-1
...@@ -19,7 +19,7 @@ pub const LoadedImageProtocol = extern struct {...@@ -19,7 +19,7 @@ pub const LoadedImageProtocol = extern struct {
19 image_size: u64,19 image_size: u64,
20 image_code_type: MemoryType,20 image_code_type: MemoryType,
21 image_data_type: MemoryType,21 image_data_type: MemoryType,
22 _unload: extern fn (*const LoadedImageProtocol, Handle) Status,22 _unload: fn (*const LoadedImageProtocol, Handle) callconv(.C) Status,
2323
24 /// Unloads an image from memory.24 /// Unloads an image from memory.
25 pub fn unload(self: *const LoadedImageProtocol, handle: Handle) Status {25 pub fn unload(self: *const LoadedImageProtocol, handle: Handle) Status {
lib/std/os/uefi/protocols/managed_network_protocol.zig+8-8
...@@ -7,14 +7,14 @@ const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;...@@ -7,14 +7,14 @@ const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
7const MacAddress = uefi.protocols.MacAddress;7const MacAddress = uefi.protocols.MacAddress;
88
9pub const ManagedNetworkProtocol = extern struct {9pub const ManagedNetworkProtocol = extern struct {
10 _get_mode_data: extern fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,10 _get_mode_data: fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
11 _configure: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) Status,11 _configure: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) callconv(.C) Status,
12 _mcast_ip_to_mac: extern fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) Status,12 _mcast_ip_to_mac: fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
13 _groups: extern fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) Status,13 _groups: fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
14 _transmit: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,14 _transmit: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
15 _receive: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,15 _receive: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
16 _cancel: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) Status,16 _cancel: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) callconv(.C) Status,
17 _poll: extern fn (*const ManagedNetworkProtocol) usize,17 _poll: fn (*const ManagedNetworkProtocol) callconv(.C) usize,
1818
19 /// Returns the operational parameters for the current MNP child driver.19 /// Returns the operational parameters for the current MNP child driver.
20 /// May also support returning the underlying SNP driver mode data.20 /// May also support returning the underlying SNP driver mode data.
lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig+2-2
...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
4const Status = uefi.Status;4const Status = uefi.Status;
55
6pub const ManagedNetworkServiceBindingProtocol = extern struct {6pub const ManagedNetworkServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) Status,7 _create_child: fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: extern fn (*const ManagedNetworkServiceBindingProtocol, Handle) Status,8 _destroy_child: fn (*const ManagedNetworkServiceBindingProtocol, Handle) callconv(.C) Status,
99
10 pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) Status {10 pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) Status {
11 return self._create_child(self, handle);11 return self._create_child(self, handle);
lib/std/os/uefi/protocols/rng_protocol.zig+2-2
...@@ -4,8 +4,8 @@ const Status = uefi.Status;...@@ -4,8 +4,8 @@ const Status = uefi.Status;
44
5/// Random Number Generator protocol5/// Random Number Generator protocol
6pub const RNGProtocol = extern struct {6pub const RNGProtocol = extern struct {
7 _get_info: extern fn (*const RNGProtocol, *usize, [*]align(8) Guid) Status,7 _get_info: fn (*const RNGProtocol, *usize, [*]align(8) Guid) callconv(.C) Status,
8 _get_rng: extern fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) Status,8 _get_rng: fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) callconv(.C) Status,
99
10 /// Returns information about the random number generation implementation.10 /// Returns information about the random number generation implementation.
11 pub fn getInfo(self: *const RNGProtocol, list_size: *usize, list: [*]align(8) Guid) Status {11 pub fn getInfo(self: *const RNGProtocol, list_size: *usize, list: [*]align(8) Guid) Status {
lib/std/os/uefi/protocols/simple_file_system_protocol.zig+1-1
...@@ -5,7 +5,7 @@ const Status = uefi.Status;...@@ -5,7 +5,7 @@ const Status = uefi.Status;
55
6pub const SimpleFileSystemProtocol = extern struct {6pub const SimpleFileSystemProtocol = extern struct {
7 revision: u64,7 revision: u64,
8 _open_volume: extern fn (*const SimpleFileSystemProtocol, **const FileProtocol) Status,8 _open_volume: fn (*const SimpleFileSystemProtocol, **const FileProtocol) callconv(.C) Status,
99
10 pub fn openVolume(self: *const SimpleFileSystemProtocol, root: **const FileProtocol) Status {10 pub fn openVolume(self: *const SimpleFileSystemProtocol, root: **const FileProtocol) Status {
11 return self._open_volume(self, root);11 return self._open_volume(self, root);
lib/std/os/uefi/protocols/simple_network_protocol.zig+13-13
...@@ -5,19 +5,19 @@ const Status = uefi.Status;...@@ -5,19 +5,19 @@ const Status = uefi.Status;
55
6pub const SimpleNetworkProtocol = extern struct {6pub const SimpleNetworkProtocol = extern struct {
7 revision: u64,7 revision: u64,
8 _start: extern fn (*const SimpleNetworkProtocol) Status,8 _start: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
9 _stop: extern fn (*const SimpleNetworkProtocol) Status,9 _stop: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
10 _initialize: extern fn (*const SimpleNetworkProtocol, usize, usize) Status,10 _initialize: fn (*const SimpleNetworkProtocol, usize, usize) callconv(.C) Status,
11 _reset: extern fn (*const SimpleNetworkProtocol, bool) Status,11 _reset: fn (*const SimpleNetworkProtocol, bool) callconv(.C) Status,
12 _shutdown: extern fn (*const SimpleNetworkProtocol) Status,12 _shutdown: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
13 _receive_filters: extern fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) Status,13 _receive_filters: fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) callconv(.C) Status,
14 _station_address: extern fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) Status,14 _station_address: fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
15 _statistics: extern fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) Status,15 _statistics: fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) callconv(.C) Status,
16 _mcast_ip_to_mac: extern fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) Status,16 _mcast_ip_to_mac: fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
17 _nvdata: extern fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) Status,17 _nvdata: fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) callconv(.C) Status,
18 _get_status: extern fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) Status,18 _get_status: fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) callconv(.C) Status,
19 _transmit: extern fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) Status,19 _transmit: fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) callconv(.C) Status,
20 _receive: extern fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) Status,20 _receive: fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) callconv(.C) Status,
21 wait_for_packet: Event,21 wait_for_packet: Event,
22 mode: *SimpleNetworkMode,22 mode: *SimpleNetworkMode,
2323
lib/std/os/uefi/protocols/simple_pointer_protocol.zig+2-2
...@@ -5,8 +5,8 @@ const Status = uefi.Status;...@@ -5,8 +5,8 @@ const Status = uefi.Status;
55
6/// Protocol for mice6/// Protocol for mice
7pub const SimplePointerProtocol = struct {7pub const SimplePointerProtocol = struct {
8 _reset: extern fn (*const SimplePointerProtocol, bool) Status,8 _reset: fn (*const SimplePointerProtocol, bool) callconv(.C) Status,
9 _get_state: extern fn (*const SimplePointerProtocol, *SimplePointerState) Status,9 _get_state: fn (*const SimplePointerProtocol, *SimplePointerState) callconv(.C) Status,
10 wait_for_input: Event,10 wait_for_input: Event,
11 mode: *SimplePointerMode,11 mode: *SimplePointerMode,
1212
lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig+6-6
...@@ -5,12 +5,12 @@ const Status = uefi.Status;...@@ -5,12 +5,12 @@ const Status = uefi.Status;
55
6/// Character input devices, e.g. Keyboard6/// Character input devices, e.g. Keyboard
7pub const SimpleTextInputExProtocol = extern struct {7pub const SimpleTextInputExProtocol = extern struct {
8 _reset: extern fn (*const SimpleTextInputExProtocol, bool) Status,8 _reset: fn (*const SimpleTextInputExProtocol, bool) callconv(.C) Status,
9 _read_key_stroke_ex: extern fn (*const SimpleTextInputExProtocol, *KeyData) Status,9 _read_key_stroke_ex: fn (*const SimpleTextInputExProtocol, *KeyData) callconv(.C) Status,
10 wait_for_key_ex: Event,10 wait_for_key_ex: Event,
11 _set_state: extern fn (*const SimpleTextInputExProtocol, *const u8) Status,11 _set_state: fn (*const SimpleTextInputExProtocol, *const u8) callconv(.C) Status,
12 _register_key_notify: extern fn (*const SimpleTextInputExProtocol, *const KeyData, extern fn (*const KeyData) usize, **c_void) Status,12 _register_key_notify: fn (*const SimpleTextInputExProtocol, *const KeyData, fn (*const KeyData) callconv(.C) usize, **c_void) callconv(.C) Status,
13 _unregister_key_notify: extern fn (*const SimpleTextInputExProtocol, *const c_void) Status,13 _unregister_key_notify: fn (*const SimpleTextInputExProtocol, *const c_void) callconv(.C) Status,
1414
15 /// Resets the input device hardware.15 /// Resets the input device hardware.
16 pub fn reset(self: *const SimpleTextInputExProtocol, verify: bool) Status {16 pub fn reset(self: *const SimpleTextInputExProtocol, verify: bool) Status {
...@@ -28,7 +28,7 @@ pub const SimpleTextInputExProtocol = extern struct {...@@ -28,7 +28,7 @@ pub const SimpleTextInputExProtocol = extern struct {
28 }28 }
2929
30 /// Register a notification function for a particular keystroke for the input device.30 /// Register a notification function for a particular keystroke for the input device.
31 pub fn registerKeyNotify(self: *const SimpleTextInputExProtocol, key_data: *const KeyData, notify: extern fn (*const KeyData) usize, handle: **c_void) Status {31 pub fn registerKeyNotify(self: *const SimpleTextInputExProtocol, key_data: *const KeyData, notify: fn (*const KeyData) callconv(.C) usize, handle: **c_void) Status {
32 return self._register_key_notify(self, key_data, notify, handle);32 return self._register_key_notify(self, key_data, notify, handle);
33 }33 }
3434
lib/std/os/uefi/protocols/simple_text_input_protocol.zig+2-2
...@@ -6,8 +6,8 @@ const Status = uefi.Status;...@@ -6,8 +6,8 @@ const Status = uefi.Status;
66
7/// Character input devices, e.g. Keyboard7/// Character input devices, e.g. Keyboard
8pub const SimpleTextInputProtocol = extern struct {8pub const SimpleTextInputProtocol = extern struct {
9 _reset: extern fn (*const SimpleTextInputProtocol, bool) usize,9 _reset: fn (*const SimpleTextInputProtocol, bool) callconv(.C) usize,
10 _read_key_stroke: extern fn (*const SimpleTextInputProtocol, *InputKey) Status,10 _read_key_stroke: fn (*const SimpleTextInputProtocol, *InputKey) callconv(.C) Status,
11 wait_for_key: Event,11 wait_for_key: Event,
1212
13 /// Resets the input device hardware.13 /// Resets the input device hardware.
lib/std/os/uefi/protocols/simple_text_output_protocol.zig+9-9
...@@ -4,15 +4,15 @@ const Status = uefi.Status;...@@ -4,15 +4,15 @@ const Status = uefi.Status;
44
5/// Character output devices5/// Character output devices
6pub const SimpleTextOutputProtocol = extern struct {6pub const SimpleTextOutputProtocol = extern struct {
7 _reset: extern fn (*const SimpleTextOutputProtocol, bool) Status,7 _reset: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
8 _output_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,8 _output_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
9 _test_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,9 _test_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
10 _query_mode: extern fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) Status,10 _query_mode: fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) callconv(.C) Status,
11 _set_mode: extern fn (*const SimpleTextOutputProtocol, usize) Status,11 _set_mode: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
12 _set_attribute: extern fn (*const SimpleTextOutputProtocol, usize) Status,12 _set_attribute: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
13 _clear_screen: extern fn (*const SimpleTextOutputProtocol) Status,13 _clear_screen: fn (*const SimpleTextOutputProtocol) callconv(.C) Status,
14 _set_cursor_position: extern fn (*const SimpleTextOutputProtocol, usize, usize) Status,14 _set_cursor_position: fn (*const SimpleTextOutputProtocol, usize, usize) callconv(.C) Status,
15 _enable_cursor: extern fn (*const SimpleTextOutputProtocol, bool) Status,15 _enable_cursor: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
16 mode: *SimpleTextOutputMode,16 mode: *SimpleTextOutputMode,
1717
18 /// Resets the text output device hardware.18 /// Resets the text output device hardware.
lib/std/os/uefi/protocols/udp6_protocol.zig+7-7
...@@ -9,13 +9,13 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;...@@ -9,13 +9,13 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
9const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;9const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
1010
11pub const Udp6Protocol = extern struct {11pub const Udp6Protocol = extern struct {
12 _get_mode_data: extern fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,12 _get_mode_data: fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
13 _configure: extern fn (*const Udp6Protocol, ?*const Udp6ConfigData) Status,13 _configure: fn (*const Udp6Protocol, ?*const Udp6ConfigData) callconv(.C) Status,
14 _groups: extern fn (*const Udp6Protocol, bool, ?*const Ip6Address) Status,14 _groups: fn (*const Udp6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
15 _transmit: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,15 _transmit: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
16 _receive: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,16 _receive: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
17 _cancel: extern fn (*const Udp6Protocol, ?*Udp6CompletionToken) Status,17 _cancel: fn (*const Udp6Protocol, ?*Udp6CompletionToken) callconv(.C) Status,
18 _poll: extern fn (*const Udp6Protocol) Status,18 _poll: fn (*const Udp6Protocol) callconv(.C) Status,
1919
20 pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {20 pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {
21 return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data);21 return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data);
lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig+2-2
...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;...@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
4const Status = uefi.Status;4const Status = uefi.Status;
55
6pub const Udp6ServiceBindingProtocol = extern struct {6pub const Udp6ServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const Udp6ServiceBindingProtocol, *?Handle) Status,7 _create_child: fn (*const Udp6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: extern fn (*const Udp6ServiceBindingProtocol, Handle) Status,8 _destroy_child: fn (*const Udp6ServiceBindingProtocol, Handle) callconv(.C) Status,
99
10 pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) Status {10 pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) Status {
11 return self._create_child(self, handle);11 return self._create_child(self, handle);
lib/std/os/uefi/tables/boot_services.zig+32-32
...@@ -21,117 +21,117 @@ pub const BootServices = extern struct {...@@ -21,117 +21,117 @@ pub const BootServices = extern struct {
21 hdr: TableHeader,21 hdr: TableHeader,
2222
23 /// Raises a task's priority level and returns its previous level.23 /// Raises a task's priority level and returns its previous level.
24 raiseTpl: extern fn (usize) usize,24 raiseTpl: fn (usize) callconv(.C) usize,
2525
26 /// Restores a task's priority level to its previous value.26 /// Restores a task's priority level to its previous value.
27 restoreTpl: extern fn (usize) void,27 restoreTpl: fn (usize) callconv(.C) void,
2828
29 /// Allocates memory pages from the system.29 /// Allocates memory pages from the system.
30 allocatePages: extern fn (AllocateType, MemoryType, usize, *[*]align(4096) u8) Status,30 allocatePages: fn (AllocateType, MemoryType, usize, *[*]align(4096) u8) callconv(.C) Status,
3131
32 /// Frees memory pages.32 /// Frees memory pages.
33 freePages: extern fn ([*]align(4096) u8, usize) Status,33 freePages: fn ([*]align(4096) u8, usize) callconv(.C) Status,
3434
35 /// Returns the current memory map.35 /// Returns the current memory map.
36 getMemoryMap: extern fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) Status,36 getMemoryMap: fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) callconv(.C) Status,
3737
38 /// Allocates pool memory.38 /// Allocates pool memory.
39 allocatePool: extern fn (MemoryType, usize, *[*]align(8) u8) Status,39 allocatePool: fn (MemoryType, usize, *[*]align(8) u8) callconv(.C) Status,
4040
41 /// Returns pool memory to the system.41 /// Returns pool memory to the system.
42 freePool: extern fn ([*]align(8) u8) Status,42 freePool: fn ([*]align(8) u8) callconv(.C) Status,
4343
44 /// Creates an event.44 /// Creates an event.
45 createEvent: extern fn (u32, usize, ?extern fn (Event, ?*c_void) void, ?*const c_void, *Event) Status,45 createEvent: fn (u32, usize, ?fn (Event, ?*c_void) callconv(.C) void, ?*const c_void, *Event) callconv(.C) Status,
4646
47 /// Sets the type of timer and the trigger time for a timer event.47 /// Sets the type of timer and the trigger time for a timer event.
48 setTimer: extern fn (Event, TimerDelay, u64) Status,48 setTimer: fn (Event, TimerDelay, u64) callconv(.C) Status,
4949
50 /// Stops execution until an event is signaled.50 /// Stops execution until an event is signaled.
51 waitForEvent: extern fn (usize, [*]const Event, *usize) Status,51 waitForEvent: fn (usize, [*]const Event, *usize) callconv(.C) Status,
5252
53 /// Signals an event.53 /// Signals an event.
54 signalEvent: extern fn (Event) Status,54 signalEvent: fn (Event) callconv(.C) Status,
5555
56 /// Closes an event.56 /// Closes an event.
57 closeEvent: extern fn (Event) Status,57 closeEvent: fn (Event) callconv(.C) Status,
5858
59 /// Checks whether an event is in the signaled state.59 /// Checks whether an event is in the signaled state.
60 checkEvent: extern fn (Event) Status,60 checkEvent: fn (Event) callconv(.C) Status,
6161
62 installProtocolInterface: Status, // TODO62 installProtocolInterface: Status, // TODO
63 reinstallProtocolInterface: Status, // TODO63 reinstallProtocolInterface: Status, // TODO
64 uninstallProtocolInterface: Status, // TODO64 uninstallProtocolInterface: Status, // TODO
6565
66 /// Queries a handle to determine if it supports a specified protocol.66 /// Queries a handle to determine if it supports a specified protocol.
67 handleProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void) Status,67 handleProtocol: fn (Handle, *align(8) const Guid, *?*c_void) callconv(.C) Status,
6868
69 reserved: *c_void,69 reserved: *c_void,
7070
71 registerProtocolNotify: Status, // TODO71 registerProtocolNotify: Status, // TODO
7272
73 /// Returns an array of handles that support a specified protocol.73 /// Returns an array of handles that support a specified protocol.
74 locateHandle: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, [*]Handle) Status,74 locateHandle: fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, [*]Handle) callconv(.C) Status,
7575
76 locateDevicePath: Status, // TODO76 locateDevicePath: Status, // TODO
77 installConfigurationTable: Status, // TODO77 installConfigurationTable: Status, // TODO
7878
79 /// Loads an EFI image into memory.79 /// Loads an EFI image into memory.
80 loadImage: extern fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) Status,80 loadImage: fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) callconv(.C) Status,
8181
82 /// Transfers control to a loaded image's entry point.82 /// Transfers control to a loaded image's entry point.
83 startImage: extern fn (Handle, ?*usize, ?*[*]u16) Status,83 startImage: fn (Handle, ?*usize, ?*[*]u16) callconv(.C) Status,
8484
85 /// Terminates a loaded EFI image and returns control to boot services.85 /// Terminates a loaded EFI image and returns control to boot services.
86 exit: extern fn (Handle, Status, usize, ?*const c_void) Status,86 exit: fn (Handle, Status, usize, ?*const c_void) callconv(.C) Status,
8787
88 /// Unloads an image.88 /// Unloads an image.
89 unloadImage: extern fn (Handle) Status,89 unloadImage: fn (Handle) callconv(.C) Status,
9090
91 /// Terminates all boot services.91 /// Terminates all boot services.
92 exitBootServices: extern fn (Handle, usize) Status,92 exitBootServices: fn (Handle, usize) callconv(.C) Status,
9393
94 /// Returns a monotonically increasing count for the platform.94 /// Returns a monotonically increasing count for the platform.
95 getNextMonotonicCount: extern fn (*u64) Status,95 getNextMonotonicCount: fn (*u64) callconv(.C) Status,
9696
97 /// Induces a fine-grained stall.97 /// Induces a fine-grained stall.
98 stall: extern fn (usize) Status,98 stall: fn (usize) callconv(.C) Status,
9999
100 /// Sets the system's watchdog timer.100 /// Sets the system's watchdog timer.
101 setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) Status,101 setWatchdogTimer: fn (usize, u64, usize, ?[*]const u16) callconv(.C) Status,
102102
103 connectController: Status, // TODO103 connectController: Status, // TODO
104 disconnectController: Status, // TODO104 disconnectController: Status, // TODO
105105
106 /// Queries a handle to determine if it supports a specified protocol.106 /// Queries a handle to determine if it supports a specified protocol.
107 openProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) Status,107 openProtocol: fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) callconv(.C) Status,
108108
109 /// Closes a protocol on a handle that was opened using openProtocol().109 /// Closes a protocol on a handle that was opened using openProtocol().
110 closeProtocol: extern fn (Handle, *align(8) const Guid, Handle, ?Handle) Status,110 closeProtocol: fn (Handle, *align(8) const Guid, Handle, ?Handle) callconv(.C) Status,
111111
112 /// Retrieves the list of agents that currently have a protocol interface opened.112 /// Retrieves the list of agents that currently have a protocol interface opened.
113 openProtocolInformation: extern fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) Status,113 openProtocolInformation: fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) callconv(.C) Status,
114114
115 /// Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool.115 /// Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool.
116 protocolsPerHandle: extern fn (Handle, *[*]*align(8) const Guid, *usize) Status,116 protocolsPerHandle: fn (Handle, *[*]*align(8) const Guid, *usize) callconv(.C) Status,
117117
118 /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.118 /// Returns an array of handles that support the requested protocol in a buffer allocated from pool.
119 locateHandleBuffer: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) Status,119 locateHandleBuffer: fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) callconv(.C) Status,
120120
121 /// Returns the first protocol instance that matches the given protocol.121 /// Returns the first protocol instance that matches the given protocol.
122 locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) Status,122 locateProtocol: fn (*align(8) const Guid, ?*const c_void, *?*c_void) callconv(.C) Status,
123123
124 installMultipleProtocolInterfaces: Status, // TODO124 installMultipleProtocolInterfaces: Status, // TODO
125 uninstallMultipleProtocolInterfaces: Status, // TODO125 uninstallMultipleProtocolInterfaces: Status, // TODO
126126
127 /// Computes and returns a 32-bit CRC for a data buffer.127 /// Computes and returns a 32-bit CRC for a data buffer.
128 calculateCrc32: extern fn ([*]const u8, usize, *u32) Status,128 calculateCrc32: fn ([*]const u8, usize, *u32) callconv(.C) Status,
129129
130 /// Copies the contents of one buffer to another buffer130 /// Copies the contents of one buffer to another buffer
131 copyMem: extern fn ([*]u8, [*]const u8, usize) void,131 copyMem: fn ([*]u8, [*]const u8, usize) callconv(.C) void,
132132
133 /// Fills a buffer with a specified value133 /// Fills a buffer with a specified value
134 setMem: extern fn ([*]u8, usize, u8) void,134 setMem: fn ([*]u8, usize, u8) callconv(.C) void,
135135
136 createEventEx: Status, // TODO136 createEventEx: Status, // TODO
137137
lib/std/os/uefi/tables/runtime_services.zig+5-5
...@@ -17,7 +17,7 @@ pub const RuntimeServices = extern struct {...@@ -17,7 +17,7 @@ pub const RuntimeServices = extern struct {
17 hdr: TableHeader,17 hdr: TableHeader,
1818
19 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.19 /// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.
20 getTime: extern fn (*uefi.Time, ?*TimeCapabilities) Status,20 getTime: fn (*uefi.Time, ?*TimeCapabilities) callconv(.C) Status,
2121
22 setTime: Status, // TODO22 setTime: Status, // TODO
23 getWakeupTime: Status, // TODO23 getWakeupTime: Status, // TODO
...@@ -26,18 +26,18 @@ pub const RuntimeServices = extern struct {...@@ -26,18 +26,18 @@ pub const RuntimeServices = extern struct {
26 convertPointer: Status, // TODO26 convertPointer: Status, // TODO
2727
28 /// Returns the value of a variable.28 /// Returns the value of a variable.
29 getVariable: extern fn ([*:0]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) Status,29 getVariable: fn ([*:0]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) callconv(.C) Status,
3030
31 /// Enumerates the current variable names.31 /// Enumerates the current variable names.
32 getNextVariableName: extern fn (*usize, [*:0]u16, *align(8) Guid) Status,32 getNextVariableName: fn (*usize, [*:0]u16, *align(8) Guid) callconv(.C) Status,
3333
34 /// Sets the value of a variable.34 /// Sets the value of a variable.
35 setVariable: extern fn ([*:0]const u16, *align(8) const Guid, u32, usize, *c_void) Status,35 setVariable: fn ([*:0]const u16, *align(8) const Guid, u32, usize, *c_void) callconv(.C) Status,
3636
37 getNextHighMonotonicCount: Status, // TODO37 getNextHighMonotonicCount: Status, // TODO
3838
39 /// Resets the entire platform.39 /// Resets the entire platform.
40 resetSystem: extern fn (ResetType, Status, usize, ?*const c_void) noreturn,40 resetSystem: fn (ResetType, Status, usize, ?*const c_void) callconv(.C) noreturn,
4141
42 updateCapsule: Status, // TODO42 updateCapsule: Status, // TODO
43 queryCapsuleCapabilities: Status, // TODO43 queryCapsuleCapabilities: Status, // TODO
lib/std/os/windows/bits.zig+6-6
...@@ -627,7 +627,7 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;...@@ -627,7 +627,7 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
627pub const MEM_DECOMMIT = 0x4000;627pub const MEM_DECOMMIT = 0x4000;
628pub const MEM_RELEASE = 0x8000;628pub const MEM_RELEASE = 0x8000;
629629
630pub const PTHREAD_START_ROUTINE = extern fn (LPVOID) DWORD;630pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;
631pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;631pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
632632
633pub const WIN32_FIND_DATAW = extern struct {633pub const WIN32_FIND_DATAW = extern struct {
...@@ -784,7 +784,7 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {...@@ -784,7 +784,7 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {
784pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;784pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
785pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;785pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
786786
787pub const PIMAGE_TLS_CALLBACK = ?extern fn (PVOID, DWORD, PVOID) void;787pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void;
788788
789pub const PROV_RSA_FULL = 1;789pub const PROV_RSA_FULL = 1;
790790
...@@ -810,7 +810,7 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;...@@ -810,7 +810,7 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;
810pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;810pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
811pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;811pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
812812
813pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?extern fn (DWORD, DWORD, *OVERLAPPED) void;813pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void;
814814
815pub const FILE_NOTIFY_CHANGE_CREATION = 64;815pub const FILE_NOTIFY_CHANGE_CREATION = 64;
816pub const FILE_NOTIFY_CHANGE_SIZE = 8;816pub const FILE_NOTIFY_CHANGE_SIZE = 8;
...@@ -863,7 +863,7 @@ pub const RTL_CRITICAL_SECTION = extern struct {...@@ -863,7 +863,7 @@ pub const RTL_CRITICAL_SECTION = extern struct {
863pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;863pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
864pub const INIT_ONCE = RTL_RUN_ONCE;864pub const INIT_ONCE = RTL_RUN_ONCE;
865pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;865pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
866pub const INIT_ONCE_FN = extern fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) BOOL;866pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) callconv(.C) BOOL;
867867
868pub const RTL_RUN_ONCE = extern struct {868pub const RTL_RUN_ONCE = extern struct {
869 Ptr: ?*c_void,869 Ptr: ?*c_void,
...@@ -1418,7 +1418,7 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {...@@ -1418,7 +1418,7 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
1418 DosPath: UNICODE_STRING,1418 DosPath: UNICODE_STRING,
1419};1419};
14201420
1421pub const PPS_POST_PROCESS_INIT_ROUTINE = ?extern fn () void;1421pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;
14221422
1423pub const FILE_BOTH_DIR_INFORMATION = extern struct {1423pub const FILE_BOTH_DIR_INFORMATION = extern struct {
1424 NextEntryOffset: ULONG,1424 NextEntryOffset: ULONG,
...@@ -1438,7 +1438,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {...@@ -1438,7 +1438,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
1438};1438};
1439pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;1439pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
14401440
1441pub const IO_APC_ROUTINE = extern fn (PVOID, *IO_STATUS_BLOCK, ULONG) void;1441pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void;
14421442
1443pub const CURDIR = extern struct {1443pub const CURDIR = extern struct {
1444 DosPath: UNICODE_STRING,1444 DosPath: UNICODE_STRING,
lib/std/os/windows/user32.zig-2
...@@ -73,7 +73,6 @@ pub const WM_XBUTTONDBLCLK = 0x020D;...@@ -73,7 +73,6 @@ pub const WM_XBUTTONDBLCLK = 0x020D;
73// WA73// WA
74pub const WA_INACTIVE = 0;74pub const WA_INACTIVE = 0;
75pub const WA_ACTIVE = 0x0006;75pub const WA_ACTIVE = 0x0006;
76pub const WM_ACTIVATE = 0x0006;
7776
78// WS77// WS
79pub const WS_OVERLAPPED = 0x00000000;78pub const WS_OVERLAPPED = 0x00000000;
...@@ -147,7 +146,6 @@ pub extern "user32" fn CreateWindowExA(...@@ -147,7 +146,6 @@ pub extern "user32" fn CreateWindowExA(
147146
148pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;147pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;
149pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;148pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;
150pub extern "user32" fn GetModuleHandleA(lpModuleName: ?LPCSTR) callconv(.Stdcall) HMODULE;
151pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(.Stdcall) bool;149pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(.Stdcall) bool;
152pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(.Stdcall) bool;150pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(.Stdcall) bool;
153pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(.Stdcall) ?HDC;151pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(.Stdcall) ?HDC;
lib/std/os/windows/ws2_32.zig+1-1
...@@ -106,7 +106,7 @@ pub const WSAOVERLAPPED = extern struct {...@@ -106,7 +106,7 @@ pub const WSAOVERLAPPED = extern struct {
106 hEvent: ?WSAEVENT,106 hEvent: ?WSAEVENT,
107};107};
108108
109pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) void;109pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) callconv(.C) void;
110110
111pub const ADDRESS_FAMILY = u16;111pub const ADDRESS_FAMILY = u16;
112112
lib/std/pdb.zig+4-4
...@@ -644,7 +644,7 @@ const MsfStream = struct {...@@ -644,7 +644,7 @@ const MsfStream = struct {
644 return stream;644 return stream;
645 }645 }
646646
647 fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {647 pub fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {
648 var list = ArrayList(u8).init(allocator);648 var list = ArrayList(u8).init(allocator);
649 while (true) {649 while (true) {
650 const byte = try self.inStream().readByte();650 const byte = try self.inStream().readByte();
...@@ -684,13 +684,13 @@ const MsfStream = struct {...@@ -684,13 +684,13 @@ const MsfStream = struct {
684 return buffer.len;684 return buffer.len;
685 }685 }
686686
687 fn seekBy(self: *MsfStream, len: i64) !void {687 pub fn seekBy(self: *MsfStream, len: i64) !void {
688 self.pos = @intCast(u64, @intCast(i64, self.pos) + len);688 self.pos = @intCast(u64, @intCast(i64, self.pos) + len);
689 if (self.pos >= self.blocks.len * self.block_size)689 if (self.pos >= self.blocks.len * self.block_size)
690 return error.EOF;690 return error.EOF;
691 }691 }
692692
693 fn seekTo(self: *MsfStream, len: u64) !void {693 pub fn seekTo(self: *MsfStream, len: u64) !void {
694 self.pos = len;694 self.pos = len;
695 if (self.pos >= self.blocks.len * self.block_size)695 if (self.pos >= self.blocks.len * self.block_size)
696 return error.EOF;696 return error.EOF;
...@@ -708,7 +708,7 @@ const MsfStream = struct {...@@ -708,7 +708,7 @@ const MsfStream = struct {
708 return block * self.block_size + offset;708 return block * self.block_size + offset;
709 }709 }
710710
711 fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {711 pub fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {
712 return .{ .context = self };712 return .{ .context = self };
713 }713 }
714};714};
lib/std/priority_queue.zig+3-3
...@@ -185,18 +185,18 @@ pub fn PriorityQueue(comptime T: type) type {...@@ -185,18 +185,18 @@ pub fn PriorityQueue(comptime T: type) type {
185 self.len = new_len;185 self.len = new_len;
186 }186 }
187187
188 const Iterator = struct {188 pub const Iterator = struct {
189 queue: *PriorityQueue(T),189 queue: *PriorityQueue(T),
190 count: usize,190 count: usize,
191191
192 fn next(it: *Iterator) ?T {192 pub fn next(it: *Iterator) ?T {
193 if (it.count > it.queue.len - 1) return null;193 if (it.count > it.queue.len - 1) return null;
194 const out = it.count;194 const out = it.count;
195 it.count += 1;195 it.count += 1;
196 return it.queue.items[out];196 return it.queue.items[out];
197 }197 }
198198
199 fn reset(it: *Iterator) void {199 pub fn reset(it: *Iterator) void {
200 it.count = 0;200 it.count = 0;
201 }201 }
202 };202 };
lib/std/special/docs/main.js+39
...@@ -1498,6 +1498,22 @@...@@ -1498,6 +1498,22 @@
1498 }1498 }
1499 ];1499 ];
15001500
1501 // Links, images and inner links don't use the same marker to wrap their content.
1502 const linksFormat = [
1503 {
1504 prefix: "[",
1505 regex: /\[([^\]]*)\]\(([^\)]*)\)/,
1506 urlIndex: 2, // Index in the match that contains the link URL
1507 textIndex: 1 // Index in the match that contains the link text
1508 },
1509 {
1510 prefix: "h",
1511 regex: /http[s]?:\/\/[^\s]+/,
1512 urlIndex: 0,
1513 textIndex: 0
1514 }
1515 ];
1516
1501 const stack = [];1517 const stack = [];
15021518
1503 var innerHTML = "";1519 var innerHTML = "";
...@@ -1548,6 +1564,29 @@...@@ -1548,6 +1564,29 @@
1548 currentRun += innerText[i];1564 currentRun += innerText[i];
1549 in_code = true;1565 in_code = true;
1550 } else {1566 } else {
1567 var foundMatches = false;
1568
1569 for (var j = 0; j < linksFormat.length; j++) {
1570 const linkFmt = linksFormat[j];
1571
1572 if (linkFmt.prefix == innerText[i]) {
1573 var remaining = innerText.substring(i);
1574 var matches = remaining.match(linkFmt.regex);
1575
1576 if (matches) {
1577 flushRun();
1578 innerHTML += ' <a href="' + matches[linkFmt.urlIndex] + '">' + matches[linkFmt.textIndex] + '</a> ';
1579 i += matches[0].length; // Skip the fragment we just consumed
1580 foundMatches = true;
1581 break;
1582 }
1583 }
1584 }
1585
1586 if (foundMatches) {
1587 continue;
1588 }
1589
1551 var any = false;1590 var any = false;
1552 for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {1591 for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
1553 const fmt = idx >= 0 ? formats[idx] : stack[stack.length - 1];1592 const fmt = idx >= 0 ? formats[idx] : stack[stack.length - 1];
lib/std/special/test_runner.zig+1-1
...@@ -34,7 +34,7 @@ pub fn main() anyerror!void {...@@ -34,7 +34,7 @@ pub fn main() anyerror!void {
34 std.heap.page_allocator.free(async_frame_buffer);34 std.heap.page_allocator.free(async_frame_buffer);
35 async_frame_buffer = try std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size);35 async_frame_buffer = try std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size);
36 }36 }
37 const casted_fn = @ptrCast(async fn () anyerror!void, test_fn.func);37 const casted_fn = @ptrCast(fn () callconv(.Async) anyerror!void, test_fn.func);
38 break :blk await @asyncCall(async_frame_buffer, {}, casted_fn);38 break :blk await @asyncCall(async_frame_buffer, {}, casted_fn);
39 },39 },
40 .blocking => {40 .blocking => {
lib/std/start.zig+1-2
...@@ -224,8 +224,7 @@ inline fn initEventLoopAndCallMain() u8 {...@@ -224,8 +224,7 @@ inline fn initEventLoopAndCallMain() u8 {
224 // and we want fewer call frames in stack traces.224 // and we want fewer call frames in stack traces.
225 return @call(.{ .modifier = .always_inline }, callMain, .{});225 return @call(.{ .modifier = .always_inline }, callMain, .{});
226}226}
227227fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 {
228async fn callMainAsync(loop: *std.event.Loop) u8 {
229 // This prevents the event loop from terminating at least until main() has returned.228 // This prevents the event loop from terminating at least until main() has returned.
230 loop.beginOneEvent();229 loop.beginOneEvent();
231 defer loop.finishOneEvent();230 defer loop.finishOneEvent();
lib/std/thread.zig+1-1
...@@ -280,7 +280,7 @@ pub const Thread = struct {...@@ -280,7 +280,7 @@ pub const Thread = struct {
280 std.debug.dumpStackTrace(trace.*);280 std.debug.dumpStackTrace(trace.*);
281 }281 }
282 };282 };
283 return 0;283 return null;
284 },284 },
285 else => @compileError(bad_startfn_ret),285 else => @compileError(bad_startfn_ret),
286 }286 }
lib/std/zig/ast.zig+24-16
...@@ -129,6 +129,7 @@ pub const Error = union(enum) {...@@ -129,6 +129,7 @@ pub const Error = union(enum) {
129 ExpectedStatement: ExpectedStatement,129 ExpectedStatement: ExpectedStatement,
130 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,130 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
131 ExpectedVarDecl: ExpectedVarDecl,131 ExpectedVarDecl: ExpectedVarDecl,
132 ExpectedFn: ExpectedFn,
132 ExpectedReturnType: ExpectedReturnType,133 ExpectedReturnType: ExpectedReturnType,
133 ExpectedAggregateKw: ExpectedAggregateKw,134 ExpectedAggregateKw: ExpectedAggregateKw,
134 UnattachedDocComment: UnattachedDocComment,135 UnattachedDocComment: UnattachedDocComment,
...@@ -165,6 +166,7 @@ pub const Error = union(enum) {...@@ -165,6 +166,7 @@ pub const Error = union(enum) {
165 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,166 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
166 ExpectedSuffixOp: ExpectedSuffixOp,167 ExpectedSuffixOp: ExpectedSuffixOp,
167 DeclBetweenFields: DeclBetweenFields,168 DeclBetweenFields: DeclBetweenFields,
169 InvalidAnd: InvalidAnd,
168170
169 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {171 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
170 switch (self.*) {172 switch (self.*) {
...@@ -177,6 +179,7 @@ pub const Error = union(enum) {...@@ -177,6 +179,7 @@ pub const Error = union(enum) {
177 .ExpectedStatement => |*x| return x.render(tokens, stream),179 .ExpectedStatement => |*x| return x.render(tokens, stream),
178 .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),180 .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
179 .ExpectedVarDecl => |*x| return x.render(tokens, stream),181 .ExpectedVarDecl => |*x| return x.render(tokens, stream),
182 .ExpectedFn => |*x| return x.render(tokens, stream),
180 .ExpectedReturnType => |*x| return x.render(tokens, stream),183 .ExpectedReturnType => |*x| return x.render(tokens, stream),
181 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),184 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),
182 .UnattachedDocComment => |*x| return x.render(tokens, stream),185 .UnattachedDocComment => |*x| return x.render(tokens, stream),
...@@ -213,6 +216,7 @@ pub const Error = union(enum) {...@@ -213,6 +216,7 @@ pub const Error = union(enum) {
213 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),216 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
214 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),217 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),
215 .DeclBetweenFields => |*x| return x.render(tokens, stream),218 .DeclBetweenFields => |*x| return x.render(tokens, stream),
219 .InvalidAnd => |*x| return x.render(tokens, stream),
216 }220 }
217 }221 }
218222
...@@ -227,6 +231,7 @@ pub const Error = union(enum) {...@@ -227,6 +231,7 @@ pub const Error = union(enum) {
227 .ExpectedStatement => |x| return x.token,231 .ExpectedStatement => |x| return x.token,
228 .ExpectedVarDeclOrFn => |x| return x.token,232 .ExpectedVarDeclOrFn => |x| return x.token,
229 .ExpectedVarDecl => |x| return x.token,233 .ExpectedVarDecl => |x| return x.token,
234 .ExpectedFn => |x| return x.token,
230 .ExpectedReturnType => |x| return x.token,235 .ExpectedReturnType => |x| return x.token,
231 .ExpectedAggregateKw => |x| return x.token,236 .ExpectedAggregateKw => |x| return x.token,
232 .UnattachedDocComment => |x| return x.token,237 .UnattachedDocComment => |x| return x.token,
...@@ -263,6 +268,7 @@ pub const Error = union(enum) {...@@ -263,6 +268,7 @@ pub const Error = union(enum) {
263 .ExpectedDerefOrUnwrap => |x| return x.token,268 .ExpectedDerefOrUnwrap => |x| return x.token,
264 .ExpectedSuffixOp => |x| return x.token,269 .ExpectedSuffixOp => |x| return x.token,
265 .DeclBetweenFields => |x| return x.token,270 .DeclBetweenFields => |x| return x.token,
271 .InvalidAnd => |x| return x.token,
266 }272 }
267 }273 }
268274
...@@ -274,6 +280,7 @@ pub const Error = union(enum) {...@@ -274,6 +280,7 @@ pub const Error = union(enum) {
274 pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");280 pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
275 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");281 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
276 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");282 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
283 pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
277 pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");284 pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
278 pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");285 pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
279 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");286 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
...@@ -308,6 +315,7 @@ pub const Error = union(enum) {...@@ -308,6 +315,7 @@ pub const Error = union(enum) {
308 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");315 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
309 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");316 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
310 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");317 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
318 pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
311319
312 pub const ExpectedCall = struct {320 pub const ExpectedCall = struct {
313 node: *Node,321 node: *Node,
...@@ -335,9 +343,6 @@ pub const Error = union(enum) {...@@ -335,9 +343,6 @@ pub const Error = union(enum) {
335 pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {343 pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {
336 const found_token = tokens.at(self.token);344 const found_token = tokens.at(self.token);
337 switch (found_token.id) {345 switch (found_token.id) {
338 .Invalid_ampersands => {
339 return stream.print("`&&` is invalid. Note that `and` is boolean AND.", .{});
340 },
341 .Invalid => {346 .Invalid => {
342 return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});347 return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
343 },348 },
...@@ -438,7 +443,7 @@ pub const Node = struct {...@@ -438,7 +443,7 @@ pub const Node = struct {
438 ContainerDecl,443 ContainerDecl,
439 Asm,444 Asm,
440 Comptime,445 Comptime,
441 Noasync,446 Nosuspend,
442 Block,447 Block,
443448
444 // Misc449 // Misc
...@@ -569,9 +574,9 @@ pub const Node = struct {...@@ -569,9 +574,9 @@ pub const Node = struct {
569574
570 return true;575 return true;
571 },576 },
572 .Noasync => {577 .Nosuspend => {
573 const noasync_node = @fieldParentPtr(Noasync, "base", n);578 const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);
574 return noasync_node.expr.id != .Block;579 return nosuspend_node.expr.id != .Block;
575 },580 },
576 else => return true,581 else => return true,
577 }582 }
...@@ -875,18 +880,20 @@ pub const Node = struct {...@@ -875,18 +880,20 @@ pub const Node = struct {
875 return_type: ReturnType,880 return_type: ReturnType,
876 var_args_token: ?TokenIndex,881 var_args_token: ?TokenIndex,
877 extern_export_inline_token: ?TokenIndex,882 extern_export_inline_token: ?TokenIndex,
878 cc_token: ?TokenIndex,
879 body_node: ?*Node,883 body_node: ?*Node,
880 lib_name: ?*Node, // populated if this is an extern declaration884 lib_name: ?*Node, // populated if this is an extern declaration
881 align_expr: ?*Node, // populated if align(A) is present885 align_expr: ?*Node, // populated if align(A) is present
882 section_expr: ?*Node, // populated if linksection(A) is present886 section_expr: ?*Node, // populated if linksection(A) is present
883 callconv_expr: ?*Node, // populated if callconv(A) is present887 callconv_expr: ?*Node, // populated if callconv(A) is present
888 is_extern_prototype: bool = false, // TODO: Remove once extern fn rewriting is
889 is_async: bool = false, // TODO: remove once async fn rewriting is
884890
885 pub const ParamList = SegmentedList(*Node, 2);891 pub const ParamList = SegmentedList(*Node, 2);
886892
887 pub const ReturnType = union(enum) {893 pub const ReturnType = union(enum) {
888 Explicit: *Node,894 Explicit: *Node,
889 InferErrorSet: *Node,895 InferErrorSet: *Node,
896 Invalid: TokenIndex,
890 };897 };
891898
892 pub fn iterate(self: *FnProto, index: usize) ?*Node {899 pub fn iterate(self: *FnProto, index: usize) ?*Node {
...@@ -915,6 +922,7 @@ pub const Node = struct {...@@ -915,6 +922,7 @@ pub const Node = struct {
915 if (i < 1) return node;922 if (i < 1) return node;
916 i -= 1;923 i -= 1;
917 },924 },
925 .Invalid => {},
918 }926 }
919927
920 if (self.body_node) |body_node| {928 if (self.body_node) |body_node| {
...@@ -929,7 +937,6 @@ pub const Node = struct {...@@ -929,7 +937,6 @@ pub const Node = struct {
929 if (self.visib_token) |visib_token| return visib_token;937 if (self.visib_token) |visib_token| return visib_token;
930 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;938 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
931 assert(self.lib_name == null);939 assert(self.lib_name == null);
932 if (self.cc_token) |cc_token| return cc_token;
933 return self.fn_token;940 return self.fn_token;
934 }941 }
935942
...@@ -937,6 +944,7 @@ pub const Node = struct {...@@ -937,6 +944,7 @@ pub const Node = struct {
937 if (self.body_node) |body_node| return body_node.lastToken();944 if (self.body_node) |body_node| return body_node.lastToken();
938 switch (self.return_type) {945 switch (self.return_type) {
939 .Explicit, .InferErrorSet => |node| return node.lastToken(),946 .Explicit, .InferErrorSet => |node| return node.lastToken(),
947 .Invalid => |tok| return tok,
940 }948 }
941 }949 }
942 };950 };
...@@ -1084,12 +1092,12 @@ pub const Node = struct {...@@ -1084,12 +1092,12 @@ pub const Node = struct {
1084 }1092 }
1085 };1093 };
10861094
1087 pub const Noasync = struct {1095 pub const Nosuspend = struct {
1088 base: Node = Node{ .id = .Noasync },1096 base: Node = Node{ .id = .Nosuspend },
1089 noasync_token: TokenIndex,1097 nosuspend_token: TokenIndex,
1090 expr: *Node,1098 expr: *Node,
10911099
1092 pub fn iterate(self: *Noasync, index: usize) ?*Node {1100 pub fn iterate(self: *Nosuspend, index: usize) ?*Node {
1093 var i = index;1101 var i = index;
10941102
1095 if (i < 1) return self.expr;1103 if (i < 1) return self.expr;
...@@ -1098,11 +1106,11 @@ pub const Node = struct {...@@ -1098,11 +1106,11 @@ pub const Node = struct {
1098 return null;1106 return null;
1099 }1107 }
11001108
1101 pub fn firstToken(self: *const Noasync) TokenIndex {1109 pub fn firstToken(self: *const Nosuspend) TokenIndex {
1102 return self.noasync_token;1110 return self.nosuspend_token;
1103 }1111 }
11041112
1105 pub fn lastToken(self: *const Noasync) TokenIndex {1113 pub fn lastToken(self: *const Nosuspend) TokenIndex {
1106 return self.expr.lastToken();1114 return self.expr.lastToken();
1107 }1115 }
1108 };1116 };
lib/std/zig/cross_target.zig+1-1
...@@ -660,7 +660,7 @@ pub const CrossTarget = struct {...@@ -660,7 +660,7 @@ pub const CrossTarget = struct {
660 return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());660 return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());
661 }661 }
662662
663 fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {663 pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
664 set.removeFeatureSet(self.cpu_features_sub);664 set.removeFeatureSet(self.cpu_features_sub);
665 set.addFeatureSet(self.cpu_features_add);665 set.addFeatureSet(self.cpu_features_add);
666 set.populateDependencies(self.getCpuArch().allFeaturesList());666 set.populateDependencies(self.getCpuArch().allFeaturesList());
lib/std/zig/parse.zig+309-129
...@@ -48,31 +48,24 @@ pub fn parse(allocator: *Allocator, source: []const u8) Allocator.Error!*Tree {...@@ -48,31 +48,24 @@ pub fn parse(allocator: *Allocator, source: []const u8) Allocator.Error!*Tree {
4848
49 while (it.peek().?.id == .LineComment) _ = it.next();49 while (it.peek().?.id == .LineComment) _ = it.next();
5050
51 tree.root_node = parseRoot(arena, &it, tree) catch |err| blk: {51 tree.root_node = try parseRoot(arena, &it, tree);
52 switch (err) {
53 error.ParseError => {
54 assert(tree.errors.len != 0);
55 break :blk undefined;
56 },
57 error.OutOfMemory => {
58 return error.OutOfMemory;
59 },
60 }
61 };
6252
63 return tree;53 return tree;
64}54}
6555
66/// Root <- skip ContainerMembers eof56/// Root <- skip ContainerMembers eof
67fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!*Node.Root {57fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node.Root {
68 const node = try arena.create(Node.Root);58 const node = try arena.create(Node.Root);
69 node.* = .{59 node.* = .{
70 .decls = try parseContainerMembers(arena, it, tree),60 .decls = try parseContainerMembers(arena, it, tree),
71 .eof_token = eatToken(it, .Eof) orelse {61 .eof_token = eatToken(it, .Eof) orelse blk: {
62 // parseContainerMembers will try to skip as much
63 // invalid tokens as it can so this can only be a '}'
64 const tok = eatToken(it, .RBrace).?;
72 try tree.errors.push(.{65 try tree.errors.push(.{
73 .ExpectedContainerMembers = .{ .token = it.index },66 .ExpectedContainerMembers = .{ .token = tok },
74 });67 });
75 return error.ParseError;68 break :blk tok;
76 },69 },
77 };70 };
78 return node;71 return node;
...@@ -108,7 +101,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -108,7 +101,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
108101
109 const doc_comments = try parseDocComment(arena, it, tree);102 const doc_comments = try parseDocComment(arena, it, tree);
110103
111 if (try parseTestDecl(arena, it, tree)) |node| {104 if (parseTestDecl(arena, it, tree) catch |err| switch (err) {
105 error.OutOfMemory => return error.OutOfMemory,
106 error.ParseError => {
107 findNextContainerMember(it);
108 continue;
109 },
110 }) |node| {
112 if (field_state == .seen) {111 if (field_state == .seen) {
113 field_state = .{ .end = node.firstToken() };112 field_state = .{ .end = node.firstToken() };
114 }113 }
...@@ -117,7 +116,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -117,7 +116,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
117 continue;116 continue;
118 }117 }
119118
120 if (try parseTopLevelComptime(arena, it, tree)) |node| {119 if (parseTopLevelComptime(arena, it, tree) catch |err| switch (err) {
120 error.OutOfMemory => return error.OutOfMemory,
121 error.ParseError => {
122 findNextContainerMember(it);
123 continue;
124 },
125 }) |node| {
121 if (field_state == .seen) {126 if (field_state == .seen) {
122 field_state = .{ .end = node.firstToken() };127 field_state = .{ .end = node.firstToken() };
123 }128 }
...@@ -128,7 +133,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -128,7 +133,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
128133
129 const visib_token = eatToken(it, .Keyword_pub);134 const visib_token = eatToken(it, .Keyword_pub);
130135
131 if (try parseTopLevelDecl(arena, it, tree)) |node| {136 if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
137 error.OutOfMemory => return error.OutOfMemory,
138 error.ParseError => {
139 findNextContainerMember(it);
140 continue;
141 },
142 }) |node| {
132 if (field_state == .seen) {143 if (field_state == .seen) {
133 field_state = .{ .end = visib_token orelse node.firstToken() };144 field_state = .{ .end = visib_token orelse node.firstToken() };
134 }145 }
...@@ -163,10 +174,18 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -163,10 +174,18 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
163 try tree.errors.push(.{174 try tree.errors.push(.{
164 .ExpectedPubItem = .{ .token = it.index },175 .ExpectedPubItem = .{ .token = it.index },
165 });176 });
166 return error.ParseError;177 // ignore this pub
178 continue;
167 }179 }
168180
169 if (try parseContainerField(arena, it, tree)) |node| {181 if (parseContainerField(arena, it, tree) catch |err| switch (err) {
182 error.OutOfMemory => return error.OutOfMemory,
183 error.ParseError => {
184 // attempt to recover
185 findNextContainerMember(it);
186 continue;
187 },
188 }) |node| {
170 switch (field_state) {189 switch (field_state) {
171 .none => field_state = .seen,190 .none => field_state = .seen,
172 .err, .seen => {},191 .err, .seen => {},
...@@ -182,7 +201,21 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -182,7 +201,21 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
182 const field = node.cast(Node.ContainerField).?;201 const field = node.cast(Node.ContainerField).?;
183 field.doc_comments = doc_comments;202 field.doc_comments = doc_comments;
184 try list.push(node);203 try list.push(node);
185 const comma = eatToken(it, .Comma) orelse break;204 const comma = eatToken(it, .Comma) orelse {
205 // try to continue parsing
206 const index = it.index;
207 findNextContainerMember(it);
208 switch (it.peek().?.id) {
209 .Eof, .RBrace => break,
210 else => {
211 // add error and continue
212 try tree.errors.push(.{
213 .ExpectedToken = .{ .token = index, .expected_id = .Comma },
214 });
215 continue;
216 },
217 }
218 };
186 if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|219 if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|
187 field.doc_comments = appended_comment;220 field.doc_comments = appended_comment;
188 continue;221 continue;
...@@ -194,12 +227,102 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No...@@ -194,12 +227,102 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
194 .UnattachedDocComment = .{ .token = doc_comments.?.firstToken() },227 .UnattachedDocComment = .{ .token = doc_comments.?.firstToken() },
195 });228 });
196 }229 }
197 break;230
231 switch (it.peek().?.id) {
232 .Eof, .RBrace => break,
233 else => {
234 // this was likely not supposed to end yet,
235 // try to find the next declaration
236 const index = it.index;
237 findNextContainerMember(it);
238 try tree.errors.push(.{
239 .ExpectedContainerMembers = .{ .token = index },
240 });
241 },
242 }
198 }243 }
199244
200 return list;245 return list;
201}246}
202247
248/// Attempts to find next container member by searching for certain tokens
249fn findNextContainerMember(it: *TokenIterator) void {
250 var level: u32 = 0;
251 while (true) {
252 const tok = nextToken(it);
253 switch (tok.ptr.id) {
254 // any of these can start a new top level declaration
255 .Keyword_test,
256 .Keyword_comptime,
257 .Keyword_pub,
258 .Keyword_export,
259 .Keyword_extern,
260 .Keyword_inline,
261 .Keyword_noinline,
262 .Keyword_usingnamespace,
263 .Keyword_threadlocal,
264 .Keyword_const,
265 .Keyword_var,
266 .Keyword_fn,
267 .Identifier,
268 => {
269 if (level == 0) {
270 putBackToken(it, tok.index);
271 return;
272 }
273 },
274 .Comma, .Semicolon => {
275 // this decl was likely meant to end here
276 if (level == 0) {
277 return;
278 }
279 },
280 .LParen, .LBracket, .LBrace => level += 1,
281 .RParen, .RBracket, .RBrace => {
282 if (level == 0) {
283 // end of container, exit
284 putBackToken(it, tok.index);
285 return;
286 }
287 level -= 1;
288 },
289 .Eof => {
290 putBackToken(it, tok.index);
291 return;
292 },
293 else => {},
294 }
295 }
296}
297
298/// Attempts to find the next statement by searching for a semicolon
299fn findNextStmt(it: *TokenIterator) void {
300 var level: u32 = 0;
301 while (true) {
302 const tok = nextToken(it);
303 switch (tok.ptr.id) {
304 .LBrace => level += 1,
305 .RBrace => {
306 if (level == 0) {
307 putBackToken(it, tok.index);
308 return;
309 }
310 level -= 1;
311 },
312 .Semicolon => {
313 if (level == 0) {
314 return;
315 }
316 },
317 .Eof => {
318 putBackToken(it, tok.index);
319 return;
320 },
321 else => {},
322 }
323 }
324}
325
203/// Eat a multiline container doc comment326/// Eat a multiline container doc comment
204fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {327fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
205 var lines = Node.DocComment.LineList.init(arena);328 var lines = Node.DocComment.LineList.init(arena);
...@@ -279,22 +402,30 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -279,22 +402,30 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
279 fn_node.*.extern_export_inline_token = extern_export_inline_token;402 fn_node.*.extern_export_inline_token = extern_export_inline_token;
280 fn_node.*.lib_name = lib_name;403 fn_node.*.lib_name = lib_name;
281 if (eatToken(it, .Semicolon)) |_| return node;404 if (eatToken(it, .Semicolon)) |_| return node;
282 if (try parseBlock(arena, it, tree)) |body_node| {405 if (parseBlock(arena, it, tree) catch |err| switch (err) {
406 error.OutOfMemory => return error.OutOfMemory,
407 // since parseBlock only return error.ParseError on
408 // a missing '}' we can assume this function was
409 // supposed to end here.
410 error.ParseError => return node,
411 }) |body_node| {
283 fn_node.body_node = body_node;412 fn_node.body_node = body_node;
284 return node;413 return node;
285 }414 }
286 try tree.errors.push(.{415 try tree.errors.push(.{
287 .ExpectedSemiOrLBrace = .{ .token = it.index },416 .ExpectedSemiOrLBrace = .{ .token = it.index },
288 });417 });
289 return null;418 return error.ParseError;
290 }419 }
291420
292 if (extern_export_inline_token) |token| {421 if (extern_export_inline_token) |token| {
293 if (tree.tokens.at(token).id == .Keyword_inline or422 if (tree.tokens.at(token).id == .Keyword_inline or
294 tree.tokens.at(token).id == .Keyword_noinline)423 tree.tokens.at(token).id == .Keyword_noinline)
295 {424 {
296 putBackToken(it, token);425 try tree.errors.push(.{
297 return null;426 .ExpectedFn = .{ .token = it.index },
427 });
428 return error.ParseError;
298 }429 }
299 }430 }
300431
...@@ -313,42 +444,40 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -313,42 +444,40 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
313 try tree.errors.push(.{444 try tree.errors.push(.{
314 .ExpectedVarDecl = .{ .token = it.index },445 .ExpectedVarDecl = .{ .token = it.index },
315 });446 });
447 // ignore this and try again;
316 return error.ParseError;448 return error.ParseError;
317 }449 }
318450
319 if (extern_export_inline_token) |token| {451 if (extern_export_inline_token) |token| {
320 if (lib_name) |string_literal_node|452 try tree.errors.push(.{
321 putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);453 .ExpectedVarDeclOrFn = .{ .token = it.index },
322 putBackToken(it, token);454 });
323 return null;455 // ignore this and try again;
456 return error.ParseError;
324 }457 }
325458
326 const use_node = (try parseUse(arena, it, tree)) orelse return null;459 return try parseUse(arena, it, tree);
327 const expr_node = try expectNode(arena, it, tree, parseExpr, .{
328 .ExpectedExpr = .{ .token = it.index },
329 });
330 const semicolon_token = try expectToken(it, tree, .Semicolon);
331 const use_node_raw = use_node.cast(Node.Use).?;
332 use_node_raw.*.expr = expr_node;
333 use_node_raw.*.semicolon_token = semicolon_token;
334
335 return use_node;
336}460}
337461
338/// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)462/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
339fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {463fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
340 const cc = parseFnCC(arena, it, tree);464 // TODO: Remove once extern/async fn rewriting is
341 const fn_token = eatToken(it, .Keyword_fn) orelse {465 var is_async = false;
342 if (cc) |fnCC| {466 var is_extern = false;
343 if (fnCC == .Extern) {467 const cc_token: ?usize = blk: {
344 putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl468 if (eatToken(it, .Keyword_extern)) |token| {
345 } else {469 is_extern = true;
346 try tree.errors.push(.{470 break :blk token;
347 .ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn },
348 });
349 return error.ParseError;
350 }
351 }471 }
472 if (eatToken(it, .Keyword_async)) |token| {
473 is_async = true;
474 break :blk token;
475 }
476 break :blk null;
477 };
478 const fn_token = eatToken(it, .Keyword_fn) orelse {
479 if (cc_token) |token|
480 putBackToken(it, token);
352 return null;481 return null;
353 };482 };
354 const name_token = eatToken(it, .Identifier);483 const name_token = eatToken(it, .Identifier);
...@@ -361,18 +490,23 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -361,18 +490,23 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
361 const exclamation_token = eatToken(it, .Bang);490 const exclamation_token = eatToken(it, .Bang);
362491
363 const return_type_expr = (try parseVarType(arena, it, tree)) orelse492 const return_type_expr = (try parseVarType(arena, it, tree)) orelse
364 try expectNode(arena, it, tree, parseTypeExpr, .{493 (try parseTypeExpr(arena, it, tree)) orelse blk: {
365 .ExpectedReturnType = .{ .token = it.index },494 try tree.errors.push(.{
366 });495 .ExpectedReturnType = .{ .token = it.index },
496 });
497 // most likely the user forgot to specify the return type.
498 // Mark return type as invalid and try to continue.
499 break :blk null;
500 };
367501
368 const return_type: Node.FnProto.ReturnType = if (exclamation_token != null)502 // TODO https://github.com/ziglang/zig/issues/3750
369 .{503 const R = Node.FnProto.ReturnType;
370 .InferErrorSet = return_type_expr,504 const return_type = if (return_type_expr == null)
371 }505 R{ .Invalid = rparen }
506 else if (exclamation_token != null)
507 R{ .InferErrorSet = return_type_expr.? }
372 else508 else
373 .{509 R{ .Explicit = return_type_expr.? };
374 .Explicit = return_type_expr,
375 };
376510
377 const var_args_token = if (params.len > 0)511 const var_args_token = if (params.len > 0)
378 params.at(params.len - 1).*.cast(Node.ParamDecl).?.var_args_token512 params.at(params.len - 1).*.cast(Node.ParamDecl).?.var_args_token
...@@ -389,21 +523,15 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -389,21 +523,15 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
389 .return_type = return_type,523 .return_type = return_type,
390 .var_args_token = var_args_token,524 .var_args_token = var_args_token,
391 .extern_export_inline_token = null,525 .extern_export_inline_token = null,
392 .cc_token = null,
393 .body_node = null,526 .body_node = null,
394 .lib_name = null,527 .lib_name = null,
395 .align_expr = align_expr,528 .align_expr = align_expr,
396 .section_expr = section_expr,529 .section_expr = section_expr,
397 .callconv_expr = callconv_expr,530 .callconv_expr = callconv_expr,
531 .is_extern_prototype = is_extern,
532 .is_async = is_async,
398 };533 };
399534
400 if (cc) |kind| {
401 switch (kind) {
402 .CC => |token| fn_proto_node.cc_token = token,
403 .Extern => |token| fn_proto_node.extern_export_inline_token = token,
404 }
405 }
406
407 return &fn_proto_node.base;535 return &fn_proto_node.base;
408}536}
409537
...@@ -495,7 +623,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -495,7 +623,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
495/// Statement623/// Statement
496/// <- KEYWORD_comptime? VarDecl624/// <- KEYWORD_comptime? VarDecl
497/// / KEYWORD_comptime BlockExprStatement625/// / KEYWORD_comptime BlockExprStatement
498/// / KEYWORD_noasync BlockExprStatement626/// / KEYWORD_nosuspend BlockExprStatement
499/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)627/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
500/// / KEYWORD_defer BlockExprStatement628/// / KEYWORD_defer BlockExprStatement
501/// / KEYWORD_errdefer Payload? BlockExprStatement629/// / KEYWORD_errdefer Payload? BlockExprStatement
...@@ -527,14 +655,14 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No...@@ -527,14 +655,14 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
527 return &node.base;655 return &node.base;
528 }656 }
529657
530 if (eatToken(it, .Keyword_noasync)) |noasync_token| {658 if (eatToken(it, .Keyword_nosuspend)) |nosuspend_token| {
531 const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{659 const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{
532 .ExpectedBlockOrAssignment = .{ .token = it.index },660 .ExpectedBlockOrAssignment = .{ .token = it.index },
533 });661 });
534662
535 const node = try arena.create(Node.Noasync);663 const node = try arena.create(Node.Nosuspend);
536 node.* = .{664 node.* = .{
537 .noasync_token = noasync_token,665 .nosuspend_token = nosuspend_token,
538 .expr = block_expr,666 .expr = block_expr,
539 };667 };
540 return &node.base;668 return &node.base;
...@@ -579,7 +707,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No...@@ -579,7 +707,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
579 if (try parseLabeledStatement(arena, it, tree)) |node| return node;707 if (try parseLabeledStatement(arena, it, tree)) |node| return node;
580 if (try parseSwitchExpr(arena, it, tree)) |node| return node;708 if (try parseSwitchExpr(arena, it, tree)) |node| return node;
581 if (try parseAssignExpr(arena, it, tree)) |node| {709 if (try parseAssignExpr(arena, it, tree)) |node| {
582 _ = try expectToken(it, tree, .Semicolon);710 _ = eatToken(it, .Semicolon) orelse {
711 try tree.errors.push(.{
712 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
713 });
714 // pretend we saw a semicolon and continue parsing
715 };
583 return node;716 return node;
584 }717 }
585718
...@@ -688,8 +821,13 @@ fn parseLoopStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod...@@ -688,8 +821,13 @@ fn parseLoopStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
688 node.cast(Node.While).?.inline_token = inline_token;821 node.cast(Node.While).?.inline_token = inline_token;
689 return node;822 return node;
690 }823 }
824 if (inline_token == null) return null;
691825
692 return null;826 // If we've seen "inline", there should have been a "for" or "while"
827 try tree.errors.push(.{
828 .ExpectedInlinable = .{ .token = it.index },
829 });
830 return error.ParseError;
693}831}
694832
695/// ForStatement833/// ForStatement
...@@ -818,7 +956,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -818,7 +956,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
818fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {956fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
819 if (try parseBlockExpr(arena, it, tree)) |node| return node;957 if (try parseBlockExpr(arena, it, tree)) |node| return node;
820 if (try parseAssignExpr(arena, it, tree)) |node| {958 if (try parseAssignExpr(arena, it, tree)) |node| {
821 _ = try expectToken(it, tree, .Semicolon);959 _ = eatToken(it, .Semicolon) orelse {
960 try tree.errors.push(.{
961 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
962 });
963 // pretend we saw a semicolon and continue parsing
964 };
822 return node;965 return node;
823 }966 }
824 return null;967 return null;
...@@ -908,7 +1051,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -908,7 +1051,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
908/// / IfExpr1051/// / IfExpr
909/// / KEYWORD_break BreakLabel? Expr?1052/// / KEYWORD_break BreakLabel? Expr?
910/// / KEYWORD_comptime Expr1053/// / KEYWORD_comptime Expr
911/// / KEYWORD_noasync Expr1054/// / KEYWORD_nosuspend Expr
912/// / KEYWORD_continue BreakLabel?1055/// / KEYWORD_continue BreakLabel?
913/// / KEYWORD_resume Expr1056/// / KEYWORD_resume Expr
914/// / KEYWORD_return Expr?1057/// / KEYWORD_return Expr?
...@@ -925,7 +1068,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -925,7 +1068,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
925 const node = try arena.create(Node.ControlFlowExpression);1068 const node = try arena.create(Node.ControlFlowExpression);
926 node.* = .{1069 node.* = .{
927 .ltoken = token,1070 .ltoken = token,
928 .kind = Node.ControlFlowExpression.Kind{ .Break = label },1071 .kind = .{ .Break = label },
929 .rhs = expr_node,1072 .rhs = expr_node,
930 };1073 };
931 return &node.base;1074 return &node.base;
...@@ -944,13 +1087,13 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -944,13 +1087,13 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
944 return &node.base;1087 return &node.base;
945 }1088 }
9461089
947 if (eatToken(it, .Keyword_noasync)) |token| {1090 if (eatToken(it, .Keyword_nosuspend)) |token| {
948 const expr_node = try expectNode(arena, it, tree, parseExpr, .{1091 const expr_node = try expectNode(arena, it, tree, parseExpr, .{
949 .ExpectedExpr = .{ .token = it.index },1092 .ExpectedExpr = .{ .token = it.index },
950 });1093 });
951 const node = try arena.create(Node.Noasync);1094 const node = try arena.create(Node.Nosuspend);
952 node.* = .{1095 node.* = .{
953 .noasync_token = token,1096 .nosuspend_token = token,
954 .expr = expr_node,1097 .expr = expr_node,
955 };1098 };
956 return &node.base;1099 return &node.base;
...@@ -961,7 +1104,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -961,7 +1104,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
961 const node = try arena.create(Node.ControlFlowExpression);1104 const node = try arena.create(Node.ControlFlowExpression);
962 node.* = .{1105 node.* = .{
963 .ltoken = token,1106 .ltoken = token,
964 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },1107 .kind = .{ .Continue = label },
965 .rhs = null,1108 .rhs = null,
966 };1109 };
967 return &node.base;1110 return &node.base;
...@@ -985,7 +1128,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -985,7 +1128,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
985 const node = try arena.create(Node.ControlFlowExpression);1128 const node = try arena.create(Node.ControlFlowExpression);
986 node.* = .{1129 node.* = .{
987 .ltoken = token,1130 .ltoken = token,
988 .kind = Node.ControlFlowExpression.Kind.Return,1131 .kind = .Return,
989 .rhs = expr_node,1132 .rhs = expr_node,
990 };1133 };
991 return &node.base;1134 return &node.base;
...@@ -1023,7 +1166,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1023,7 +1166,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10231166
1024 var statements = Node.Block.StatementList.init(arena);1167 var statements = Node.Block.StatementList.init(arena);
1025 while (true) {1168 while (true) {
1026 const statement = (try parseStatement(arena, it, tree)) orelse break;1169 const statement = (parseStatement(arena, it, tree) catch |err| switch (err) {
1170 error.OutOfMemory => return error.OutOfMemory,
1171 error.ParseError => {
1172 // try to skip to the next statement
1173 findNextStmt(it);
1174 continue;
1175 },
1176 }) orelse break;
1027 try statements.push(statement);1177 try statements.push(statement);
1028 }1178 }
10291179
...@@ -1197,6 +1347,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1197,6 +1347,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1197 if (maybe_async) |async_token| {1347 if (maybe_async) |async_token| {
1198 const token_fn = eatToken(it, .Keyword_fn);1348 const token_fn = eatToken(it, .Keyword_fn);
1199 if (token_fn != null) {1349 if (token_fn != null) {
1350 // TODO: remove this hack when async fn rewriting is
1200 // HACK: If we see the keyword `fn`, then we assume that1351 // HACK: If we see the keyword `fn`, then we assume that
1201 // we are parsing an async fn proto, and not a call.1352 // we are parsing an async fn proto, and not a call.
1202 // We therefore put back all tokens consumed by the async1353 // We therefore put back all tokens consumed by the async
...@@ -1205,7 +1356,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1205,7 +1356,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1205 putBackToken(it, async_token);1356 putBackToken(it, async_token);
1206 return parsePrimaryTypeExpr(arena, it, tree);1357 return parsePrimaryTypeExpr(arena, it, tree);
1207 }1358 }
1208 // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
1209 var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{1359 var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
1210 .ExpectedPrimaryTypeExpr = .{ .token = it.index },1360 .ExpectedPrimaryTypeExpr = .{ .token = it.index },
1211 });1361 });
...@@ -1223,7 +1373,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1223,7 +1373,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1223 try tree.errors.push(.{1373 try tree.errors.push(.{
1224 .ExpectedParamList = .{ .token = it.index },1374 .ExpectedParamList = .{ .token = it.index },
1225 });1375 });
1226 return null;1376 // ignore this, continue parsing
1377 return res;
1227 };1378 };
1228 const node = try arena.create(Node.SuffixOp);1379 const node = try arena.create(Node.SuffixOp);
1229 node.* = .{1380 node.* = .{
...@@ -1288,7 +1439,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1288,7 +1439,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1288/// / IfTypeExpr1439/// / IfTypeExpr
1289/// / INTEGER1440/// / INTEGER
1290/// / KEYWORD_comptime TypeExpr1441/// / KEYWORD_comptime TypeExpr
1291/// / KEYWORD_noasync TypeExpr
1292/// / KEYWORD_error DOT IDENTIFIER1442/// / KEYWORD_error DOT IDENTIFIER
1293/// / KEYWORD_false1443/// / KEYWORD_false
1294/// / KEYWORD_null1444/// / KEYWORD_null
...@@ -1327,15 +1477,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N...@@ -1327,15 +1477,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
1327 };1477 };
1328 return &node.base;1478 return &node.base;
1329 }1479 }
1330 if (eatToken(it, .Keyword_noasync)) |token| {
1331 const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
1332 const node = try arena.create(Node.Noasync);
1333 node.* = .{
1334 .noasync_token = token,
1335 .expr = expr,
1336 };
1337 return &node.base;
1338 }
1339 if (eatToken(it, .Keyword_error)) |token| {1480 if (eatToken(it, .Keyword_error)) |token| {
1340 const period = try expectToken(it, tree, .Period);1481 const period = try expectToken(it, tree, .Period);
1341 const identifier = try expectNode(arena, it, tree, parseIdentifier, .{1482 const identifier = try expectNode(arena, it, tree, parseIdentifier, .{
...@@ -1778,24 +1919,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -1778,24 +1919,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1778 return expr_node;1919 return expr_node;
1779}1920}
17801921
1781/// FnCC
1782/// <- KEYWORD_nakedcc
1783/// / KEYWORD_stdcallcc
1784/// / KEYWORD_extern
1785/// / KEYWORD_async
1786fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC {
1787 if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token };
1788 if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token };
1789 if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token };
1790 if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token };
1791 return null;
1792}
1793
1794const FnCC = union(enum) {
1795 CC: TokenIndex,
1796 Extern: TokenIndex,
1797};
1798
1799/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType1922/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
1800fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1923fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1801 const doc_comments = try parseDocComment(arena, it, tree);1924 const doc_comments = try parseDocComment(arena, it, tree);
...@@ -2290,7 +2413,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2290,7 +2413,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2290 const node = try arena.create(Node.AnyFrameType);2413 const node = try arena.create(Node.AnyFrameType);
2291 node.* = .{2414 node.* = .{
2292 .anyframe_token = token,2415 .anyframe_token = token,
2293 .result = Node.AnyFrameType.Result{2416 .result = .{
2294 .arrow_token = arrow,2417 .arrow_token = arrow,
2295 .return_type = undefined, // set by caller2418 .return_type = undefined, // set by caller
2296 },2419 },
...@@ -2331,6 +2454,13 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2331,6 +2454,13 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2331 } else null;2454 } else null;
2332 _ = try expectToken(it, tree, .RParen);2455 _ = try expectToken(it, tree, .RParen);
23332456
2457 if (ptr_info.align_info != null) {
2458 try tree.errors.push(.{
2459 .ExtraAlignQualifier = .{ .token = it.index - 1 },
2460 });
2461 continue;
2462 }
2463
2334 ptr_info.align_info = Node.PrefixOp.PtrInfo.Align{2464 ptr_info.align_info = Node.PrefixOp.PtrInfo.Align{
2335 .node = expr_node,2465 .node = expr_node,
2336 .bit_range = bit_range,2466 .bit_range = bit_range,
...@@ -2339,14 +2469,32 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2339,14 +2469,32 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2339 continue;2469 continue;
2340 }2470 }
2341 if (eatToken(it, .Keyword_const)) |const_token| {2471 if (eatToken(it, .Keyword_const)) |const_token| {
2472 if (ptr_info.const_token != null) {
2473 try tree.errors.push(.{
2474 .ExtraConstQualifier = .{ .token = it.index - 1 },
2475 });
2476 continue;
2477 }
2342 ptr_info.const_token = const_token;2478 ptr_info.const_token = const_token;
2343 continue;2479 continue;
2344 }2480 }
2345 if (eatToken(it, .Keyword_volatile)) |volatile_token| {2481 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2482 if (ptr_info.volatile_token != null) {
2483 try tree.errors.push(.{
2484 .ExtraVolatileQualifier = .{ .token = it.index - 1 },
2485 });
2486 continue;
2487 }
2346 ptr_info.volatile_token = volatile_token;2488 ptr_info.volatile_token = volatile_token;
2347 continue;2489 continue;
2348 }2490 }
2349 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {2491 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2492 if (ptr_info.allowzero_token != null) {
2493 try tree.errors.push(.{
2494 .ExtraAllowZeroQualifier = .{ .token = it.index - 1 },
2495 });
2496 continue;
2497 }
2350 ptr_info.allowzero_token = allowzero_token;2498 ptr_info.allowzero_token = allowzero_token;
2351 continue;2499 continue;
2352 }2500 }
...@@ -2365,9 +2513,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2365,9 +2513,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2365 if (try parseByteAlign(arena, it, tree)) |align_expr| {2513 if (try parseByteAlign(arena, it, tree)) |align_expr| {
2366 if (slice_type.align_info != null) {2514 if (slice_type.align_info != null) {
2367 try tree.errors.push(.{2515 try tree.errors.push(.{
2368 .ExtraAlignQualifier = .{ .token = it.index },2516 .ExtraAlignQualifier = .{ .token = it.index - 1 },
2369 });2517 });
2370 return error.ParseError;2518 continue;
2371 }2519 }
2372 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{2520 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
2373 .node = align_expr,2521 .node = align_expr,
...@@ -2378,9 +2526,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2378,9 +2526,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2378 if (eatToken(it, .Keyword_const)) |const_token| {2526 if (eatToken(it, .Keyword_const)) |const_token| {
2379 if (slice_type.const_token != null) {2527 if (slice_type.const_token != null) {
2380 try tree.errors.push(.{2528 try tree.errors.push(.{
2381 .ExtraConstQualifier = .{ .token = it.index },2529 .ExtraConstQualifier = .{ .token = it.index - 1 },
2382 });2530 });
2383 return error.ParseError;2531 continue;
2384 }2532 }
2385 slice_type.const_token = const_token;2533 slice_type.const_token = const_token;
2386 continue;2534 continue;
...@@ -2388,9 +2536,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2388,9 +2536,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2388 if (eatToken(it, .Keyword_volatile)) |volatile_token| {2536 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
2389 if (slice_type.volatile_token != null) {2537 if (slice_type.volatile_token != null) {
2390 try tree.errors.push(.{2538 try tree.errors.push(.{
2391 .ExtraVolatileQualifier = .{ .token = it.index },2539 .ExtraVolatileQualifier = .{ .token = it.index - 1 },
2392 });2540 });
2393 return error.ParseError;2541 continue;
2394 }2542 }
2395 slice_type.volatile_token = volatile_token;2543 slice_type.volatile_token = volatile_token;
2396 continue;2544 continue;
...@@ -2398,9 +2546,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2398,9 +2546,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2398 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {2546 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
2399 if (slice_type.allowzero_token != null) {2547 if (slice_type.allowzero_token != null) {
2400 try tree.errors.push(.{2548 try tree.errors.push(.{
2401 .ExtraAllowZeroQualifier = .{ .token = it.index },2549 .ExtraAllowZeroQualifier = .{ .token = it.index - 1 },
2402 });2550 });
2403 return error.ParseError;2551 continue;
2404 }2552 }
2405 slice_type.allowzero_token = allowzero_token;2553 slice_type.allowzero_token = allowzero_token;
2406 continue;2554 continue;
...@@ -2749,7 +2897,19 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {...@@ -2749,7 +2897,19 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
2749 var list = L.init(arena);2897 var list = L.init(arena);
2750 while (try nodeParseFn(arena, it, tree)) |node| {2898 while (try nodeParseFn(arena, it, tree)) |node| {
2751 try list.push(node);2899 try list.push(node);
2752 if (eatToken(it, .Comma) == null) break;2900
2901 switch (it.peek().?.id) {
2902 .Comma => _ = nextToken(it),
2903 // all possible delimiters
2904 .Colon, .RParen, .RBrace, .RBracket => break,
2905 else => {
2906 // this is likely just a missing comma,
2907 // continue parsing this list and give an error
2908 try tree.errors.push(.{
2909 .ExpectedToken = .{ .token = it.index, .expected_id = .Comma },
2910 });
2911 },
2912 }
2753 }2913 }
2754 return list;2914 return list;
2755 }2915 }
...@@ -2759,7 +2919,17 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {...@@ -2759,7 +2919,17 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
2759fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) NodeParseFn {2919fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) NodeParseFn {
2760 return struct {2920 return struct {
2761 pub fn parse(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {2921 pub fn parse(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
2762 const op_token = eatToken(it, token) orelse return null;2922 const op_token = if (token == .Keyword_and) switch (it.peek().?.id) {
2923 .Keyword_and => nextToken(it).index,
2924 .Invalid_ampersands => blk: {
2925 try tree.errors.push(.{
2926 .InvalidAnd = .{ .token = it.index },
2927 });
2928 break :blk nextToken(it).index;
2929 },
2930 else => return null,
2931 } else eatToken(it, token) orelse return null;
2932
2763 const node = try arena.create(Node.InfixOp);2933 const node = try arena.create(Node.InfixOp);
2764 node.* = .{2934 node.* = .{
2765 .op_token = op_token,2935 .op_token = op_token,
...@@ -2780,7 +2950,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node...@@ -2780,7 +2950,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
2780 try tree.errors.push(.{2950 try tree.errors.push(.{
2781 .ExpectedParamList = .{ .token = it.index },2951 .ExpectedParamList = .{ .token = it.index },
2782 });2952 });
2783 return error.ParseError;2953
2954 // lets pretend this was an identifier so we can continue parsing
2955 const node = try arena.create(Node.Identifier);
2956 node.* = .{
2957 .token = token,
2958 };
2959 return &node.base;
2784 };2960 };
2785 const node = try arena.create(Node.BuiltinCall);2961 const node = try arena.create(Node.BuiltinCall);
2786 node.* = .{2962 node.* = .{
...@@ -2896,8 +3072,10 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -2896,8 +3072,10 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2896 .doc_comments = null,3072 .doc_comments = null,
2897 .visib_token = null,3073 .visib_token = null,
2898 .use_token = token,3074 .use_token = token,
2899 .expr = undefined, // set by caller3075 .expr = try expectNode(arena, it, tree, parseExpr, .{
2900 .semicolon_token = undefined, // set by caller3076 .ExpectedExpr = .{ .token = it.index },
3077 }),
3078 .semicolon_token = try expectToken(it, tree, .Semicolon),
2901 };3079 };
2902 return &node.base;3080 return &node.base;
2903}3081}
...@@ -3077,6 +3255,8 @@ fn expectToken(it: *TokenIterator, tree: *Tree, id: Token.Id) Error!TokenIndex {...@@ -3077,6 +3255,8 @@ fn expectToken(it: *TokenIterator, tree: *Tree, id: Token.Id) Error!TokenIndex {
3077 try tree.errors.push(.{3255 try tree.errors.push(.{
3078 .ExpectedToken = .{ .token = token.index, .expected_id = id },3256 .ExpectedToken = .{ .token = token.index, .expected_id = id },
3079 });3257 });
3258 // go back so that we can recover properly
3259 putBackToken(it, token.index);
3080 return error.ParseError;3260 return error.ParseError;
3081 }3261 }
3082 return token.index;3262 return token.index;
lib/std/zig/parser_test.zig+211-43
...@@ -1,3 +1,153 @@...@@ -1,3 +1,153 @@
1test "recovery: top level" {
2 try testError(
3 \\test "" {inline}
4 \\test "" {inline}
5 , &[_]Error{
6 .ExpectedInlinable,
7 .ExpectedInlinable,
8 });
9}
10
11test "recovery: block statements" {
12 try testError(
13 \\test "" {
14 \\ foo + +;
15 \\ inline;
16 \\}
17 , &[_]Error{
18 .InvalidToken,
19 .ExpectedInlinable,
20 });
21}
22
23test "recovery: missing comma" {
24 try testError(
25 \\test "" {
26 \\ switch (foo) {
27 \\ 2 => {}
28 \\ 3 => {}
29 \\ else => {
30 \\ foo && bar +;
31 \\ }
32 \\ }
33 \\}
34 , &[_]Error{
35 .ExpectedToken,
36 .ExpectedToken,
37 .InvalidAnd,
38 .InvalidToken,
39 });
40}
41
42test "recovery: extra qualifier" {
43 try testError(
44 \\const a: *const const u8;
45 \\test ""
46 , &[_]Error{
47 .ExtraConstQualifier,
48 .ExpectedLBrace,
49 });
50}
51
52test "recovery: missing return type" {
53 try testError(
54 \\fn foo() {
55 \\ a && b;
56 \\}
57 \\test ""
58 , &[_]Error{
59 .ExpectedReturnType,
60 .InvalidAnd,
61 .ExpectedLBrace,
62 });
63}
64
65test "recovery: continue after invalid decl" {
66 try testError(
67 \\fn foo {
68 \\ inline;
69 \\}
70 \\pub test "" {
71 \\ async a && b;
72 \\}
73 , &[_]Error{
74 .ExpectedToken,
75 .ExpectedPubItem,
76 .ExpectedParamList,
77 .InvalidAnd,
78 });
79 try testError(
80 \\threadlocal test "" {
81 \\ @a && b;
82 \\}
83 , &[_]Error{
84 .ExpectedVarDecl,
85 .ExpectedParamList,
86 .InvalidAnd,
87 });
88}
89
90test "recovery: invalid extern/inline" {
91 try testError(
92 \\inline test "" { a && b; }
93 , &[_]Error{
94 .ExpectedFn,
95 .InvalidAnd,
96 });
97 try testError(
98 \\extern "" test "" { a && b; }
99 , &[_]Error{
100 .ExpectedVarDeclOrFn,
101 .InvalidAnd,
102 });
103}
104
105test "recovery: missing semicolon" {
106 try testError(
107 \\test "" {
108 \\ comptime a && b
109 \\ c && d
110 \\ @foo
111 \\}
112 , &[_]Error{
113 .InvalidAnd,
114 .ExpectedToken,
115 .InvalidAnd,
116 .ExpectedToken,
117 .ExpectedParamList,
118 .ExpectedToken,
119 });
120}
121
122test "recovery: invalid container members" {
123 try testError(
124 \\usingnamespace;
125 \\foo+
126 \\bar@,
127 \\while (a == 2) { test "" {}}
128 \\test "" {
129 \\ a && b
130 \\}
131 , &[_]Error{
132 .ExpectedExpr,
133 .ExpectedToken,
134 .ExpectedToken,
135 .ExpectedContainerMembers,
136 .InvalidAnd,
137 .ExpectedToken,
138 });
139}
140
141test "recovery: invalid parameter" {
142 try testError(
143 \\fn main() void {
144 \\ a(comptime T: type)
145 \\}
146 , &[_]Error{
147 .ExpectedToken,
148 });
149}
150
1test "zig fmt: top-level fields" {151test "zig fmt: top-level fields" {
2 try testCanonical(152 try testCanonical(
3 \\a: did_you_know,153 \\a: did_you_know,
...@@ -19,7 +169,9 @@ test "zig fmt: decl between fields" {...@@ -19,7 +169,9 @@ test "zig fmt: decl between fields" {
19 \\ const baz1 = 2;169 \\ const baz1 = 2;
20 \\ b: usize,170 \\ b: usize,
21 \\};171 \\};
22 );172 , &[_]Error{
173 .DeclBetweenFields,
174 });
23}175}
24176
25test "zig fmt: errdefer with payload" {177test "zig fmt: errdefer with payload" {
...@@ -35,10 +187,10 @@ test "zig fmt: errdefer with payload" {...@@ -35,10 +187,10 @@ test "zig fmt: errdefer with payload" {
35 );187 );
36}188}
37189
38test "zig fmt: noasync block" {190test "zig fmt: nosuspend block" {
39 try testCanonical(191 try testCanonical(
40 \\pub fn main() anyerror!void {192 \\pub fn main() anyerror!void {
41 \\ noasync {193 \\ nosuspend {
42 \\ var foo: Foo = .{ .bar = 42 };194 \\ var foo: Foo = .{ .bar = 42 };
43 \\ }195 \\ }
44 \\}196 \\}
...@@ -46,10 +198,10 @@ test "zig fmt: noasync block" {...@@ -46,10 +198,10 @@ test "zig fmt: noasync block" {
46 );198 );
47}199}
48200
49test "zig fmt: noasync await" {201test "zig fmt: nosuspend await" {
50 try testCanonical(202 try testCanonical(
51 \\fn foo() void {203 \\fn foo() void {
52 \\ x = noasync await y;204 \\ x = nosuspend await y;
53 \\}205 \\}
54 \\206 \\
55 );207 );
...@@ -123,22 +275,6 @@ test "zig fmt: trailing comma in fn parameter list" {...@@ -123,22 +275,6 @@ test "zig fmt: trailing comma in fn parameter list" {
123 );275 );
124}276}
125277
126// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977
127test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
128 try testTransform(
129 \\nakedcc fn foo1() void {}
130 \\stdcallcc fn foo2() void {}
131 \\extern fn foo3() void {}
132 \\extern "mylib" fn foo4() void {}
133 ,
134 \\fn foo1() callconv(.Naked) void {}
135 \\fn foo2() callconv(.Stdcall) void {}
136 \\fn foo3() callconv(.C) void {}
137 \\fn foo4() callconv(.C) void {}
138 \\
139 );
140}
141
142test "zig fmt: comptime struct field" {278test "zig fmt: comptime struct field" {
143 try testCanonical(279 try testCanonical(
144 \\const Foo = struct {280 \\const Foo = struct {
...@@ -252,10 +388,10 @@ test "zig fmt: anon list literal syntax" {...@@ -252,10 +388,10 @@ test "zig fmt: anon list literal syntax" {
252test "zig fmt: async function" {388test "zig fmt: async function" {
253 try testCanonical(389 try testCanonical(
254 \\pub const Server = struct {390 \\pub const Server = struct {
255 \\ handleRequestFn: async fn (*Server, *const std.net.Address, File) void,391 \\ handleRequestFn: fn (*Server, *const std.net.Address, File) callconv(.Async) void,
256 \\};392 \\};
257 \\test "hi" {393 \\test "hi" {
258 \\ var ptr = @ptrCast(async fn (i32) void, other);394 \\ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
259 \\}395 \\}
260 \\396 \\
261 );397 );
...@@ -451,15 +587,6 @@ test "zig fmt: aligned struct field" {...@@ -451,15 +587,6 @@ test "zig fmt: aligned struct field" {
451 );587 );
452}588}
453589
454test "zig fmt: preserve space between async fn definitions" {
455 try testCanonical(
456 \\async fn a() void {}
457 \\
458 \\async fn b() void {}
459 \\
460 );
461}
462
463test "zig fmt: comment to disable/enable zig fmt first" {590test "zig fmt: comment to disable/enable zig fmt first" {
464 try testCanonical(591 try testCanonical(
465 \\// Test trailing comma syntax592 \\// Test trailing comma syntax
...@@ -1515,7 +1642,7 @@ test "zig fmt: line comments in struct initializer" {...@@ -1515,7 +1642,7 @@ test "zig fmt: line comments in struct initializer" {
15151642
1516test "zig fmt: first line comment in struct initializer" {1643test "zig fmt: first line comment in struct initializer" {
1517 try testCanonical(1644 try testCanonical(
1518 \\pub async fn acquire(self: *Self) HeldLock {1645 \\pub fn acquire(self: *Self) HeldLock {
1519 \\ return HeldLock{1646 \\ return HeldLock{
1520 \\ // guaranteed allocation elision1647 \\ // guaranteed allocation elision
1521 \\ .held = self.lock.acquire(),1648 \\ .held = self.lock.acquire(),
...@@ -2477,8 +2604,7 @@ test "zig fmt: fn type" {...@@ -2477,8 +2604,7 @@ test "zig fmt: fn type" {
2477 \\}2604 \\}
2478 \\2605 \\
2479 \\const a: fn (u8) u8 = undefined;2606 \\const a: fn (u8) u8 = undefined;
2480 \\const b: extern fn (u8) u8 = undefined;2607 \\const b: fn (u8) callconv(.Naked) u8 = undefined;
2481 \\const c: fn (u8) callconv(.Naked) u8 = undefined;
2482 \\const ap: fn (u8) u8 = a;2608 \\const ap: fn (u8) u8 = a;
2483 \\2609 \\
2484 );2610 );
...@@ -2500,7 +2626,7 @@ test "zig fmt: inline asm" {...@@ -2500,7 +2626,7 @@ test "zig fmt: inline asm" {
25002626
2501test "zig fmt: async functions" {2627test "zig fmt: async functions" {
2502 try testCanonical(2628 try testCanonical(
2503 \\async fn simpleAsyncFn() void {2629 \\fn simpleAsyncFn() void {
2504 \\ const a = async a.b();2630 \\ const a = async a.b();
2505 \\ x += 1;2631 \\ x += 1;
2506 \\ suspend;2632 \\ suspend;
...@@ -2519,9 +2645,9 @@ test "zig fmt: async functions" {...@@ -2519,9 +2645,9 @@ test "zig fmt: async functions" {
2519 );2645 );
2520}2646}
25212647
2522test "zig fmt: noasync" {2648test "zig fmt: nosuspend" {
2523 try testCanonical(2649 try testCanonical(
2524 \\const a = noasync foo();2650 \\const a = nosuspend foo();
2525 \\2651 \\
2526 );2652 );
2527}2653}
...@@ -2854,7 +2980,10 @@ test "zig fmt: extern without container keyword returns error" {...@@ -2854,7 +2980,10 @@ test "zig fmt: extern without container keyword returns error" {
2854 try testError(2980 try testError(
2855 \\const container = extern {};2981 \\const container = extern {};
2856 \\2982 \\
2857 );2983 , &[_]Error{
2984 .ExpectedExpr,
2985 .ExpectedVarDeclOrFn,
2986 });
2858}2987}
28592988
2860test "zig fmt: integer literals with underscore separators" {2989test "zig fmt: integer literals with underscore separators" {
...@@ -2926,6 +3055,40 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {...@@ -2926,6 +3055,40 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
2926 );3055 );
2927}3056}
29283057
3058test "zig fmt: noasync to nosuspend" {
3059 // TODO: remove this
3060 try testTransform(
3061 \\pub fn main() void {
3062 \\ noasync call();
3063 \\}
3064 ,
3065 \\pub fn main() void {
3066 \\ nosuspend call();
3067 \\}
3068 \\
3069 );
3070}
3071
3072test "zig fmt: convert async fn into callconv(.Async)" {
3073 try testTransform(
3074 \\async fn foo() void {}
3075 ,
3076 \\fn foo() callconv(.Async) void {}
3077 \\
3078 );
3079}
3080
3081test "zig fmt: convert extern fn proto into callconv(.C)" {
3082 try testTransform(
3083 \\extern fn foo0() void {}
3084 \\const foo1 = extern fn () void;
3085 ,
3086 \\extern fn foo0() void {}
3087 \\const foo1 = fn () callconv(.C) void;
3088 \\
3089 );
3090}
3091
2929const std = @import("std");3092const std = @import("std");
2930const mem = std.mem;3093const mem = std.mem;
2931const warn = std.debug.warn;3094const warn = std.debug.warn;
...@@ -2972,7 +3135,6 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -2972,7 +3135,6 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
2972 anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);3135 anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);
2973 return buffer.toOwnedSlice();3136 return buffer.toOwnedSlice();
2974}3137}
2975
2976fn testTransform(source: []const u8, expected_source: []const u8) !void {3138fn testTransform(source: []const u8, expected_source: []const u8) !void {
2977 const needed_alloc_count = x: {3139 const needed_alloc_count = x: {
2978 // Try it once with unlimited memory, make sure it works3140 // Try it once with unlimited memory, make sure it works
...@@ -3020,14 +3182,20 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {...@@ -3020,14 +3182,20 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
3020 }3182 }
3021 }3183 }
3022}3184}
3023
3024fn testCanonical(source: []const u8) !void {3185fn testCanonical(source: []const u8) !void {
3025 return testTransform(source, source);3186 return testTransform(source, source);
3026}3187}
30273188
3028fn testError(source: []const u8) !void {3189const Error = @TagType(std.zig.ast.Error);
3190
3191fn testError(source: []const u8, expected_errors: []const Error) !void {
3029 const tree = try std.zig.parse(std.testing.allocator, source);3192 const tree = try std.zig.parse(std.testing.allocator, source);
3030 defer tree.deinit();3193 defer tree.deinit();
30313194
3032 std.testing.expect(tree.errors.len != 0);3195 std.testing.expect(tree.errors.len == expected_errors.len);
3196 for (expected_errors) |expected, i| {
3197 const err = tree.errors.at(i);
3198
3199 std.testing.expect(expected == err.*);
3200 }
3033}3201}
lib/std/zig/render.zig+22-30
...@@ -13,6 +13,9 @@ pub const Error = error{...@@ -13,6 +13,9 @@ pub const Error = error{
1313
14/// Returns whether anything changed14/// Returns whether anything changed
15pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool {15pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool {
16 // cannot render an invalid tree
17 std.debug.assert(tree.errors.len == 0);
18
16 // make a passthrough stream that checks whether something changed19 // make a passthrough stream that checks whether something changed
17 const MyStream = struct {20 const MyStream = struct {
18 const MyStream = @This();21 const MyStream = @This();
...@@ -391,11 +394,15 @@ fn renderExpression(...@@ -391,11 +394,15 @@ fn renderExpression(
391 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);394 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
392 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);395 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
393 },396 },
394 .Noasync => {397 .Nosuspend => {
395 const noasync_node = @fieldParentPtr(ast.Node.Noasync, "base", base);398 const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base);
396399 if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) {
397 try renderToken(tree, stream, noasync_node.noasync_token, indent, start_col, Space.Space);400 // TODO: remove this
398 return renderExpression(allocator, stream, tree, indent, start_col, noasync_node.expr, space);401 try stream.writeAll("nosuspend ");
402 } else {
403 try renderToken(tree, stream, nosuspend_node.nosuspend_token, indent, start_col, Space.Space);
404 }
405 return renderExpression(allocator, stream, tree, indent, start_col, nosuspend_node.expr, space);
399 },406 },
400407
401 .Suspend => {408 .Suspend => {
...@@ -1409,32 +1416,15 @@ fn renderExpression(...@@ -1409,32 +1416,15 @@ fn renderExpression(
1409 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub1416 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
1410 }1417 }
14111418
1412 // Some extra machinery is needed to rewrite the old-style cc
1413 // notation to the new callconv one
1414 var cc_rewrite_str: ?[*:0]const u8 = null;
1415 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {1419 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
1416 const tok = tree.tokens.at(extern_export_inline_token);1420 if (!fn_proto.is_extern_prototype)
1417 if (tok.id != .Keyword_extern or fn_proto.body_node == null) {1421 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export/inline
1418 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
1419 } else {
1420 cc_rewrite_str = ".C";
1421 fn_proto.lib_name = null;
1422 }
1423 }1422 }
14241423
1425 if (fn_proto.lib_name) |lib_name| {1424 if (fn_proto.lib_name) |lib_name| {
1426 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);1425 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
1427 }1426 }
14281427
1429 if (fn_proto.cc_token) |cc_token| {
1430 var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
1431 if (mem.eql(u8, str, "stdcallcc")) {
1432 cc_rewrite_str = ".Stdcall";
1433 } else if (mem.eql(u8, str, "nakedcc")) {
1434 cc_rewrite_str = ".Naked";
1435 } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
1436 }
1437
1438 const lparen = if (fn_proto.name_token) |name_token| blk: {1428 const lparen = if (fn_proto.name_token) |name_token| blk: {
1439 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn1429 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
1440 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name1430 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
...@@ -1457,6 +1447,7 @@ fn renderExpression(...@@ -1457,6 +1447,7 @@ fn renderExpression(
1457 else switch (fn_proto.return_type) {1447 else switch (fn_proto.return_type) {
1458 .Explicit => |node| node.firstToken(),1448 .Explicit => |node| node.firstToken(),
1459 .InferErrorSet => |node| tree.prevToken(node.firstToken()),1449 .InferErrorSet => |node| tree.prevToken(node.firstToken()),
1450 .Invalid => unreachable,
1460 });1451 });
1461 assert(tree.tokens.at(rparen).id == .RParen);1452 assert(tree.tokens.at(rparen).id == .RParen);
14621453
...@@ -1524,20 +1515,21 @@ fn renderExpression(...@@ -1524,20 +1515,21 @@ fn renderExpression(
1524 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (1515 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
1525 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);1516 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
1526 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )1517 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
1527 } else if (cc_rewrite_str) |str| {1518 } else if (fn_proto.is_extern_prototype) {
1528 try stream.writeAll("callconv(");1519 try stream.writeAll("callconv(.C) ");
1529 try stream.writeAll(mem.spanZ(str));1520 } else if (fn_proto.is_async) {
1530 try stream.writeAll(") ");1521 try stream.writeAll("callconv(.Async) ");
1531 }1522 }
15321523
1533 switch (fn_proto.return_type) {1524 switch (fn_proto.return_type) {
1534 ast.Node.FnProto.ReturnType.Explicit => |node| {1525 .Explicit => |node| {
1535 return renderExpression(allocator, stream, tree, indent, start_col, node, space);1526 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
1536 },1527 },
1537 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {1528 .InferErrorSet => |node| {
1538 try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !1529 try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !
1539 return renderExpression(allocator, stream, tree, indent, start_col, node, space);1530 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
1540 },1531 },
1532 .Invalid => unreachable,
1541 }1533 }
1542 },1534 },
15431535
lib/std/zig/system.zig+1
...@@ -837,6 +837,7 @@ pub const NativeTargetInfo = struct {...@@ -837,6 +837,7 @@ pub const NativeTargetInfo = struct {
837 error.BrokenPipe => return error.UnableToReadElfFile,837 error.BrokenPipe => return error.UnableToReadElfFile,
838 error.Unseekable => return error.UnableToReadElfFile,838 error.Unseekable => return error.UnableToReadElfFile,
839 error.ConnectionResetByPeer => return error.UnableToReadElfFile,839 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
840 error.ConnectionTimedOut => return error.UnableToReadElfFile,
840 error.Unexpected => return error.Unexpected,841 error.Unexpected => return error.Unexpected,
841 error.InputOutput => return error.FileSystem,842 error.InputOutput => return error.FileSystem,
842 };843 };
lib/std/zig/system/macos.zig+9-4
...@@ -39,7 +39,7 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {...@@ -39,7 +39,7 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
39 zend += 1;39 zend += 1;
40 }40 }
41 if (zend == yindex + 1) return error.InvalidVersion;41 if (zend == yindex + 1) return error.InvalidVersion;
42 const z = std.fmt.parseUnsigned(u16, build[yindex + 1..zend], 10) catch return error.InvalidVersion;42 const z = std.fmt.parseUnsigned(u16, build[yindex + 1 .. zend], 10) catch return error.InvalidVersion;
4343
44 result.patch = switch (result.minor) {44 result.patch = switch (result.minor) {
45 // TODO: compiler complains without explicit @as() coercion45 // TODO: compiler complains without explicit @as() coercion
...@@ -97,7 +97,9 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {...@@ -97,7 +97,9 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
97 4 => @as(u32, switch (y) { // Tiger: 10.497 4 => @as(u32, switch (y) { // Tiger: 10.4
98 'A' => 0,98 'A' => 0,
99 'B' => 1,99 'B' => 1,
100 'C', 'E', => 2,100 'C',
101 'E',
102 => 2,
101 'F' => 3,103 'F' => 3,
102 'G' => @as(u32, block: {104 'G' => @as(u32, block: {
103 if (z >= 1454) break :block 5;105 if (z >= 1454) break :block 5;
...@@ -105,7 +107,10 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {...@@ -105,7 +107,10 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
105 }),107 }),
106 'H' => 5,108 'H' => 5,
107 'I' => 6,109 'I' => 6,
108 'J', 'K', 'N', => 7,110 'J',
111 'K',
112 'N',
113 => 7,
109 'L' => 8,114 'L' => 8,
110 'P' => 9,115 'P' => 9,
111 'R' => 10,116 'R' => 10,
...@@ -438,7 +443,7 @@ test "version_from_build" {...@@ -438,7 +443,7 @@ test "version_from_build" {
438 for (known) |pair| {443 for (known) |pair| {
439 var buf: [32]u8 = undefined;444 var buf: [32]u8 = undefined;
440 const ver = try version_from_build(pair[0]);445 const ver = try version_from_build(pair[0]);
441 const sver = try std.fmt.bufPrint(buf[0..], "{}.{}.{}", .{ver.major, ver.minor, ver.patch});446 const sver = try std.fmt.bufPrint(buf[0..], "{}.{}.{}", .{ ver.major, ver.minor, ver.patch });
442 std.testing.expect(std.mem.eql(u8, sver, pair[1]));447 std.testing.expect(std.mem.eql(u8, sver, pair[1]));
443 }448 }
444}449}
lib/std/zig/tokenizer.zig+481-486
...@@ -47,10 +47,10 @@ pub const Token = struct {...@@ -47,10 +47,10 @@ pub const Token = struct {
47 Keyword.init("for", .Keyword_for),47 Keyword.init("for", .Keyword_for),
48 Keyword.init("if", .Keyword_if),48 Keyword.init("if", .Keyword_if),
49 Keyword.init("inline", .Keyword_inline),49 Keyword.init("inline", .Keyword_inline),
50 Keyword.init("nakedcc", .Keyword_nakedcc),
51 Keyword.init("noalias", .Keyword_noalias),50 Keyword.init("noalias", .Keyword_noalias),
52 Keyword.init("noasync", .Keyword_noasync),51 Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
53 Keyword.init("noinline", .Keyword_noinline),52 Keyword.init("noinline", .Keyword_noinline),
53 Keyword.init("nosuspend", .Keyword_nosuspend),
54 Keyword.init("null", .Keyword_null),54 Keyword.init("null", .Keyword_null),
55 Keyword.init("or", .Keyword_or),55 Keyword.init("or", .Keyword_or),
56 Keyword.init("orelse", .Keyword_orelse),56 Keyword.init("orelse", .Keyword_orelse),
...@@ -59,7 +59,6 @@ pub const Token = struct {...@@ -59,7 +59,6 @@ pub const Token = struct {
59 Keyword.init("resume", .Keyword_resume),59 Keyword.init("resume", .Keyword_resume),
60 Keyword.init("return", .Keyword_return),60 Keyword.init("return", .Keyword_return),
61 Keyword.init("linksection", .Keyword_linksection),61 Keyword.init("linksection", .Keyword_linksection),
62 Keyword.init("stdcallcc", .Keyword_stdcallcc),
63 Keyword.init("struct", .Keyword_struct),62 Keyword.init("struct", .Keyword_struct),
64 Keyword.init("suspend", .Keyword_suspend),63 Keyword.init("suspend", .Keyword_suspend),
65 Keyword.init("switch", .Keyword_switch),64 Keyword.init("switch", .Keyword_switch),
...@@ -180,10 +179,9 @@ pub const Token = struct {...@@ -180,10 +179,9 @@ pub const Token = struct {
180 Keyword_for,179 Keyword_for,
181 Keyword_if,180 Keyword_if,
182 Keyword_inline,181 Keyword_inline,
183 Keyword_nakedcc,
184 Keyword_noalias,182 Keyword_noalias,
185 Keyword_noasync,
186 Keyword_noinline,183 Keyword_noinline,
184 Keyword_nosuspend,
187 Keyword_null,185 Keyword_null,
188 Keyword_or,186 Keyword_or,
189 Keyword_orelse,187 Keyword_orelse,
...@@ -193,7 +191,6 @@ pub const Token = struct {...@@ -193,7 +191,6 @@ pub const Token = struct {
193 Keyword_resume,191 Keyword_resume,
194 Keyword_return,192 Keyword_return,
195 Keyword_linksection,193 Keyword_linksection,
196 Keyword_stdcallcc,
197 Keyword_struct,194 Keyword_struct,
198 Keyword_suspend,195 Keyword_suspend,
199 Keyword_switch,196 Keyword_switch,
...@@ -305,10 +302,9 @@ pub const Token = struct {...@@ -305,10 +302,9 @@ pub const Token = struct {
305 .Keyword_for => "for",302 .Keyword_for => "for",
306 .Keyword_if => "if",303 .Keyword_if => "if",
307 .Keyword_inline => "inline",304 .Keyword_inline => "inline",
308 .Keyword_nakedcc => "nakedcc",
309 .Keyword_noalias => "noalias",305 .Keyword_noalias => "noalias",
310 .Keyword_noasync => "noasync",
311 .Keyword_noinline => "noinline",306 .Keyword_noinline => "noinline",
307 .Keyword_nosuspend => "nosuspend",
312 .Keyword_null => "null",308 .Keyword_null => "null",
313 .Keyword_or => "or",309 .Keyword_or => "or",
314 .Keyword_orelse => "orelse",310 .Keyword_orelse => "orelse",
...@@ -317,7 +313,6 @@ pub const Token = struct {...@@ -317,7 +313,6 @@ pub const Token = struct {
317 .Keyword_resume => "resume",313 .Keyword_resume => "resume",
318 .Keyword_return => "return",314 .Keyword_return => "return",
319 .Keyword_linksection => "linksection",315 .Keyword_linksection => "linksection",
320 .Keyword_stdcallcc => "stdcallcc",
321 .Keyword_struct => "struct",316 .Keyword_struct => "struct",
322 .Keyword_suspend => "suspend",317 .Keyword_suspend => "suspend",
323 .Keyword_switch => "switch",318 .Keyword_switch => "switch",
...@@ -358,64 +353,64 @@ pub const Tokenizer = struct {...@@ -358,64 +353,64 @@ pub const Tokenizer = struct {
358 }353 }
359354
360 const State = enum {355 const State = enum {
361 Start,356 start,
362 Identifier,357 identifier,
363 Builtin,358 builtin,
364 StringLiteral,359 string_literal,
365 StringLiteralBackslash,360 string_literal_backslash,
366 MultilineStringLiteralLine,361 multiline_string_literal_line,
367 CharLiteral,362 char_literal,
368 CharLiteralBackslash,363 char_literal_backslash,
369 CharLiteralHexEscape,364 char_literal_hex_escape,
370 CharLiteralUnicodeEscapeSawU,365 char_literal_unicode_escape_saw_u,
371 CharLiteralUnicodeEscape,366 char_literal_unicode_escape,
372 CharLiteralUnicodeInvalid,367 char_literal_unicode_invalid,
373 CharLiteralUnicode,368 char_literal_unicode,
374 CharLiteralEnd,369 char_literal_end,
375 Backslash,370 backslash,
376 Equal,371 equal,
377 Bang,372 bang,
378 Pipe,373 pipe,
379 Minus,374 minus,
380 MinusPercent,375 minus_percent,
381 Asterisk,376 asterisk,
382 AsteriskPercent,377 asterisk_percent,
383 Slash,378 slash,
384 LineCommentStart,379 line_comment_start,
385 LineComment,380 line_comment,
386 DocCommentStart,381 doc_comment_start,
387 DocComment,382 doc_comment,
388 ContainerDocComment,383 container_doc_comment,
389 Zero,384 zero,
390 IntegerLiteralDec,385 int_literal_dec,
391 IntegerLiteralDecNoUnderscore,386 int_literal_dec_no_underscore,
392 IntegerLiteralBin,387 int_literal_bin,
393 IntegerLiteralBinNoUnderscore,388 int_literal_bin_no_underscore,
394 IntegerLiteralOct,389 int_literal_oct,
395 IntegerLiteralOctNoUnderscore,390 int_literal_oct_no_underscore,
396 IntegerLiteralHex,391 int_literal_hex,
397 IntegerLiteralHexNoUnderscore,392 int_literal_hex_no_underscore,
398 NumberDotDec,393 num_dot_dec,
399 NumberDotHex,394 num_dot_hex,
400 FloatFractionDec,395 float_fraction_dec,
401 FloatFractionDecNoUnderscore,396 float_fraction_dec_no_underscore,
402 FloatFractionHex,397 float_fraction_hex,
403 FloatFractionHexNoUnderscore,398 float_fraction_hex_no_underscore,
404 FloatExponentUnsigned,399 float_exponent_unsigned,
405 FloatExponentNumber,400 float_exponent_num,
406 FloatExponentNumberNoUnderscore,401 float_exponent_num_no_underscore,
407 Ampersand,402 ampersand,
408 Caret,403 caret,
409 Percent,404 percent,
410 Plus,405 plus,
411 PlusPercent,406 plus_percent,
412 AngleBracketLeft,407 angle_bracket_left,
413 AngleBracketAngleBracketLeft,408 angle_bracket_angle_bracket_left,
414 AngleBracketRight,409 angle_bracket_right,
415 AngleBracketAngleBracketRight,410 angle_bracket_angle_bracket_right,
416 Period,411 period,
417 Period2,412 period_2,
418 SawAtSign,413 saw_at_sign,
419 };414 };
420415
421 fn isIdentifierChar(char: u8) bool {416 fn isIdentifierChar(char: u8) bool {
...@@ -428,9 +423,9 @@ pub const Tokenizer = struct {...@@ -428,9 +423,9 @@ pub const Tokenizer = struct {
428 return token;423 return token;
429 }424 }
430 const start_index = self.index;425 const start_index = self.index;
431 var state = State.Start;426 var state: State = .start;
432 var result = Token{427 var result = Token{
433 .id = Token.Id.Eof,428 .id = .Eof,
434 .start = self.index,429 .start = self.index,
435 .end = undefined,430 .end = undefined,
436 };431 };
...@@ -439,40 +434,40 @@ pub const Tokenizer = struct {...@@ -439,40 +434,40 @@ pub const Tokenizer = struct {
439 while (self.index < self.buffer.len) : (self.index += 1) {434 while (self.index < self.buffer.len) : (self.index += 1) {
440 const c = self.buffer[self.index];435 const c = self.buffer[self.index];
441 switch (state) {436 switch (state) {
442 State.Start => switch (c) {437 .start => switch (c) {
443 ' ', '\n', '\t', '\r' => {438 ' ', '\n', '\t', '\r' => {
444 result.start = self.index + 1;439 result.start = self.index + 1;
445 },440 },
446 '"' => {441 '"' => {
447 state = State.StringLiteral;442 state = .string_literal;
448 result.id = Token.Id.StringLiteral;443 result.id = .StringLiteral;
449 },444 },
450 '\'' => {445 '\'' => {
451 state = State.CharLiteral;446 state = .char_literal;
452 },447 },
453 'a'...'z', 'A'...'Z', '_' => {448 'a'...'z', 'A'...'Z', '_' => {
454 state = State.Identifier;449 state = .identifier;
455 result.id = Token.Id.Identifier;450 result.id = .Identifier;
456 },451 },
457 '@' => {452 '@' => {
458 state = State.SawAtSign;453 state = .saw_at_sign;
459 },454 },
460 '=' => {455 '=' => {
461 state = State.Equal;456 state = .equal;
462 },457 },
463 '!' => {458 '!' => {
464 state = State.Bang;459 state = .bang;
465 },460 },
466 '|' => {461 '|' => {
467 state = State.Pipe;462 state = .pipe;
468 },463 },
469 '(' => {464 '(' => {
470 result.id = Token.Id.LParen;465 result.id = .LParen;
471 self.index += 1;466 self.index += 1;
472 break;467 break;
473 },468 },
474 ')' => {469 ')' => {
475 result.id = Token.Id.RParen;470 result.id = .RParen;
476 self.index += 1;471 self.index += 1;
477 break;472 break;
478 },473 },
...@@ -482,213 +477,213 @@ pub const Tokenizer = struct {...@@ -482,213 +477,213 @@ pub const Tokenizer = struct {
482 break;477 break;
483 },478 },
484 ']' => {479 ']' => {
485 result.id = Token.Id.RBracket;480 result.id = .RBracket;
486 self.index += 1;481 self.index += 1;
487 break;482 break;
488 },483 },
489 ';' => {484 ';' => {
490 result.id = Token.Id.Semicolon;485 result.id = .Semicolon;
491 self.index += 1;486 self.index += 1;
492 break;487 break;
493 },488 },
494 ',' => {489 ',' => {
495 result.id = Token.Id.Comma;490 result.id = .Comma;
496 self.index += 1;491 self.index += 1;
497 break;492 break;
498 },493 },
499 '?' => {494 '?' => {
500 result.id = Token.Id.QuestionMark;495 result.id = .QuestionMark;
501 self.index += 1;496 self.index += 1;
502 break;497 break;
503 },498 },
504 ':' => {499 ':' => {
505 result.id = Token.Id.Colon;500 result.id = .Colon;
506 self.index += 1;501 self.index += 1;
507 break;502 break;
508 },503 },
509 '%' => {504 '%' => {
510 state = State.Percent;505 state = .percent;
511 },506 },
512 '*' => {507 '*' => {
513 state = State.Asterisk;508 state = .asterisk;
514 },509 },
515 '+' => {510 '+' => {
516 state = State.Plus;511 state = .plus;
517 },512 },
518 '<' => {513 '<' => {
519 state = State.AngleBracketLeft;514 state = .angle_bracket_left;
520 },515 },
521 '>' => {516 '>' => {
522 state = State.AngleBracketRight;517 state = .angle_bracket_right;
523 },518 },
524 '^' => {519 '^' => {
525 state = State.Caret;520 state = .caret;
526 },521 },
527 '\\' => {522 '\\' => {
528 state = State.Backslash;523 state = .backslash;
529 result.id = Token.Id.MultilineStringLiteralLine;524 result.id = .MultilineStringLiteralLine;
530 },525 },
531 '{' => {526 '{' => {
532 result.id = Token.Id.LBrace;527 result.id = .LBrace;
533 self.index += 1;528 self.index += 1;
534 break;529 break;
535 },530 },
536 '}' => {531 '}' => {
537 result.id = Token.Id.RBrace;532 result.id = .RBrace;
538 self.index += 1;533 self.index += 1;
539 break;534 break;
540 },535 },
541 '~' => {536 '~' => {
542 result.id = Token.Id.Tilde;537 result.id = .Tilde;
543 self.index += 1;538 self.index += 1;
544 break;539 break;
545 },540 },
546 '.' => {541 '.' => {
547 state = State.Period;542 state = .period;
548 },543 },
549 '-' => {544 '-' => {
550 state = State.Minus;545 state = .minus;
551 },546 },
552 '/' => {547 '/' => {
553 state = State.Slash;548 state = .slash;
554 },549 },
555 '&' => {550 '&' => {
556 state = State.Ampersand;551 state = .ampersand;
557 },552 },
558 '0' => {553 '0' => {
559 state = State.Zero;554 state = .zero;
560 result.id = Token.Id.IntegerLiteral;555 result.id = .IntegerLiteral;
561 },556 },
562 '1'...'9' => {557 '1'...'9' => {
563 state = State.IntegerLiteralDec;558 state = .int_literal_dec;
564 result.id = Token.Id.IntegerLiteral;559 result.id = .IntegerLiteral;
565 },560 },
566 else => {561 else => {
567 result.id = Token.Id.Invalid;562 result.id = .Invalid;
568 self.index += 1;563 self.index += 1;
569 break;564 break;
570 },565 },
571 },566 },
572567
573 State.SawAtSign => switch (c) {568 .saw_at_sign => switch (c) {
574 '"' => {569 '"' => {
575 result.id = Token.Id.Identifier;570 result.id = .Identifier;
576 state = State.StringLiteral;571 state = .string_literal;
577 },572 },
578 else => {573 else => {
579 // reinterpret as a builtin574 // reinterpret as a builtin
580 self.index -= 1;575 self.index -= 1;
581 state = State.Builtin;576 state = .builtin;
582 result.id = Token.Id.Builtin;577 result.id = .Builtin;
583 },578 },
584 },579 },
585580
586 State.Ampersand => switch (c) {581 .ampersand => switch (c) {
587 '&' => {582 '&' => {
588 result.id = Token.Id.Invalid_ampersands;583 result.id = .Invalid_ampersands;
589 self.index += 1;584 self.index += 1;
590 break;585 break;
591 },586 },
592 '=' => {587 '=' => {
593 result.id = Token.Id.AmpersandEqual;588 result.id = .AmpersandEqual;
594 self.index += 1;589 self.index += 1;
595 break;590 break;
596 },591 },
597 else => {592 else => {
598 result.id = Token.Id.Ampersand;593 result.id = .Ampersand;
599 break;594 break;
600 },595 },
601 },596 },
602597
603 State.Asterisk => switch (c) {598 .asterisk => switch (c) {
604 '=' => {599 '=' => {
605 result.id = Token.Id.AsteriskEqual;600 result.id = .AsteriskEqual;
606 self.index += 1;601 self.index += 1;
607 break;602 break;
608 },603 },
609 '*' => {604 '*' => {
610 result.id = Token.Id.AsteriskAsterisk;605 result.id = .AsteriskAsterisk;
611 self.index += 1;606 self.index += 1;
612 break;607 break;
613 },608 },
614 '%' => {609 '%' => {
615 state = State.AsteriskPercent;610 state = .asterisk_percent;
616 },611 },
617 else => {612 else => {
618 result.id = Token.Id.Asterisk;613 result.id = .Asterisk;
619 break;614 break;
620 },615 },
621 },616 },
622617
623 State.AsteriskPercent => switch (c) {618 .asterisk_percent => switch (c) {
624 '=' => {619 '=' => {
625 result.id = Token.Id.AsteriskPercentEqual;620 result.id = .AsteriskPercentEqual;
626 self.index += 1;621 self.index += 1;
627 break;622 break;
628 },623 },
629 else => {624 else => {
630 result.id = Token.Id.AsteriskPercent;625 result.id = .AsteriskPercent;
631 break;626 break;
632 },627 },
633 },628 },
634629
635 State.Percent => switch (c) {630 .percent => switch (c) {
636 '=' => {631 '=' => {
637 result.id = Token.Id.PercentEqual;632 result.id = .PercentEqual;
638 self.index += 1;633 self.index += 1;
639 break;634 break;
640 },635 },
641 else => {636 else => {
642 result.id = Token.Id.Percent;637 result.id = .Percent;
643 break;638 break;
644 },639 },
645 },640 },
646641
647 State.Plus => switch (c) {642 .plus => switch (c) {
648 '=' => {643 '=' => {
649 result.id = Token.Id.PlusEqual;644 result.id = .PlusEqual;
650 self.index += 1;645 self.index += 1;
651 break;646 break;
652 },647 },
653 '+' => {648 '+' => {
654 result.id = Token.Id.PlusPlus;649 result.id = .PlusPlus;
655 self.index += 1;650 self.index += 1;
656 break;651 break;
657 },652 },
658 '%' => {653 '%' => {
659 state = State.PlusPercent;654 state = .plus_percent;
660 },655 },
661 else => {656 else => {
662 result.id = Token.Id.Plus;657 result.id = .Plus;
663 break;658 break;
664 },659 },
665 },660 },
666661
667 State.PlusPercent => switch (c) {662 .plus_percent => switch (c) {
668 '=' => {663 '=' => {
669 result.id = Token.Id.PlusPercentEqual;664 result.id = .PlusPercentEqual;
670 self.index += 1;665 self.index += 1;
671 break;666 break;
672 },667 },
673 else => {668 else => {
674 result.id = Token.Id.PlusPercent;669 result.id = .PlusPercent;
675 break;670 break;
676 },671 },
677 },672 },
678673
679 State.Caret => switch (c) {674 .caret => switch (c) {
680 '=' => {675 '=' => {
681 result.id = Token.Id.CaretEqual;676 result.id = .CaretEqual;
682 self.index += 1;677 self.index += 1;
683 break;678 break;
684 },679 },
685 else => {680 else => {
686 result.id = Token.Id.Caret;681 result.id = .Caret;
687 break;682 break;
688 },683 },
689 },684 },
690685
691 State.Identifier => switch (c) {686 .identifier => switch (c) {
692 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},687 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
693 else => {688 else => {
694 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {689 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
...@@ -697,19 +692,19 @@ pub const Tokenizer = struct {...@@ -697,19 +692,19 @@ pub const Tokenizer = struct {
697 break;692 break;
698 },693 },
699 },694 },
700 State.Builtin => switch (c) {695 .builtin => switch (c) {
701 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},696 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
702 else => break,697 else => break,
703 },698 },
704 State.Backslash => switch (c) {699 .backslash => switch (c) {
705 '\\' => {700 '\\' => {
706 state = State.MultilineStringLiteralLine;701 state = .multiline_string_literal_line;
707 },702 },
708 else => break,703 else => break,
709 },704 },
710 State.StringLiteral => switch (c) {705 .string_literal => switch (c) {
711 '\\' => {706 '\\' => {
712 state = State.StringLiteralBackslash;707 state = .string_literal_backslash;
713 },708 },
714 '"' => {709 '"' => {
715 self.index += 1;710 self.index += 1;
...@@ -719,98 +714,98 @@ pub const Tokenizer = struct {...@@ -719,98 +714,98 @@ pub const Tokenizer = struct {
719 else => self.checkLiteralCharacter(),714 else => self.checkLiteralCharacter(),
720 },715 },
721716
722 State.StringLiteralBackslash => switch (c) {717 .string_literal_backslash => switch (c) {
723 '\n', '\r' => break, // Look for this error later.718 '\n', '\r' => break, // Look for this error later.
724 else => {719 else => {
725 state = State.StringLiteral;720 state = .string_literal;
726 },721 },
727 },722 },
728723
729 State.CharLiteral => switch (c) {724 .char_literal => switch (c) {
730 '\\' => {725 '\\' => {
731 state = State.CharLiteralBackslash;726 state = .char_literal_backslash;
732 },727 },
733 '\'', 0x80...0xbf, 0xf8...0xff => {728 '\'', 0x80...0xbf, 0xf8...0xff => {
734 result.id = Token.Id.Invalid;729 result.id = .Invalid;
735 break;730 break;
736 },731 },
737 0xc0...0xdf => { // 110xxxxx732 0xc0...0xdf => { // 110xxxxx
738 remaining_code_units = 1;733 remaining_code_units = 1;
739 state = State.CharLiteralUnicode;734 state = .char_literal_unicode;
740 },735 },
741 0xe0...0xef => { // 1110xxxx736 0xe0...0xef => { // 1110xxxx
742 remaining_code_units = 2;737 remaining_code_units = 2;
743 state = State.CharLiteralUnicode;738 state = .char_literal_unicode;
744 },739 },
745 0xf0...0xf7 => { // 11110xxx740 0xf0...0xf7 => { // 11110xxx
746 remaining_code_units = 3;741 remaining_code_units = 3;
747 state = State.CharLiteralUnicode;742 state = .char_literal_unicode;
748 },743 },
749 else => {744 else => {
750 state = State.CharLiteralEnd;745 state = .char_literal_end;
751 },746 },
752 },747 },
753748
754 State.CharLiteralBackslash => switch (c) {749 .char_literal_backslash => switch (c) {
755 '\n' => {750 '\n' => {
756 result.id = Token.Id.Invalid;751 result.id = .Invalid;
757 break;752 break;
758 },753 },
759 'x' => {754 'x' => {
760 state = State.CharLiteralHexEscape;755 state = .char_literal_hex_escape;
761 seen_escape_digits = 0;756 seen_escape_digits = 0;
762 },757 },
763 'u' => {758 'u' => {
764 state = State.CharLiteralUnicodeEscapeSawU;759 state = .char_literal_unicode_escape_saw_u;
765 },760 },
766 else => {761 else => {
767 state = State.CharLiteralEnd;762 state = .char_literal_end;
768 },763 },
769 },764 },
770765
771 State.CharLiteralHexEscape => switch (c) {766 .char_literal_hex_escape => switch (c) {
772 '0'...'9', 'a'...'f', 'A'...'F' => {767 '0'...'9', 'a'...'f', 'A'...'F' => {
773 seen_escape_digits += 1;768 seen_escape_digits += 1;
774 if (seen_escape_digits == 2) {769 if (seen_escape_digits == 2) {
775 state = State.CharLiteralEnd;770 state = .char_literal_end;
776 }771 }
777 },772 },
778 else => {773 else => {
779 result.id = Token.Id.Invalid;774 result.id = .Invalid;
780 break;775 break;
781 },776 },
782 },777 },
783778
784 State.CharLiteralUnicodeEscapeSawU => switch (c) {779 .char_literal_unicode_escape_saw_u => switch (c) {
785 '{' => {780 '{' => {
786 state = State.CharLiteralUnicodeEscape;781 state = .char_literal_unicode_escape;
787 seen_escape_digits = 0;782 seen_escape_digits = 0;
788 },783 },
789 else => {784 else => {
790 result.id = Token.Id.Invalid;785 result.id = .Invalid;
791 state = State.CharLiteralUnicodeInvalid;786 state = .char_literal_unicode_invalid;
792 },787 },
793 },788 },
794789
795 State.CharLiteralUnicodeEscape => switch (c) {790 .char_literal_unicode_escape => switch (c) {
796 '0'...'9', 'a'...'f', 'A'...'F' => {791 '0'...'9', 'a'...'f', 'A'...'F' => {
797 seen_escape_digits += 1;792 seen_escape_digits += 1;
798 },793 },
799 '}' => {794 '}' => {
800 if (seen_escape_digits == 0) {795 if (seen_escape_digits == 0) {
801 result.id = Token.Id.Invalid;796 result.id = .Invalid;
802 state = State.CharLiteralUnicodeInvalid;797 state = .char_literal_unicode_invalid;
803 } else {798 } else {
804 state = State.CharLiteralEnd;799 state = .char_literal_end;
805 }800 }
806 },801 },
807 else => {802 else => {
808 result.id = Token.Id.Invalid;803 result.id = .Invalid;
809 state = State.CharLiteralUnicodeInvalid;804 state = .char_literal_unicode_invalid;
810 },805 },
811 },806 },
812807
813 State.CharLiteralUnicodeInvalid => switch (c) {808 .char_literal_unicode_invalid => switch (c) {
814 // Keep consuming characters until an obvious stopping point.809 // Keep consuming characters until an obvious stopping point.
815 // This consolidates e.g. `u{0ab1Q}` into a single invalid token810 // This consolidates e.g. `u{0ab1Q}` into a single invalid token
816 // instead of creating the tokens `u{0ab1`, `Q`, `}`811 // instead of creating the tokens `u{0ab1`, `Q`, `}`
...@@ -818,32 +813,32 @@ pub const Tokenizer = struct {...@@ -818,32 +813,32 @@ pub const Tokenizer = struct {
818 else => break,813 else => break,
819 },814 },
820815
821 State.CharLiteralEnd => switch (c) {816 .char_literal_end => switch (c) {
822 '\'' => {817 '\'' => {
823 result.id = Token.Id.CharLiteral;818 result.id = .CharLiteral;
824 self.index += 1;819 self.index += 1;
825 break;820 break;
826 },821 },
827 else => {822 else => {
828 result.id = Token.Id.Invalid;823 result.id = .Invalid;
829 break;824 break;
830 },825 },
831 },826 },
832827
833 State.CharLiteralUnicode => switch (c) {828 .char_literal_unicode => switch (c) {
834 0x80...0xbf => {829 0x80...0xbf => {
835 remaining_code_units -= 1;830 remaining_code_units -= 1;
836 if (remaining_code_units == 0) {831 if (remaining_code_units == 0) {
837 state = State.CharLiteralEnd;832 state = .char_literal_end;
838 }833 }
839 },834 },
840 else => {835 else => {
841 result.id = Token.Id.Invalid;836 result.id = .Invalid;
842 break;837 break;
843 },838 },
844 },839 },
845840
846 State.MultilineStringLiteralLine => switch (c) {841 .multiline_string_literal_line => switch (c) {
847 '\n' => {842 '\n' => {
848 self.index += 1;843 self.index += 1;
849 break;844 break;
...@@ -852,449 +847,449 @@ pub const Tokenizer = struct {...@@ -852,449 +847,449 @@ pub const Tokenizer = struct {
852 else => self.checkLiteralCharacter(),847 else => self.checkLiteralCharacter(),
853 },848 },
854849
855 State.Bang => switch (c) {850 .bang => switch (c) {
856 '=' => {851 '=' => {
857 result.id = Token.Id.BangEqual;852 result.id = .BangEqual;
858 self.index += 1;853 self.index += 1;
859 break;854 break;
860 },855 },
861 else => {856 else => {
862 result.id = Token.Id.Bang;857 result.id = .Bang;
863 break;858 break;
864 },859 },
865 },860 },
866861
867 State.Pipe => switch (c) {862 .pipe => switch (c) {
868 '=' => {863 '=' => {
869 result.id = Token.Id.PipeEqual;864 result.id = .PipeEqual;
870 self.index += 1;865 self.index += 1;
871 break;866 break;
872 },867 },
873 '|' => {868 '|' => {
874 result.id = Token.Id.PipePipe;869 result.id = .PipePipe;
875 self.index += 1;870 self.index += 1;
876 break;871 break;
877 },872 },
878 else => {873 else => {
879 result.id = Token.Id.Pipe;874 result.id = .Pipe;
880 break;875 break;
881 },876 },
882 },877 },
883878
884 State.Equal => switch (c) {879 .equal => switch (c) {
885 '=' => {880 '=' => {
886 result.id = Token.Id.EqualEqual;881 result.id = .EqualEqual;
887 self.index += 1;882 self.index += 1;
888 break;883 break;
889 },884 },
890 '>' => {885 '>' => {
891 result.id = Token.Id.EqualAngleBracketRight;886 result.id = .EqualAngleBracketRight;
892 self.index += 1;887 self.index += 1;
893 break;888 break;
894 },889 },
895 else => {890 else => {
896 result.id = Token.Id.Equal;891 result.id = .Equal;
897 break;892 break;
898 },893 },
899 },894 },
900895
901 State.Minus => switch (c) {896 .minus => switch (c) {
902 '>' => {897 '>' => {
903 result.id = Token.Id.Arrow;898 result.id = .Arrow;
904 self.index += 1;899 self.index += 1;
905 break;900 break;
906 },901 },
907 '=' => {902 '=' => {
908 result.id = Token.Id.MinusEqual;903 result.id = .MinusEqual;
909 self.index += 1;904 self.index += 1;
910 break;905 break;
911 },906 },
912 '%' => {907 '%' => {
913 state = State.MinusPercent;908 state = .minus_percent;
914 },909 },
915 else => {910 else => {
916 result.id = Token.Id.Minus;911 result.id = .Minus;
917 break;912 break;
918 },913 },
919 },914 },
920915
921 State.MinusPercent => switch (c) {916 .minus_percent => switch (c) {
922 '=' => {917 '=' => {
923 result.id = Token.Id.MinusPercentEqual;918 result.id = .MinusPercentEqual;
924 self.index += 1;919 self.index += 1;
925 break;920 break;
926 },921 },
927 else => {922 else => {
928 result.id = Token.Id.MinusPercent;923 result.id = .MinusPercent;
929 break;924 break;
930 },925 },
931 },926 },
932927
933 State.AngleBracketLeft => switch (c) {928 .angle_bracket_left => switch (c) {
934 '<' => {929 '<' => {
935 state = State.AngleBracketAngleBracketLeft;930 state = .angle_bracket_angle_bracket_left;
936 },931 },
937 '=' => {932 '=' => {
938 result.id = Token.Id.AngleBracketLeftEqual;933 result.id = .AngleBracketLeftEqual;
939 self.index += 1;934 self.index += 1;
940 break;935 break;
941 },936 },
942 else => {937 else => {
943 result.id = Token.Id.AngleBracketLeft;938 result.id = .AngleBracketLeft;
944 break;939 break;
945 },940 },
946 },941 },
947942
948 State.AngleBracketAngleBracketLeft => switch (c) {943 .angle_bracket_angle_bracket_left => switch (c) {
949 '=' => {944 '=' => {
950 result.id = Token.Id.AngleBracketAngleBracketLeftEqual;945 result.id = .AngleBracketAngleBracketLeftEqual;
951 self.index += 1;946 self.index += 1;
952 break;947 break;
953 },948 },
954 else => {949 else => {
955 result.id = Token.Id.AngleBracketAngleBracketLeft;950 result.id = .AngleBracketAngleBracketLeft;
956 break;951 break;
957 },952 },
958 },953 },
959954
960 State.AngleBracketRight => switch (c) {955 .angle_bracket_right => switch (c) {
961 '>' => {956 '>' => {
962 state = State.AngleBracketAngleBracketRight;957 state = .angle_bracket_angle_bracket_right;
963 },958 },
964 '=' => {959 '=' => {
965 result.id = Token.Id.AngleBracketRightEqual;960 result.id = .AngleBracketRightEqual;
966 self.index += 1;961 self.index += 1;
967 break;962 break;
968 },963 },
969 else => {964 else => {
970 result.id = Token.Id.AngleBracketRight;965 result.id = .AngleBracketRight;
971 break;966 break;
972 },967 },
973 },968 },
974969
975 State.AngleBracketAngleBracketRight => switch (c) {970 .angle_bracket_angle_bracket_right => switch (c) {
976 '=' => {971 '=' => {
977 result.id = Token.Id.AngleBracketAngleBracketRightEqual;972 result.id = .AngleBracketAngleBracketRightEqual;
978 self.index += 1;973 self.index += 1;
979 break;974 break;
980 },975 },
981 else => {976 else => {
982 result.id = Token.Id.AngleBracketAngleBracketRight;977 result.id = .AngleBracketAngleBracketRight;
983 break;978 break;
984 },979 },
985 },980 },
986981
987 State.Period => switch (c) {982 .period => switch (c) {
988 '.' => {983 '.' => {
989 state = State.Period2;984 state = .period_2;
990 },985 },
991 '*' => {986 '*' => {
992 result.id = Token.Id.PeriodAsterisk;987 result.id = .PeriodAsterisk;
993 self.index += 1;988 self.index += 1;
994 break;989 break;
995 },990 },
996 else => {991 else => {
997 result.id = Token.Id.Period;992 result.id = .Period;
998 break;993 break;
999 },994 },
1000 },995 },
1001996
1002 State.Period2 => switch (c) {997 .period_2 => switch (c) {
1003 '.' => {998 '.' => {
1004 result.id = Token.Id.Ellipsis3;999 result.id = .Ellipsis3;
1005 self.index += 1;1000 self.index += 1;
1006 break;1001 break;
1007 },1002 },
1008 else => {1003 else => {
1009 result.id = Token.Id.Ellipsis2;1004 result.id = .Ellipsis2;
1010 break;1005 break;
1011 },1006 },
1012 },1007 },
10131008
1014 State.Slash => switch (c) {1009 .slash => switch (c) {
1015 '/' => {1010 '/' => {
1016 state = State.LineCommentStart;1011 state = .line_comment_start;
1017 result.id = Token.Id.LineComment;1012 result.id = .LineComment;
1018 },1013 },
1019 '=' => {1014 '=' => {
1020 result.id = Token.Id.SlashEqual;1015 result.id = .SlashEqual;
1021 self.index += 1;1016 self.index += 1;
1022 break;1017 break;
1023 },1018 },
1024 else => {1019 else => {
1025 result.id = Token.Id.Slash;1020 result.id = .Slash;
1026 break;1021 break;
1027 },1022 },
1028 },1023 },
1029 State.LineCommentStart => switch (c) {1024 .line_comment_start => switch (c) {
1030 '/' => {1025 '/' => {
1031 state = State.DocCommentStart;1026 state = .doc_comment_start;
1032 },1027 },
1033 '!' => {1028 '!' => {
1034 result.id = Token.Id.ContainerDocComment;1029 result.id = .ContainerDocComment;
1035 state = State.ContainerDocComment;1030 state = .container_doc_comment;
1036 },1031 },
1037 '\n' => break,1032 '\n' => break,
1038 else => {1033 else => {
1039 state = State.LineComment;1034 state = .line_comment;
1040 self.checkLiteralCharacter();1035 self.checkLiteralCharacter();
1041 },1036 },
1042 },1037 },
1043 State.DocCommentStart => switch (c) {1038 .doc_comment_start => switch (c) {
1044 '/' => {1039 '/' => {
1045 state = State.LineComment;1040 state = .line_comment;
1046 },1041 },
1047 '\n' => {1042 '\n' => {
1048 result.id = Token.Id.DocComment;1043 result.id = .DocComment;
1049 break;1044 break;
1050 },1045 },
1051 else => {1046 else => {
1052 state = State.DocComment;1047 state = .doc_comment;
1053 result.id = Token.Id.DocComment;1048 result.id = .DocComment;
1054 self.checkLiteralCharacter();1049 self.checkLiteralCharacter();
1055 },1050 },
1056 },1051 },
1057 State.LineComment, State.DocComment, State.ContainerDocComment => switch (c) {1052 .line_comment, .doc_comment, .container_doc_comment => switch (c) {
1058 '\n' => break,1053 '\n' => break,
1059 else => self.checkLiteralCharacter(),1054 else => self.checkLiteralCharacter(),
1060 },1055 },
1061 State.Zero => switch (c) {1056 .zero => switch (c) {
1062 'b' => {1057 'b' => {
1063 state = State.IntegerLiteralBinNoUnderscore;1058 state = .int_literal_bin_no_underscore;
1064 },1059 },
1065 'o' => {1060 'o' => {
1066 state = State.IntegerLiteralOctNoUnderscore;1061 state = .int_literal_oct_no_underscore;
1067 },1062 },
1068 'x' => {1063 'x' => {
1069 state = State.IntegerLiteralHexNoUnderscore;1064 state = .int_literal_hex_no_underscore;
1070 },1065 },
1071 '0'...'9', '_', '.', 'e', 'E' => {1066 '0'...'9', '_', '.', 'e', 'E' => {
1072 // reinterpret as a decimal number1067 // reinterpret as a decimal number
1073 self.index -= 1;1068 self.index -= 1;
1074 state = State.IntegerLiteralDec;1069 state = .int_literal_dec;
1075 },1070 },
1076 else => {1071 else => {
1077 if (isIdentifierChar(c)) {1072 if (isIdentifierChar(c)) {
1078 result.id = Token.Id.Invalid;1073 result.id = .Invalid;
1079 }1074 }
1080 break;1075 break;
1081 },1076 },
1082 },1077 },
1083 State.IntegerLiteralBinNoUnderscore => switch (c) {1078 .int_literal_bin_no_underscore => switch (c) {
1084 '0'...'1' => {1079 '0'...'1' => {
1085 state = State.IntegerLiteralBin;1080 state = .int_literal_bin;
1086 },1081 },
1087 else => {1082 else => {
1088 result.id = Token.Id.Invalid;1083 result.id = .Invalid;
1089 break;1084 break;
1090 },1085 },
1091 },1086 },
1092 State.IntegerLiteralBin => switch (c) {1087 .int_literal_bin => switch (c) {
1093 '_' => {1088 '_' => {
1094 state = State.IntegerLiteralBinNoUnderscore;1089 state = .int_literal_bin_no_underscore;
1095 },1090 },
1096 '0'...'1' => {},1091 '0'...'1' => {},
1097 else => {1092 else => {
1098 if (isIdentifierChar(c)) {1093 if (isIdentifierChar(c)) {
1099 result.id = Token.Id.Invalid;1094 result.id = .Invalid;
1100 }1095 }
1101 break;1096 break;
1102 },1097 },
1103 },1098 },
1104 State.IntegerLiteralOctNoUnderscore => switch (c) {1099 .int_literal_oct_no_underscore => switch (c) {
1105 '0'...'7' => {1100 '0'...'7' => {
1106 state = State.IntegerLiteralOct;1101 state = .int_literal_oct;
1107 },1102 },
1108 else => {1103 else => {
1109 result.id = Token.Id.Invalid;1104 result.id = .Invalid;
1110 break;1105 break;
1111 },1106 },
1112 },1107 },
1113 State.IntegerLiteralOct => switch (c) {1108 .int_literal_oct => switch (c) {
1114 '_' => {1109 '_' => {
1115 state = State.IntegerLiteralOctNoUnderscore;1110 state = .int_literal_oct_no_underscore;
1116 },1111 },
1117 '0'...'7' => {},1112 '0'...'7' => {},
1118 else => {1113 else => {
1119 if (isIdentifierChar(c)) {1114 if (isIdentifierChar(c)) {
1120 result.id = Token.Id.Invalid;1115 result.id = .Invalid;
1121 }1116 }
1122 break;1117 break;
1123 },1118 },
1124 },1119 },
1125 State.IntegerLiteralDecNoUnderscore => switch (c) {1120 .int_literal_dec_no_underscore => switch (c) {
1126 '0'...'9' => {1121 '0'...'9' => {
1127 state = State.IntegerLiteralDec;1122 state = .int_literal_dec;
1128 },1123 },
1129 else => {1124 else => {
1130 result.id = Token.Id.Invalid;1125 result.id = .Invalid;
1131 break;1126 break;
1132 },1127 },
1133 },1128 },
1134 State.IntegerLiteralDec => switch (c) {1129 .int_literal_dec => switch (c) {
1135 '_' => {1130 '_' => {
1136 state = State.IntegerLiteralDecNoUnderscore;1131 state = .int_literal_dec_no_underscore;
1137 },1132 },
1138 '.' => {1133 '.' => {
1139 state = State.NumberDotDec;1134 state = .num_dot_dec;
1140 result.id = Token.Id.FloatLiteral;1135 result.id = .FloatLiteral;
1141 },1136 },
1142 'e', 'E' => {1137 'e', 'E' => {
1143 state = State.FloatExponentUnsigned;1138 state = .float_exponent_unsigned;
1144 result.id = Token.Id.FloatLiteral;1139 result.id = .FloatLiteral;
1145 },1140 },
1146 '0'...'9' => {},1141 '0'...'9' => {},
1147 else => {1142 else => {
1148 if (isIdentifierChar(c)) {1143 if (isIdentifierChar(c)) {
1149 result.id = Token.Id.Invalid;1144 result.id = .Invalid;
1150 }1145 }
1151 break;1146 break;
1152 },1147 },
1153 },1148 },
1154 State.IntegerLiteralHexNoUnderscore => switch (c) {1149 .int_literal_hex_no_underscore => switch (c) {
1155 '0'...'9', 'a'...'f', 'A'...'F' => {1150 '0'...'9', 'a'...'f', 'A'...'F' => {
1156 state = State.IntegerLiteralHex;1151 state = .int_literal_hex;
1157 },1152 },
1158 else => {1153 else => {
1159 result.id = Token.Id.Invalid;1154 result.id = .Invalid;
1160 break;1155 break;
1161 },1156 },
1162 },1157 },
1163 State.IntegerLiteralHex => switch (c) {1158 .int_literal_hex => switch (c) {
1164 '_' => {1159 '_' => {
1165 state = State.IntegerLiteralHexNoUnderscore;1160 state = .int_literal_hex_no_underscore;
1166 },1161 },
1167 '.' => {1162 '.' => {
1168 state = State.NumberDotHex;1163 state = .num_dot_hex;
1169 result.id = Token.Id.FloatLiteral;1164 result.id = .FloatLiteral;
1170 },1165 },
1171 'p', 'P' => {1166 'p', 'P' => {
1172 state = State.FloatExponentUnsigned;1167 state = .float_exponent_unsigned;
1173 result.id = Token.Id.FloatLiteral;1168 result.id = .FloatLiteral;
1174 },1169 },
1175 '0'...'9', 'a'...'f', 'A'...'F' => {},1170 '0'...'9', 'a'...'f', 'A'...'F' => {},
1176 else => {1171 else => {
1177 if (isIdentifierChar(c)) {1172 if (isIdentifierChar(c)) {
1178 result.id = Token.Id.Invalid;1173 result.id = .Invalid;
1179 }1174 }
1180 break;1175 break;
1181 },1176 },
1182 },1177 },
1183 State.NumberDotDec => switch (c) {1178 .num_dot_dec => switch (c) {
1184 '.' => {1179 '.' => {
1185 self.index -= 1;1180 self.index -= 1;
1186 state = State.Start;1181 state = .start;
1187 break;1182 break;
1188 },1183 },
1189 'e', 'E' => {1184 'e', 'E' => {
1190 state = State.FloatExponentUnsigned;1185 state = .float_exponent_unsigned;
1191 },1186 },
1192 '0'...'9' => {1187 '0'...'9' => {
1193 result.id = Token.Id.FloatLiteral;1188 result.id = .FloatLiteral;
1194 state = State.FloatFractionDec;1189 state = .float_fraction_dec;
1195 },1190 },
1196 else => {1191 else => {
1197 if (isIdentifierChar(c)) {1192 if (isIdentifierChar(c)) {
1198 result.id = Token.Id.Invalid;1193 result.id = .Invalid;
1199 }1194 }
1200 break;1195 break;
1201 },1196 },
1202 },1197 },
1203 State.NumberDotHex => switch (c) {1198 .num_dot_hex => switch (c) {
1204 '.' => {1199 '.' => {
1205 self.index -= 1;1200 self.index -= 1;
1206 state = State.Start;1201 state = .start;
1207 break;1202 break;
1208 },1203 },
1209 'p', 'P' => {1204 'p', 'P' => {
1210 state = State.FloatExponentUnsigned;1205 state = .float_exponent_unsigned;
1211 },1206 },
1212 '0'...'9', 'a'...'f', 'A'...'F' => {1207 '0'...'9', 'a'...'f', 'A'...'F' => {
1213 result.id = Token.Id.FloatLiteral;1208 result.id = .FloatLiteral;
1214 state = State.FloatFractionHex;1209 state = .float_fraction_hex;
1215 },1210 },
1216 else => {1211 else => {
1217 if (isIdentifierChar(c)) {1212 if (isIdentifierChar(c)) {
1218 result.id = Token.Id.Invalid;1213 result.id = .Invalid;
1219 }1214 }
1220 break;1215 break;
1221 },1216 },
1222 },1217 },
1223 State.FloatFractionDecNoUnderscore => switch (c) {1218 .float_fraction_dec_no_underscore => switch (c) {
1224 '0'...'9' => {1219 '0'...'9' => {
1225 state = State.FloatFractionDec;1220 state = .float_fraction_dec;
1226 },1221 },
1227 else => {1222 else => {
1228 result.id = Token.Id.Invalid;1223 result.id = .Invalid;
1229 break;1224 break;
1230 },1225 },
1231 },1226 },
1232 State.FloatFractionDec => switch (c) {1227 .float_fraction_dec => switch (c) {
1233 '_' => {1228 '_' => {
1234 state = State.FloatFractionDecNoUnderscore;1229 state = .float_fraction_dec_no_underscore;
1235 },1230 },
1236 'e', 'E' => {1231 'e', 'E' => {
1237 state = State.FloatExponentUnsigned;1232 state = .float_exponent_unsigned;
1238 },1233 },
1239 '0'...'9' => {},1234 '0'...'9' => {},
1240 else => {1235 else => {
1241 if (isIdentifierChar(c)) {1236 if (isIdentifierChar(c)) {
1242 result.id = Token.Id.Invalid;1237 result.id = .Invalid;
1243 }1238 }
1244 break;1239 break;
1245 },1240 },
1246 },1241 },
1247 State.FloatFractionHexNoUnderscore => switch (c) {1242 .float_fraction_hex_no_underscore => switch (c) {
1248 '0'...'9', 'a'...'f', 'A'...'F' => {1243 '0'...'9', 'a'...'f', 'A'...'F' => {
1249 state = State.FloatFractionHex;1244 state = .float_fraction_hex;
1250 },1245 },
1251 else => {1246 else => {
1252 result.id = Token.Id.Invalid;1247 result.id = .Invalid;
1253 break;1248 break;
1254 },1249 },
1255 },1250 },
1256 State.FloatFractionHex => switch (c) {1251 .float_fraction_hex => switch (c) {
1257 '_' => {1252 '_' => {
1258 state = State.FloatFractionHexNoUnderscore;1253 state = .float_fraction_hex_no_underscore;
1259 },1254 },
1260 'p', 'P' => {1255 'p', 'P' => {
1261 state = State.FloatExponentUnsigned;1256 state = .float_exponent_unsigned;
1262 },1257 },
1263 '0'...'9', 'a'...'f', 'A'...'F' => {},1258 '0'...'9', 'a'...'f', 'A'...'F' => {},
1264 else => {1259 else => {
1265 if (isIdentifierChar(c)) {1260 if (isIdentifierChar(c)) {
1266 result.id = Token.Id.Invalid;1261 result.id = .Invalid;
1267 }1262 }
1268 break;1263 break;
1269 },1264 },
1270 },1265 },
1271 State.FloatExponentUnsigned => switch (c) {1266 .float_exponent_unsigned => switch (c) {
1272 '+', '-' => {1267 '+', '-' => {
1273 state = State.FloatExponentNumberNoUnderscore;1268 state = .float_exponent_num_no_underscore;
1274 },1269 },
1275 else => {1270 else => {
1276 // reinterpret as a normal exponent number1271 // reinterpret as a normal exponent number
1277 self.index -= 1;1272 self.index -= 1;
1278 state = State.FloatExponentNumberNoUnderscore;1273 state = .float_exponent_num_no_underscore;
1279 },1274 },
1280 },1275 },
1281 State.FloatExponentNumberNoUnderscore => switch (c) {1276 .float_exponent_num_no_underscore => switch (c) {
1282 '0'...'9' => {1277 '0'...'9' => {
1283 state = State.FloatExponentNumber;1278 state = .float_exponent_num;
1284 },1279 },
1285 else => {1280 else => {
1286 result.id = Token.Id.Invalid;1281 result.id = .Invalid;
1287 break;1282 break;
1288 },1283 },
1289 },1284 },
1290 State.FloatExponentNumber => switch (c) {1285 .float_exponent_num => switch (c) {
1291 '_' => {1286 '_' => {
1292 state = State.FloatExponentNumberNoUnderscore;1287 state = .float_exponent_num_no_underscore;
1293 },1288 },
1294 '0'...'9' => {},1289 '0'...'9' => {},
1295 else => {1290 else => {
1296 if (isIdentifierChar(c)) {1291 if (isIdentifierChar(c)) {
1297 result.id = Token.Id.Invalid;1292 result.id = .Invalid;
1298 }1293 }
1299 break;1294 break;
1300 },1295 },
...@@ -1302,123 +1297,123 @@ pub const Tokenizer = struct {...@@ -1302,123 +1297,123 @@ pub const Tokenizer = struct {
1302 }1297 }
1303 } else if (self.index == self.buffer.len) {1298 } else if (self.index == self.buffer.len) {
1304 switch (state) {1299 switch (state) {
1305 State.Start,1300 .start,
1306 State.IntegerLiteralDec,1301 .int_literal_dec,
1307 State.IntegerLiteralBin,1302 .int_literal_bin,
1308 State.IntegerLiteralOct,1303 .int_literal_oct,
1309 State.IntegerLiteralHex,1304 .int_literal_hex,
1310 State.NumberDotDec,1305 .num_dot_dec,
1311 State.NumberDotHex,1306 .num_dot_hex,
1312 State.FloatFractionDec,1307 .float_fraction_dec,
1313 State.FloatFractionHex,1308 .float_fraction_hex,
1314 State.FloatExponentNumber,1309 .float_exponent_num,
1315 State.StringLiteral, // find this error later1310 .string_literal, // find this error later
1316 State.MultilineStringLiteralLine,1311 .multiline_string_literal_line,
1317 State.Builtin,1312 .builtin,
1318 => {},1313 => {},
13191314
1320 State.Identifier => {1315 .identifier => {
1321 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {1316 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
1322 result.id = id;1317 result.id = id;
1323 }1318 }
1324 },1319 },
1325 State.LineCommentStart, State.LineComment => {1320 .line_comment, .line_comment_start => {
1326 result.id = Token.Id.LineComment;1321 result.id = .LineComment;
1327 },1322 },
1328 State.DocComment, State.DocCommentStart => {1323 .doc_comment, .doc_comment_start => {
1329 result.id = Token.Id.DocComment;1324 result.id = .DocComment;
1330 },1325 },
1331 State.ContainerDocComment => {1326 .container_doc_comment => {
1332 result.id = Token.Id.ContainerDocComment;1327 result.id = .ContainerDocComment;
1333 },1328 },
13341329
1335 State.IntegerLiteralDecNoUnderscore,1330 .int_literal_dec_no_underscore,
1336 State.IntegerLiteralBinNoUnderscore,1331 .int_literal_bin_no_underscore,
1337 State.IntegerLiteralOctNoUnderscore,1332 .int_literal_oct_no_underscore,
1338 State.IntegerLiteralHexNoUnderscore,1333 .int_literal_hex_no_underscore,
1339 State.FloatFractionDecNoUnderscore,1334 .float_fraction_dec_no_underscore,
1340 State.FloatFractionHexNoUnderscore,1335 .float_fraction_hex_no_underscore,
1341 State.FloatExponentNumberNoUnderscore,1336 .float_exponent_num_no_underscore,
1342 State.FloatExponentUnsigned,1337 .float_exponent_unsigned,
1343 State.SawAtSign,1338 .saw_at_sign,
1344 State.Backslash,1339 .backslash,
1345 State.CharLiteral,1340 .char_literal,
1346 State.CharLiteralBackslash,1341 .char_literal_backslash,
1347 State.CharLiteralHexEscape,1342 .char_literal_hex_escape,
1348 State.CharLiteralUnicodeEscapeSawU,1343 .char_literal_unicode_escape_saw_u,
1349 State.CharLiteralUnicodeEscape,1344 .char_literal_unicode_escape,
1350 State.CharLiteralUnicodeInvalid,1345 .char_literal_unicode_invalid,
1351 State.CharLiteralEnd,1346 .char_literal_end,
1352 State.CharLiteralUnicode,1347 .char_literal_unicode,
1353 State.StringLiteralBackslash,1348 .string_literal_backslash,
1354 => {1349 => {
1355 result.id = Token.Id.Invalid;1350 result.id = .Invalid;
1356 },1351 },
13571352
1358 State.Equal => {1353 .equal => {
1359 result.id = Token.Id.Equal;1354 result.id = .Equal;
1360 },1355 },
1361 State.Bang => {1356 .bang => {
1362 result.id = Token.Id.Bang;1357 result.id = .Bang;
1363 },1358 },
1364 State.Minus => {1359 .minus => {
1365 result.id = Token.Id.Minus;1360 result.id = .Minus;
1366 },1361 },
1367 State.Slash => {1362 .slash => {
1368 result.id = Token.Id.Slash;1363 result.id = .Slash;
1369 },1364 },
1370 State.Zero => {1365 .zero => {
1371 result.id = Token.Id.IntegerLiteral;1366 result.id = .IntegerLiteral;
1372 },1367 },
1373 State.Ampersand => {1368 .ampersand => {
1374 result.id = Token.Id.Ampersand;1369 result.id = .Ampersand;
1375 },1370 },
1376 State.Period => {1371 .period => {
1377 result.id = Token.Id.Period;1372 result.id = .Period;
1378 },1373 },
1379 State.Period2 => {1374 .period_2 => {
1380 result.id = Token.Id.Ellipsis2;1375 result.id = .Ellipsis2;
1381 },1376 },
1382 State.Pipe => {1377 .pipe => {
1383 result.id = Token.Id.Pipe;1378 result.id = .Pipe;
1384 },1379 },
1385 State.AngleBracketAngleBracketRight => {1380 .angle_bracket_angle_bracket_right => {
1386 result.id = Token.Id.AngleBracketAngleBracketRight;1381 result.id = .AngleBracketAngleBracketRight;
1387 },1382 },
1388 State.AngleBracketRight => {1383 .angle_bracket_right => {
1389 result.id = Token.Id.AngleBracketRight;1384 result.id = .AngleBracketRight;
1390 },1385 },
1391 State.AngleBracketAngleBracketLeft => {1386 .angle_bracket_angle_bracket_left => {
1392 result.id = Token.Id.AngleBracketAngleBracketLeft;1387 result.id = .AngleBracketAngleBracketLeft;
1393 },1388 },
1394 State.AngleBracketLeft => {1389 .angle_bracket_left => {
1395 result.id = Token.Id.AngleBracketLeft;1390 result.id = .AngleBracketLeft;
1396 },1391 },
1397 State.PlusPercent => {1392 .plus_percent => {
1398 result.id = Token.Id.PlusPercent;1393 result.id = .PlusPercent;
1399 },1394 },
1400 State.Plus => {1395 .plus => {
1401 result.id = Token.Id.Plus;1396 result.id = .Plus;
1402 },1397 },
1403 State.Percent => {1398 .percent => {
1404 result.id = Token.Id.Percent;1399 result.id = .Percent;
1405 },1400 },
1406 State.Caret => {1401 .caret => {
1407 result.id = Token.Id.Caret;1402 result.id = .Caret;
1408 },1403 },
1409 State.AsteriskPercent => {1404 .asterisk_percent => {
1410 result.id = Token.Id.AsteriskPercent;1405 result.id = .AsteriskPercent;
1411 },1406 },
1412 State.Asterisk => {1407 .asterisk => {
1413 result.id = Token.Id.Asterisk;1408 result.id = .Asterisk;
1414 },1409 },
1415 State.MinusPercent => {1410 .minus_percent => {
1416 result.id = Token.Id.MinusPercent;1411 result.id = .MinusPercent;
1417 },1412 },
1418 }1413 }
1419 }1414 }
14201415
1421 if (result.id == Token.Id.Eof) {1416 if (result.id == .Eof) {
1422 if (self.pending_invalid_token) |token| {1417 if (self.pending_invalid_token) |token| {
1423 self.pending_invalid_token = null;1418 self.pending_invalid_token = null;
1424 return token;1419 return token;
...@@ -1433,8 +1428,8 @@ pub const Tokenizer = struct {...@@ -1433,8 +1428,8 @@ pub const Tokenizer = struct {
1433 if (self.pending_invalid_token != null) return;1428 if (self.pending_invalid_token != null) return;
1434 const invalid_length = self.getInvalidCharacterLength();1429 const invalid_length = self.getInvalidCharacterLength();
1435 if (invalid_length == 0) return;1430 if (invalid_length == 0) return;
1436 self.pending_invalid_token = Token{1431 self.pending_invalid_token = .{
1437 .id = Token.Id.Invalid,1432 .id = .Invalid,
1438 .start = self.index,1433 .start = self.index,
1439 .end = self.index + invalid_length,1434 .end = self.index + invalid_length,
1440 };1435 };
...@@ -1479,7 +1474,7 @@ pub const Tokenizer = struct {...@@ -1479,7 +1474,7 @@ pub const Tokenizer = struct {
1479};1474};
14801475
1481test "tokenizer" {1476test "tokenizer" {
1482 testTokenize("test", &[_]Token.Id{Token.Id.Keyword_test});1477 testTokenize("test", &[_]Token.Id{.Keyword_test});
1483}1478}
14841479
1485test "tokenizer - unknown length pointer and then c pointer" {1480test "tokenizer - unknown length pointer and then c pointer" {
...@@ -1487,15 +1482,15 @@ test "tokenizer - unknown length pointer and then c pointer" {...@@ -1487,15 +1482,15 @@ test "tokenizer - unknown length pointer and then c pointer" {
1487 \\[*]u81482 \\[*]u8
1488 \\[*c]u81483 \\[*c]u8
1489 , &[_]Token.Id{1484 , &[_]Token.Id{
1490 Token.Id.LBracket,1485 .LBracket,
1491 Token.Id.Asterisk,1486 .Asterisk,
1492 Token.Id.RBracket,1487 .RBracket,
1493 Token.Id.Identifier,1488 .Identifier,
1494 Token.Id.LBracket,1489 .LBracket,
1495 Token.Id.Asterisk,1490 .Asterisk,
1496 Token.Id.Identifier,1491 .Identifier,
1497 Token.Id.RBracket,1492 .RBracket,
1498 Token.Id.Identifier,1493 .Identifier,
1499 });1494 });
1500}1495}
15011496
...@@ -1566,125 +1561,125 @@ test "tokenizer - char literal with unicode code point" {...@@ -1566,125 +1561,125 @@ test "tokenizer - char literal with unicode code point" {
15661561
1567test "tokenizer - float literal e exponent" {1562test "tokenizer - float literal e exponent" {
1568 testTokenize("a = 4.94065645841246544177e-324;\n", &[_]Token.Id{1563 testTokenize("a = 4.94065645841246544177e-324;\n", &[_]Token.Id{
1569 Token.Id.Identifier,1564 .Identifier,
1570 Token.Id.Equal,1565 .Equal,
1571 Token.Id.FloatLiteral,1566 .FloatLiteral,
1572 Token.Id.Semicolon,1567 .Semicolon,
1573 });1568 });
1574}1569}
15751570
1576test "tokenizer - float literal p exponent" {1571test "tokenizer - float literal p exponent" {
1577 testTokenize("a = 0x1.a827999fcef32p+1022;\n", &[_]Token.Id{1572 testTokenize("a = 0x1.a827999fcef32p+1022;\n", &[_]Token.Id{
1578 Token.Id.Identifier,1573 .Identifier,
1579 Token.Id.Equal,1574 .Equal,
1580 Token.Id.FloatLiteral,1575 .FloatLiteral,
1581 Token.Id.Semicolon,1576 .Semicolon,
1582 });1577 });
1583}1578}
15841579
1585test "tokenizer - chars" {1580test "tokenizer - chars" {
1586 testTokenize("'c'", &[_]Token.Id{Token.Id.CharLiteral});1581 testTokenize("'c'", &[_]Token.Id{.CharLiteral});
1587}1582}
15881583
1589test "tokenizer - invalid token characters" {1584test "tokenizer - invalid token characters" {
1590 testTokenize("#", &[_]Token.Id{Token.Id.Invalid});1585 testTokenize("#", &[_]Token.Id{.Invalid});
1591 testTokenize("`", &[_]Token.Id{Token.Id.Invalid});1586 testTokenize("`", &[_]Token.Id{.Invalid});
1592 testTokenize("'c", &[_]Token.Id{Token.Id.Invalid});1587 testTokenize("'c", &[_]Token.Id{.Invalid});
1593 testTokenize("'", &[_]Token.Id{Token.Id.Invalid});1588 testTokenize("'", &[_]Token.Id{.Invalid});
1594 testTokenize("''", &[_]Token.Id{ Token.Id.Invalid, Token.Id.Invalid });1589 testTokenize("''", &[_]Token.Id{ .Invalid, .Invalid });
1595}1590}
15961591
1597test "tokenizer - invalid literal/comment characters" {1592test "tokenizer - invalid literal/comment characters" {
1598 testTokenize("\"\x00\"", &[_]Token.Id{1593 testTokenize("\"\x00\"", &[_]Token.Id{
1599 Token.Id.StringLiteral,1594 .StringLiteral,
1600 Token.Id.Invalid,1595 .Invalid,
1601 });1596 });
1602 testTokenize("//\x00", &[_]Token.Id{1597 testTokenize("//\x00", &[_]Token.Id{
1603 Token.Id.LineComment,1598 .LineComment,
1604 Token.Id.Invalid,1599 .Invalid,
1605 });1600 });
1606 testTokenize("//\x1f", &[_]Token.Id{1601 testTokenize("//\x1f", &[_]Token.Id{
1607 Token.Id.LineComment,1602 .LineComment,
1608 Token.Id.Invalid,1603 .Invalid,
1609 });1604 });
1610 testTokenize("//\x7f", &[_]Token.Id{1605 testTokenize("//\x7f", &[_]Token.Id{
1611 Token.Id.LineComment,1606 .LineComment,
1612 Token.Id.Invalid,1607 .Invalid,
1613 });1608 });
1614}1609}
16151610
1616test "tokenizer - utf8" {1611test "tokenizer - utf8" {
1617 testTokenize("//\xc2\x80", &[_]Token.Id{Token.Id.LineComment});1612 testTokenize("//\xc2\x80", &[_]Token.Id{.LineComment});
1618 testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{Token.Id.LineComment});1613 testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{.LineComment});
1619}1614}
16201615
1621test "tokenizer - invalid utf8" {1616test "tokenizer - invalid utf8" {
1622 testTokenize("//\x80", &[_]Token.Id{1617 testTokenize("//\x80", &[_]Token.Id{
1623 Token.Id.LineComment,1618 .LineComment,
1624 Token.Id.Invalid,1619 .Invalid,
1625 });1620 });
1626 testTokenize("//\xbf", &[_]Token.Id{1621 testTokenize("//\xbf", &[_]Token.Id{
1627 Token.Id.LineComment,1622 .LineComment,
1628 Token.Id.Invalid,1623 .Invalid,
1629 });1624 });
1630 testTokenize("//\xf8", &[_]Token.Id{1625 testTokenize("//\xf8", &[_]Token.Id{
1631 Token.Id.LineComment,1626 .LineComment,
1632 Token.Id.Invalid,1627 .Invalid,
1633 });1628 });
1634 testTokenize("//\xff", &[_]Token.Id{1629 testTokenize("//\xff", &[_]Token.Id{
1635 Token.Id.LineComment,1630 .LineComment,
1636 Token.Id.Invalid,1631 .Invalid,
1637 });1632 });
1638 testTokenize("//\xc2\xc0", &[_]Token.Id{1633 testTokenize("//\xc2\xc0", &[_]Token.Id{
1639 Token.Id.LineComment,1634 .LineComment,
1640 Token.Id.Invalid,1635 .Invalid,
1641 });1636 });
1642 testTokenize("//\xe0", &[_]Token.Id{1637 testTokenize("//\xe0", &[_]Token.Id{
1643 Token.Id.LineComment,1638 .LineComment,
1644 Token.Id.Invalid,1639 .Invalid,
1645 });1640 });
1646 testTokenize("//\xf0", &[_]Token.Id{1641 testTokenize("//\xf0", &[_]Token.Id{
1647 Token.Id.LineComment,1642 .LineComment,
1648 Token.Id.Invalid,1643 .Invalid,
1649 });1644 });
1650 testTokenize("//\xf0\x90\x80\xc0", &[_]Token.Id{1645 testTokenize("//\xf0\x90\x80\xc0", &[_]Token.Id{
1651 Token.Id.LineComment,1646 .LineComment,
1652 Token.Id.Invalid,1647 .Invalid,
1653 });1648 });
1654}1649}
16551650
1656test "tokenizer - illegal unicode codepoints" {1651test "tokenizer - illegal unicode codepoints" {
1657 // unicode newline characters.U+0085, U+2028, U+20291652 // unicode newline characters.U+0085, U+2028, U+2029
1658 testTokenize("//\xc2\x84", &[_]Token.Id{Token.Id.LineComment});1653 testTokenize("//\xc2\x84", &[_]Token.Id{.LineComment});
1659 testTokenize("//\xc2\x85", &[_]Token.Id{1654 testTokenize("//\xc2\x85", &[_]Token.Id{
1660 Token.Id.LineComment,1655 .LineComment,
1661 Token.Id.Invalid,1656 .Invalid,
1662 });1657 });
1663 testTokenize("//\xc2\x86", &[_]Token.Id{Token.Id.LineComment});1658 testTokenize("//\xc2\x86", &[_]Token.Id{.LineComment});
1664 testTokenize("//\xe2\x80\xa7", &[_]Token.Id{Token.Id.LineComment});1659 testTokenize("//\xe2\x80\xa7", &[_]Token.Id{.LineComment});
1665 testTokenize("//\xe2\x80\xa8", &[_]Token.Id{1660 testTokenize("//\xe2\x80\xa8", &[_]Token.Id{
1666 Token.Id.LineComment,1661 .LineComment,
1667 Token.Id.Invalid,1662 .Invalid,
1668 });1663 });
1669 testTokenize("//\xe2\x80\xa9", &[_]Token.Id{1664 testTokenize("//\xe2\x80\xa9", &[_]Token.Id{
1670 Token.Id.LineComment,1665 .LineComment,
1671 Token.Id.Invalid,1666 .Invalid,
1672 });1667 });
1673 testTokenize("//\xe2\x80\xaa", &[_]Token.Id{Token.Id.LineComment});1668 testTokenize("//\xe2\x80\xaa", &[_]Token.Id{.LineComment});
1674}1669}
16751670
1676test "tokenizer - string identifier and builtin fns" {1671test "tokenizer - string identifier and builtin fns" {
1677 testTokenize(1672 testTokenize(
1678 \\const @"if" = @import("std");1673 \\const @"if" = @import("std");
1679 , &[_]Token.Id{1674 , &[_]Token.Id{
1680 Token.Id.Keyword_const,1675 .Keyword_const,
1681 Token.Id.Identifier,1676 .Identifier,
1682 Token.Id.Equal,1677 .Equal,
1683 Token.Id.Builtin,1678 .Builtin,
1684 Token.Id.LParen,1679 .LParen,
1685 Token.Id.StringLiteral,1680 .StringLiteral,
1686 Token.Id.RParen,1681 .RParen,
1687 Token.Id.Semicolon,1682 .Semicolon,
1688 });1683 });
1689}1684}
16901685
...@@ -1692,26 +1687,26 @@ test "tokenizer - multiline string literal with literal tab" {...@@ -1692,26 +1687,26 @@ test "tokenizer - multiline string literal with literal tab" {
1692 testTokenize(1687 testTokenize(
1693 \\\\foo bar1688 \\\\foo bar
1694 , &[_]Token.Id{1689 , &[_]Token.Id{
1695 Token.Id.MultilineStringLiteralLine,1690 .MultilineStringLiteralLine,
1696 });1691 });
1697}1692}
16981693
1699test "tokenizer - pipe and then invalid" {1694test "tokenizer - pipe and then invalid" {
1700 testTokenize("||=", &[_]Token.Id{1695 testTokenize("||=", &[_]Token.Id{
1701 Token.Id.PipePipe,1696 .PipePipe,
1702 Token.Id.Equal,1697 .Equal,
1703 });1698 });
1704}1699}
17051700
1706test "tokenizer - line comment and doc comment" {1701test "tokenizer - line comment and doc comment" {
1707 testTokenize("//", &[_]Token.Id{Token.Id.LineComment});1702 testTokenize("//", &[_]Token.Id{.LineComment});
1708 testTokenize("// a / b", &[_]Token.Id{Token.Id.LineComment});1703 testTokenize("// a / b", &[_]Token.Id{.LineComment});
1709 testTokenize("// /", &[_]Token.Id{Token.Id.LineComment});1704 testTokenize("// /", &[_]Token.Id{.LineComment});
1710 testTokenize("/// a", &[_]Token.Id{Token.Id.DocComment});1705 testTokenize("/// a", &[_]Token.Id{.DocComment});
1711 testTokenize("///", &[_]Token.Id{Token.Id.DocComment});1706 testTokenize("///", &[_]Token.Id{.DocComment});
1712 testTokenize("////", &[_]Token.Id{Token.Id.LineComment});1707 testTokenize("////", &[_]Token.Id{.LineComment});
1713 testTokenize("//!", &[_]Token.Id{Token.Id.ContainerDocComment});1708 testTokenize("//!", &[_]Token.Id{.ContainerDocComment});
1714 testTokenize("//!!", &[_]Token.Id{Token.Id.ContainerDocComment});1709 testTokenize("//!!", &[_]Token.Id{.ContainerDocComment});
1715}1710}
17161711
1717test "tokenizer - line comment followed by identifier" {1712test "tokenizer - line comment followed by identifier" {
...@@ -1720,28 +1715,28 @@ test "tokenizer - line comment followed by identifier" {...@@ -1720,28 +1715,28 @@ test "tokenizer - line comment followed by identifier" {
1720 \\ // another1715 \\ // another
1721 \\ Another,1716 \\ Another,
1722 , &[_]Token.Id{1717 , &[_]Token.Id{
1723 Token.Id.Identifier,1718 .Identifier,
1724 Token.Id.Comma,1719 .Comma,
1725 Token.Id.LineComment,1720 .LineComment,
1726 Token.Id.Identifier,1721 .Identifier,
1727 Token.Id.Comma,1722 .Comma,
1728 });1723 });
1729}1724}
17301725
1731test "tokenizer - UTF-8 BOM is recognized and skipped" {1726test "tokenizer - UTF-8 BOM is recognized and skipped" {
1732 testTokenize("\xEF\xBB\xBFa;\n", &[_]Token.Id{1727 testTokenize("\xEF\xBB\xBFa;\n", &[_]Token.Id{
1733 Token.Id.Identifier,1728 .Identifier,
1734 Token.Id.Semicolon,1729 .Semicolon,
1735 });1730 });
1736}1731}
17371732
1738test "correctly parse pointer assignment" {1733test "correctly parse pointer assignment" {
1739 testTokenize("b.*=3;\n", &[_]Token.Id{1734 testTokenize("b.*=3;\n", &[_]Token.Id{
1740 Token.Id.Identifier,1735 .Identifier,
1741 Token.Id.PeriodAsterisk,1736 .PeriodAsterisk,
1742 Token.Id.Equal,1737 .Equal,
1743 Token.Id.IntegerLiteral,1738 .IntegerLiteral,
1744 Token.Id.Semicolon,1739 .Semicolon,
1745 });1740 });
1746}1741}
17471742
...@@ -1984,5 +1979,5 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {...@@ -1984,5 +1979,5 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
1984 }1979 }
1985 }1980 }
1986 const last_token = tokenizer.next();1981 const last_token = tokenizer.next();
1987 std.testing.expect(last_token.id == Token.Id.Eof);1982 std.testing.expect(last_token.id == .Eof);
1988}1983}
src-self-hosted/clang.zig+1-1
...@@ -781,7 +781,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigCla...@@ -781,7 +781,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigCla
781pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;781pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
782pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;782pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
783pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;783pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
784pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;784pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?fn (?*c_void, *const struct_ZigClangDecl) callconv(.C) bool) bool;
785pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;785pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
786pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClangTagDecl) bool;786pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClangTagDecl) bool;
787pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;787pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;
src-self-hosted/stage2.zig+1
...@@ -589,6 +589,7 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [...@@ -589,6 +589,7 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [
589 error.EndOfStream => return .EndOfFile,589 error.EndOfStream => return .EndOfFile,
590 error.IsDir => return .IsDir,590 error.IsDir => return .IsDir,
591 error.ConnectionResetByPeer => unreachable,591 error.ConnectionResetByPeer => unreachable,
592 error.ConnectionTimedOut => unreachable,
592 error.OutOfMemory => return .OutOfMemory,593 error.OutOfMemory => return .OutOfMemory,
593 error.Unseekable => unreachable,594 error.Unseekable => unreachable,
594 error.SharingViolation => return .SharingViolation,595 error.SharingViolation => return .SharingViolation,
src-self-hosted/translate_c.zig+60-36
...@@ -668,6 +668,31 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe...@@ -668,6 +668,31 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
668 return transCreateNodeIdentifier(c, builtin_name);668 return transCreateNodeIdentifier(c, builtin_name);
669}669}
670670
671fn checkForBuiltinTypedef(checked_name: []const u8) ?[]const u8 {
672 const table = [_][2][]const u8{
673 .{ "uint8_t", "u8" },
674 .{ "int8_t", "i8" },
675 .{ "uint16_t", "u16" },
676 .{ "int16_t", "i16" },
677 .{ "uint32_t", "u32" },
678 .{ "int32_t", "i32" },
679 .{ "uint64_t", "u64" },
680 .{ "int64_t", "i64" },
681 .{ "intptr_t", "isize" },
682 .{ "uintptr_t", "usize" },
683 .{ "ssize_t", "isize" },
684 .{ "size_t", "usize" },
685 };
686
687 for (table) |entry| {
688 if (mem.eql(u8, checked_name, entry[0])) {
689 return entry[1];
690 }
691 }
692
693 return null;
694}
695
671fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {696fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
672 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|697 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
673 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice698 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
...@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l...@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
678 // TODO https://github.com/ziglang/zig/issues/3756703 // TODO https://github.com/ziglang/zig/issues/3756
679 // TODO https://github.com/ziglang/zig/issues/1802704 // TODO https://github.com/ziglang/zig/issues/1802
680 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;705 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
681706 if (checkForBuiltinTypedef(checked_name)) |builtin| {
682 if (mem.eql(u8, checked_name, "uint8_t"))707 return transTypeDefAsBuiltin(c, typedef_decl, builtin);
683 return transTypeDefAsBuiltin(c, typedef_decl, "u8")708 }
684 else if (mem.eql(u8, checked_name, "int8_t"))
685 return transTypeDefAsBuiltin(c, typedef_decl, "i8")
686 else if (mem.eql(u8, checked_name, "uint16_t"))
687 return transTypeDefAsBuiltin(c, typedef_decl, "u16")
688 else if (mem.eql(u8, checked_name, "int16_t"))
689 return transTypeDefAsBuiltin(c, typedef_decl, "i16")
690 else if (mem.eql(u8, checked_name, "uint32_t"))
691 return transTypeDefAsBuiltin(c, typedef_decl, "u32")
692 else if (mem.eql(u8, checked_name, "int32_t"))
693 return transTypeDefAsBuiltin(c, typedef_decl, "i32")
694 else if (mem.eql(u8, checked_name, "uint64_t"))
695 return transTypeDefAsBuiltin(c, typedef_decl, "u64")
696 else if (mem.eql(u8, checked_name, "int64_t"))
697 return transTypeDefAsBuiltin(c, typedef_decl, "i64")
698 else if (mem.eql(u8, checked_name, "intptr_t"))
699 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
700 else if (mem.eql(u8, checked_name, "uintptr_t"))
701 return transTypeDefAsBuiltin(c, typedef_decl, "usize")
702 else if (mem.eql(u8, checked_name, "ssize_t"))
703 return transTypeDefAsBuiltin(c, typedef_decl, "isize")
704 else if (mem.eql(u8, checked_name, "size_t"))
705 return transTypeDefAsBuiltin(c, typedef_decl, "usize");
706709
707 if (!top_level_visit) {710 if (!top_level_visit) {
708 return transCreateNodeIdentifier(c, checked_name);711 return transCreateNodeIdentifier(c, checked_name);
709 }712 }
710713
711 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);714 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
712 const visib_tok = try appendToken(c, .Keyword_pub, "pub");715 const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
713 const const_tok = try appendToken(c, .Keyword_const, "const");716 try addTopLevelDecl(c, checked_name, &node.base);
714 const node = try transCreateNodeVarDecl(c, true, true, checked_name);717 return transCreateNodeIdentifier(c, checked_name);
715 node.eq_token = try appendToken(c, .Equal, "=");718}
719
720fn transCreateNodeTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl {
721 const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name);
722 node.eq_token = try appendToken(rp.c, .Equal, "=");
716723
717 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);724 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
718 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);725 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
719 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {726 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
720 error.UnsupportedType => {727 error.UnsupportedType => {
721 try failDecl(c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});728 try failDecl(rp.c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});
722 return null;729 return null;
723 },730 },
724 error.OutOfMemory => |e| return e,731 error.OutOfMemory => |e| return e,
725 };732 };
726 node.semicolon_token = try appendToken(c, .Semicolon, ";");733
727 try addTopLevelDecl(c, checked_name, &node.base);734 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
728 return transCreateNodeIdentifier(c, checked_name);735 return node;
729}736}
730737
731fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {738fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {
...@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)...@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
1394 node.semicolon_token = try appendToken(c, .Semicolon, ";");1401 node.semicolon_token = try appendToken(c, .Semicolon, ";");
1395 try block_scope.block_node.statements.push(&node.base);1402 try block_scope.block_node.statements.push(&node.base);
1396 },1403 },
1404 .Typedef => {
1405 const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
1406 const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
1407 @ptrCast(*const ZigClangNamedDecl, typedef_decl),
1408 ));
1409
1410 const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
1411 const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
1412
1413 const mangled_name = try block_scope.makeMangledName(c, name);
1414 if (checkForBuiltinTypedef(name)) |builtin| {
1415 try block_scope.variables.push(.{
1416 .alias = builtin,
1417 .name = mangled_name,
1418 });
1419 } else {
1420 const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;
1421 try block_scope.block_node.statements.push(&node.base);
1422 }
1423 },
1397 else => |kind| return revertAndWarn(1424 else => |kind| return revertAndWarn(
1398 rp,1425 rp,
1399 error.UnsupportedTranslation,1426 error.UnsupportedTranslation,
...@@ -4094,7 +4121,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a...@@ -4094,7 +4121,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
4094 .return_type = proto_alias.return_type,4121 .return_type = proto_alias.return_type,
4095 .var_args_token = null,4122 .var_args_token = null,
4096 .extern_export_inline_token = inline_tok,4123 .extern_export_inline_token = inline_tok,
4097 .cc_token = null,
4098 .body_node = null,4124 .body_node = null,
4099 .lib_name = null,4125 .lib_name = null,
4100 .align_expr = null,4126 .align_expr = null,
...@@ -4753,7 +4779,6 @@ fn finishTransFnProto(...@@ -4753,7 +4779,6 @@ fn finishTransFnProto(
4753 .return_type = .{ .Explicit = return_type_node },4779 .return_type = .{ .Explicit = return_type_node },
4754 .var_args_token = null, // TODO this field is broken in the AST data model4780 .var_args_token = null, // TODO this field is broken in the AST data model
4755 .extern_export_inline_token = extern_export_inline_tok,4781 .extern_export_inline_token = extern_export_inline_tok,
4756 .cc_token = null,
4757 .body_node = null,4782 .body_node = null,
4758 .lib_name = null,4783 .lib_name = null,
4759 .align_expr = align_expr,4784 .align_expr = align_expr,
...@@ -5119,7 +5144,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5119,7 +5144,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5119 .return_type = .{ .Explicit = &type_of.base },5144 .return_type = .{ .Explicit = &type_of.base },
5120 .doc_comments = null,5145 .doc_comments = null,
5121 .var_args_token = null,5146 .var_args_token = null,
5122 .cc_token = null,
5123 .body_node = null,5147 .body_node = null,
5124 .lib_name = null,5148 .lib_name = null,
5125 .align_expr = null,5149 .align_expr = null,
src-self-hosted/zir.zig+1-1
...@@ -283,7 +283,7 @@ pub const Inst = struct {...@@ -283,7 +283,7 @@ pub const Inst = struct {
283 comptime_int,283 comptime_int,
284 comptime_float,284 comptime_float,
285285
286 fn toType(self: BuiltinType) Type {286 pub fn toType(self: BuiltinType) Type {
287 return switch (self) {287 return switch (self) {
288 .isize => Type.initTag(.isize),288 .isize => Type.initTag(.isize),
289 .usize => Type.initTag(.usize),289 .usize => Type.initTag(.usize),
src/all_types.hpp+11-12
...@@ -672,7 +672,7 @@ enum NodeType {...@@ -672,7 +672,7 @@ enum NodeType {
672 NodeTypeSwitchProng,672 NodeTypeSwitchProng,
673 NodeTypeSwitchRange,673 NodeTypeSwitchRange,
674 NodeTypeCompTime,674 NodeTypeCompTime,
675 NodeTypeNoAsync,675 NodeTypeNoSuspend,
676 NodeTypeBreak,676 NodeTypeBreak,
677 NodeTypeContinue,677 NodeTypeContinue,
678 NodeTypeAsmExpr,678 NodeTypeAsmExpr,
...@@ -718,7 +718,6 @@ struct AstNodeFnProto {...@@ -718,7 +718,6 @@ struct AstNodeFnProto {
718 Buf doc_comments;718 Buf doc_comments;
719719
720 FnInline fn_inline;720 FnInline fn_inline;
721 bool is_async;
722721
723 VisibMod visib_mod;722 VisibMod visib_mod;
724 bool auto_err_set;723 bool auto_err_set;
...@@ -862,7 +861,7 @@ enum CallModifier {...@@ -862,7 +861,7 @@ enum CallModifier {
862 CallModifierAsync,861 CallModifierAsync,
863 CallModifierNeverTail,862 CallModifierNeverTail,
864 CallModifierNeverInline,863 CallModifierNeverInline,
865 CallModifierNoAsync,864 CallModifierNoSuspend,
866 CallModifierAlwaysTail,865 CallModifierAlwaysTail,
867 CallModifierAlwaysInline,866 CallModifierAlwaysInline,
868 CallModifierCompileTime,867 CallModifierCompileTime,
...@@ -1014,7 +1013,7 @@ struct AstNodeCompTime {...@@ -1014,7 +1013,7 @@ struct AstNodeCompTime {
1014 AstNode *expr;1013 AstNode *expr;
1015};1014};
10161015
1017struct AstNodeNoAsync {1016struct AstNodeNoSuspend {
1018 AstNode *expr;1017 AstNode *expr;
1019};1018};
10201019
...@@ -1225,7 +1224,7 @@ struct AstNode {...@@ -1225,7 +1224,7 @@ struct AstNode {
1225 AstNodeSwitchProng switch_prong;1224 AstNodeSwitchProng switch_prong;
1226 AstNodeSwitchRange switch_range;1225 AstNodeSwitchRange switch_range;
1227 AstNodeCompTime comptime_expr;1226 AstNodeCompTime comptime_expr;
1228 AstNodeNoAsync noasync_expr;1227 AstNodeNoSuspend nosuspend_expr;
1229 AstNodeAsmExpr asm_expr;1228 AstNodeAsmExpr asm_expr;
1230 AstNodeFieldAccessExpr field_access_expr;1229 AstNodeFieldAccessExpr field_access_expr;
1231 AstNodePtrDerefExpr ptr_deref_expr;1230 AstNodePtrDerefExpr ptr_deref_expr;
...@@ -1858,7 +1857,7 @@ enum PanicMsgId {...@@ -1858,7 +1857,7 @@ enum PanicMsgId {
1858 PanicMsgIdResumedAnAwaitingFn,1857 PanicMsgIdResumedAnAwaitingFn,
1859 PanicMsgIdFrameTooSmall,1858 PanicMsgIdFrameTooSmall,
1860 PanicMsgIdResumedFnPendingAwait,1859 PanicMsgIdResumedFnPendingAwait,
1861 PanicMsgIdBadNoAsyncCall,1860 PanicMsgIdBadNoSuspendCall,
1862 PanicMsgIdResumeNotSuspendedFn,1861 PanicMsgIdResumeNotSuspendedFn,
1863 PanicMsgIdBadSentinel,1862 PanicMsgIdBadSentinel,
1864 PanicMsgIdShxTooBigRhs,1863 PanicMsgIdShxTooBigRhs,
...@@ -2376,7 +2375,7 @@ enum ScopeId {...@@ -2376,7 +2375,7 @@ enum ScopeId {
2376 ScopeIdRuntime,2375 ScopeIdRuntime,
2377 ScopeIdTypeOf,2376 ScopeIdTypeOf,
2378 ScopeIdExpr,2377 ScopeIdExpr,
2379 ScopeIdNoAsync,2378 ScopeIdNoSuspend,
2380};2379};
23812380
2382struct Scope {2381struct Scope {
...@@ -2510,9 +2509,9 @@ struct ScopeCompTime {...@@ -2510,9 +2509,9 @@ struct ScopeCompTime {
2510 Scope base;2509 Scope base;
2511};2510};
25122511
2513// This scope is created for a noasync expression.2512// This scope is created for a nosuspend expression.
2514// NodeTypeNoAsync2513// NodeTypeNoSuspend
2515struct ScopeNoAsync {2514struct ScopeNoSuspend {
2516 Scope base;2515 Scope base;
2517};2516};
25182517
...@@ -4488,7 +4487,7 @@ struct IrInstSrcAwait {...@@ -4488,7 +4487,7 @@ struct IrInstSrcAwait {
44884487
4489 IrInstSrc *frame;4488 IrInstSrc *frame;
4490 ResultLoc *result_loc;4489 ResultLoc *result_loc;
4491 bool is_noasync;4490 bool is_nosuspend;
4492};4491};
44934492
4494struct IrInstGenAwait {4493struct IrInstGenAwait {
...@@ -4497,7 +4496,7 @@ struct IrInstGenAwait {...@@ -4497,7 +4496,7 @@ struct IrInstGenAwait {
4497 IrInstGen *frame;4496 IrInstGen *frame;
4498 IrInstGen *result_loc;4497 IrInstGen *result_loc;
4499 ZigFn *target_fn;4498 ZigFn *target_fn;
4500 bool is_noasync;4499 bool is_nosuspend;
4501};4500};
45024501
4503struct IrInstSrcResume {4502struct IrInstSrcResume {
src/analyze.cpp+9-11
...@@ -106,7 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {...@@ -106,7 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {
106 case ScopeIdDecls:106 case ScopeIdDecls:
107 case ScopeIdFnDef:107 case ScopeIdFnDef:
108 case ScopeIdCompTime:108 case ScopeIdCompTime:
109 case ScopeIdNoAsync:109 case ScopeIdNoSuspend:
110 case ScopeIdVarDecl:110 case ScopeIdVarDecl:
111 case ScopeIdCImport:111 case ScopeIdCImport:
112 case ScopeIdSuspend:112 case ScopeIdSuspend:
...@@ -227,9 +227,9 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {...@@ -227,9 +227,9 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
227 return &scope->base;227 return &scope->base;
228}228}
229229
230Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) {230Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
231 ScopeNoAsync *scope = heap::c_allocator.create<ScopeNoAsync>();231 ScopeNoSuspend *scope = heap::c_allocator.create<ScopeNoSuspend>();
232 init_scope(g, &scope->base, ScopeIdNoAsync, node, parent);232 init_scope(g, &scope->base, ScopeIdNoSuspend, node, parent);
233 return &scope->base;233 return &scope->base;
234}234}
235235
...@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1528}1528}
15291529
1530CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {1530CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
1531 if (fn_proto->is_async)
1532 return CallingConventionAsync;
1533 // Compatible with the C ABI1531 // Compatible with the C ABI
1534 if (fn_proto->is_extern || fn_proto->is_export)1532 if (fn_proto->is_extern || fn_proto->is_export)
1535 return CallingConventionC;1533 return CallingConventionC;
...@@ -3771,7 +3769,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -3771,7 +3769,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
3771 case NodeTypeCompTime:3769 case NodeTypeCompTime:
3772 preview_comptime_decl(g, node, decls_scope);3770 preview_comptime_decl(g, node, decls_scope);
3773 break;3771 break;
3774 case NodeTypeNoAsync:3772 case NodeTypeNoSuspend:
3775 case NodeTypeParamDecl:3773 case NodeTypeParamDecl:
3776 case NodeTypeReturnExpr:3774 case NodeTypeReturnExpr:
3777 case NodeTypeDefer:3775 case NodeTypeDefer:
...@@ -4689,7 +4687,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {...@@ -4689,7 +4687,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {
4689static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,4687static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,
4690 bool must_not_be_async, CallModifier modifier)4688 bool must_not_be_async, CallModifier modifier)
4691{4689{
4692 if (modifier == CallModifierNoAsync)4690 if (modifier == CallModifierNoSuspend)
4693 return ErrorNone;4691 return ErrorNone;
4694 bool callee_is_async = false;4692 bool callee_is_async = false;
4695 switch (callee->type_entry->data.fn.fn_type_id.cc) {4693 switch (callee->type_entry->data.fn.fn_type_id.cc) {
...@@ -4812,7 +4810,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {...@@ -4812,7 +4810,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
4812 }4810 }
4813 for (size_t i = 0; i < fn->await_list.length; i += 1) {4811 for (size_t i = 0; i < fn->await_list.length; i += 1) {
4814 IrInstGenAwait *await = fn->await_list.at(i);4812 IrInstGenAwait *await = fn->await_list.at(i);
4815 if (await->is_noasync) continue;4813 if (await->is_nosuspend) continue;
4816 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,4814 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
4817 CallModifierNone))4815 CallModifierNone))
4818 {4816 {
...@@ -6239,7 +6237,7 @@ static void mark_suspension_point(Scope *scope) {...@@ -6239,7 +6237,7 @@ static void mark_suspension_point(Scope *scope) {
6239 case ScopeIdDecls:6237 case ScopeIdDecls:
6240 case ScopeIdFnDef:6238 case ScopeIdFnDef:
6241 case ScopeIdCompTime:6239 case ScopeIdCompTime:
6242 case ScopeIdNoAsync:6240 case ScopeIdNoSuspend:
6243 case ScopeIdCImport:6241 case ScopeIdCImport:
6244 case ScopeIdSuspend:6242 case ScopeIdSuspend:
6245 case ScopeIdTypeOf:6243 case ScopeIdTypeOf:
...@@ -6472,7 +6470,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {...@@ -6472,7 +6470,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
6472 // The funtion call result of foo() must be spilled.6470 // The funtion call result of foo() must be spilled.
6473 for (size_t i = 0; i < fn->await_list.length; i += 1) {6471 for (size_t i = 0; i < fn->await_list.length; i += 1) {
6474 IrInstGenAwait *await = fn->await_list.at(i);6472 IrInstGenAwait *await = fn->await_list.at(i);
6475 if (await->is_noasync) {6473 if (await->is_nosuspend) {
6476 continue;6474 continue;
6477 }6475 }
6478 if (await->base.value->special != ConstValSpecialRuntime) {6476 if (await->base.value->special != ConstValSpecialRuntime) {
src/analyze.hpp+1-1
...@@ -125,7 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);...@@ -125,7 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
125ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);125ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
126ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);126ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
127Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);127Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
128Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent);128Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent);
129Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);129Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
130Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);130Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
131ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);131ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
src/ast_render.cpp+7-7
...@@ -220,8 +220,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -220,8 +220,8 @@ static const char *node_type_str(NodeType node_type) {
220 return "SwitchRange";220 return "SwitchRange";
221 case NodeTypeCompTime:221 case NodeTypeCompTime:
222 return "CompTime";222 return "CompTime";
223 case NodeTypeNoAsync:223 case NodeTypeNoSuspend:
224 return "NoAsync";224 return "NoSuspend";
225 case NodeTypeBreak:225 case NodeTypeBreak:
226 return "Break";226 return "Break";
227 case NodeTypeContinue:227 case NodeTypeContinue:
...@@ -709,8 +709,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -709,8 +709,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
709 switch (node->data.fn_call_expr.modifier) {709 switch (node->data.fn_call_expr.modifier) {
710 case CallModifierNone:710 case CallModifierNone:
711 break;711 break;
712 case CallModifierNoAsync:712 case CallModifierNoSuspend:
713 fprintf(ar->f, "noasync ");713 fprintf(ar->f, "nosuspend ");
714 break;714 break;
715 case CallModifierAsync:715 case CallModifierAsync:
716 fprintf(ar->f, "async ");716 fprintf(ar->f, "async ");
...@@ -1093,10 +1093,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -1093,10 +1093,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
1093 render_node_grouped(ar, node->data.comptime_expr.expr);1093 render_node_grouped(ar, node->data.comptime_expr.expr);
1094 break;1094 break;
1095 }1095 }
1096 case NodeTypeNoAsync:1096 case NodeTypeNoSuspend:
1097 {1097 {
1098 fprintf(ar->f, "noasync ");1098 fprintf(ar->f, "nosuspend ");
1099 render_node_grouped(ar, node->data.noasync_expr.expr);1099 render_node_grouped(ar, node->data.nosuspend_expr.expr);
1100 break;1100 break;
1101 }1101 }
1102 case NodeTypeForExpr:1102 case NodeTypeForExpr:
src/bigint.cpp+1
...@@ -243,6 +243,7 @@ bool bigint_fits_in_bits(const BigInt *bn, size_t bit_count, bool is_signed) {...@@ -243,6 +243,7 @@ bool bigint_fits_in_bits(const BigInt *bn, size_t bit_count, bool is_signed) {
243 }243 }
244244
245 if (!is_signed) {245 if (!is_signed) {
246 if(bn->is_negative) return false;
246 size_t full_bits = bn->digit_count * 64;247 size_t full_bits = bn->digit_count * 64;
247 size_t leading_zero_count = bigint_clz(bn, full_bits);248 size_t leading_zero_count = bigint_clz(bn, full_bits);
248 return bit_count >= full_bits - leading_zero_count;249 return bit_count >= full_bits - leading_zero_count;
src/codegen.cpp+15-15
...@@ -685,7 +685,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -685,7 +685,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
685 case ScopeIdLoop:685 case ScopeIdLoop:
686 case ScopeIdSuspend:686 case ScopeIdSuspend:
687 case ScopeIdCompTime:687 case ScopeIdCompTime:
688 case ScopeIdNoAsync:688 case ScopeIdNoSuspend:
689 case ScopeIdRuntime:689 case ScopeIdRuntime:
690 case ScopeIdTypeOf:690 case ScopeIdTypeOf:
691 case ScopeIdExpr:691 case ScopeIdExpr:
...@@ -966,8 +966,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {...@@ -966,8 +966,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
966 return buf_create_from_str("frame too small");966 return buf_create_from_str("frame too small");
967 case PanicMsgIdResumedFnPendingAwait:967 case PanicMsgIdResumedFnPendingAwait:
968 return buf_create_from_str("resumed an async function which can only be awaited");968 return buf_create_from_str("resumed an async function which can only be awaited");
969 case PanicMsgIdBadNoAsyncCall:969 case PanicMsgIdBadNoSuspendCall:
970 return buf_create_from_str("async function called in noasync scope suspended");970 return buf_create_from_str("async function called in nosuspend scope suspended");
971 case PanicMsgIdResumeNotSuspendedFn:971 case PanicMsgIdResumeNotSuspendedFn:
972 return buf_create_from_str("resumed a non-suspended function");972 return buf_create_from_str("resumed a non-suspended function");
973 case PanicMsgIdBadSentinel:973 case PanicMsgIdBadSentinel:
...@@ -4071,7 +4071,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {...@@ -4071,7 +4071,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
4071 case ScopeIdLoop:4071 case ScopeIdLoop:
4072 case ScopeIdSuspend:4072 case ScopeIdSuspend:
4073 case ScopeIdCompTime:4073 case ScopeIdCompTime:
4074 case ScopeIdNoAsync:4074 case ScopeIdNoSuspend:
4075 case ScopeIdRuntime:4075 case ScopeIdRuntime:
4076 case ScopeIdTypeOf:4076 case ScopeIdTypeOf:
4077 case ScopeIdExpr:4077 case ScopeIdExpr:
...@@ -4222,9 +4222,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn...@@ -4222,9 +4222,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4222 // even if prefix_arg_err_ret_stack is true, let the async function do its own4222 // even if prefix_arg_err_ret_stack is true, let the async function do its own
4223 // initialization.4223 // initialization.
4224 } else {4224 } else {
4225 if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) {4225 if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
4226 // Async function called as a normal function, and calling function is not async.4226 // Async function called as a normal function, and calling function is not async.
4227 // This is allowed because it was called with `noasync` which asserts that it will4227 // This is allowed because it was called with `nosuspend` which asserts that it will
4228 // never suspend.4228 // never suspend.
4229 awaiter_init_val = zero;4229 awaiter_init_val = zero;
4230 } else {4230 } else {
...@@ -4335,7 +4335,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn...@@ -4335,7 +4335,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4335 case CallModifierCompileTime:4335 case CallModifierCompileTime:
4336 zig_unreachable();4336 zig_unreachable();
4337 case CallModifierNone:4337 case CallModifierNone:
4338 case CallModifierNoAsync:4338 case CallModifierNoSuspend:
4339 case CallModifierAsync:4339 case CallModifierAsync:
4340 call_attr = ZigLLVM_CallAttrAuto;4340 call_attr = ZigLLVM_CallAttrAuto;
4341 break;4341 break;
...@@ -4411,7 +4411,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn...@@ -4411,7 +4411,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4411 get_llvm_type(g, instruction->base.value->type), "");4411 get_llvm_type(g, instruction->base.value->type), "");
4412 }4412 }
4413 return nullptr;4413 return nullptr;
4414 } else if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) {4414 } else if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
4415 gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);4415 gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
44164416
4417 if (ir_want_runtime_safety(g, &instruction->base)) {4417 if (ir_want_runtime_safety(g, &instruction->base)) {
...@@ -4422,13 +4422,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn...@@ -4422,13 +4422,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
4422 all_ones, LLVMAtomicOrderingRelease);4422 all_ones, LLVMAtomicOrderingRelease);
4423 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, "");4423 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, "");
44244424
4425 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic");4425 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendPanic");
4426 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk");4426 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendOk");
4427 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);4427 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
44284428
4429 // The async function suspended, but this noasync call asserted it wouldn't.4429 // The async function suspended, but this nosuspend call asserted it wouldn't.
4430 LLVMPositionBuilderAtEnd(g->builder, bad_block);4430 LLVMPositionBuilderAtEnd(g->builder, bad_block);
4431 gen_safety_crash(g, PanicMsgIdBadNoAsyncCall);4431 gen_safety_crash(g, PanicMsgIdBadNoSuspendCall);
44324432
4433 LLVMPositionBuilderAtEnd(g->builder, ok_block);4433 LLVMPositionBuilderAtEnd(g->builder, ok_block);
4434 }4434 }
...@@ -6401,7 +6401,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI...@@ -6401,7 +6401,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
6401 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?6401 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
6402 nullptr : ir_llvm_value(g, instruction->result_loc);6402 nullptr : ir_llvm_value(g, instruction->result_loc);
64036403
6404 if (instruction->is_noasync ||6404 if (instruction->is_nosuspend ||
6405 (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))6405 (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
6406 {6406 {
6407 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,6407 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
...@@ -7928,7 +7928,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7928,7 +7928,7 @@ static void do_code_gen(CodeGen *g) {
7928 }7928 }
79297929
7930 if (!is_async) {7930 if (!is_async) {
7931 // allocate async frames for noasync calls & awaits to async functions7931 // allocate async frames for nosuspend calls & awaits to async functions
7932 ZigType *largest_call_frame_type = nullptr;7932 ZigType *largest_call_frame_type = nullptr;
7933 IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,7933 IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,
7934 fn_table_entry->body_node, fn_table_entry, g->builtin_types.entry_void, "@async_call_frame");7934 fn_table_entry->body_node, fn_table_entry, g->builtin_types.entry_void, "@async_call_frame");
...@@ -7938,7 +7938,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7938,7 +7938,7 @@ static void do_code_gen(CodeGen *g) {
7938 continue;7938 continue;
7939 if (!fn_is_async(call->fn_entry))7939 if (!fn_is_async(call->fn_entry))
7940 continue;7940 continue;
7941 if (call->modifier != CallModifierNoAsync)7941 if (call->modifier != CallModifierNoSuspend)
7942 continue;7942 continue;
7943 if (call->frame_result_loc != nullptr)7943 if (call->frame_result_loc != nullptr)
7944 continue;7944 continue;
src/ir.cpp+62-35
...@@ -4846,12 +4846,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins...@@ -4846,12 +4846,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins
4846}4846}
48474847
4848static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,4848static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4849 IrInstSrc *frame, ResultLoc *result_loc, bool is_noasync)4849 IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend)
4850{4850{
4851 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);4851 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
4852 instruction->frame = frame;4852 instruction->frame = frame;
4853 instruction->result_loc = result_loc;4853 instruction->result_loc = result_loc;
4854 instruction->is_noasync = is_noasync;4854 instruction->is_nosuspend = is_nosuspend;
48554855
4856 ir_ref_instruction(frame, irb->current_basic_block);4856 ir_ref_instruction(frame, irb->current_basic_block);
48574857
...@@ -4859,14 +4859,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s...@@ -4859,14 +4859,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s
4859}4859}
48604860
4861static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,4861static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
4862 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_noasync)4862 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend)
4863{4863{
4864 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,4864 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
4865 source_instruction->scope, source_instruction->source_node);4865 source_instruction->scope, source_instruction->source_node);
4866 instruction->base.value->type = result_type;4866 instruction->base.value->type = result_type;
4867 instruction->frame = frame;4867 instruction->frame = frame;
4868 instruction->result_loc = result_loc;4868 instruction->result_loc = result_loc;
4869 instruction->is_noasync = is_noasync;4869 instruction->is_nosuspend = is_nosuspend;
48704870
4871 ir_ref_inst_gen(frame);4871 ir_ref_inst_gen(frame);
4872 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);4872 if (result_loc != nullptr) ir_ref_inst_gen(result_loc);
...@@ -4982,7 +4982,7 @@ static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_...@@ -4982,7 +4982,7 @@ static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_
4982 case ScopeIdLoop:4982 case ScopeIdLoop:
4983 case ScopeIdSuspend:4983 case ScopeIdSuspend:
4984 case ScopeIdCompTime:4984 case ScopeIdCompTime:
4985 case ScopeIdNoAsync:4985 case ScopeIdNoSuspend:
4986 case ScopeIdRuntime:4986 case ScopeIdRuntime:
4987 case ScopeIdTypeOf:4987 case ScopeIdTypeOf:
4988 case ScopeIdExpr:4988 case ScopeIdExpr:
...@@ -5072,7 +5072,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope...@@ -5072,7 +5072,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope
5072 case ScopeIdLoop:5072 case ScopeIdLoop:
5073 case ScopeIdSuspend:5073 case ScopeIdSuspend:
5074 case ScopeIdCompTime:5074 case ScopeIdCompTime:
5075 case ScopeIdNoAsync:5075 case ScopeIdNoSuspend:
5076 case ScopeIdRuntime:5076 case ScopeIdRuntime:
5077 case ScopeIdTypeOf:5077 case ScopeIdTypeOf:
5078 case ScopeIdExpr:5078 case ScopeIdExpr:
...@@ -7335,10 +7335,10 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -7335,10 +7335,10 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
7335 zig_unreachable();7335 zig_unreachable();
7336}7336}
73377337
7338static ScopeNoAsync *get_scope_noasync(Scope *scope) {7338static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
7339 while (scope) {7339 while (scope) {
7340 if (scope->id == ScopeIdNoAsync)7340 if (scope->id == ScopeIdNoSuspend)
7341 return (ScopeNoAsync *)scope;7341 return (ScopeNoSuspend *)scope;
7342 if (scope->id == ScopeIdFnDef)7342 if (scope->id == ScopeIdFnDef)
7343 return nullptr;7343 return nullptr;
73447344
...@@ -7355,15 +7355,15 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,...@@ -7355,15 +7355,15 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,
7355 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)7355 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
7356 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);7356 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
73577357
7358 bool is_noasync = get_scope_noasync(scope) != nullptr;7358 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
7359 CallModifier modifier = node->data.fn_call_expr.modifier;7359 CallModifier modifier = node->data.fn_call_expr.modifier;
7360 if (is_noasync) {7360 if (is_nosuspend) {
7361 if (modifier == CallModifierAsync) {7361 if (modifier == CallModifierAsync) {
7362 add_node_error(irb->codegen, node,7362 add_node_error(irb->codegen, node,
7363 buf_sprintf("async call in noasync scope"));7363 buf_sprintf("async call in nosuspend scope"));
7364 return irb->codegen->invalid_inst_src;7364 return irb->codegen->invalid_inst_src;
7365 }7365 }
7366 modifier = CallModifierNoAsync;7366 modifier = CallModifierNoSuspend;
7367 }7367 }
73687368
7369 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;7369 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
...@@ -9222,10 +9222,10 @@ static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNod...@@ -9222,10 +9222,10 @@ static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNod
9222 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);9222 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
9223}9223}
92249224
9225static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {9225static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
9226 assert(node->type == NodeTypeNoAsync);9226 assert(node->type == NodeTypeNoSuspend);
92279227
9228 Scope *child_scope = create_noasync_scope(irb->codegen, node, parent_scope);9228 Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope);
9229 // purposefully pass null for result_loc and let EndExpr handle it9229 // purposefully pass null for result_loc and let EndExpr handle it
9230 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);9230 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
9231}9231}
...@@ -9813,8 +9813,8 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod...@@ -9813,8 +9813,8 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
98139813
9814static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {9814static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
9815 assert(node->type == NodeTypeResume);9815 assert(node->type == NodeTypeResume);
9816 if (get_scope_noasync(scope) != nullptr) {9816 if (get_scope_nosuspend(scope) != nullptr) {
9817 add_node_error(irb->codegen, node, buf_sprintf("resume in noasync scope"));9817 add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope"));
9818 return irb->codegen->invalid_inst_src;9818 return irb->codegen->invalid_inst_src;
9819 }9819 }
98209820
...@@ -9830,7 +9830,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -9830,7 +9830,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
9830{9830{
9831 assert(node->type == NodeTypeAwaitExpr);9831 assert(node->type == NodeTypeAwaitExpr);
98329832
9833 bool is_noasync = get_scope_noasync(scope) != nullptr;9833 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
98349834
9835 AstNode *expr_node = node->data.await_expr.expr;9835 AstNode *expr_node = node->data.await_expr.expr;
9836 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {9836 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
...@@ -9864,7 +9864,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -9864,7 +9864,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
9864 if (target_inst == irb->codegen->invalid_inst_src)9864 if (target_inst == irb->codegen->invalid_inst_src)
9865 return irb->codegen->invalid_inst_src;9865 return irb->codegen->invalid_inst_src;
98669866
9867 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_noasync);9867 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_nosuspend);
9868 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);9868 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
9869}9869}
98709870
...@@ -9876,8 +9876,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode...@@ -9876,8 +9876,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode
9876 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));9876 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
9877 return irb->codegen->invalid_inst_src;9877 return irb->codegen->invalid_inst_src;
9878 }9878 }
9879 if (get_scope_noasync(parent_scope) != nullptr) {9879 if (get_scope_nosuspend(parent_scope) != nullptr) {
9880 add_node_error(irb->codegen, node, buf_sprintf("suspend in noasync scope"));9880 add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope"));
9881 return irb->codegen->invalid_inst_src;9881 return irb->codegen->invalid_inst_src;
9882 }9882 }
98839883
...@@ -10017,8 +10017,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope...@@ -10017,8 +10017,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
10017 return ir_gen_switch_expr(irb, scope, node, lval, result_loc);10017 return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
10018 case NodeTypeCompTime:10018 case NodeTypeCompTime:
10019 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);10019 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
10020 case NodeTypeNoAsync:10020 case NodeTypeNoSuspend:
10021 return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc);10021 return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc);
10022 case NodeTypeErrorType:10022 case NodeTypeErrorType:
10023 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);10023 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
10024 case NodeTypeBreak:10024 case NodeTypeBreak:
...@@ -10105,7 +10105,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco...@@ -10105,7 +10105,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco
10105 case NodeTypeIfOptional:10105 case NodeTypeIfOptional:
10106 case NodeTypeSwitchExpr:10106 case NodeTypeSwitchExpr:
10107 case NodeTypeCompTime:10107 case NodeTypeCompTime:
10108 case NodeTypeNoAsync:10108 case NodeTypeNoSuspend:
10109 case NodeTypeErrorType:10109 case NodeTypeErrorType:
10110 case NodeTypeBreak:10110 case NodeTypeBreak:
10111 case NodeTypeContinue:10111 case NodeTypeContinue:
...@@ -12760,9 +12760,7 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,...@@ -12760,9 +12760,7 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
12760 const_val->type = new_type;12760 const_val->type = new_type;
12761 break;12761 break;
12762 case CastOpIntToFloat:12762 case CastOpIntToFloat:
12763 {12763 if (new_type->id == ZigTypeIdFloat) {
12764 assert(new_type->id == ZigTypeIdFloat);
12765
12766 BigFloat bigfloat;12764 BigFloat bigfloat;
12767 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint);12765 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint);
12768 switch (new_type->data.floating.bit_count) {12766 switch (new_type->data.floating.bit_count) {
...@@ -12783,9 +12781,13 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,...@@ -12783,9 +12781,13 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
12783 default:12781 default:
12784 zig_unreachable();12782 zig_unreachable();
12785 }12783 }
12786 const_val->special = ConstValSpecialStatic;12784 } else if (new_type->id == ZigTypeIdComptimeFloat) {
12787 break;12785 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint);
12786 } else {
12787 zig_unreachable();
12788 }12788 }
12789 const_val->special = ConstValSpecialStatic;
12790 break;
12789 case CastOpFloatToInt:12791 case CastOpFloatToInt:
12790 float_init_bigint(&const_val->data.x_bigint, other_val);12792 float_init_bigint(&const_val->data.x_bigint, other_val);
12791 if (new_type->id == ZigTypeIdInt) {12793 if (new_type->id == ZigTypeIdInt) {
...@@ -19999,6 +20001,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -19999,6 +20001,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
19999 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {20001 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
20000 return result_loc;20002 return result_loc;
20001 }20003 }
20004 if (result_loc->value->type->data.pointer.is_const) {
20005 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
20006 return ira->codegen->invalid_inst_gen;
20007 }
20008
20002 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type);20009 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type);
20003 dummy_value->value->special = ConstValSpecialRuntime;20010 dummy_value->value->special = ConstValSpecialRuntime;
20004 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,20011 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
...@@ -20025,7 +20032,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20025,7 +20032,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2002520032
20026 if (impl_fn_type_id->cc == CallingConventionAsync &&20033 if (impl_fn_type_id->cc == CallingConventionAsync &&
20027 parent_fn_entry->inferred_async_node == nullptr &&20034 parent_fn_entry->inferred_async_node == nullptr &&
20028 modifier != CallModifierNoAsync)20035 modifier != CallModifierNoSuspend)
20029 {20036 {
20030 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;20037 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
20031 parent_fn_entry->inferred_async_fn = impl_fn;20038 parent_fn_entry->inferred_async_fn = impl_fn;
...@@ -20123,7 +20130,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20123,7 +20130,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2012320130
20124 if (fn_type_id->cc == CallingConventionAsync &&20131 if (fn_type_id->cc == CallingConventionAsync &&
20125 parent_fn_entry->inferred_async_node == nullptr &&20132 parent_fn_entry->inferred_async_node == nullptr &&
20126 modifier != CallModifierNoAsync)20133 modifier != CallModifierNoSuspend)
20127 {20134 {
20128 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;20135 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
20129 parent_fn_entry->inferred_async_fn = fn_entry;20136 parent_fn_entry->inferred_async_fn = fn_entry;
...@@ -20137,6 +20144,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,...@@ -20137,6 +20144,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
20137 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {20144 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
20138 return result_loc;20145 return result_loc;
20139 }20146 }
20147 if (result_loc->value->type->data.pointer.is_const) {
20148 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
20149 return ira->codegen->invalid_inst_gen;
20150 }
20151
20140 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);20152 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
20141 dummy_value->value->special = ConstValSpecialRuntime;20153 dummy_value->value->special = ConstValSpecialRuntime;
20142 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,20154 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
...@@ -20233,7 +20245,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,...@@ -20233,7 +20245,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
20233 case CallModifierNone:20245 case CallModifierNone:
20234 case CallModifierAlwaysInline:20246 case CallModifierAlwaysInline:
20235 case CallModifierAlwaysTail:20247 case CallModifierAlwaysTail:
20236 case CallModifierNoAsync:20248 case CallModifierNoSuspend:
20237 modifier = CallModifierCompileTime;20249 modifier = CallModifierCompileTime;
20238 break;20250 break;
20239 case CallModifierNeverInline:20251 case CallModifierNeverInline:
...@@ -21614,6 +21626,15 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira,...@@ -21614,6 +21626,15 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira,
21614 if (tld->resolution == TldResolutionResolving)21626 if (tld->resolution == TldResolutionResolving)
21615 return ir_error_dependency_loop(ira, source_instr);21627 return ir_error_dependency_loop(ira, source_instr);
2161621628
21629 if (tld->visib_mod == VisibModPrivate &&
21630 tld->import != get_scope_import(source_instr->scope))
21631 {
21632 ErrorMsg *msg = ir_add_error(ira, source_instr,
21633 buf_sprintf("'%s' is private", buf_ptr(field_name)));
21634 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
21635 return ira->codegen->invalid_inst_gen;
21636 }
21637
21617 TldFn *tld_fn = (TldFn *)tld;21638 TldFn *tld_fn = (TldFn *)tld;
21618 ZigFn *fn_entry = tld_fn->fn_entry;21639 ZigFn *fn_entry = tld_fn->fn_entry;
21619 assert(fn_entry != nullptr);21640 assert(fn_entry != nullptr);
...@@ -21687,6 +21708,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins...@@ -21687,6 +21708,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
21687 if (field->is_comptime) {21708 if (field->is_comptime) {
21688 IrInstGen *elem = ir_const(ira, source_instr, field_type);21709 IrInstGen *elem = ir_const(ira, source_instr, field_type);
21689 memoize_field_init_val(ira->codegen, struct_type, field);21710 memoize_field_init_val(ira->codegen, struct_type, field);
21711 if(field->init_val != nullptr && type_is_invalid(field->init_val->type)){
21712 return ira->codegen->invalid_inst_gen;
21713 }
21690 copy_const_val(ira->codegen, elem->value, field->init_val);21714 copy_const_val(ira->codegen, elem->value, field->init_val);
21691 return ir_get_ref2(ira, source_instr, elem, field_type, true, false);21715 return ir_get_ref2(ira, source_instr, elem, field_type, true, false);
21692 }21716 }
...@@ -25043,6 +25067,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25043,6 +25067,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25043 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);25067 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
25044 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;25068 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;
25045 memoize_field_init_val(ira->codegen, type_entry, struct_field);25069 memoize_field_init_val(ira->codegen, type_entry, struct_field);
25070 if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){
25071 return ErrorSemanticAnalyzeFail;
25072 }
25046 set_optional_payload(inner_fields[3], struct_field->init_val);25073 set_optional_payload(inner_fields[3], struct_field->init_val);
2504725074
25048 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;25075 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;
...@@ -30277,7 +30304,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i...@@ -30277,7 +30304,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
30277 ir_assert(fn_entry != nullptr, &instruction->base.base);30304 ir_assert(fn_entry != nullptr, &instruction->base.base);
3027830305
30279 // If it's not @Frame(func) then it's definitely a suspend point30306 // If it's not @Frame(func) then it's definitely a suspend point
30280 if (target_fn == nullptr && !instruction->is_noasync) {30307 if (target_fn == nullptr && !instruction->is_nosuspend) {
30281 if (fn_entry->inferred_async_node == nullptr) {30308 if (fn_entry->inferred_async_node == nullptr) {
30282 fn_entry->inferred_async_node = instruction->base.base.source_node;30309 fn_entry->inferred_async_node = instruction->base.base.source_node;
30283 }30310 }
...@@ -30301,7 +30328,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i...@@ -30301,7 +30328,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
30301 }30328 }
3030230329
30303 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,30330 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,
30304 instruction->is_noasync);30331 instruction->is_nosuspend);
30305 result->target_fn = target_fn;30332 result->target_fn = target_fn;
30306 fn_entry->await_list.append(result);30333 fn_entry->await_list.append(result);
30307 return ir_finish_anal(ira, &result->base);30334 return ir_finish_anal(ira, &result->base);
src/ir_print.cpp+4-4
...@@ -861,8 +861,8 @@ static void ir_print_call_src(IrPrintSrc *irp, IrInstSrcCall *call_instruction)...@@ -861,8 +861,8 @@ static void ir_print_call_src(IrPrintSrc *irp, IrInstSrcCall *call_instruction)
861 switch (call_instruction->modifier) {861 switch (call_instruction->modifier) {
862 case CallModifierNone:862 case CallModifierNone:
863 break;863 break;
864 case CallModifierNoAsync:864 case CallModifierNoSuspend:
865 fprintf(irp->f, "noasync ");865 fprintf(irp->f, "nosuspend ");
866 break;866 break;
867 case CallModifierAsync:867 case CallModifierAsync:
868 fprintf(irp->f, "async ");868 fprintf(irp->f, "async ");
...@@ -906,8 +906,8 @@ static void ir_print_call_gen(IrPrintGen *irp, IrInstGenCall *call_instruction)...@@ -906,8 +906,8 @@ static void ir_print_call_gen(IrPrintGen *irp, IrInstGenCall *call_instruction)
906 switch (call_instruction->modifier) {906 switch (call_instruction->modifier) {
907 case CallModifierNone:907 case CallModifierNone:
908 break;908 break;
909 case CallModifierNoAsync:909 case CallModifierNoSuspend:
910 fprintf(irp->f, "noasync ");910 fprintf(irp->f, "nosuspend ");
911 break;911 break;
912 case CallModifierAsync:912 case CallModifierAsync:
913 fprintf(irp->f, "async ");913 fprintf(irp->f, "async ");
src/parser.cpp+16-73
...@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);...@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);
93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);93static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
94static AstNode *ast_parse_link_section(ParseContext *pc);94static AstNode *ast_parse_link_section(ParseContext *pc);
95static AstNode *ast_parse_callconv(ParseContext *pc);95static AstNode *ast_parse_callconv(ParseContext *pc);
96static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
97static AstNode *ast_parse_param_decl(ParseContext *pc);96static AstNode *ast_parse_param_decl(ParseContext *pc);
98static AstNode *ast_parse_param_type(ParseContext *pc);97static AstNode *ast_parse_param_type(ParseContext *pc);
99static AstNode *ast_parse_if_prefix(ParseContext *pc);98static AstNode *ast_parse_if_prefix(ParseContext *pc);
...@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
707 fn_proto->column = first->start_column;706 fn_proto->column = first->start_column;
708 fn_proto->data.fn_proto.visib_mod = visib_mod;707 fn_proto->data.fn_proto.visib_mod = visib_mod;
709 fn_proto->data.fn_proto.doc_comments = *doc_comments;708 fn_proto->data.fn_proto.doc_comments = *doc_comments;
710 // ast_parse_fn_cc may set it
711 if (!fn_proto->data.fn_proto.is_extern)709 if (!fn_proto->data.fn_proto.is_extern)
712 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;710 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
713 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;711 fn_proto->data.fn_proto.is_export = first->id == TokenIdKeywordExport;
...@@ -788,29 +786,11 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -788,29 +786,11 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
788 return nullptr;786 return nullptr;
789}787}
790788
791// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)789// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
792static AstNode *ast_parse_fn_proto(ParseContext *pc) {790static AstNode *ast_parse_fn_proto(ParseContext *pc) {
793 Token *first = peek_token(pc);791 Token *first = eat_token_if(pc, TokenIdKeywordFn);
794 AstNodeFnProto fn_cc;792 if (first == nullptr) {
795 Token *fn;793 return nullptr;
796 if (ast_parse_fn_cc(pc).unwrap(&fn_cc)) {
797 // The extern keyword for fn CC is also used for container decls.
798 // We therefore put it back, as allow container decl to consume it
799 // later.
800 if (fn_cc.is_extern) {
801 fn = eat_token_if(pc, TokenIdKeywordFn);
802 if (fn == nullptr) {
803 put_back_token(pc);
804 return nullptr;
805 }
806 } else {
807 fn = expect_token(pc, TokenIdKeywordFn);
808 }
809 } else {
810 fn_cc = {};
811 fn = eat_token_if(pc, TokenIdKeywordFn);
812 if (fn == nullptr)
813 return nullptr;
814 }794 }
815795
816 Token *identifier = eat_token_if(pc, TokenIdSymbol);796 Token *identifier = eat_token_if(pc, TokenIdSymbol);
...@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {...@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
830 }810 }
831811
832 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);812 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
833 res->data.fn_proto = fn_cc;813 res->data.fn_proto = {};
834 res->data.fn_proto.name = token_buf(identifier);814 res->data.fn_proto.name = token_buf(identifier);
835 res->data.fn_proto.params = params;815 res->data.fn_proto.params = params;
836 res->data.fn_proto.align_expr = align_expr;816 res->data.fn_proto.align_expr = align_expr;
...@@ -913,7 +893,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {...@@ -913,7 +893,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
913// Statement893// Statement
914// <- KEYWORD_comptime? VarDecl894// <- KEYWORD_comptime? VarDecl
915// / KEYWORD_comptime BlockExprStatement895// / KEYWORD_comptime BlockExprStatement
916// / KEYWORD_noasync BlockExprStatement896// / KEYWORD_nosuspend BlockExprStatement
917// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)897// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
918// / KEYWORD_defer BlockExprStatement898// / KEYWORD_defer BlockExprStatement
919// / KEYWORD_errdefer Payload? BlockExprStatement899// / KEYWORD_errdefer Payload? BlockExprStatement
...@@ -937,11 +917,11 @@ static AstNode *ast_parse_statement(ParseContext *pc) {...@@ -937,11 +917,11 @@ static AstNode *ast_parse_statement(ParseContext *pc) {
937 return res;917 return res;
938 }918 }
939919
940 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);920 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
941 if (noasync != nullptr) {921 if (nosuspend != nullptr) {
942 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);922 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
943 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);923 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
944 res->data.noasync_expr.expr = statement;924 res->data.nosuspend_expr.expr = statement;
945 return res;925 return res;
946 }926 }
947927
...@@ -1289,7 +1269,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {...@@ -1289,7 +1269,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
1289// / IfExpr1269// / IfExpr
1290// / KEYWORD_break BreakLabel? Expr?1270// / KEYWORD_break BreakLabel? Expr?
1291// / KEYWORD_comptime Expr1271// / KEYWORD_comptime Expr
1292// / KEYWORD_noasync Expr1272// / KEYWORD_nosuspend Expr
1293// / KEYWORD_continue BreakLabel?1273// / KEYWORD_continue BreakLabel?
1294// / KEYWORD_resume Expr1274// / KEYWORD_resume Expr
1295// / KEYWORD_return Expr?1275// / KEYWORD_return Expr?
...@@ -1324,11 +1304,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {...@@ -1324,11 +1304,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
1324 return res;1304 return res;
1325 }1305 }
13261306
1327 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);1307 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
1328 if (noasync != nullptr) {1308 if (nosuspend != nullptr) {
1329 AstNode *expr = ast_expect(pc, ast_parse_expr);1309 AstNode *expr = ast_expect(pc, ast_parse_expr);
1330 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);1310 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
1331 res->data.noasync_expr.expr = expr;1311 res->data.nosuspend_expr.expr = expr;
1332 return res;1312 return res;
1333 }1313 }
13341314
...@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {...@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
1524static AstNode *ast_parse_suffix_expr(ParseContext *pc) {1504static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1525 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);1505 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
1526 if (async_token) {1506 if (async_token) {
1527 if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
1528 // HACK: If we see the keyword `fn`, then we assume that
1529 // we are parsing an async fn proto, and not a call.
1530 // We therefore put back all tokens consumed by the async
1531 // prefix...
1532 put_back_token(pc);
1533 put_back_token(pc);
1534
1535 return ast_parse_primary_type_expr(pc);
1536 }
1537
1538 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);1507 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
1539 while (true) {1508 while (true) {
1540 AstNode *suffix = ast_parse_suffix_op(pc);1509 AstNode *suffix = ast_parse_suffix_op(pc);
...@@ -1640,7 +1609,6 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {...@@ -1640,7 +1609,6 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
1640// / IfTypeExpr1609// / IfTypeExpr
1641// / INTEGER1610// / INTEGER
1642// / KEYWORD_comptime TypeExpr1611// / KEYWORD_comptime TypeExpr
1643// / KEYWORD_noasync TypeExpr
1644// / KEYWORD_error DOT IDENTIFIER1612// / KEYWORD_error DOT IDENTIFIER
1645// / KEYWORD_false1613// / KEYWORD_false
1646// / KEYWORD_null1614// / KEYWORD_null
...@@ -1742,14 +1710,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {...@@ -1742,14 +1710,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
1742 return res;1710 return res;
1743 }1711 }
17441712
1745 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
1746 if (noasync != nullptr) {
1747 AstNode *expr = ast_expect(pc, ast_parse_type_expr);
1748 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
1749 res->data.noasync_expr.expr = expr;
1750 return res;
1751 }
1752
1753 Token *error = eat_token_if(pc, TokenIdKeywordError);1713 Token *error = eat_token_if(pc, TokenIdKeywordError);
1754 if (error != nullptr) {1714 if (error != nullptr) {
1755 Token *dot = expect_token(pc, TokenIdDot);1715 Token *dot = expect_token(pc, TokenIdDot);
...@@ -2187,23 +2147,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {...@@ -2187,23 +2147,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
2187 return res;2147 return res;
2188}2148}
21892149
2190// FnCC
2191// <- KEYWORD_extern
2192// / KEYWORD_async
2193static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc) {
2194 AstNodeFnProto res = {};
2195 if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
2196 res.is_async = true;
2197 return Optional<AstNodeFnProto>::some(res);
2198 }
2199 if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
2200 res.is_extern = true;
2201 return Optional<AstNodeFnProto>::some(res);
2202 }
2203
2204 return Optional<AstNodeFnProto>::none();
2205}
2206
2207// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType2150// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
2208static AstNode *ast_parse_param_decl(ParseContext *pc) {2151static AstNode *ast_parse_param_decl(ParseContext *pc) {
2209 Buf doc_comments = BUF_INIT;2152 Buf doc_comments = BUF_INIT;
...@@ -3189,7 +3132,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -3189,7 +3132,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
3189 case NodeTypeCompTime:3132 case NodeTypeCompTime:
3190 visit_field(&node->data.comptime_expr.expr, visit, context);3133 visit_field(&node->data.comptime_expr.expr, visit, context);
3191 break;3134 break;
3192 case NodeTypeNoAsync:3135 case NodeTypeNoSuspend:
3193 visit_field(&node->data.comptime_expr.expr, visit, context);3136 visit_field(&node->data.comptime_expr.expr, visit, context);
3194 break;3137 break;
3195 case NodeTypeBreak:3138 case NodeTypeBreak:
src/tokenizer.cpp+2-2
...@@ -128,8 +128,8 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -128,8 +128,8 @@ static const struct ZigKeyword zig_keywords[] = {
128 {"if", TokenIdKeywordIf},128 {"if", TokenIdKeywordIf},
129 {"inline", TokenIdKeywordInline},129 {"inline", TokenIdKeywordInline},
130 {"noalias", TokenIdKeywordNoAlias},130 {"noalias", TokenIdKeywordNoAlias},
131 {"noasync", TokenIdKeywordNoAsync},
132 {"noinline", TokenIdKeywordNoInline},131 {"noinline", TokenIdKeywordNoInline},
132 {"nosuspend", TokenIdKeywordNoSuspend},
133 {"null", TokenIdKeywordNull},133 {"null", TokenIdKeywordNull},
134 {"or", TokenIdKeywordOr},134 {"or", TokenIdKeywordOr},
135 {"orelse", TokenIdKeywordOrElse},135 {"orelse", TokenIdKeywordOrElse},
...@@ -1589,8 +1589,8 @@ const char * token_name(TokenId id) {...@@ -1589,8 +1589,8 @@ const char * token_name(TokenId id) {
1589 case TokenIdKeywordIf: return "if";1589 case TokenIdKeywordIf: return "if";
1590 case TokenIdKeywordInline: return "inline";1590 case TokenIdKeywordInline: return "inline";
1591 case TokenIdKeywordNoAlias: return "noalias";1591 case TokenIdKeywordNoAlias: return "noalias";
1592 case TokenIdKeywordNoAsync: return "noasync";
1593 case TokenIdKeywordNoInline: return "noinline";1592 case TokenIdKeywordNoInline: return "noinline";
1593 case TokenIdKeywordNoSuspend: return "nosuspend";
1594 case TokenIdKeywordNull: return "null";1594 case TokenIdKeywordNull: return "null";
1595 case TokenIdKeywordOr: return "or";1595 case TokenIdKeywordOr: return "or";
1596 case TokenIdKeywordOrElse: return "orelse";1596 case TokenIdKeywordOrElse: return "orelse";
src/tokenizer.hpp+1-1
...@@ -78,7 +78,7 @@ enum TokenId {...@@ -78,7 +78,7 @@ enum TokenId {
78 TokenIdKeywordNoInline,78 TokenIdKeywordNoInline,
79 TokenIdKeywordLinkSection,79 TokenIdKeywordLinkSection,
80 TokenIdKeywordNoAlias,80 TokenIdKeywordNoAlias,
81 TokenIdKeywordNoAsync,81 TokenIdKeywordNoSuspend,
82 TokenIdKeywordNull,82 TokenIdKeywordNull,
83 TokenIdKeywordOr,83 TokenIdKeywordOr,
84 TokenIdKeywordOrElse,84 TokenIdKeywordOrElse,
test/compile_errors.zig+105-16
...@@ -2,6 +2,29 @@ const tests = @import("tests.zig");...@@ -2,6 +2,29 @@ const tests = @import("tests.zig");
2const std = @import("std");2const std = @import("std");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add("call assigned to constant",
6 \\const Foo = struct {
7 \\ x: i32,
8 \\};
9 \\fn foo() Foo {
10 \\ return .{ .x = 42 };
11 \\}
12 \\fn bar(val: var) Foo {
13 \\ return .{ .x = val };
14 \\}
15 \\export fn entry() void {
16 \\ const baz: Foo = undefined;
17 \\ baz = foo();
18 \\}
19 \\export fn entry1() void {
20 \\ const baz: Foo = undefined;
21 \\ baz = bar(42);
22 \\}
23 , &[_][]const u8{
24 "tmp.zig:12:14: error: cannot assign to constant",
25 "tmp.zig:16:14: error: cannot assign to constant",
26 });
27
5 cases.add("invalid pointer syntax",28 cases.add("invalid pointer syntax",
6 \\export fn foo() void {29 \\export fn foo() void {
7 \\ var guid: *:0 const u8 = undefined;30 \\ var guid: *:0 const u8 = undefined;
...@@ -243,9 +266,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -243,9 +266,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
243 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",266 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",
244 });267 });
245268
246 cases.addTest("combination of noasync and async",269 cases.addTest("combination of nosuspend and async",
247 \\export fn entry() void {270 \\export fn entry() void {
248 \\ noasync {271 \\ nosuspend {
249 \\ const bar = async foo();272 \\ const bar = async foo();
250 \\ suspend;273 \\ suspend;
251 \\ resume bar;274 \\ resume bar;
...@@ -253,9 +276,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -253,9 +276,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
253 \\}276 \\}
254 \\fn foo() void {}277 \\fn foo() void {}
255 , &[_][]const u8{278 , &[_][]const u8{
256 "tmp.zig:3:21: error: async call in noasync scope",279 "tmp.zig:3:21: error: async call in nosuspend scope",
257 "tmp.zig:4:9: error: suspend in noasync scope",280 "tmp.zig:4:9: error: suspend in nosuspend scope",
258 "tmp.zig:5:9: error: resume in noasync scope",281 "tmp.zig:5:9: error: resume in nosuspend scope",
259 });282 });
260283
261 cases.add("atomicrmw with bool op not .Xchg",284 cases.add("atomicrmw with bool op not .Xchg",
...@@ -779,7 +802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -779,7 +802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
779 });802 });
780803
781 cases.add("exported async function",804 cases.add("exported async function",
782 \\export async fn foo() void {}805 \\export fn foo() callconv(.Async) void {}
783 , &[_][]const u8{806 , &[_][]const u8{
784 "tmp.zig:1:1: error: exported function cannot be async",807 "tmp.zig:1:1: error: exported function cannot be async",
785 });808 });
...@@ -1258,11 +1281,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1258,11 +1281,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12581281
1259 cases.add("bad alignment in @asyncCall",1282 cases.add("bad alignment in @asyncCall",
1260 \\export fn entry() void {1283 \\export fn entry() void {
1261 \\ var ptr: async fn () void = func;1284 \\ var ptr: fn () callconv(.Async) void = func;
1262 \\ var bytes: [64]u8 = undefined;1285 \\ var bytes: [64]u8 = undefined;
1263 \\ _ = @asyncCall(&bytes, {}, ptr);1286 \\ _ = @asyncCall(&bytes, {}, ptr);
1264 \\}1287 \\}
1265 \\async fn func() void {}1288 \\fn func() callconv(.Async) void {}
1266 , &[_][]const u8{1289 , &[_][]const u8{
1267 "tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'",1290 "tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'",
1268 });1291 });
...@@ -1408,7 +1431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1408,7 +1431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1408 \\export fn entry() void {1431 \\export fn entry() void {
1409 \\ _ = async amain();1432 \\ _ = async amain();
1410 \\}1433 \\}
1411 \\async fn amain() void {1434 \\fn amain() callconv(.Async) void {
1412 \\ other();1435 \\ other();
1413 \\}1436 \\}
1414 \\fn other() void {1437 \\fn other() void {
...@@ -1424,7 +1447,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1424,7 +1447,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1424 \\export fn entry() void {1447 \\export fn entry() void {
1425 \\ _ = async amain();1448 \\ _ = async amain();
1426 \\}1449 \\}
1427 \\async fn amain() void {1450 \\fn amain() callconv(.Async) void {
1428 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;1451 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
1429 \\}1452 \\}
1430 , &[_][]const u8{1453 , &[_][]const u8{
...@@ -1451,7 +1474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1451,7 +1474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1451 \\ var ptr = afunc;1474 \\ var ptr = afunc;
1452 \\ _ = ptr();1475 \\ _ = ptr();
1453 \\}1476 \\}
1454 \\async fn afunc() void {}1477 \\fn afunc() callconv(.Async) void {}
1455 , &[_][]const u8{1478 , &[_][]const u8{
1456 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",1479 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
1457 });1480 });
...@@ -1462,7 +1485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1462,7 +1485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1462 \\ _ = async ptr();1485 \\ _ = async ptr();
1463 \\}1486 \\}
1464 \\1487 \\
1465 \\async fn afunc() void { }1488 \\fn afunc() callconv(.Async) void { }
1466 , &[_][]const u8{1489 , &[_][]const u8{
1467 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",1490 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
1468 });1491 });
...@@ -3051,7 +3074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3051,7 +3074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3051 \\export fn entry() void {3074 \\export fn entry() void {
3052 \\ _ = async foo();3075 \\ _ = async foo();
3053 \\}3076 \\}
3054 \\async fn foo() void {3077 \\fn foo() void {
3055 \\ suspend {3078 \\ suspend {
3056 \\ suspend {3079 \\ suspend {
3057 \\ }3080 \\ }
...@@ -3099,7 +3122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3099,7 +3122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3099 \\export fn entry() void {3122 \\export fn entry() void {
3100 \\ _ = async amain();3123 \\ _ = async amain();
3101 \\}3124 \\}
3102 \\async fn amain() void {3125 \\fn amain() callconv(.Async) void {
3103 \\ return error.ShouldBeCompileError;3126 \\ return error.ShouldBeCompileError;
3104 \\}3127 \\}
3105 , &[_][]const u8{3128 , &[_][]const u8{
...@@ -3569,7 +3592,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3569,7 +3592,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3569 });3592 });
35703593
3571 cases.add("attempt to use 0 bit type in extern fn",3594 cases.add("attempt to use 0 bit type in extern fn",
3572 \\extern fn foo(ptr: extern fn(*void) void) void;3595 \\extern fn foo(ptr: fn(*void) callconv(.C) void) void;
3573 \\3596 \\
3574 \\export fn entry() void {3597 \\export fn entry() void {
3575 \\ foo(bar);3598 \\ foo(bar);
...@@ -3580,7 +3603,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3580,7 +3603,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3580 \\ bar(&{});3603 \\ bar(&{});
3581 \\}3604 \\}
3582 , &[_][]const u8{3605 , &[_][]const u8{
3583 "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",3606 "tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
3584 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",3607 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
3585 });3608 });
35863609
...@@ -5352,6 +5375,50 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5352,6 +5375,50 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5352 break :x tc;5375 break :x tc;
5353 });5376 });
53545377
5378 cases.addCase(x: {
5379 const tc = cases.create("multiple files with private member instance function (canonical invocation) error",
5380 \\const Foo = @import("foo.zig",).Foo;
5381 \\
5382 \\export fn callPrivFunction() void {
5383 \\ var foo = Foo{};
5384 \\ Foo.privateFunction(foo);
5385 \\}
5386 , &[_][]const u8{
5387 "tmp.zig:5:8: error: 'privateFunction' is private",
5388 "foo.zig:2:5: note: declared here",
5389 });
5390
5391 tc.addSourceFile("foo.zig",
5392 \\pub const Foo = struct {
5393 \\ fn privateFunction(self: *Foo) void { }
5394 \\};
5395 );
5396
5397 break :x tc;
5398 });
5399
5400 cases.addCase(x: {
5401 const tc = cases.create("multiple files with private member instance function error",
5402 \\const Foo = @import("foo.zig",).Foo;
5403 \\
5404 \\export fn callPrivFunction() void {
5405 \\ var foo = Foo{};
5406 \\ foo.privateFunction();
5407 \\}
5408 , &[_][]const u8{
5409 "tmp.zig:5:8: error: 'privateFunction' is private",
5410 "foo.zig:2:5: note: declared here",
5411 });
5412
5413 tc.addSourceFile("foo.zig",
5414 \\pub const Foo = struct {
5415 \\ fn privateFunction(self: *Foo) void { }
5416 \\};
5417 );
5418
5419 break :x tc;
5420 });
5421
5355 cases.add("container init with non-type",5422 cases.add("container init with non-type",
5356 \\const zero: i32 = 0;5423 \\const zero: i32 = 0;
5357 \\const a = zero{1};5424 \\const a = zero{1};
...@@ -7330,4 +7397,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7330,4 +7397,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7330 ":3:18: error: expected type '[*:0]const u8', found '*[64]u8'",7397 ":3:18: error: expected type '[*:0]const u8', found '*[64]u8'",
7331 ":3:18: note: destination pointer requires a terminating '0' sentinel",7398 ":3:18: note: destination pointer requires a terminating '0' sentinel",
7332 });7399 });
7400
7401 cases.add("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
7402 \\fn ignore(comptime param: var) void {}
7403 \\
7404 \\export fn foo() void {
7405 \\ const MyStruct = struct {
7406 \\ wrong_type: []u8 = "foo",
7407 \\ };
7408 \\
7409 \\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);
7410 \\}
7411 , &[_][]const u8{
7412 ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
7413 });
7414
7415 cases.add("integer underflow error",
7416 \\export fn entry() void {
7417 \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1);
7418 \\}
7419 , &[_][]const u8{
7420 ":2:75: error: operation caused overflow",
7421 });
7333}7422}
test/run_translated_c.zig+13
...@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
243 \\ return 0;243 \\ return 0;
244 \\}244 \\}
245 , "");245 , "");
246
247 cases.add("scoped typedef",
248 \\int main(int argc, char **argv) {
249 \\ typedef int Foo;
250 \\ typedef Foo Bar;
251 \\ typedef void (*func)(int);
252 \\ typedef int uint32_t;
253 \\ uint32_t a;
254 \\ Foo i;
255 \\ Bar j;
256 \\ return 0;
257 \\}
258 , "");
246}259}
test/runtime_safety.zig+6-6
...@@ -234,12 +234,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -234,12 +234,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
234 \\}234 \\}
235 );235 );
236236
237 cases.addRuntimeSafety("noasync function call, callee suspends",237 cases.addRuntimeSafety("nosuspend function call, callee suspends",
238 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {238 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
239 \\ @import("std").os.exit(126);239 \\ @import("std").os.exit(126);
240 \\}240 \\}
241 \\pub fn main() void {241 \\pub fn main() void {
242 \\ _ = noasync add(101, 100);242 \\ _ = nosuspend add(101, 100);
243 \\}243 \\}
244 \\fn add(a: i32, b: i32) i32 {244 \\fn add(a: i32, b: i32) i32 {
245 \\ if (a > 100) {245 \\ if (a > 100) {
...@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
282 \\ var ptr = other;282 \\ var ptr = other;
283 \\ var frame = @asyncCall(&bytes, {}, ptr);283 \\ var frame = @asyncCall(&bytes, {}, ptr);
284 \\}284 \\}
285 \\async fn other() void {285 \\fn other() callconv(.Async) void {
286 \\ suspend;286 \\ suspend;
287 \\}287 \\}
288 );288 );
...@@ -874,16 +874,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -874,16 +874,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
874 \\ return &failing_frame;874 \\ return &failing_frame;
875 \\}875 \\}
876 \\876 \\
877 \\async fn failing() anyerror!void {877 \\fn failing() anyerror!void {
878 \\ suspend;878 \\ suspend;
879 \\ return second();879 \\ return second();
880 \\}880 \\}
881 \\881 \\
882 \\async fn second() anyerror!void {882 \\fn second() callconv(.Async) anyerror!void {
883 \\ return error.Fail;883 \\ return error.Fail;
884 \\}884 \\}
885 \\885 \\
886 \\async fn printTrace(p: anyframe->anyerror!void) void {886 \\fn printTrace(p: anyframe->anyerror!void) void {
887 \\ (await p) catch unreachable;887 \\ (await p) catch unreachable;
888 \\}888 \\}
889 );889 );
test/stack_traces.zig+1-1
...@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {...@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
282 \\source.zig:10:8: [address] in main (test)282 \\source.zig:10:8: [address] in main (test)
283 \\ foo();283 \\ foo();
284 \\ ^284 \\ ^
285 \\start.zig:250:29: [address] in std.start.posixCallMainAndExit (test)285 \\start.zig:249:29: [address] in std.start.posixCallMainAndExit (test)
286 \\ return root.main();286 \\ return root.main();
287 \\ ^287 \\ ^
288 \\start.zig:123:5: [address] in std.start._start (test)288 \\start.zig:123:5: [address] in std.start._start (test)
test/stage1/behavior/async_fn.zig+33-37
...@@ -112,12 +112,12 @@ test "@frameSize" {...@@ -112,12 +112,12 @@ test "@frameSize" {
112 const S = struct {112 const S = struct {
113 fn doTheTest() void {113 fn doTheTest() void {
114 {114 {
115 var ptr = @ptrCast(async fn (i32) void, other);115 var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
116 const size = @frameSize(ptr);116 const size = @frameSize(ptr);
117 expect(size == @sizeOf(@Frame(other)));117 expect(size == @sizeOf(@Frame(other)));
118 }118 }
119 {119 {
120 var ptr = @ptrCast(async fn () void, first);120 var ptr = @ptrCast(fn () callconv(.Async) void, first);
121 const size = @frameSize(ptr);121 const size = @frameSize(ptr);
122 expect(size == @sizeOf(@Frame(first)));122 expect(size == @sizeOf(@Frame(first)));
123 }123 }
...@@ -184,7 +184,7 @@ test "coroutine suspend with block" {...@@ -184,7 +184,7 @@ test "coroutine suspend with block" {
184184
185var a_promise: anyframe = undefined;185var a_promise: anyframe = undefined;
186var global_result = false;186var global_result = false;
187async fn testSuspendBlock() void {187fn testSuspendBlock() callconv(.Async) void {
188 suspend {188 suspend {
189 comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock));189 comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock));
190 a_promise = @frame();190 a_promise = @frame();
...@@ -209,14 +209,14 @@ test "coroutine await" {...@@ -209,14 +209,14 @@ test "coroutine await" {
209 expect(await_final_result == 1234);209 expect(await_final_result == 1234);
210 expect(std.mem.eql(u8, &await_points, "abcdefghi"));210 expect(std.mem.eql(u8, &await_points, "abcdefghi"));
211}211}
212async fn await_amain() void {212fn await_amain() callconv(.Async) void {
213 await_seq('b');213 await_seq('b');
214 var p = async await_another();214 var p = async await_another();
215 await_seq('e');215 await_seq('e');
216 await_final_result = await p;216 await_final_result = await p;
217 await_seq('h');217 await_seq('h');
218}218}
219async fn await_another() i32 {219fn await_another() callconv(.Async) i32 {
220 await_seq('c');220 await_seq('c');
221 suspend {221 suspend {
222 await_seq('d');222 await_seq('d');
...@@ -243,14 +243,14 @@ test "coroutine await early return" {...@@ -243,14 +243,14 @@ test "coroutine await early return" {
243 expect(early_final_result == 1234);243 expect(early_final_result == 1234);
244 expect(std.mem.eql(u8, &early_points, "abcdef"));244 expect(std.mem.eql(u8, &early_points, "abcdef"));
245}245}
246async fn early_amain() void {246fn early_amain() callconv(.Async) void {
247 early_seq('b');247 early_seq('b');
248 var p = async early_another();248 var p = async early_another();
249 early_seq('d');249 early_seq('d');
250 early_final_result = await p;250 early_final_result = await p;
251 early_seq('e');251 early_seq('e');
252}252}
253async fn early_another() i32 {253fn early_another() callconv(.Async) i32 {
254 early_seq('c');254 early_seq('c');
255 return 1234;255 return 1234;
256}256}
...@@ -266,7 +266,7 @@ fn early_seq(c: u8) void {...@@ -266,7 +266,7 @@ fn early_seq(c: u8) void {
266test "async function with dot syntax" {266test "async function with dot syntax" {
267 const S = struct {267 const S = struct {
268 var y: i32 = 1;268 var y: i32 = 1;
269 async fn foo() void {269 fn foo() callconv(.Async) void {
270 y += 1;270 y += 1;
271 suspend;271 suspend;
272 }272 }
...@@ -278,7 +278,7 @@ test "async function with dot syntax" {...@@ -278,7 +278,7 @@ test "async function with dot syntax" {
278test "async fn pointer in a struct field" {278test "async fn pointer in a struct field" {
279 var data: i32 = 1;279 var data: i32 = 1;
280 const Foo = struct {280 const Foo = struct {
281 bar: async fn (*i32) void,281 bar: fn (*i32) callconv(.Async) void,
282 };282 };
283 var foo = Foo{ .bar = simpleAsyncFn2 };283 var foo = Foo{ .bar = simpleAsyncFn2 };
284 var bytes: [64]u8 align(16) = undefined;284 var bytes: [64]u8 align(16) = undefined;
...@@ -294,8 +294,7 @@ test "async fn pointer in a struct field" {...@@ -294,8 +294,7 @@ test "async fn pointer in a struct field" {
294fn doTheAwait(f: anyframe->void) void {294fn doTheAwait(f: anyframe->void) void {
295 await f;295 await f;
296}296}
297297fn simpleAsyncFn2(y: *i32) callconv(.Async) void {
298async fn simpleAsyncFn2(y: *i32) void {
299 defer y.* += 2;298 defer y.* += 2;
300 y.* += 1;299 y.* += 1;
301 suspend;300 suspend;
...@@ -303,11 +302,10 @@ async fn simpleAsyncFn2(y: *i32) void {...@@ -303,11 +302,10 @@ async fn simpleAsyncFn2(y: *i32) void {
303302
304test "@asyncCall with return type" {303test "@asyncCall with return type" {
305 const Foo = struct {304 const Foo = struct {
306 bar: async fn () i32,305 bar: fn () callconv(.Async) i32,
307306
308 var global_frame: anyframe = undefined;307 var global_frame: anyframe = undefined;
309308 fn middle() callconv(.Async) i32 {
310 async fn middle() i32 {
311 return afunc();309 return afunc();
312 }310 }
313311
...@@ -338,8 +336,7 @@ test "async fn with inferred error set" {...@@ -338,8 +336,7 @@ test "async fn with inferred error set" {
338 resume global_frame;336 resume global_frame;
339 std.testing.expectError(error.Fail, result);337 std.testing.expectError(error.Fail, result);
340 }338 }
341339 fn middle() callconv(.Async) !void {
342 async fn middle() !void {
343 var f = async middle2();340 var f = async middle2();
344 return await f;341 return await f;
345 }342 }
...@@ -376,11 +373,11 @@ fn nonFailing() (anyframe->anyerror!void) {...@@ -376,11 +373,11 @@ fn nonFailing() (anyframe->anyerror!void) {
376 Static.frame = async suspendThenFail();373 Static.frame = async suspendThenFail();
377 return &Static.frame;374 return &Static.frame;
378}375}
379async fn suspendThenFail() anyerror!void {376fn suspendThenFail() callconv(.Async) anyerror!void {
380 suspend;377 suspend;
381 return error.Fail;378 return error.Fail;
382}379}
383async fn printTrace(p: anyframe->(anyerror!void)) void {380fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void {
384 (await p) catch |e| {381 (await p) catch |e| {
385 std.testing.expect(e == error.Fail);382 std.testing.expect(e == error.Fail);
386 if (@errorReturnTrace()) |trace| {383 if (@errorReturnTrace()) |trace| {
...@@ -397,7 +394,7 @@ test "break from suspend" {...@@ -397,7 +394,7 @@ test "break from suspend" {
397 const p = async testBreakFromSuspend(&my_result);394 const p = async testBreakFromSuspend(&my_result);
398 std.testing.expect(my_result == 2);395 std.testing.expect(my_result == 2);
399}396}
400async fn testBreakFromSuspend(my_result: *i32) void {397fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void {
401 suspend {398 suspend {
402 resume @frame();399 resume @frame();
403 }400 }
...@@ -826,7 +823,7 @@ test "cast fn to async fn when it is inferred to be async" {...@@ -826,7 +823,7 @@ test "cast fn to async fn when it is inferred to be async" {
826 var ok = false;823 var ok = false;
827824
828 fn doTheTest() void {825 fn doTheTest() void {
829 var ptr: async fn () i32 = undefined;826 var ptr: fn () callconv(.Async) i32 = undefined;
830 ptr = func;827 ptr = func;
831 var buf: [100]u8 align(16) = undefined;828 var buf: [100]u8 align(16) = undefined;
832 var result: i32 = undefined;829 var result: i32 = undefined;
...@@ -854,7 +851,7 @@ test "cast fn to async fn when it is inferred to be async, awaited directly" {...@@ -854,7 +851,7 @@ test "cast fn to async fn when it is inferred to be async, awaited directly" {
854 var ok = false;851 var ok = false;
855852
856 fn doTheTest() void {853 fn doTheTest() void {
857 var ptr: async fn () i32 = undefined;854 var ptr: fn () callconv(.Async) i32 = undefined;
858 ptr = func;855 ptr = func;
859 var buf: [100]u8 align(16) = undefined;856 var buf: [100]u8 align(16) = undefined;
860 var result: i32 = undefined;857 var result: i32 = undefined;
...@@ -958,8 +955,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {...@@ -958,8 +955,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
958 resume global_frame;955 resume global_frame;
959 std.testing.expectError(error.Fail, result);956 std.testing.expectError(error.Fail, result);
960 }957 }
961958 fn middle() callconv(.Async) !void {
962 async fn middle() !void {
963 var f = async middle2();959 var f = async middle2();
964 return await f;960 return await f;
965 }961 }
...@@ -993,7 +989,7 @@ test "@asyncCall with actual frame instead of byte buffer" {...@@ -993,7 +989,7 @@ test "@asyncCall with actual frame instead of byte buffer" {
993989
994test "@asyncCall using the result location inside the frame" {990test "@asyncCall using the result location inside the frame" {
995 const S = struct {991 const S = struct {
996 async fn simple2(y: *i32) i32 {992 fn simple2(y: *i32) callconv(.Async) i32 {
997 defer y.* += 2;993 defer y.* += 2;
998 y.* += 1;994 y.* += 1;
999 suspend;995 suspend;
...@@ -1005,7 +1001,7 @@ test "@asyncCall using the result location inside the frame" {...@@ -1005,7 +1001,7 @@ test "@asyncCall using the result location inside the frame" {
1005 };1001 };
1006 var data: i32 = 1;1002 var data: i32 = 1;
1007 const Foo = struct {1003 const Foo = struct {
1008 bar: async fn (*i32) i32,1004 bar: fn (*i32) callconv(.Async) i32,
1009 };1005 };
1010 var foo = Foo{ .bar = S.simple2 };1006 var foo = Foo{ .bar = S.simple2 };
1011 var bytes: [64]u8 align(16) = undefined;1007 var bytes: [64]u8 align(16) = undefined;
...@@ -1090,10 +1086,10 @@ test "recursive call of await @asyncCall with struct return type" {...@@ -1090,10 +1086,10 @@ test "recursive call of await @asyncCall with struct return type" {
1090 expect(res.z == 3);1086 expect(res.z == 3);
1091}1087}
10921088
1093test "noasync function call" {1089test "nosuspend function call" {
1094 const S = struct {1090 const S = struct {
1095 fn doTheTest() void {1091 fn doTheTest() void {
1096 const result = noasync add(50, 100);1092 const result = nosuspend add(50, 100);
1097 expect(result == 150);1093 expect(result == 150);
1098 }1094 }
1099 fn add(a: i32, b: i32) i32 {1095 fn add(a: i32, b: i32) i32 {
...@@ -1115,7 +1111,7 @@ test "await used in expression and awaiting fn with no suspend but async calling...@@ -1115,7 +1111,7 @@ test "await used in expression and awaiting fn with no suspend but async calling
1115 const sum = (await f1) + (await f2);1111 const sum = (await f1) + (await f2);
1116 expect(sum == 10);1112 expect(sum == 10);
1117 }1113 }
1118 async fn add(a: i32, b: i32) i32 {1114 fn add(a: i32, b: i32) callconv(.Async) i32 {
1119 return a + b;1115 return a + b;
1120 }1116 }
1121 };1117 };
...@@ -1130,7 +1126,7 @@ test "await used in expression after a fn call" {...@@ -1130,7 +1126,7 @@ test "await used in expression after a fn call" {
1130 sum = foo() + await f1;1126 sum = foo() + await f1;
1131 expect(sum == 8);1127 expect(sum == 8);
1132 }1128 }
1133 async fn add(a: i32, b: i32) i32 {1129 fn add(a: i32, b: i32) callconv(.Async) i32 {
1134 return a + b;1130 return a + b;
1135 }1131 }
1136 fn foo() i32 {1132 fn foo() i32 {
...@@ -1147,7 +1143,7 @@ test "async fn call used in expression after a fn call" {...@@ -1147,7 +1143,7 @@ test "async fn call used in expression after a fn call" {
1147 sum = foo() + add(3, 4);1143 sum = foo() + add(3, 4);
1148 expect(sum == 8);1144 expect(sum == 8);
1149 }1145 }
1150 async fn add(a: i32, b: i32) i32 {1146 fn add(a: i32, b: i32) callconv(.Async) i32 {
1151 return a + b;1147 return a + b;
1152 }1148 }
1153 fn foo() i32 {1149 fn foo() i32 {
...@@ -1403,7 +1399,7 @@ test "async function call resolves target fn frame, runtime func" {...@@ -1403,7 +1399,7 @@ test "async function call resolves target fn frame, runtime func" {
1403 fn foo() anyerror!void {1399 fn foo() anyerror!void {
1404 const stack_size = 1000;1400 const stack_size = 1000;
1405 var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;1401 var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;
1406 var func: async fn () anyerror!void = bar;1402 var func: fn () callconv(.Async) anyerror!void = bar;
1407 return await @asyncCall(&stack_frame, {}, func);1403 return await @asyncCall(&stack_frame, {}, func);
1408 }1404 }
14091405
...@@ -1511,13 +1507,13 @@ test "take address of temporary async frame" {...@@ -1511,13 +1507,13 @@ test "take address of temporary async frame" {
1511 S.doTheTest();1507 S.doTheTest();
1512}1508}
15131509
1514test "noasync await" {1510test "nosuspend await" {
1515 const S = struct {1511 const S = struct {
1516 var finished = false;1512 var finished = false;
15171513
1518 fn doTheTest() void {1514 fn doTheTest() void {
1519 var frame = async foo(false);1515 var frame = async foo(false);
1520 expect(noasync await frame == 42);1516 expect(nosuspend await frame == 42);
1521 finished = true;1517 finished = true;
1522 }1518 }
15231519
...@@ -1532,7 +1528,7 @@ test "noasync await" {...@@ -1532,7 +1528,7 @@ test "noasync await" {
1532 expect(S.finished);1528 expect(S.finished);
1533}1529}
15341530
1535test "noasync on function calls" {1531test "nosuspend on function calls" {
1536 const S0 = struct {1532 const S0 = struct {
1537 b: i32 = 42,1533 b: i32 = 42,
1538 };1534 };
...@@ -1544,8 +1540,8 @@ test "noasync on function calls" {...@@ -1544,8 +1540,8 @@ test "noasync on function calls" {
1544 return S0{};1540 return S0{};
1545 }1541 }
1546 };1542 };
1547 expectEqual(@as(i32, 42), noasync S1.c().b);1543 expectEqual(@as(i32, 42), nosuspend S1.c().b);
1548 expectEqual(@as(i32, 42), (try noasync S1.d()).b);1544 expectEqual(@as(i32, 42), (try nosuspend S1.d()).b);
1549}1545}
15501546
1551test "avoid forcing frame alignment resolution implicit cast to *c_void" {1547test "avoid forcing frame alignment resolution implicit cast to *c_void" {
...@@ -1561,5 +1557,5 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {...@@ -1561,5 +1557,5 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {
1561 };1557 };
1562 var frame = async S.foo();1558 var frame = async S.foo();
1563 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));1559 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
1564 expect(noasync await frame);1560 expect(nosuspend await frame);
1565}1561}
test/stage1/behavior/await_struct.zig+2-2
...@@ -18,14 +18,14 @@ test "coroutine await struct" {...@@ -18,14 +18,14 @@ test "coroutine await struct" {
18 expect(await_final_result.x == 1234);18 expect(await_final_result.x == 1234);
19 expect(std.mem.eql(u8, &await_points, "abcdefghi"));19 expect(std.mem.eql(u8, &await_points, "abcdefghi"));
20}20}
21async fn await_amain() void {21fn await_amain() callconv(.Async) void {
22 await_seq('b');22 await_seq('b');
23 var p = async await_another();23 var p = async await_another();
24 await_seq('e');24 await_seq('e');
25 await_final_result = await p;25 await_final_result = await p;
26 await_seq('h');26 await_seq('h');
27}27}
28async fn await_another() Foo {28fn await_another() callconv(.Async) Foo {
29 await_seq('c');29 await_seq('c');
30 suspend {30 suspend {
31 await_seq('d');31 await_seq('d');
test/stage1/behavior/cast.zig+11-2
...@@ -762,7 +762,7 @@ test "variable initialization uses result locations properly with regards to the...@@ -762,7 +762,7 @@ test "variable initialization uses result locations properly with regards to the
762762
763test "cast between [*c]T and ?[*:0]T on fn parameter" {763test "cast between [*c]T and ?[*:0]T on fn parameter" {
764 const S = struct {764 const S = struct {
765 const Handler = ?extern fn ([*c]const u8) void;765 const Handler = ?fn ([*c]const u8) callconv(.C) void;
766 fn addCallback(handler: Handler) void {}766 fn addCallback(handler: Handler) void {}
767767
768 fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}768 fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}
...@@ -823,7 +823,16 @@ test "peer type resolve array pointer and unknown pointer" {...@@ -823,7 +823,16 @@ test "peer type resolve array pointer and unknown pointer" {
823823
824 comptime expect(@TypeOf(&array, const_ptr) == [*]const u8);824 comptime expect(@TypeOf(&array, const_ptr) == [*]const u8);
825 comptime expect(@TypeOf(const_ptr, &array) == [*]const u8);825 comptime expect(@TypeOf(const_ptr, &array) == [*]const u8);
826 826
827 comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);827 comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
828 comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);828 comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
829}829}
830
831test "comptime float casts" {
832 const a = @intToFloat(comptime_float, 1);
833 expect(a == 1);
834 expect(@TypeOf(a) == comptime_float);
835 const b = @floatToInt(comptime_int, 2);
836 expect(b == 2);
837 expect(@TypeOf(b) == comptime_int);
838}
test/standalone/main_return_error/error_u8.zig+1-3
...@@ -1,6 +1,4 @@...@@ -1,6 +1,4 @@
1const Err = error {1const Err = error{Foo};
2 Foo
3};
42
5pub fn main() !u8 {3pub fn main() !u8 {
6 return Err.Foo;4 return Err.Foo;
test/standalone/main_return_error/error_u8_non_zero.zig+5-2
...@@ -1,6 +1,9 @@...@@ -1,6 +1,9 @@
1const Err = error { Foo };1const Err = error{Foo};
22
3fn foo() u8 { var x = @intCast(u8, 9); return x; }3fn foo() u8 {
4 var x = @intCast(u8, 9);
5 return x;
6}
47
5pub fn main() !u8 {8pub fn main() !u8 {
6 if (foo() == 7) return Err.Foo;9 if (foo() == 7) return Err.Foo;
tools/zig-gdb.py created+39
...@@ -0,0 +1,39 @@
1# pretty printing for stage1
2# put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically
3
4import gdb.printing
5
6class ZigListPrinter:
7 def __init__(self, val):
8 self.val = val
9
10 def to_string(self):
11 return '%s of length %d, capacity %d' % (self.val.type.name, int(self.val['length']), int(self.val['capacity']))
12
13 def children(self):
14 def it(ziglist):
15 for i in range(int(ziglist.val['length'])):
16 item = ziglist.val['items'] + i
17 yield ('[%d]' % i, item.dereference())
18 return it(self)
19
20 def display_hint(self):
21 return 'array'
22
23# handle both Buf and ZigList<char> because Buf* doesn't work otherwise (gdb bug?)
24class BufPrinter:
25 def __init__(self, val):
26 self.val = val['list'] if val.type.name == 'Buf' else val
27
28 def to_string(self):
29 return self.val['items'].string(length=int(self.val['length']))
30
31 def display_hint(self):
32 return 'string'
33
34pp = gdb.printing.RegexpCollectionPrettyPrinter('zig')
35pp.add_printer('Buf', '^Buf$', BufPrinter)
36pp.add_printer('ZigList<char>', '^ZigList<char>$', BufPrinter)
37pp.add_printer('ZigList', '^ZigList<.*>$', ZigListPrinter)
38
39gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)