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
800800 .Keyword_for,
801801 .Keyword_if,
802802 .Keyword_inline,
803 .Keyword_nakedcc,
804803 .Keyword_noalias,
805 .Keyword_noasync,
806804 .Keyword_noinline,
805 .Keyword_nosuspend,
807806 .Keyword_or,
808807 .Keyword_orelse,
809808 .Keyword_packed,
......@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
813812 .Keyword_return,
814813 .Keyword_linksection,
815814 .Keyword_callconv,
816 .Keyword_stdcallcc,
817815 .Keyword_struct,
818816 .Keyword_suspend,
819817 .Keyword_switch,
doc/langref.html.in+16-12
......@@ -1565,7 +1565,7 @@ value == null{#endsyntax#}</pre>
15651565const array1 = [_]u32{1,2};
15661566const array2 = [_]u32{3,4};
15671567const 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>
15691569 </td>
15701570 </tr>
15711571 <tr>
......@@ -6713,7 +6713,7 @@ const assert = std.debug.assert;
67136713test "async fn pointer in a struct field" {
67146714 var data: i32 = 1;
67156715 const Foo = struct {
6716 bar: async fn (*i32) void,
6716 bar: fn (*i32) callconv(.Async) void,
67176717 };
67186718 var foo = Foo{ .bar = func };
67196719 var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
......@@ -6723,7 +6723,7 @@ test "async fn pointer in a struct field" {
67236723 assert(data == 4);
67246724}
67256725
6726async fn func(y: *i32) void {
6726fn func(y: *i32) void {
67276727 defer y.* += 2;
67286728 y.* += 1;
67296729 suspend;
......@@ -8189,9 +8189,7 @@ fn List(comptime T: type) type {
81898189 {#code_end#}
81908190 <p>
81918191 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 struct
8193 type instead. See
8194 <a href="https://github.com/ziglang/zig/issues/1047">#1047</a> for details.
8192 struct that corresponds to the current file.
81958193 </p>
81968194 {#header_close#}
81978195
......@@ -9990,6 +9988,13 @@ coding style.
99909988 conventions.
99919989 </p>
99929990 <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>
99939998 These are general rules of thumb; if it makes sense to do something different,
99949999 do what makes sense. For example, if there is an established convention such as
999510000 {#syntax#}ENOENT{#endsyntax#}, follow the established convention.
......@@ -9998,6 +10003,7 @@ coding style.
999810003 {#header_open|Examples#}
999910004 {#code_begin|syntax#}
1000010005const namespace_name = @import("dir_name/file_name.zig");
10006const TypeName = @import("dir_name/TypeName.zig");
1000110007var global_var: i32 = undefined;
1000210008const const_name = 42;
1000310009const primitive_type_alias = f32;
......@@ -10088,7 +10094,7 @@ TopLevelDecl
1008810094 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
1008910095 / 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
1009310099VarDecl &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)?
1009810104Statement
1009910105 &lt;- KEYWORD_comptime? VarDecl
1010010106 / KEYWORD_comptime BlockExprStatement
10107 / KEYWORD_nosuspend BlockExprStatement
1010110108 / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
1010210109 / KEYWORD_defer BlockExprStatement
1010310110 / KEYWORD_errdefer BlockExprStatement
......@@ -10154,6 +10161,7 @@ PrimaryExpr
1015410161 / IfExpr
1015510162 / KEYWORD_break BreakLabel? Expr?
1015610163 / KEYWORD_comptime Expr
10164 / KEYWORD_nosuspend Expr
1015710165 / KEYWORD_continue BreakLabel?
1015810166 / KEYWORD_resume Expr
1015910167 / KEYWORD_return Expr?
......@@ -10255,11 +10263,6 @@ WhileContinueExpr &lt;- COLON LPAREN AssignExpr RPAREN
1025510263
1025610264LinkSection &lt;- KEYWORD_linksection LPAREN Expr RPAREN
1025710265
10258# Fn specific
10259FnCC
10260 &lt;- KEYWORD_extern
10261 / KEYWORD_async
10262
1026310266ParamDecl &lt;- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
1026410267
1026510268ParamType
......@@ -10521,6 +10524,7 @@ KEYWORD_for &lt;- 'for' end_of_word
1052110524KEYWORD_if &lt;- 'if' end_of_word
1052210525KEYWORD_inline &lt;- 'inline' end_of_word
1052310526KEYWORD_noalias &lt;- 'noalias' end_of_word
10527KEYWORD_nosuspend &lt;- 'nosuspend' end_of_word
1052410528KEYWORD_null &lt;- 'null' end_of_word
1052510529KEYWORD_or &lt;- 'or' end_of_word
1052610530KEYWORD_orelse &lt;- 'orelse' end_of_word
lib/std/ascii.zig+21-2
......@@ -227,6 +227,8 @@ test "ascii character classes" {
227227 testing.expect(isSpace(' '));
228228}
229229
230/// Allocates a lower case copy of `ascii_string`.
231/// Caller owns returned string and must free with `allocator`.
230232pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {
231233 const result = try allocator.alloc(u8, ascii_string.len);
232234 for (result) |*c, i| {
......@@ -241,6 +243,23 @@ test "allocLowerString" {
241243 std.testing.expect(std.mem.eql(u8, "abcdefghijklmnopqrst0234+💩!", result));
242244}
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.
244263pub fn eqlIgnoreCase(a: []const u8, b: []const u8) bool {
245264 if (a.len != b.len) return false;
246265 for (a) |a_c, i| {
......@@ -255,7 +274,7 @@ test "eqlIgnoreCase" {
255274 std.testing.expect(!eqlIgnoreCase("hElLo!", "helro!"));
256275}
257276
258/// Finds `substr` in `container`, starting at `start_index`.
277/// Finds `substr` in `container`, ignoring case, starting at `start_index`.
259278/// TODO boyer-moore algorithm
260279pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
261280 if (substr.len > container.len) return null;
......@@ -268,7 +287,7 @@ pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: [
268287 return null;
269288}
270289
271/// Finds `substr` in `container`, starting at `start_index`.
290/// Finds `substr` in `container`, ignoring case, starting at index 0.
272291pub fn indexOfIgnoreCase(container: []const u8, substr: []const u8) ?usize {
273292 return indexOfIgnoreCasePos(container, 0, substr);
274293}
lib/std/build.zig+11-6
......@@ -284,11 +284,11 @@ pub const Builder = struct {
284284 return run_step;
285285 }
286286
287 fn dupe(self: *Builder, bytes: []const u8) []u8 {
287 pub fn dupe(self: *Builder, bytes: []const u8) []u8 {
288288 return mem.dupe(self.allocator, u8, bytes) catch unreachable;
289289 }
290290
291 fn dupePath(self: *Builder, bytes: []const u8) []u8 {
291 pub fn dupePath(self: *Builder, bytes: []const u8) []u8 {
292292 const the_copy = self.dupe(bytes);
293293 for (the_copy) |*byte| {
294294 switch (byte.*) {
......@@ -717,7 +717,7 @@ pub const Builder = struct {
717717 return self.invalid_user_input;
718718 }
719719
720 fn spawnChild(self: *Builder, argv: []const []const u8) !void {
720 pub fn spawnChild(self: *Builder, argv: []const []const u8) !void {
721721 return self.spawnChildEnvMap(null, self.env_map, argv);
722722 }
723723
......@@ -843,7 +843,7 @@ pub const Builder = struct {
843843 }) catch unreachable;
844844 }
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 {
847847 if (self.verbose) {
848848 warn("cp {} {} ", .{ source_path, dest_path });
849849 }
......@@ -855,7 +855,7 @@ pub const Builder = struct {
855855 };
856856 }
857857
858 fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
858 pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
859859 return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;
860860 }
861861
......@@ -985,7 +985,7 @@ pub const Builder = struct {
985985 self.search_prefixes.append(search_prefix) catch unreachable;
986986 }
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 {
989989 const base_dir = switch (dir) {
990990 .Prefix => self.install_path,
991991 .Bin => self.exe_dir,
......@@ -1132,6 +1132,7 @@ pub const LibExeObjStep = struct {
11321132 name_prefix: []const u8,
11331133 filter: ?[]const u8,
11341134 single_threaded: bool,
1135 test_evented_io: bool = false,
11351136 code_model: builtin.CodeModel = .default,
11361137
11371138 root_src: ?FileSource,
......@@ -1864,6 +1865,10 @@ pub const LibExeObjStep = struct {
18641865 try zig_args.append(filter);
18651866 }
18661867
1868 if (self.test_evented_io) {
1869 try zig_args.append("--test-evented-io");
1870 }
1871
18671872 if (self.name_prefix.len != 0) {
18681873 try zig_args.append("--test-name-prefix");
18691874 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;
217217pub extern "c" fn utimensat(dirfd: fd_t, pathname: [*:0]const u8, times: *[2]timespec, flags: u32) c_int;
218218pub 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;
221221pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
222222pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
223223pub 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;
99pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
1010pub 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;
1313pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
1414
1515pub const pthread_mutex_t = extern struct {
lib/std/c/freebsd.zig+1-1
......@@ -24,7 +24,7 @@ pub extern "c" fn sendfile(
2424 flags: u32,
2525) 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;
2828pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
2929
3030pub 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)
7575/// See std.elf for constants for this
7676pub 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;
7979pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
8080
8181pub 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;
66extern "c" fn __errno() *c_int;
77pub 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;
1010pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
1111
1212pub 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 {
338338 }
339339
340340 // 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 {
342342 // This chunk might complete some subtrees. For each completed subtree,
343343 // its left child will be the current top entry in the CV stack, and
344344 // its right child will be the current value of `new_cv`. Pop each left
......@@ -346,6 +346,7 @@ pub const Blake3 = struct {
346346 // with the result. After all these merges, push the final value of
347347 // `new_cv` onto the stack. The number of completed subtrees is given
348348 // by the number of trailing 0-bits in the new total number of chunks.
349 var new_cv = first_cv;
349350 var chunk_counter = total_chunks;
350351 while (chunk_counter & 1 == 0) {
351352 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 {
6262 const held = stderr_mutex.acquire();
6363 defer held.release();
6464 const stderr = getStderrStream();
65 noasync stderr.print(fmt, args) catch return;
65 nosuspend stderr.print(fmt, args) catch return;
6666}
6767
6868pub fn getStderrStream() *File.OutStream {
......@@ -112,7 +112,7 @@ pub fn detectTTYConfig() TTY.Config {
112112/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
113113/// TODO multithreaded awareness
114114pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
115 noasync {
115 nosuspend {
116116 const stderr = getStderrStream();
117117 if (builtin.strip_debug_info) {
118118 stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
......@@ -133,7 +133,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
133133/// unbuffered, and ignores any error returned.
134134/// TODO multithreaded awareness
135135pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
136 noasync {
136 nosuspend {
137137 const stderr = getStderrStream();
138138 if (builtin.strip_debug_info) {
139139 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
203203/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
204204/// TODO multithreaded awareness
205205pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
206 noasync {
206 nosuspend {
207207 const stderr = getStderrStream();
208208 if (builtin.strip_debug_info) {
209209 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
261261 resetSegfaultHandler();
262262 }
263263
264 noasync switch (panic_stage) {
264 nosuspend switch (panic_stage) {
265265 0 => {
266266 panic_stage = 1;
267267
......@@ -357,7 +357,7 @@ pub const StackIterator = struct {
357357 else
358358 0;
359359
360 fn next(self: *StackIterator) ?usize {
360 pub fn next(self: *StackIterator) ?usize {
361361 var address = self.next_internal() orelse return null;
362362
363363 if (self.first_address) |first_address| {
......@@ -447,7 +447,7 @@ pub const TTY = struct {
447447 windows_api,
448448
449449 fn setColor(conf: Config, out_stream: var, color: Color) void {
450 noasync switch (conf) {
450 nosuspend switch (conf) {
451451 .no_color => return,
452452 .escape_codes => switch (color) {
453453 .Red => out_stream.writeAll(RED) catch return,
......@@ -604,7 +604,7 @@ fn printLineInfo(
604604 tty_config: TTY.Config,
605605 comptime printLineFromFile: var,
606606) !void {
607 noasync {
607 nosuspend {
608608 tty_config.setColor(out_stream, .White);
609609
610610 if (line_info) |*li| {
......@@ -651,7 +651,7 @@ pub const OpenSelfDebugInfoError = error{
651651
652652/// TODO resources https://github.com/ziglang/zig/issues/4353
653653pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
654 noasync {
654 nosuspend {
655655 if (builtin.strip_debug_info)
656656 return error.MissingDebugInfo;
657657 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 {
672672
673673/// TODO resources https://github.com/ziglang/zig/issues/4353
674674fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {
675 noasync {
675 nosuspend {
676676 const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
677677 errdefer coff_file.close();
678678
......@@ -853,7 +853,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
853853
854854/// TODO resources https://github.com/ziglang/zig/issues/4353
855855pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {
856 noasync {
856 nosuspend {
857857 const mapped_mem = try mapWholeFile(elf_file_path);
858858 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
859859 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
......@@ -1056,7 +1056,7 @@ const MachoSymbol = struct {
10561056};
10571057
10581058fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
1059 noasync {
1059 nosuspend {
10601060 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
10611061 defer file.close();
10621062
......@@ -1418,7 +1418,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
14181418 }
14191419
14201420 fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
1421 noasync {
1421 nosuspend {
14221422 // Translate the VA into an address into this object
14231423 const relocated_address = address - self.base_address;
14241424 assert(relocated_address >= 0x100000000);
......@@ -1643,14 +1643,14 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
16431643 // Translate the VA into an address into this object
16441644 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| {
16471647 return SymbolInfo{
1648 .symbol_name = noasync self.dwarf.getSymbolName(relocated_address) orelse "???",
1648 .symbol_name = nosuspend self.dwarf.getSymbolName(relocated_address) orelse "???",
16491649 .compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) {
16501650 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
16511651 else => return err,
16521652 },
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) {
16541654 error.MissingDebugInfo, error.InvalidDebugInfo => null,
16551655 else => return err,
16561656 },
lib/std/dwarf.zig+29-29
......@@ -121,7 +121,7 @@ const Die = struct {
121121 };
122122 }
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 {
125125 const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
126126 return switch (form_value.*) {
127127 FormValue.String => |value| value,
......@@ -248,17 +248,17 @@ fn readUnitLength(in_stream: var, endian: builtin.Endian, is_64: *bool) !u64 {
248248 }
249249}
250250
251// TODO the noasyncs here are workarounds
251// TODO the nosuspends here are workarounds
252252fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
253253 const buf = try allocator.alloc(u8, size);
254254 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;
256256 return buf;
257257}
258258
259// TODO the noasyncs here are workarounds
259// TODO the nosuspends here are workarounds
260260fn readAddress(in_stream: var, endian: builtin.Endian, is_64: bool) !u64 {
261 return noasync if (is_64)
261 return nosuspend if (is_64)
262262 try in_stream.readInt(u64, endian)
263263 else
264264 @as(u64, try in_stream.readInt(u32, endian));
......@@ -269,29 +269,29 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
269269 return FormValue{ .Block = buf };
270270}
271271
272// TODO the noasyncs here are workarounds
272// TODO the nosuspends here are workarounds
273273fn 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);
275275 return parseFormValueBlockLen(allocator, in_stream, block_len);
276276}
277277
278278fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, endian: builtin.Endian, comptime size: i32) !FormValue {
279279 // 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.
281281 return FormValue{
282282 .Const = Constant{
283283 .signed = signed,
284284 .payload = switch (size) {
285 1 => try noasync in_stream.readInt(u8, endian),
286 2 => try noasync in_stream.readInt(u16, endian),
287 4 => try noasync in_stream.readInt(u32, endian),
288 8 => try noasync in_stream.readInt(u64, endian),
285 1 => try nosuspend in_stream.readInt(u8, endian),
286 2 => try nosuspend in_stream.readInt(u16, endian),
287 4 => try nosuspend in_stream.readInt(u32, endian),
288 8 => try nosuspend in_stream.readInt(u64, endian),
289289 -1 => blk: {
290290 if (signed) {
291 const x = try noasync leb.readILEB128(i64, in_stream);
291 const x = try nosuspend leb.readILEB128(i64, in_stream);
292292 break :blk @bitCast(u64, x);
293293 } else {
294 const x = try noasync leb.readULEB128(u64, in_stream);
294 const x = try nosuspend leb.readULEB128(u64, in_stream);
295295 break :blk x;
296296 }
297297 },
......@@ -301,21 +301,21 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
301301 };
302302}
303303
304// TODO the noasyncs here are workarounds
304// TODO the nosuspends here are workarounds
305305fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {
306306 return FormValue{
307307 .Ref = switch (size) {
308 1 => try noasync in_stream.readInt(u8, endian),
309 2 => try noasync in_stream.readInt(u16, endian),
310 4 => try noasync in_stream.readInt(u32, endian),
311 8 => try noasync in_stream.readInt(u64, endian),
312 -1 => try noasync leb.readULEB128(u64, in_stream),
308 1 => try nosuspend in_stream.readInt(u8, endian),
309 2 => try nosuspend in_stream.readInt(u16, endian),
310 4 => try nosuspend in_stream.readInt(u32, endian),
311 8 => try nosuspend in_stream.readInt(u64, endian),
312 -1 => try nosuspend leb.readULEB128(u64, in_stream),
313313 else => unreachable,
314314 },
315315 };
316316}
317317
318// TODO the noasyncs here are workarounds
318// TODO the nosuspends here are workarounds
319319fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {
320320 return switch (form_id) {
321321 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
323323 FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
324324 FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
325325 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);
327327 return parseFormValueBlockLen(allocator, in_stream, block_len);
328328 },
329329 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
335335 return parseFormValueConstant(allocator, in_stream, signed, endian, -1);
336336 },
337337 FORM_exprloc => {
338 const size = try noasync leb.readULEB128(usize, in_stream);
338 const size = try nosuspend leb.readULEB128(usize, in_stream);
339339 const buf = try readAllocBytes(allocator, in_stream, size);
340340 return FormValue{ .ExprLoc = buf };
341341 },
342 FORM_flag => FormValue{ .Flag = (try noasync in_stream.readByte()) != 0 },
342 FORM_flag => FormValue{ .Flag = (try nosuspend in_stream.readByte()) != 0 },
343343 FORM_flag_present => FormValue{ .Flag = true },
344344 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
350350 FORM_ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),
351351
352352 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
355355 FORM_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
356356 FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
357357 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);
359359 const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
360360 var frame = try allocator.create(F);
361361 defer allocator.destroy(frame);
......@@ -389,7 +389,7 @@ pub const DwarfInfo = struct {
389389 return self.abbrev_table_list.allocator;
390390 }
391391
392 fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {
392 pub fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {
393393 for (di.func_list.span()) |*func| {
394394 if (func.pc_range) |range| {
395395 if (address >= range.start and address < range.end) {
......@@ -578,7 +578,7 @@ pub const DwarfInfo = struct {
578578 }
579579 }
580580
581 fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
581 pub fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
582582 for (di.compile_unit_list.span()) |*compile_unit| {
583583 if (compile_unit.pc_range) |range| {
584584 if (target_address >= range.start and target_address < range.end) return compile_unit;
......@@ -690,7 +690,7 @@ pub const DwarfInfo = struct {
690690 return result;
691691 }
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 {
694694 var stream = io.fixedBufferStream(di.debug_line);
695695 const in = &stream.inStream();
696696 const seekable = &stream.seekableStream();
lib/std/dynamic_library.zig+2-2
......@@ -33,11 +33,11 @@ const LinkMap = extern struct {
3333 pub const Iterator = struct {
3434 current: ?*LinkMap,
3535
36 fn end(self: *Iterator) bool {
36 pub fn end(self: *Iterator) bool {
3737 return self.current == null;
3838 }
3939
40 fn next(self: *Iterator) ?*LinkMap {
40 pub fn next(self: *Iterator) ?*LinkMap {
4141 if (self.current) |it| {
4242 self.current = it.l_next;
4343 return it;
lib/std/elf.zig+1
......@@ -548,6 +548,7 @@ fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void {
548548 error.BrokenPipe => return error.UnableToReadElfFile,
549549 error.Unseekable => return error.UnableToReadElfFile,
550550 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
551 error.ConnectionTimedOut => return error.UnableToReadElfFile,
551552 error.InputOutput => return error.FileSystem,
552553 error.Unexpected => return error.Unexpected,
553554 error.WouldBlock => return error.Unexpected,
lib/std/event/batch.zig+3-3
......@@ -21,7 +21,7 @@ pub fn Batch(
2121 /// usual recommended option for this parameter.
2222 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,
2525 /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
2626 never_async,
2727
......@@ -75,7 +75,7 @@ pub fn Batch(
7575 const job = &self.jobs[self.next_job_index];
7676 self.next_job_index = (self.next_job_index + 1) % max_jobs;
7777 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;
7979 if (CollectedResult != void) {
8080 job.result catch |err| {
8181 self.collected_result = err;
......@@ -94,7 +94,7 @@ pub fn Batch(
9494 /// a time, however, it need not be the same thread.
9595 pub fn wait(self: *Self) CollectedResult {
9696 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;
9898 if (CollectedResult != void) {
9999 job.result catch |err| {
100100 self.collected_result = err;
lib/std/event/channel.zig+4-7
......@@ -105,7 +105,7 @@ pub fn Channel(comptime T: type) type {
105105
106106 /// await this function to get an item from the channel. If the buffer is empty, the frame will
107107 /// 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 {
109109 // TODO https://github.com/ziglang/zig/issues/2765
110110 var result: T = undefined;
111111 var my_tick_node = Loop.NextTickNode.init(@frame());
......@@ -305,8 +305,7 @@ test "std.event.Channel wraparound" {
305305 channel.put(7);
306306 testing.expectEqual(@as(i32, 7), channel.get());
307307}
308
309async fn testChannelGetter(channel: *Channel(i32)) void {
308fn testChannelGetter(channel: *Channel(i32)) callconv(.Async) void {
310309 const value1 = channel.get();
311310 testing.expect(value1 == 1234);
312311
......@@ -321,12 +320,10 @@ async fn testChannelGetter(channel: *Channel(i32)) void {
321320 testing.expect(value4.? == 4444);
322321 await last_put;
323322}
324
325async fn testChannelPutter(channel: *Channel(i32)) void {
323fn testChannelPutter(channel: *Channel(i32)) callconv(.Async) void {
326324 channel.put(1234);
327325 channel.put(4567);
328326}
329
330async fn testPut(channel: *Channel(i32), value: i32) void {
327fn testPut(channel: *Channel(i32), value: i32) callconv(.Async) void {
331328 channel.put(value);
332329}
lib/std/event/future.zig+2-2
......@@ -34,7 +34,7 @@ pub fn Future(comptime T: type) type {
3434 /// Obtain the value. If it's not available, wait until it becomes
3535 /// available.
3636 /// Thread-safe.
37 pub async fn get(self: *Self) *T {
37 pub fn get(self: *Self) callconv(.Async) *T {
3838 if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
3939 return &self.data;
4040 }
......@@ -59,7 +59,7 @@ pub fn Future(comptime T: type) type {
5959 /// should start working on the data.
6060 /// It's not required to call start() before resolve() but it can be useful since
6161 /// this method is thread-safe.
62 pub async fn start(self: *Self) ?*T {
62 pub fn start(self: *Self) callconv(.Async) ?*T {
6363 const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
6464 switch (state) {
6565 .Started => {
lib/std/event/group.zig+6-10
......@@ -84,7 +84,7 @@ pub fn Group(comptime ReturnType: type) type {
8484 /// Wait for all the calls and promises of the group to complete.
8585 /// Thread-safe.
8686 /// Safe to call any number of times.
87 pub async fn wait(self: *Self) ReturnType {
87 pub fn wait(self: *Self) callconv(.Async) ReturnType {
8888 const held = self.lock.acquire();
8989 defer held.release();
9090
......@@ -127,8 +127,7 @@ test "std.event.Group" {
127127
128128 const handle = async testGroup(std.heap.page_allocator);
129129}
130
131async fn testGroup(allocator: *Allocator) void {
130fn testGroup(allocator: *Allocator) callconv(.Async) void {
132131 var count: usize = 0;
133132 var group = Group(void).init(allocator);
134133 var sleep_a_little_frame = async sleepALittle(&count);
......@@ -145,20 +144,17 @@ async fn testGroup(allocator: *Allocator) void {
145144 another.add(&something_that_fails_frame) catch @panic("memory");
146145 testing.expectError(error.ItBroke, another.wait());
147146}
148
149async fn sleepALittle(count: *usize) void {
147fn sleepALittle(count: *usize) callconv(.Async) void {
150148 std.time.sleep(1 * std.time.millisecond);
151149 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
152150}
153
154async fn increaseByTen(count: *usize) void {
151fn increaseByTen(count: *usize) callconv(.Async) void {
155152 var i: usize = 0;
156153 while (i < 10) : (i += 1) {
157154 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
158155 }
159156}
160
161async fn doSomethingThatFails() anyerror!void {}
162async fn somethingElse() anyerror!void {
157fn doSomethingThatFails() callconv(.Async) anyerror!void {}
158fn somethingElse() callconv(.Async) anyerror!void {
163159 return error.ItBroke;
164160}
lib/std/event/lock.zig+3-5
......@@ -89,7 +89,7 @@ pub const Lock = struct {
8989 while (self.queue.get()) |node| resume node.data;
9090 }
9191
92 pub async fn acquire(self: *Lock) Held {
92 pub fn acquire(self: *Lock) callconv(.Async) Held {
9393 var my_tick_node = Loop.NextTickNode.init(@frame());
9494
9595 errdefer _ = self.queue.remove(&my_tick_node); // TODO test canceling an acquire
......@@ -134,8 +134,7 @@ test "std.event.Lock" {
134134 const expected_result = [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
135135 testing.expectEqualSlices(i32, &expected_result, &shared_test_data);
136136}
137
138async fn testLock(lock: *Lock) void {
137fn testLock(lock: *Lock) callconv(.Async) void {
139138 var handle1 = async lockRunner(lock);
140139 var tick_node1 = Loop.NextTickNode{
141140 .prev = undefined,
......@@ -167,8 +166,7 @@ async fn testLock(lock: *Lock) void {
167166
168167var shared_test_data = [1]i32{0} ** 10;
169168var shared_test_index: usize = 0;
170
171async fn lockRunner(lock: *Lock) void {
169fn lockRunner(lock: *Lock) callconv(.Async) void {
172170 suspend; // resumed by onNextTick
173171
174172 var i: usize = 0;
lib/std/event/locked.zig+1-1
......@@ -31,7 +31,7 @@ pub fn Locked(comptime T: type) type {
3131 self.lock.deinit();
3232 }
3333
34 pub async fn acquire(self: *Self) HeldLock {
34 pub fn acquire(self: *Self) callconv(.Async) HeldLock {
3535 return HeldLock{
3636 // TODO guaranteed allocation elision
3737 .held = self.lock.acquire(),
lib/std/event/loop.zig+28-19
......@@ -195,7 +195,7 @@ pub const Loop = struct {
195195 const wakeup_bytes = [_]u8{0x1} ** 8;
196196
197197 fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {
198 noasync switch (builtin.os.tag) {
198 nosuspend switch (builtin.os.tag) {
199199 .linux => {
200200 errdefer {
201201 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
......@@ -371,7 +371,7 @@ pub const Loop = struct {
371371 }
372372
373373 fn deinitOsData(self: *Loop) void {
374 noasync switch (builtin.os.tag) {
374 nosuspend switch (builtin.os.tag) {
375375 .linux => {
376376 os.close(self.os_data.final_eventfd);
377377 while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
......@@ -493,7 +493,7 @@ pub const Loop = struct {
493493 pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {
494494 switch (builtin.os.tag) {
495495 .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);
497497 },
498498 .macosx, .freebsd, .netbsd, .dragonfly => {
499499 self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
......@@ -503,7 +503,7 @@ pub const Loop = struct {
503503 }
504504 }
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 {
507507 var resume_node = ResumeNode.Basic{
508508 .base = ResumeNode{
509509 .id = ResumeNode.Id.Basic,
......@@ -512,21 +512,28 @@ pub const Loop = struct {
512512 },
513513 .kev = undefined,
514514 };
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
516523 suspend {
517 self.bsdAddKev(&resume_node, ident, filter, fflags) catch unreachable;
524 self.bsdAddKev(&resume_node, ident, filter, flags) catch unreachable;
518525 }
519526 }
520527
521528 /// 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 {
523530 self.beginOneEvent();
524531 errdefer self.finishOneEvent();
525532 var kev = [1]os.Kevent{os.Kevent{
526533 .ident = ident,
527534 .filter = filter,
528 .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR,
529 .fflags = fflags,
535 .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR | flags,
536 .fflags = 0,
530537 .data = 0,
531538 .udata = @ptrToInt(&resume_node.base),
532539 }};
......@@ -616,14 +623,16 @@ pub const Loop = struct {
616623
617624 self.workerRun();
618625
619 switch (builtin.os.tag) {
620 .linux,
621 .macosx,
622 .freebsd,
623 .netbsd,
624 .dragonfly,
625 => self.fs_thread.wait(),
626 else => {},
626 if (!builtin.single_threaded) {
627 switch (builtin.os.tag) {
628 .linux,
629 .macosx,
630 .freebsd,
631 .netbsd,
632 .dragonfly,
633 => self.fs_thread.wait(),
634 else => {},
635 }
627636 }
628637
629638 for (self.extra_threads) |extra_thread| {
......@@ -663,7 +672,7 @@ pub const Loop = struct {
663672 }
664673
665674 pub fn finishOneEvent(self: *Loop) void {
666 noasync {
675 nosuspend {
667676 const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst);
668677 if (prev != 1) return;
669678
......@@ -1041,7 +1050,7 @@ pub const Loop = struct {
10411050 }
10421051
10431052 fn posixFsRun(self: *Loop) void {
1044 noasync while (true) {
1053 nosuspend while (true) {
10451054 self.fs_thread_wakeup.reset();
10461055 while (self.fs_queue.get()) |node| {
10471056 switch (node.data.msg) {
lib/std/event/rwlock.zig+5-8
......@@ -97,7 +97,7 @@ pub const RwLock = struct {
9797 while (self.reader_queue.get()) |node| resume node.data;
9898 }
9999
100 pub async fn acquireRead(self: *RwLock) HeldRead {
100 pub fn acquireRead(self: *RwLock) callconv(.Async) HeldRead {
101101 _ = @atomicRmw(usize, &self.reader_lock_count, .Add, 1, .SeqCst);
102102
103103 suspend {
......@@ -130,7 +130,7 @@ pub const RwLock = struct {
130130 return HeldRead{ .lock = self };
131131 }
132132
133 pub async fn acquireWrite(self: *RwLock) HeldWrite {
133 pub fn acquireWrite(self: *RwLock) callconv(.Async) HeldWrite {
134134 suspend {
135135 var my_tick_node = Loop.NextTickNode{
136136 .data = @frame(),
......@@ -225,8 +225,7 @@ test "std.event.RwLock" {
225225 const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
226226 testing.expectEqualSlices(i32, expected_result, shared_test_data);
227227}
228
229async fn testLock(allocator: *Allocator, lock: *RwLock) void {
228fn testLock(allocator: *Allocator, lock: *RwLock) callconv(.Async) void {
230229 var read_nodes: [100]Loop.NextTickNode = undefined;
231230 for (read_nodes) |*read_node| {
232231 const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");
......@@ -259,8 +258,7 @@ const shared_it_count = 10;
259258var shared_test_data = [1]i32{0} ** 10;
260259var shared_test_index: usize = 0;
261260var shared_count: usize = 0;
262
263async fn writeRunner(lock: *RwLock) void {
261fn writeRunner(lock: *RwLock) callconv(.Async) void {
264262 suspend; // resumed by onNextTick
265263
266264 var i: usize = 0;
......@@ -277,8 +275,7 @@ async fn writeRunner(lock: *RwLock) void {
277275 shared_test_index = 0;
278276 }
279277}
280
281async fn readRunner(lock: *RwLock) void {
278fn readRunner(lock: *RwLock) callconv(.Async) void {
282279 suspend; // resumed by onNextTick
283280 std.time.sleep(1);
284281
lib/std/event/rwlocked.zig+2-2
......@@ -40,14 +40,14 @@ pub fn RwLocked(comptime T: type) type {
4040 self.lock.deinit();
4141 }
4242
43 pub async fn acquireRead(self: *Self) HeldReadLock {
43 pub fn acquireRead(self: *Self) callconv(.Async) HeldReadLock {
4444 return HeldReadLock{
4545 .held = self.lock.acquireRead(),
4646 .value = &self.locked_data,
4747 };
4848 }
4949
50 pub async fn acquireWrite(self: *Self) HeldWriteLock {
50 pub fn acquireWrite(self: *Self) callconv(.Async) HeldWriteLock {
5151 return HeldWriteLock{
5252 .held = self.lock.acquireWrite(),
5353 .value = &self.locked_data,
lib/std/fs/file.zig+2-2
......@@ -66,7 +66,7 @@ pub const File = struct {
6666 lock_nonblocking: bool = false,
6767
6868 /// 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 functions
69 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
7070 /// related to opening the file, reading, writing, and locking.
7171 intended_io_mode: io.ModeOverride = io.default_mode,
7272 };
......@@ -112,7 +112,7 @@ pub const File = struct {
112112 mode: Mode = default_mode,
113113
114114 /// 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 functions
115 /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
116116 /// related to opening the file, reading, writing, and locking.
117117 intended_io_mode: io.ModeOverride = io.default_mode,
118118 };
lib/std/hash/auto_hash.zig+1-3
......@@ -113,11 +113,9 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
113113 hasher.update(mem.asBytes(&key));
114114 } else {
115115 // 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;
118116 comptime var i = 0;
119117 inline while (i < info.len) : (i += 1) {
120 hash(hasher, array[i], strat);
118 hash(hasher, key[i], strat);
121119 }
122120 }
123121 },
lib/std/json.zig+4-4
......@@ -136,7 +136,7 @@ pub const Token = union(enum) {
136136/// they are encountered. No copies or allocations are performed during parsing and the entire
137137/// parsing state requires ~40-50 bytes of stack space.
138138///
139/// Conforms strictly to RFC8529.
139/// Conforms strictly to RFC8259.
140140///
141141/// For a non-byte based wrapper, consider using TokenStream instead.
142142pub const StreamingParser = struct {
......@@ -2194,7 +2194,7 @@ test "write json then parse it" {
21942194 try jw.emitBool(true);
21952195
21962196 try jw.objectField("int");
2197 try jw.emitNumber(@as(i32, 1234));
2197 try jw.emitNumber(1234);
21982198
21992199 try jw.objectField("array");
22002200 try jw.beginArray();
......@@ -2203,7 +2203,7 @@ test "write json then parse it" {
22032203 try jw.emitNull();
22042204
22052205 try jw.arrayElem();
2206 try jw.emitNumber(@as(f64, 12.34));
2206 try jw.emitNumber(12.34);
22072207
22082208 try jw.endArray();
22092209
......@@ -2336,7 +2336,7 @@ pub const StringifyOptions = struct {
23362336 /// After a colon, should whitespace be inserted?
23372337 separator: bool = true,
23382338
2339 fn outputIndent(
2339 pub fn outputIndent(
23402340 whitespace: @This(),
23412341 out_stream: var,
23422342 ) @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 {
168168 return;
169169 }
170170 },
171 .Float => if (@floatCast(f64, value) == value) {
172 try self.stream.print("{}", .{value});
171 .ComptimeInt => {
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)});
173176 self.popState();
174177 return;
175178 },
......@@ -180,6 +183,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
180183 }
181184
182185 pub fn emitString(self: *Self, string: []const u8) !void {
186 assert(self.state[self.state_index] == State.Value);
183187 try self.writeEscapedString(string);
184188 self.popState();
185189 }
......@@ -191,7 +195,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
191195
192196 /// Writes the complete json into the output stream
193197 pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void {
198 assert(self.state[self.state_index] == State.Value);
194199 try self.stringify(json);
200 self.popState();
195201 }
196202
197203 fn indent(self: *Self) !void {
......@@ -233,7 +239,32 @@ test "json write stream" {
233239 defer arena_allocator.deinit();
234240
235241 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
238269 const result = slice_stream.getWritten();
239270 const expected =
......@@ -246,38 +277,18 @@ test "json write stream" {
246277 \\ "array": [
247278 \\ "Another string",
248279 \\ 1,
249 \\ 3.14e+00
280 \\ 3.5e+00
250281 \\ ],
251282 \\ "int": 10,
252 \\ "float": 3.14e+00
283 \\ "float": 3.5e+00
253284 \\}
254285 ;
255286 std.testing.expect(std.mem.eql(u8, expected, result));
256287}
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
268289fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {
269290 var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
270291 _ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });
271292 _ = try value.Object.put("two", std.json.Value{ .Float = 2.0 });
272293 return value;
273294}
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 {
124124
125125 fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, comptime sentinel: ?Elem) type {
126126 if (sentinel) |s| {
127 return [:s]align(alignment orelse @alignOf(T)) Elem;
127 return [:s]align(alignment orelse @alignOf(Elem)) Elem;
128128 } else {
129 return []align(alignment orelse @alignOf(T)) Elem;
129 return []align(alignment orelse @alignOf(Elem)) Elem;
130130 }
131131 }
132132
......@@ -296,6 +296,22 @@ pub const Allocator = struct {
296296 }
297297};
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
299315/// Copy all of source into dest at position 0.
300316/// dest.len must be >= source.len.
301317/// dest.ptr must be <= src.ptr.
......@@ -381,6 +397,9 @@ pub fn zeroes(comptime T: type) T {
381397 }
382398 },
383399 .Array => |info| {
400 if (info.sentinel) |sentinel| {
401 return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
402 }
384403 return [_]info.child{zeroes(info.child)} ** info.len;
385404 },
386405 .Vector,
......@@ -441,6 +460,7 @@ test "mem.zeroes" {
441460 array: [2]u32,
442461 optional_int: ?u8,
443462 empty: void,
463 sentinel: [3:0]u8,
444464 };
445465
446466 const b = zeroes(ZigStruct);
......@@ -465,6 +485,9 @@ test "mem.zeroes" {
465485 testing.expectEqual(@as(u32, 0), e);
466486 }
467487 testing.expectEqual(@as(?u8, null), b.optional_int);
488 for (b.sentinel) |e| {
489 testing.expectEqual(@as(u8, 0), e);
490 }
468491}
469492
470493pub fn secureZero(comptime T: type, s: []T) void {
lib/std/net.zig+6-3
......@@ -341,7 +341,7 @@ pub const Address = extern union {
341341 return mem.eql(u8, a_bytes, b_bytes);
342342 }
343343
344 fn getOsSockLen(self: Address) os.socklen_t {
344 pub fn getOsSockLen(self: Address) os.socklen_t {
345345 switch (self.any.family) {
346346 os.AF_INET => return @sizeOf(os.sockaddr_in),
347347 os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
......@@ -377,7 +377,6 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
377377
378378 return fs.File{
379379 .handle = sockfd,
380 .io_mode = std.io.mode,
381380 };
382381}
383382
......@@ -386,7 +385,7 @@ pub const AddressList = struct {
386385 addrs: []Address,
387386 canon_name: ?[]u8,
388387
389 fn deinit(self: *AddressList) void {
388 pub fn deinit(self: *AddressList) void {
390389 // Here we copy the arena allocator into stack memory, because
391390 // otherwise it would destroy itself while it was still working.
392391 var arena = self.arena;
......@@ -1366,6 +1365,10 @@ pub const StreamServer = struct {
13661365
13671366 /// Firewall rules forbid connection.
13681367 BlockedByFirewall,
1368
1369 /// Permission to create a socket of the specified type and/or
1370 /// protocol is denied.
1371 PermissionDenied,
13691372 } || os.UnexpectedError;
13701373
13711374 pub const Connection = struct {
lib/std/net/test.zig+1-1
......@@ -81,7 +81,7 @@ test "resolve DNS" {
8181test "listen on a port, send bytes, receive bytes" {
8282 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()) {
8585 // TODO build abstractions for other operating systems
8686 return error.SkipZigTest;
8787 }
lib/std/os.zig+18-8
......@@ -292,6 +292,7 @@ pub const ReadError = error{
292292 OperationAborted,
293293 BrokenPipe,
294294 ConnectionResetByPeer,
295 ConnectionTimedOut,
295296
296297 /// This error occurs when no global event loop is configured,
297298 /// and reading from the file descriptor would block.
......@@ -351,6 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
351352 ENOBUFS => return error.SystemResources,
352353 ENOMEM => return error.SystemResources,
353354 ECONNRESET => return error.ConnectionResetByPeer,
355 ETIMEDOUT => return error.ConnectionTimedOut,
354356 else => |err| return unexpectedErrno(err),
355357 }
356358 }
......@@ -2156,6 +2158,9 @@ pub const SocketError = error{
21562158
21572159 /// The protocol type or the specified protocol is not supported within this domain.
21582160 ProtocolNotSupported,
2161
2162 /// The socket type is not supported by the protocol.
2163 SocketTypeNotSupported,
21592164} || UnexpectedError;
21602165
21612166pub 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 {
21642169 socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC)
21652170 else
21662171 socket_type;
2167 const rc = system.socket(domain, socket_type, protocol);
2172 const rc = system.socket(domain, filtered_sock_type, protocol);
21682173 switch (errno(rc)) {
21692174 0 => {
21702175 const fd = @intCast(fd_t, rc);
2171 if (!have_sock_flags and filtered_sock_type != socket_type) {
2176 if (!have_sock_flags) {
21722177 try setSockFlags(fd, socket_type);
21732178 }
21742179 return fd;
......@@ -2181,6 +2186,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
21812186 ENOBUFS => return error.SystemResources,
21822187 ENOMEM => return error.SystemResources,
21832188 EPROTONOSUPPORT => return error.ProtocolNotSupported,
2189 EPROTOTYPE => return error.SocketTypeNotSupported,
21842190 else => |err| return unexpectedErrno(err),
21852191 }
21862192}
......@@ -2290,6 +2296,10 @@ pub const AcceptError = error{
22902296 /// This error occurs when no global event loop is configured,
22912297 /// and accepting from the socket would block.
22922298 WouldBlock,
2299
2300 /// Permission to create a socket of the specified type and/or
2301 /// protocol is denied.
2302 PermissionDenied,
22932303} || UnexpectedError;
22942304
22952305/// Accept a connection on a socket.
......@@ -2331,7 +2341,7 @@ pub fn accept(
23312341 switch (errno(rc)) {
23322342 0 => {
23332343 const fd = @intCast(fd_t, rc);
2334 if (!have_accept4 and flags != 0) {
2344 if (!have_accept4) {
23352345 try setSockFlags(fd, flags);
23362346 }
23372347 return fd;
......@@ -2539,7 +2549,7 @@ pub fn connect(sockfd: fd_t, sock_addr: *const sockaddr, len: socklen_t) Connect
25392549 EAFNOSUPPORT => return error.AddressFamilyNotSupported,
25402550 EAGAIN, EINPROGRESS => {
25412551 const loop = std.event.Loop.instance orelse return error.WouldBlock;
2542 loop.waitUntilFdWritableOrReadable(sockfd);
2552 loop.waitUntilFdWritable(sockfd);
25432553 return getsockoptError(sockfd);
25442554 },
25452555 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 {
32673277}
32683278
32693279fn setSockFlags(fd: fd_t, flags: u32) !void {
3270 {
3280 if ((flags & SOCK_CLOEXEC) != 0) {
32713281 var fd_flags = fcntl(fd, F_GETFD, 0) catch |err| switch (err) {
32723282 error.FileBusy => unreachable,
32733283 error.Locked => unreachable,
32743284 else => |e| return e,
32753285 };
3276 if ((flags & SOCK_NONBLOCK) != 0) fd_flags |= FD_CLOEXEC;
3286 fd_flags |= FD_CLOEXEC;
32773287 _ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {
32783288 error.FileBusy => unreachable,
32793289 error.Locked => unreachable,
32803290 else => |e| return e,
32813291 };
32823292 }
3283 {
3293 if ((flags & SOCK_NONBLOCK) != 0) {
32843294 var fl_flags = fcntl(fd, F_GETFL, 0) catch |err| switch (err) {
32853295 error.FileBusy => unreachable,
32863296 error.Locked => unreachable,
32873297 else => |e| return e,
32883298 };
3289 if ((flags & SOCK_CLOEXEC) != 0) fl_flags |= O_NONBLOCK;
3299 fl_flags |= O_NONBLOCK;
32903300 _ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {
32913301 error.FileBusy => unreachable,
32923302 error.Locked => unreachable,
lib/std/os/bits/darwin.zig+5-5
......@@ -125,7 +125,7 @@ pub const empty_sigset = sigset_t(0);
125125
126126/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
127127pub const Sigaction = extern struct {
128 handler: extern fn (c_int) void,
128 handler: fn (c_int) callconv(.C) void,
129129 sa_mask: sigset_t,
130130 sa_flags: c_int,
131131};
......@@ -1263,10 +1263,10 @@ pub const RTLD_NOLOAD = 0x10;
12631263pub const RTLD_NODELETE = 0x80;
12641264pub const RTLD_FIRST = 0x100;
12651265
1266pub const RTLD_NEXT = @intToPtr(*c_void, ~maxInt(usize));
1267pub const RTLD_DEFAULT = @intToPtr(*c_void, ~maxInt(usize) - 1);
1268pub const RTLD_SELF = @intToPtr(*c_void, ~maxInt(usize) - 2);
1269pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, ~maxInt(usize) - 4);
1266pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
1267pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
1268pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
1269pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, @bitCast(usize, @as(isize, -5)));
12701270
12711271/// duplicate file descriptor
12721272pub const F_DUPFD = 0;
lib/std/os/bits/dragonfly.zig+6-6
......@@ -458,9 +458,9 @@ pub const S_IFSOCK = 49152;
458458pub const S_IFWHT = 57344;
459459pub const S_IFMT = 61440;
460460
461pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
462pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
463pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
461pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
462pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
463pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
464464pub const BADSIG = SIG_ERR;
465465pub const SIG_BLOCK = 1;
466466pub const SIG_UNBLOCK = 2;
......@@ -519,13 +519,13 @@ pub const sigset_t = extern struct {
519519pub const sig_atomic_t = c_int;
520520pub const Sigaction = extern struct {
521521 __sigaction_u: extern union {
522 __sa_handler: ?extern fn (c_int) void,
523 __sa_sigaction: ?extern fn (c_int, [*c]siginfo_t, ?*c_void) void,
522 __sa_handler: ?fn (c_int) callconv(.C) void,
523 __sa_sigaction: ?fn (c_int, [*c]siginfo_t, ?*c_void) callconv(.C) void,
524524 },
525525 sa_flags: c_int,
526526 sa_mask: sigset_t,
527527};
528pub const sig_t = [*c]extern fn (c_int) void;
528pub const sig_t = [*c]fn (c_int) callconv(.C) void;
529529
530530pub const sigvec = extern struct {
531531 sv_handler: [*c]__sighandler_t,
lib/std/os/bits/freebsd.zig+5-5
......@@ -725,16 +725,16 @@ pub const winsize = extern struct {
725725
726726const NSIG = 32;
727727
728pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
729pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
730pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
728pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
729pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
730pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
731731
732732/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
733733pub const Sigaction = extern struct {
734734 /// signal handler
735735 __sigaction_u: extern union {
736 __sa_handler: extern fn (i32) void,
737 __sa_sigaction: extern fn (i32, *__siginfo, usize) void,
736 __sa_handler: fn (i32) callconv(.C) void,
737 __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
738738 },
739739
740740 /// 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
813813pub const k_sigaction = if (is_mips)
814814 extern struct {
815815 flags: usize,
816 sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
816 sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
817817 mask: [4]u32,
818 restorer: extern fn () void,
818 restorer: fn () callconv(.C) void,
819819 }
820820else
821821 extern struct {
822 sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
822 sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
823823 flags: usize,
824 restorer: extern fn () void,
824 restorer: fn () callconv(.C) void,
825825 mask: [2]u32,
826826 };
827827
......@@ -831,7 +831,7 @@ pub const Sigaction = extern struct {
831831 sigaction: ?sigaction_fn,
832832 mask: sigset_t,
833833 flags: u32,
834 restorer: ?extern fn () void = null,
834 restorer: ?fn () callconv(.C) void = null,
835835};
836836
837837pub 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 {
599599var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
600600
601601// 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
604604pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
605605 if (@hasDecl(@This(), "VDSO_CGT_SYM")) {
......@@ -791,7 +791,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
791791 .sigaction = act.sigaction,
792792 .flags = act.flags | SA_RESTORER,
793793 .mask = undefined,
794 .restorer = @ptrCast(extern fn () void, restorer_fn),
794 .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
795795 };
796796 var ksa_old: k_sigaction = undefined;
797797 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(
8686}
8787
8888/// 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
9191pub fn restore() callconv(.Naked) void {
9292 return asm volatile ("svc #0"
lib/std/os/linux/arm64.zig+1-1
......@@ -86,7 +86,7 @@ pub fn syscall6(
8686}
8787
8888/// 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
9191pub 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 {
106106}
107107
108108/// 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
111111pub fn restore() callconv(.Naked) void {
112112 return asm volatile ("int $0x80"
lib/std/os/linux/mips.zig+1-1
......@@ -142,7 +142,7 @@ pub fn syscall6(
142142}
143143
144144/// 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
147147pub fn restore() callconv(.Naked) void {
148148 return asm volatile ("syscall"
lib/std/os/linux/riscv64.zig+1-1
......@@ -85,7 +85,7 @@ pub fn syscall6(
8585 );
8686}
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
9090pub const restore = restore_rt;
9191
lib/std/os/linux/x86_64.zig+1-1
......@@ -86,7 +86,7 @@ pub fn syscall6(
8686}
8787
8888/// 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
9191pub const restore = restore_rt;
9292
lib/std/os/uefi/protocols/absolute_pointer_protocol.zig+2-2
......@@ -5,8 +5,8 @@ const Status = uefi.Status;
55
66/// Protocol for touchscreens
77pub const AbsolutePointerProtocol = extern struct {
8 _reset: extern fn (*const AbsolutePointerProtocol, bool) Status,
9 _get_state: extern fn (*const AbsolutePointerProtocol, *AbsolutePointerState) Status,
8 _reset: fn (*const AbsolutePointerProtocol, bool) callconv(.C) Status,
9 _get_state: fn (*const AbsolutePointerProtocol, *AbsolutePointerState) callconv(.C) Status,
1010 wait_for_input: Event,
1111 mode: *AbsolutePointerMode,
1212
lib/std/os/uefi/protocols/edid_override_protocol.zig+1-1
......@@ -5,7 +5,7 @@ const Status = uefi.Status;
55
66/// Override EDID information
77pub 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
1010 /// Returns policy information and potentially a replacement EDID for the specified video output device.
1111 /// attributes must be align(4)
lib/std/os/uefi/protocols/file_protocol.zig+10-10
......@@ -5,16 +5,16 @@ const Status = uefi.Status;
55
66pub const FileProtocol = extern struct {
77 revision: u64,
8 _open: extern fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) Status,
9 _close: extern fn (*const FileProtocol) Status,
10 _delete: extern fn (*const FileProtocol) Status,
11 _read: extern fn (*const FileProtocol, *usize, [*]u8) Status,
12 _write: extern fn (*const FileProtocol, *usize, [*]const u8) Status,
13 _get_position: extern fn (*const FileProtocol, *u64) Status,
14 _set_position: extern fn (*const FileProtocol, *const u64) Status,
15 _get_info: extern fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) Status,
16 _set_info: extern fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) Status,
17 _flush: extern fn (*const FileProtocol) Status,
8 _open: fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) callconv(.C) Status,
9 _close: fn (*const FileProtocol) callconv(.C) Status,
10 _delete: fn (*const FileProtocol) callconv(.C) Status,
11 _read: fn (*const FileProtocol, *usize, [*]u8) callconv(.C) Status,
12 _write: fn (*const FileProtocol, *usize, [*]const u8) callconv(.C) Status,
13 _get_position: fn (*const FileProtocol, *u64) callconv(.C) Status,
14 _set_position: fn (*const FileProtocol, *const u64) callconv(.C) Status,
15 _get_info: fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) callconv(.C) Status,
16 _set_info: fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) callconv(.C) Status,
17 _flush: fn (*const FileProtocol) callconv(.C) Status,
1818
1919 pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {
2020 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;
44
55/// Graphics output
66pub const GraphicsOutputProtocol = extern struct {
7 _query_mode: extern fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) Status,
8 _set_mode: extern fn (*const GraphicsOutputProtocol, u32) Status,
9 _blt: extern fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) Status,
7 _query_mode: fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) callconv(.C) Status,
8 _set_mode: fn (*const GraphicsOutputProtocol, u32) callconv(.C) Status,
9 _blt: fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) callconv(.C) Status,
1010 mode: *GraphicsOutputProtocolMode,
1111
1212 /// 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;
66/// Database manager for HII-related data structures.
77pub const HIIDatabaseProtocol = extern struct {
88 _new_package_list: Status, // TODO
9 _remove_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle) Status,
10 _update_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) Status,
11 _list_package_lists: extern fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) Status,
12 _export_package_lists: extern fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) Status,
9 _remove_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle) callconv(.C) Status,
10 _update_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) callconv(.C) Status,
11 _list_package_lists: fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) callconv(.C) Status,
12 _export_package_lists: fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) callconv(.C) Status,
1313 _register_package_notify: Status, // TODO
1414 _unregister_package_notify: Status, // TODO
1515 _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;
66/// Display a popup window
77pub const HIIPopupProtocol = extern struct {
88 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
1111 /// Displays a popup window.
1212 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;
44const Status = uefi.Status;
55
66pub const Ip6ConfigProtocol = extern struct {
7 _set_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) Status,
8 _get_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) Status,
9 _register_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,
10 _unregister_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,
7 _set_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) callconv(.C) Status,
8 _get_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) callconv(.C) Status,
9 _register_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
10 _unregister_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
1111
1212 pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) Status {
1313 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;
77const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
88
99pub const Ip6Protocol = extern struct {
10 _get_mode_data: extern fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
11 _configure: extern fn (*const Ip6Protocol, ?*const Ip6ConfigData) Status,
12 _groups: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address) Status,
13 _routes: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) Status,
14 _neighbors: extern fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) Status,
15 _transmit: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,
16 _receive: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,
17 _cancel: extern fn (*const Ip6Protocol, ?*Ip6CompletionToken) Status,
18 _poll: extern fn (*const Ip6Protocol) Status,
10 _get_mode_data: fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
11 _configure: fn (*const Ip6Protocol, ?*const Ip6ConfigData) callconv(.C) Status,
12 _groups: fn (*const Ip6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
13 _routes: fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) callconv(.C) Status,
14 _neighbors: fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) callconv(.C) Status,
15 _transmit: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
16 _receive: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
17 _cancel: fn (*const Ip6Protocol, ?*Ip6CompletionToken) callconv(.C) Status,
18 _poll: fn (*const Ip6Protocol) callconv(.C) Status,
1919
2020 /// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
2121 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;
44const Status = uefi.Status;
55
66pub const Ip6ServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const Ip6ServiceBindingProtocol, *?Handle) Status,
8 _destroy_child: extern fn (*const Ip6ServiceBindingProtocol, Handle) Status,
7 _create_child: fn (*const Ip6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: fn (*const Ip6ServiceBindingProtocol, Handle) callconv(.C) Status,
99
1010 pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) Status {
1111 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 {
1919 image_size: u64,
2020 image_code_type: MemoryType,
2121 image_data_type: MemoryType,
22 _unload: extern fn (*const LoadedImageProtocol, Handle) Status,
22 _unload: fn (*const LoadedImageProtocol, Handle) callconv(.C) Status,
2323
2424 /// Unloads an image from memory.
2525 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;
77const MacAddress = uefi.protocols.MacAddress;
88
99pub const ManagedNetworkProtocol = extern struct {
10 _get_mode_data: extern fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
11 _configure: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) Status,
12 _mcast_ip_to_mac: extern fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) Status,
13 _groups: extern fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) Status,
14 _transmit: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,
15 _receive: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,
16 _cancel: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) Status,
17 _poll: extern fn (*const ManagedNetworkProtocol) usize,
10 _get_mode_data: fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
11 _configure: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) callconv(.C) Status,
12 _mcast_ip_to_mac: fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
13 _groups: fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
14 _transmit: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
15 _receive: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
16 _cancel: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) callconv(.C) Status,
17 _poll: fn (*const ManagedNetworkProtocol) callconv(.C) usize,
1818
1919 /// Returns the operational parameters for the current MNP child driver.
2020 /// 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;
44const Status = uefi.Status;
55
66pub const ManagedNetworkServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) Status,
8 _destroy_child: extern fn (*const ManagedNetworkServiceBindingProtocol, Handle) Status,
7 _create_child: fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: fn (*const ManagedNetworkServiceBindingProtocol, Handle) callconv(.C) Status,
99
1010 pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) Status {
1111 return self._create_child(self, handle);
lib/std/os/uefi/protocols/rng_protocol.zig+2-2
......@@ -4,8 +4,8 @@ const Status = uefi.Status;
44
55/// Random Number Generator protocol
66pub const RNGProtocol = extern struct {
7 _get_info: extern fn (*const RNGProtocol, *usize, [*]align(8) Guid) Status,
8 _get_rng: extern fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) Status,
7 _get_info: fn (*const RNGProtocol, *usize, [*]align(8) Guid) callconv(.C) Status,
8 _get_rng: fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) callconv(.C) Status,
99
1010 /// Returns information about the random number generation implementation.
1111 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;
55
66pub const SimpleFileSystemProtocol = extern struct {
77 revision: u64,
8 _open_volume: extern fn (*const SimpleFileSystemProtocol, **const FileProtocol) Status,
8 _open_volume: fn (*const SimpleFileSystemProtocol, **const FileProtocol) callconv(.C) Status,
99
1010 pub fn openVolume(self: *const SimpleFileSystemProtocol, root: **const FileProtocol) Status {
1111 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;
55
66pub const SimpleNetworkProtocol = extern struct {
77 revision: u64,
8 _start: extern fn (*const SimpleNetworkProtocol) Status,
9 _stop: extern fn (*const SimpleNetworkProtocol) Status,
10 _initialize: extern fn (*const SimpleNetworkProtocol, usize, usize) Status,
11 _reset: extern fn (*const SimpleNetworkProtocol, bool) Status,
12 _shutdown: extern fn (*const SimpleNetworkProtocol) Status,
13 _receive_filters: extern fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) Status,
14 _station_address: extern fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) Status,
15 _statistics: extern fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) Status,
16 _mcast_ip_to_mac: extern fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) Status,
17 _nvdata: extern fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) Status,
18 _get_status: extern fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) Status,
19 _transmit: extern fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) Status,
20 _receive: extern fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) Status,
8 _start: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
9 _stop: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
10 _initialize: fn (*const SimpleNetworkProtocol, usize, usize) callconv(.C) Status,
11 _reset: fn (*const SimpleNetworkProtocol, bool) callconv(.C) Status,
12 _shutdown: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
13 _receive_filters: fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) callconv(.C) Status,
14 _station_address: fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
15 _statistics: fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) callconv(.C) Status,
16 _mcast_ip_to_mac: fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
17 _nvdata: fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) callconv(.C) Status,
18 _get_status: fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) callconv(.C) Status,
19 _transmit: fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) callconv(.C) Status,
20 _receive: fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) callconv(.C) Status,
2121 wait_for_packet: Event,
2222 mode: *SimpleNetworkMode,
2323
lib/std/os/uefi/protocols/simple_pointer_protocol.zig+2-2
......@@ -5,8 +5,8 @@ const Status = uefi.Status;
55
66/// Protocol for mice
77pub const SimplePointerProtocol = struct {
8 _reset: extern fn (*const SimplePointerProtocol, bool) Status,
9 _get_state: extern fn (*const SimplePointerProtocol, *SimplePointerState) Status,
8 _reset: fn (*const SimplePointerProtocol, bool) callconv(.C) Status,
9 _get_state: fn (*const SimplePointerProtocol, *SimplePointerState) callconv(.C) Status,
1010 wait_for_input: Event,
1111 mode: *SimplePointerMode,
1212
lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig+6-6
......@@ -5,12 +5,12 @@ const Status = uefi.Status;
55
66/// Character input devices, e.g. Keyboard
77pub const SimpleTextInputExProtocol = extern struct {
8 _reset: extern fn (*const SimpleTextInputExProtocol, bool) Status,
9 _read_key_stroke_ex: extern fn (*const SimpleTextInputExProtocol, *KeyData) Status,
8 _reset: fn (*const SimpleTextInputExProtocol, bool) callconv(.C) Status,
9 _read_key_stroke_ex: fn (*const SimpleTextInputExProtocol, *KeyData) callconv(.C) Status,
1010 wait_for_key_ex: Event,
11 _set_state: extern fn (*const SimpleTextInputExProtocol, *const u8) Status,
12 _register_key_notify: extern fn (*const SimpleTextInputExProtocol, *const KeyData, extern fn (*const KeyData) usize, **c_void) Status,
13 _unregister_key_notify: extern fn (*const SimpleTextInputExProtocol, *const c_void) Status,
11 _set_state: fn (*const SimpleTextInputExProtocol, *const u8) callconv(.C) 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: fn (*const SimpleTextInputExProtocol, *const c_void) callconv(.C) Status,
1414
1515 /// Resets the input device hardware.
1616 pub fn reset(self: *const SimpleTextInputExProtocol, verify: bool) Status {
......@@ -28,7 +28,7 @@ pub const SimpleTextInputExProtocol = extern struct {
2828 }
2929
3030 /// 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 {
3232 return self._register_key_notify(self, key_data, notify, handle);
3333 }
3434
lib/std/os/uefi/protocols/simple_text_input_protocol.zig+2-2
......@@ -6,8 +6,8 @@ const Status = uefi.Status;
66
77/// Character input devices, e.g. Keyboard
88pub const SimpleTextInputProtocol = extern struct {
9 _reset: extern fn (*const SimpleTextInputProtocol, bool) usize,
10 _read_key_stroke: extern fn (*const SimpleTextInputProtocol, *InputKey) Status,
9 _reset: fn (*const SimpleTextInputProtocol, bool) callconv(.C) usize,
10 _read_key_stroke: fn (*const SimpleTextInputProtocol, *InputKey) callconv(.C) Status,
1111 wait_for_key: Event,
1212
1313 /// 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;
44
55/// Character output devices
66pub const SimpleTextOutputProtocol = extern struct {
7 _reset: extern fn (*const SimpleTextOutputProtocol, bool) Status,
8 _output_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,
9 _test_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,
10 _query_mode: extern fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) Status,
11 _set_mode: extern fn (*const SimpleTextOutputProtocol, usize) Status,
12 _set_attribute: extern fn (*const SimpleTextOutputProtocol, usize) Status,
13 _clear_screen: extern fn (*const SimpleTextOutputProtocol) Status,
14 _set_cursor_position: extern fn (*const SimpleTextOutputProtocol, usize, usize) Status,
15 _enable_cursor: extern fn (*const SimpleTextOutputProtocol, bool) Status,
7 _reset: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
8 _output_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
9 _test_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
10 _query_mode: fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) callconv(.C) Status,
11 _set_mode: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
12 _set_attribute: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
13 _clear_screen: fn (*const SimpleTextOutputProtocol) callconv(.C) Status,
14 _set_cursor_position: fn (*const SimpleTextOutputProtocol, usize, usize) callconv(.C) Status,
15 _enable_cursor: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
1616 mode: *SimpleTextOutputMode,
1717
1818 /// 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;
99const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
1010
1111pub const Udp6Protocol = extern struct {
12 _get_mode_data: extern fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
13 _configure: extern fn (*const Udp6Protocol, ?*const Udp6ConfigData) Status,
14 _groups: extern fn (*const Udp6Protocol, bool, ?*const Ip6Address) Status,
15 _transmit: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,
16 _receive: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,
17 _cancel: extern fn (*const Udp6Protocol, ?*Udp6CompletionToken) Status,
18 _poll: extern fn (*const Udp6Protocol) Status,
12 _get_mode_data: fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
13 _configure: fn (*const Udp6Protocol, ?*const Udp6ConfigData) callconv(.C) Status,
14 _groups: fn (*const Udp6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
15 _transmit: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
16 _receive: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
17 _cancel: fn (*const Udp6Protocol, ?*Udp6CompletionToken) callconv(.C) Status,
18 _poll: fn (*const Udp6Protocol) callconv(.C) Status,
1919
2020 pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {
2121 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;
44const Status = uefi.Status;
55
66pub const Udp6ServiceBindingProtocol = extern struct {
7 _create_child: extern fn (*const Udp6ServiceBindingProtocol, *?Handle) Status,
8 _destroy_child: extern fn (*const Udp6ServiceBindingProtocol, Handle) Status,
7 _create_child: fn (*const Udp6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
8 _destroy_child: fn (*const Udp6ServiceBindingProtocol, Handle) callconv(.C) Status,
99
1010 pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) Status {
1111 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 {
2121 hdr: TableHeader,
2222
2323 /// 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
2626 /// Restores a task's priority level to its previous value.
27 restoreTpl: extern fn (usize) void,
27 restoreTpl: fn (usize) callconv(.C) void,
2828
2929 /// 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
3232 /// Frees memory pages.
33 freePages: extern fn ([*]align(4096) u8, usize) Status,
33 freePages: fn ([*]align(4096) u8, usize) callconv(.C) Status,
3434
3535 /// 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
3838 /// 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
4141 /// Returns pool memory to the system.
42 freePool: extern fn ([*]align(8) u8) Status,
42 freePool: fn ([*]align(8) u8) callconv(.C) Status,
4343
4444 /// 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
4747 /// 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
5050 /// 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
5353 /// Signals an event.
54 signalEvent: extern fn (Event) Status,
54 signalEvent: fn (Event) callconv(.C) Status,
5555
5656 /// Closes an event.
57 closeEvent: extern fn (Event) Status,
57 closeEvent: fn (Event) callconv(.C) Status,
5858
5959 /// Checks whether an event is in the signaled state.
60 checkEvent: extern fn (Event) Status,
60 checkEvent: fn (Event) callconv(.C) Status,
6161
6262 installProtocolInterface: Status, // TODO
6363 reinstallProtocolInterface: Status, // TODO
6464 uninstallProtocolInterface: Status, // TODO
6565
6666 /// 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
6969 reserved: *c_void,
7070
7171 registerProtocolNotify: Status, // TODO
7272
7373 /// 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
7676 locateDevicePath: Status, // TODO
7777 installConfigurationTable: Status, // TODO
7878
7979 /// 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
8282 /// 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
8585 /// 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
8888 /// Unloads an image.
89 unloadImage: extern fn (Handle) Status,
89 unloadImage: fn (Handle) callconv(.C) Status,
9090
9191 /// Terminates all boot services.
92 exitBootServices: extern fn (Handle, usize) Status,
92 exitBootServices: fn (Handle, usize) callconv(.C) Status,
9393
9494 /// Returns a monotonically increasing count for the platform.
95 getNextMonotonicCount: extern fn (*u64) Status,
95 getNextMonotonicCount: fn (*u64) callconv(.C) Status,
9696
9797 /// Induces a fine-grained stall.
98 stall: extern fn (usize) Status,
98 stall: fn (usize) callconv(.C) Status,
9999
100100 /// 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
103103 connectController: Status, // TODO
104104 disconnectController: Status, // TODO
105105
106106 /// 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
109109 /// 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
112112 /// 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
115115 /// 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
118118 /// 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
121121 /// 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
124124 installMultipleProtocolInterfaces: Status, // TODO
125125 uninstallMultipleProtocolInterfaces: Status, // TODO
126126
127127 /// 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
130130 /// 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
133133 /// 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
136136 createEventEx: Status, // TODO
137137
lib/std/os/uefi/tables/runtime_services.zig+5-5
......@@ -17,7 +17,7 @@ pub const RuntimeServices = extern struct {
1717 hdr: TableHeader,
1818
1919 /// 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
2222 setTime: Status, // TODO
2323 getWakeupTime: Status, // TODO
......@@ -26,18 +26,18 @@ pub const RuntimeServices = extern struct {
2626 convertPointer: Status, // TODO
2727
2828 /// 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
3131 /// 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
3434 /// 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
3737 getNextHighMonotonicCount: Status, // TODO
3838
3939 /// 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
4242 updateCapsule: Status, // TODO
4343 queryCapsuleCapabilities: Status, // TODO
lib/std/os/windows/bits.zig+6-6
......@@ -627,7 +627,7 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
627627pub const MEM_DECOMMIT = 0x4000;
628628pub const MEM_RELEASE = 0x8000;
629629
630pub const PTHREAD_START_ROUTINE = extern fn (LPVOID) DWORD;
630pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;
631631pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
632632
633633pub const WIN32_FIND_DATAW = extern struct {
......@@ -784,7 +784,7 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {
784784pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
785785pub 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
789789pub const PROV_RSA_FULL = 1;
790790
......@@ -810,7 +810,7 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;
810810pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
811811pub 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
815815pub const FILE_NOTIFY_CHANGE_CREATION = 64;
816816pub const FILE_NOTIFY_CHANGE_SIZE = 8;
......@@ -863,7 +863,7 @@ pub const RTL_CRITICAL_SECTION = extern struct {
863863pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
864864pub const INIT_ONCE = RTL_RUN_ONCE;
865865pub 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
868868pub const RTL_RUN_ONCE = extern struct {
869869 Ptr: ?*c_void,
......@@ -1418,7 +1418,7 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
14181418 DosPath: UNICODE_STRING,
14191419};
14201420
1421pub const PPS_POST_PROCESS_INIT_ROUTINE = ?extern fn () void;
1421pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;
14221422
14231423pub const FILE_BOTH_DIR_INFORMATION = extern struct {
14241424 NextEntryOffset: ULONG,
......@@ -1438,7 +1438,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
14381438};
14391439pub 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
14431443pub const CURDIR = extern struct {
14441444 DosPath: UNICODE_STRING,
lib/std/os/windows/user32.zig-2
......@@ -73,7 +73,6 @@ pub const WM_XBUTTONDBLCLK = 0x020D;
7373// WA
7474pub const WA_INACTIVE = 0;
7575pub const WA_ACTIVE = 0x0006;
76pub const WM_ACTIVATE = 0x0006;
7776
7877// WS
7978pub const WS_OVERLAPPED = 0x00000000;
......@@ -147,7 +146,6 @@ pub extern "user32" fn CreateWindowExA(
147146
148147pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;
149148pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;
150pub extern "user32" fn GetModuleHandleA(lpModuleName: ?LPCSTR) callconv(.Stdcall) HMODULE;
151149pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(.Stdcall) bool;
152150pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(.Stdcall) bool;
153151pub 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 {
106106 hEvent: ?WSAEVENT,
107107};
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
111111pub const ADDRESS_FAMILY = u16;
112112
lib/std/pdb.zig+4-4
......@@ -644,7 +644,7 @@ const MsfStream = struct {
644644 return stream;
645645 }
646646
647 fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {
647 pub fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {
648648 var list = ArrayList(u8).init(allocator);
649649 while (true) {
650650 const byte = try self.inStream().readByte();
......@@ -684,13 +684,13 @@ const MsfStream = struct {
684684 return buffer.len;
685685 }
686686
687 fn seekBy(self: *MsfStream, len: i64) !void {
687 pub fn seekBy(self: *MsfStream, len: i64) !void {
688688 self.pos = @intCast(u64, @intCast(i64, self.pos) + len);
689689 if (self.pos >= self.blocks.len * self.block_size)
690690 return error.EOF;
691691 }
692692
693 fn seekTo(self: *MsfStream, len: u64) !void {
693 pub fn seekTo(self: *MsfStream, len: u64) !void {
694694 self.pos = len;
695695 if (self.pos >= self.blocks.len * self.block_size)
696696 return error.EOF;
......@@ -708,7 +708,7 @@ const MsfStream = struct {
708708 return block * self.block_size + offset;
709709 }
710710
711 fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {
711 pub fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {
712712 return .{ .context = self };
713713 }
714714};
lib/std/priority_queue.zig+3-3
......@@ -185,18 +185,18 @@ pub fn PriorityQueue(comptime T: type) type {
185185 self.len = new_len;
186186 }
187187
188 const Iterator = struct {
188 pub const Iterator = struct {
189189 queue: *PriorityQueue(T),
190190 count: usize,
191191
192 fn next(it: *Iterator) ?T {
192 pub fn next(it: *Iterator) ?T {
193193 if (it.count > it.queue.len - 1) return null;
194194 const out = it.count;
195195 it.count += 1;
196196 return it.queue.items[out];
197197 }
198198
199 fn reset(it: *Iterator) void {
199 pub fn reset(it: *Iterator) void {
200200 it.count = 0;
201201 }
202202 };
lib/std/special/docs/main.js+39
......@@ -1498,6 +1498,22 @@
14981498 }
14991499 ];
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
15011517 const stack = [];
15021518
15031519 var innerHTML = "";
......@@ -1548,6 +1564,29 @@
15481564 currentRun += innerText[i];
15491565 in_code = true;
15501566 } 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
15511590 var any = false;
15521591 for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
15531592 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 {
3434 std.heap.page_allocator.free(async_frame_buffer);
3535 async_frame_buffer = try std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size);
3636 }
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);
3838 break :blk await @asyncCall(async_frame_buffer, {}, casted_fn);
3939 },
4040 .blocking => {
lib/std/start.zig+1-2
......@@ -224,8 +224,7 @@ inline fn initEventLoopAndCallMain() u8 {
224224 // and we want fewer call frames in stack traces.
225225 return @call(.{ .modifier = .always_inline }, callMain, .{});
226226}
227
228async fn callMainAsync(loop: *std.event.Loop) u8 {
227fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 {
229228 // This prevents the event loop from terminating at least until main() has returned.
230229 loop.beginOneEvent();
231230 defer loop.finishOneEvent();
lib/std/thread.zig+1-1
......@@ -280,7 +280,7 @@ pub const Thread = struct {
280280 std.debug.dumpStackTrace(trace.*);
281281 }
282282 };
283 return 0;
283 return null;
284284 },
285285 else => @compileError(bad_startfn_ret),
286286 }
lib/std/zig/ast.zig+24-16
......@@ -129,6 +129,7 @@ pub const Error = union(enum) {
129129 ExpectedStatement: ExpectedStatement,
130130 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
131131 ExpectedVarDecl: ExpectedVarDecl,
132 ExpectedFn: ExpectedFn,
132133 ExpectedReturnType: ExpectedReturnType,
133134 ExpectedAggregateKw: ExpectedAggregateKw,
134135 UnattachedDocComment: UnattachedDocComment,
......@@ -165,6 +166,7 @@ pub const Error = union(enum) {
165166 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
166167 ExpectedSuffixOp: ExpectedSuffixOp,
167168 DeclBetweenFields: DeclBetweenFields,
169 InvalidAnd: InvalidAnd,
168170
169171 pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
170172 switch (self.*) {
......@@ -177,6 +179,7 @@ pub const Error = union(enum) {
177179 .ExpectedStatement => |*x| return x.render(tokens, stream),
178180 .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
179181 .ExpectedVarDecl => |*x| return x.render(tokens, stream),
182 .ExpectedFn => |*x| return x.render(tokens, stream),
180183 .ExpectedReturnType => |*x| return x.render(tokens, stream),
181184 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),
182185 .UnattachedDocComment => |*x| return x.render(tokens, stream),
......@@ -213,6 +216,7 @@ pub const Error = union(enum) {
213216 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
214217 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),
215218 .DeclBetweenFields => |*x| return x.render(tokens, stream),
219 .InvalidAnd => |*x| return x.render(tokens, stream),
216220 }
217221 }
218222
......@@ -227,6 +231,7 @@ pub const Error = union(enum) {
227231 .ExpectedStatement => |x| return x.token,
228232 .ExpectedVarDeclOrFn => |x| return x.token,
229233 .ExpectedVarDecl => |x| return x.token,
234 .ExpectedFn => |x| return x.token,
230235 .ExpectedReturnType => |x| return x.token,
231236 .ExpectedAggregateKw => |x| return x.token,
232237 .UnattachedDocComment => |x| return x.token,
......@@ -263,6 +268,7 @@ pub const Error = union(enum) {
263268 .ExpectedDerefOrUnwrap => |x| return x.token,
264269 .ExpectedSuffixOp => |x| return x.token,
265270 .DeclBetweenFields => |x| return x.token,
271 .InvalidAnd => |x| return x.token,
266272 }
267273 }
268274
......@@ -274,6 +280,7 @@ pub const Error = union(enum) {
274280 pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
275281 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
276282 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
283 pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
277284 pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
278285 pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
279286 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
......@@ -308,6 +315,7 @@ pub const Error = union(enum) {
308315 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
309316 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
310317 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
312320 pub const ExpectedCall = struct {
313321 node: *Node,
......@@ -335,9 +343,6 @@ pub const Error = union(enum) {
335343 pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {
336344 const found_token = tokens.at(self.token);
337345 switch (found_token.id) {
338 .Invalid_ampersands => {
339 return stream.print("`&&` is invalid. Note that `and` is boolean AND.", .{});
340 },
341346 .Invalid => {
342347 return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
343348 },
......@@ -438,7 +443,7 @@ pub const Node = struct {
438443 ContainerDecl,
439444 Asm,
440445 Comptime,
441 Noasync,
446 Nosuspend,
442447 Block,
443448
444449 // Misc
......@@ -569,9 +574,9 @@ pub const Node = struct {
569574
570575 return true;
571576 },
572 .Noasync => {
573 const noasync_node = @fieldParentPtr(Noasync, "base", n);
574 return noasync_node.expr.id != .Block;
577 .Nosuspend => {
578 const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);
579 return nosuspend_node.expr.id != .Block;
575580 },
576581 else => return true,
577582 }
......@@ -875,18 +880,20 @@ pub const Node = struct {
875880 return_type: ReturnType,
876881 var_args_token: ?TokenIndex,
877882 extern_export_inline_token: ?TokenIndex,
878 cc_token: ?TokenIndex,
879883 body_node: ?*Node,
880884 lib_name: ?*Node, // populated if this is an extern declaration
881885 align_expr: ?*Node, // populated if align(A) is present
882886 section_expr: ?*Node, // populated if linksection(A) is present
883887 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
885891 pub const ParamList = SegmentedList(*Node, 2);
886892
887893 pub const ReturnType = union(enum) {
888894 Explicit: *Node,
889895 InferErrorSet: *Node,
896 Invalid: TokenIndex,
890897 };
891898
892899 pub fn iterate(self: *FnProto, index: usize) ?*Node {
......@@ -915,6 +922,7 @@ pub const Node = struct {
915922 if (i < 1) return node;
916923 i -= 1;
917924 },
925 .Invalid => {},
918926 }
919927
920928 if (self.body_node) |body_node| {
......@@ -929,7 +937,6 @@ pub const Node = struct {
929937 if (self.visib_token) |visib_token| return visib_token;
930938 if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
931939 assert(self.lib_name == null);
932 if (self.cc_token) |cc_token| return cc_token;
933940 return self.fn_token;
934941 }
935942
......@@ -937,6 +944,7 @@ pub const Node = struct {
937944 if (self.body_node) |body_node| return body_node.lastToken();
938945 switch (self.return_type) {
939946 .Explicit, .InferErrorSet => |node| return node.lastToken(),
947 .Invalid => |tok| return tok,
940948 }
941949 }
942950 };
......@@ -1084,12 +1092,12 @@ pub const Node = struct {
10841092 }
10851093 };
10861094
1087 pub const Noasync = struct {
1088 base: Node = Node{ .id = .Noasync },
1089 noasync_token: TokenIndex,
1095 pub const Nosuspend = struct {
1096 base: Node = Node{ .id = .Nosuspend },
1097 nosuspend_token: TokenIndex,
10901098 expr: *Node,
10911099
1092 pub fn iterate(self: *Noasync, index: usize) ?*Node {
1100 pub fn iterate(self: *Nosuspend, index: usize) ?*Node {
10931101 var i = index;
10941102
10951103 if (i < 1) return self.expr;
......@@ -1098,11 +1106,11 @@ pub const Node = struct {
10981106 return null;
10991107 }
11001108
1101 pub fn firstToken(self: *const Noasync) TokenIndex {
1102 return self.noasync_token;
1109 pub fn firstToken(self: *const Nosuspend) TokenIndex {
1110 return self.nosuspend_token;
11031111 }
11041112
1105 pub fn lastToken(self: *const Noasync) TokenIndex {
1113 pub fn lastToken(self: *const Nosuspend) TokenIndex {
11061114 return self.expr.lastToken();
11071115 }
11081116 };
lib/std/zig/cross_target.zig+1-1
......@@ -660,7 +660,7 @@ pub const CrossTarget = struct {
660660 return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());
661661 }
662662
663 fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
663 pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
664664 set.removeFeatureSet(self.cpu_features_sub);
665665 set.addFeatureSet(self.cpu_features_add);
666666 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 {
4848
4949 while (it.peek().?.id == .LineComment) _ = it.next();
5050
51 tree.root_node = parseRoot(arena, &it, tree) catch |err| blk: {
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 };
51 tree.root_node = try parseRoot(arena, &it, tree);
6252
6353 return tree;
6454}
6555
6656/// 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 {
6858 const node = try arena.create(Node.Root);
6959 node.* = .{
7060 .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).?;
7265 try tree.errors.push(.{
73 .ExpectedContainerMembers = .{ .token = it.index },
66 .ExpectedContainerMembers = .{ .token = tok },
7467 });
75 return error.ParseError;
68 break :blk tok;
7669 },
7770 };
7871 return node;
......@@ -108,7 +101,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
108101
109102 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| {
112111 if (field_state == .seen) {
113112 field_state = .{ .end = node.firstToken() };
114113 }
......@@ -117,7 +116,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
117116 continue;
118117 }
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| {
121126 if (field_state == .seen) {
122127 field_state = .{ .end = node.firstToken() };
123128 }
......@@ -128,7 +133,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
128133
129134 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| {
132143 if (field_state == .seen) {
133144 field_state = .{ .end = visib_token orelse node.firstToken() };
134145 }
......@@ -163,10 +174,18 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
163174 try tree.errors.push(.{
164175 .ExpectedPubItem = .{ .token = it.index },
165176 });
166 return error.ParseError;
177 // ignore this pub
178 continue;
167179 }
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| {
170189 switch (field_state) {
171190 .none => field_state = .seen,
172191 .err, .seen => {},
......@@ -182,7 +201,21 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
182201 const field = node.cast(Node.ContainerField).?;
183202 field.doc_comments = doc_comments;
184203 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 };
186219 if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|
187220 field.doc_comments = appended_comment;
188221 continue;
......@@ -194,12 +227,102 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
194227 .UnattachedDocComment = .{ .token = doc_comments.?.firstToken() },
195228 });
196229 }
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 }
198243 }
199244
200245 return list;
201246}
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
203326/// Eat a multiline container doc comment
204327fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
205328 var lines = Node.DocComment.LineList.init(arena);
......@@ -279,22 +402,30 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
279402 fn_node.*.extern_export_inline_token = extern_export_inline_token;
280403 fn_node.*.lib_name = lib_name;
281404 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| {
283412 fn_node.body_node = body_node;
284413 return node;
285414 }
286415 try tree.errors.push(.{
287416 .ExpectedSemiOrLBrace = .{ .token = it.index },
288417 });
289 return null;
418 return error.ParseError;
290419 }
291420
292421 if (extern_export_inline_token) |token| {
293422 if (tree.tokens.at(token).id == .Keyword_inline or
294423 tree.tokens.at(token).id == .Keyword_noinline)
295424 {
296 putBackToken(it, token);
297 return null;
425 try tree.errors.push(.{
426 .ExpectedFn = .{ .token = it.index },
427 });
428 return error.ParseError;
298429 }
299430 }
300431
......@@ -313,42 +444,40 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
313444 try tree.errors.push(.{
314445 .ExpectedVarDecl = .{ .token = it.index },
315446 });
447 // ignore this and try again;
316448 return error.ParseError;
317449 }
318450
319451 if (extern_export_inline_token) |token| {
320 if (lib_name) |string_literal_node|
321 putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);
322 putBackToken(it, token);
323 return null;
452 try tree.errors.push(.{
453 .ExpectedVarDeclOrFn = .{ .token = it.index },
454 });
455 // ignore this and try again;
456 return error.ParseError;
324457 }
325458
326 const use_node = (try parseUse(arena, it, tree)) orelse return null;
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;
459 return try parseUse(arena, it, tree);
336460}
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)
339463fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
340 const cc = parseFnCC(arena, it, tree);
341 const fn_token = eatToken(it, .Keyword_fn) orelse {
342 if (cc) |fnCC| {
343 if (fnCC == .Extern) {
344 putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl
345 } else {
346 try tree.errors.push(.{
347 .ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn },
348 });
349 return error.ParseError;
350 }
464 // TODO: Remove once extern/async fn rewriting is
465 var is_async = false;
466 var is_extern = false;
467 const cc_token: ?usize = blk: {
468 if (eatToken(it, .Keyword_extern)) |token| {
469 is_extern = true;
470 break :blk token;
351471 }
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);
352481 return null;
353482 };
354483 const name_token = eatToken(it, .Identifier);
......@@ -361,18 +490,23 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
361490 const exclamation_token = eatToken(it, .Bang);
362491
363492 const return_type_expr = (try parseVarType(arena, it, tree)) orelse
364 try expectNode(arena, it, tree, parseTypeExpr, .{
365 .ExpectedReturnType = .{ .token = it.index },
366 });
493 (try parseTypeExpr(arena, it, tree)) orelse blk: {
494 try tree.errors.push(.{
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)
369 .{
370 .InferErrorSet = return_type_expr,
371 }
502 // TODO https://github.com/ziglang/zig/issues/3750
503 const R = Node.FnProto.ReturnType;
504 const return_type = if (return_type_expr == null)
505 R{ .Invalid = rparen }
506 else if (exclamation_token != null)
507 R{ .InferErrorSet = return_type_expr.? }
372508 else
373 .{
374 .Explicit = return_type_expr,
375 };
509 R{ .Explicit = return_type_expr.? };
376510
377511 const var_args_token = if (params.len > 0)
378512 params.at(params.len - 1).*.cast(Node.ParamDecl).?.var_args_token
......@@ -389,21 +523,15 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
389523 .return_type = return_type,
390524 .var_args_token = var_args_token,
391525 .extern_export_inline_token = null,
392 .cc_token = null,
393526 .body_node = null,
394527 .lib_name = null,
395528 .align_expr = align_expr,
396529 .section_expr = section_expr,
397530 .callconv_expr = callconv_expr,
531 .is_extern_prototype = is_extern,
532 .is_async = is_async,
398533 };
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
407535 return &fn_proto_node.base;
408536}
409537
......@@ -495,7 +623,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
495623/// Statement
496624/// <- KEYWORD_comptime? VarDecl
497625/// / KEYWORD_comptime BlockExprStatement
498/// / KEYWORD_noasync BlockExprStatement
626/// / KEYWORD_nosuspend BlockExprStatement
499627/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
500628/// / KEYWORD_defer BlockExprStatement
501629/// / KEYWORD_errdefer Payload? BlockExprStatement
......@@ -527,14 +655,14 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
527655 return &node.base;
528656 }
529657
530 if (eatToken(it, .Keyword_noasync)) |noasync_token| {
658 if (eatToken(it, .Keyword_nosuspend)) |nosuspend_token| {
531659 const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{
532660 .ExpectedBlockOrAssignment = .{ .token = it.index },
533661 });
534662
535 const node = try arena.create(Node.Noasync);
663 const node = try arena.create(Node.Nosuspend);
536664 node.* = .{
537 .noasync_token = noasync_token,
665 .nosuspend_token = nosuspend_token,
538666 .expr = block_expr,
539667 };
540668 return &node.base;
......@@ -579,7 +707,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
579707 if (try parseLabeledStatement(arena, it, tree)) |node| return node;
580708 if (try parseSwitchExpr(arena, it, tree)) |node| return node;
581709 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 };
583716 return node;
584717 }
585718
......@@ -688,8 +821,13 @@ fn parseLoopStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
688821 node.cast(Node.While).?.inline_token = inline_token;
689822 return node;
690823 }
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;
693831}
694832
695833/// ForStatement
......@@ -818,7 +956,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
818956fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
819957 if (try parseBlockExpr(arena, it, tree)) |node| return node;
820958 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 };
822965 return node;
823966 }
824967 return null;
......@@ -908,7 +1051,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
9081051/// / IfExpr
9091052/// / KEYWORD_break BreakLabel? Expr?
9101053/// / KEYWORD_comptime Expr
911/// / KEYWORD_noasync Expr
1054/// / KEYWORD_nosuspend Expr
9121055/// / KEYWORD_continue BreakLabel?
9131056/// / KEYWORD_resume Expr
9141057/// / KEYWORD_return Expr?
......@@ -925,7 +1068,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
9251068 const node = try arena.create(Node.ControlFlowExpression);
9261069 node.* = .{
9271070 .ltoken = token,
928 .kind = Node.ControlFlowExpression.Kind{ .Break = label },
1071 .kind = .{ .Break = label },
9291072 .rhs = expr_node,
9301073 };
9311074 return &node.base;
......@@ -944,13 +1087,13 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
9441087 return &node.base;
9451088 }
9461089
947 if (eatToken(it, .Keyword_noasync)) |token| {
1090 if (eatToken(it, .Keyword_nosuspend)) |token| {
9481091 const expr_node = try expectNode(arena, it, tree, parseExpr, .{
9491092 .ExpectedExpr = .{ .token = it.index },
9501093 });
951 const node = try arena.create(Node.Noasync);
1094 const node = try arena.create(Node.Nosuspend);
9521095 node.* = .{
953 .noasync_token = token,
1096 .nosuspend_token = token,
9541097 .expr = expr_node,
9551098 };
9561099 return &node.base;
......@@ -961,7 +1104,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
9611104 const node = try arena.create(Node.ControlFlowExpression);
9621105 node.* = .{
9631106 .ltoken = token,
964 .kind = Node.ControlFlowExpression.Kind{ .Continue = label },
1107 .kind = .{ .Continue = label },
9651108 .rhs = null,
9661109 };
9671110 return &node.base;
......@@ -985,7 +1128,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
9851128 const node = try arena.create(Node.ControlFlowExpression);
9861129 node.* = .{
9871130 .ltoken = token,
988 .kind = Node.ControlFlowExpression.Kind.Return,
1131 .kind = .Return,
9891132 .rhs = expr_node,
9901133 };
9911134 return &node.base;
......@@ -1023,7 +1166,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
10231166
10241167 var statements = Node.Block.StatementList.init(arena);
10251168 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;
10271177 try statements.push(statement);
10281178 }
10291179
......@@ -1197,6 +1347,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
11971347 if (maybe_async) |async_token| {
11981348 const token_fn = eatToken(it, .Keyword_fn);
11991349 if (token_fn != null) {
1350 // TODO: remove this hack when async fn rewriting is
12001351 // HACK: If we see the keyword `fn`, then we assume that
12011352 // we are parsing an async fn proto, and not a call.
12021353 // We therefore put back all tokens consumed by the async
......@@ -1205,7 +1356,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
12051356 putBackToken(it, async_token);
12061357 return parsePrimaryTypeExpr(arena, it, tree);
12071358 }
1208 // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
12091359 var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
12101360 .ExpectedPrimaryTypeExpr = .{ .token = it.index },
12111361 });
......@@ -1223,7 +1373,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
12231373 try tree.errors.push(.{
12241374 .ExpectedParamList = .{ .token = it.index },
12251375 });
1226 return null;
1376 // ignore this, continue parsing
1377 return res;
12271378 };
12281379 const node = try arena.create(Node.SuffixOp);
12291380 node.* = .{
......@@ -1288,7 +1439,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
12881439/// / IfTypeExpr
12891440/// / INTEGER
12901441/// / KEYWORD_comptime TypeExpr
1291/// / KEYWORD_noasync TypeExpr
12921442/// / KEYWORD_error DOT IDENTIFIER
12931443/// / KEYWORD_false
12941444/// / KEYWORD_null
......@@ -1327,15 +1477,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
13271477 };
13281478 return &node.base;
13291479 }
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 }
13391480 if (eatToken(it, .Keyword_error)) |token| {
13401481 const period = try expectToken(it, tree, .Period);
13411482 const identifier = try expectNode(arena, it, tree, parseIdentifier, .{
......@@ -1778,24 +1919,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
17781919 return expr_node;
17791920}
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
17991922/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
18001923fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
18011924 const doc_comments = try parseDocComment(arena, it, tree);
......@@ -2290,7 +2413,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
22902413 const node = try arena.create(Node.AnyFrameType);
22912414 node.* = .{
22922415 .anyframe_token = token,
2293 .result = Node.AnyFrameType.Result{
2416 .result = .{
22942417 .arrow_token = arrow,
22952418 .return_type = undefined, // set by caller
22962419 },
......@@ -2331,6 +2454,13 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23312454 } else null;
23322455 _ = 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
23342464 ptr_info.align_info = Node.PrefixOp.PtrInfo.Align{
23352465 .node = expr_node,
23362466 .bit_range = bit_range,
......@@ -2339,14 +2469,32 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23392469 continue;
23402470 }
23412471 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 }
23422478 ptr_info.const_token = const_token;
23432479 continue;
23442480 }
23452481 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 }
23462488 ptr_info.volatile_token = volatile_token;
23472489 continue;
23482490 }
23492491 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 }
23502498 ptr_info.allowzero_token = allowzero_token;
23512499 continue;
23522500 }
......@@ -2365,9 +2513,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23652513 if (try parseByteAlign(arena, it, tree)) |align_expr| {
23662514 if (slice_type.align_info != null) {
23672515 try tree.errors.push(.{
2368 .ExtraAlignQualifier = .{ .token = it.index },
2516 .ExtraAlignQualifier = .{ .token = it.index - 1 },
23692517 });
2370 return error.ParseError;
2518 continue;
23712519 }
23722520 slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
23732521 .node = align_expr,
......@@ -2378,9 +2526,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23782526 if (eatToken(it, .Keyword_const)) |const_token| {
23792527 if (slice_type.const_token != null) {
23802528 try tree.errors.push(.{
2381 .ExtraConstQualifier = .{ .token = it.index },
2529 .ExtraConstQualifier = .{ .token = it.index - 1 },
23822530 });
2383 return error.ParseError;
2531 continue;
23842532 }
23852533 slice_type.const_token = const_token;
23862534 continue;
......@@ -2388,9 +2536,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23882536 if (eatToken(it, .Keyword_volatile)) |volatile_token| {
23892537 if (slice_type.volatile_token != null) {
23902538 try tree.errors.push(.{
2391 .ExtraVolatileQualifier = .{ .token = it.index },
2539 .ExtraVolatileQualifier = .{ .token = it.index - 1 },
23922540 });
2393 return error.ParseError;
2541 continue;
23942542 }
23952543 slice_type.volatile_token = volatile_token;
23962544 continue;
......@@ -2398,9 +2546,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
23982546 if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
23992547 if (slice_type.allowzero_token != null) {
24002548 try tree.errors.push(.{
2401 .ExtraAllowZeroQualifier = .{ .token = it.index },
2549 .ExtraAllowZeroQualifier = .{ .token = it.index - 1 },
24022550 });
2403 return error.ParseError;
2551 continue;
24042552 }
24052553 slice_type.allowzero_token = allowzero_token;
24062554 continue;
......@@ -2749,7 +2897,19 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
27492897 var list = L.init(arena);
27502898 while (try nodeParseFn(arena, it, tree)) |node| {
27512899 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 }
27532913 }
27542914 return list;
27552915 }
......@@ -2759,7 +2919,17 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
27592919fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) NodeParseFn {
27602920 return struct {
27612921 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
27632933 const node = try arena.create(Node.InfixOp);
27642934 node.* = .{
27652935 .op_token = op_token,
......@@ -2780,7 +2950,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
27802950 try tree.errors.push(.{
27812951 .ExpectedParamList = .{ .token = it.index },
27822952 });
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;
27842960 };
27852961 const node = try arena.create(Node.BuiltinCall);
27862962 node.* = .{
......@@ -2896,8 +3072,10 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
28963072 .doc_comments = null,
28973073 .visib_token = null,
28983074 .use_token = token,
2899 .expr = undefined, // set by caller
2900 .semicolon_token = undefined, // set by caller
3075 .expr = try expectNode(arena, it, tree, parseExpr, .{
3076 .ExpectedExpr = .{ .token = it.index },
3077 }),
3078 .semicolon_token = try expectToken(it, tree, .Semicolon),
29013079 };
29023080 return &node.base;
29033081}
......@@ -3077,6 +3255,8 @@ fn expectToken(it: *TokenIterator, tree: *Tree, id: Token.Id) Error!TokenIndex {
30773255 try tree.errors.push(.{
30783256 .ExpectedToken = .{ .token = token.index, .expected_id = id },
30793257 });
3258 // go back so that we can recover properly
3259 putBackToken(it, token.index);
30803260 return error.ParseError;
30813261 }
30823262 return token.index;
lib/std/zig/parser_test.zig+211-43
......@@ -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
1151test "zig fmt: top-level fields" {
2152 try testCanonical(
3153 \\a: did_you_know,
......@@ -19,7 +169,9 @@ test "zig fmt: decl between fields" {
19169 \\ const baz1 = 2;
20170 \\ b: usize,
21171 \\};
22 );
172 , &[_]Error{
173 .DeclBetweenFields,
174 });
23175}
24176
25177test "zig fmt: errdefer with payload" {
......@@ -35,10 +187,10 @@ test "zig fmt: errdefer with payload" {
35187 );
36188}
37189
38test "zig fmt: noasync block" {
190test "zig fmt: nosuspend block" {
39191 try testCanonical(
40192 \\pub fn main() anyerror!void {
41 \\ noasync {
193 \\ nosuspend {
42194 \\ var foo: Foo = .{ .bar = 42 };
43195 \\ }
44196 \\}
......@@ -46,10 +198,10 @@ test "zig fmt: noasync block" {
46198 );
47199}
48200
49test "zig fmt: noasync await" {
201test "zig fmt: nosuspend await" {
50202 try testCanonical(
51203 \\fn foo() void {
52 \\ x = noasync await y;
204 \\ x = nosuspend await y;
53205 \\}
54206 \\
55207 );
......@@ -123,22 +275,6 @@ test "zig fmt: trailing comma in fn parameter list" {
123275 );
124276}
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
142278test "zig fmt: comptime struct field" {
143279 try testCanonical(
144280 \\const Foo = struct {
......@@ -252,10 +388,10 @@ test "zig fmt: anon list literal syntax" {
252388test "zig fmt: async function" {
253389 try testCanonical(
254390 \\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,
256392 \\};
257393 \\test "hi" {
258 \\ var ptr = @ptrCast(async fn (i32) void, other);
394 \\ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
259395 \\}
260396 \\
261397 );
......@@ -451,15 +587,6 @@ test "zig fmt: aligned struct field" {
451587 );
452588}
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
463590test "zig fmt: comment to disable/enable zig fmt first" {
464591 try testCanonical(
465592 \\// Test trailing comma syntax
......@@ -1515,7 +1642,7 @@ test "zig fmt: line comments in struct initializer" {
15151642
15161643test "zig fmt: first line comment in struct initializer" {
15171644 try testCanonical(
1518 \\pub async fn acquire(self: *Self) HeldLock {
1645 \\pub fn acquire(self: *Self) HeldLock {
15191646 \\ return HeldLock{
15201647 \\ // guaranteed allocation elision
15211648 \\ .held = self.lock.acquire(),
......@@ -2477,8 +2604,7 @@ test "zig fmt: fn type" {
24772604 \\}
24782605 \\
24792606 \\const a: fn (u8) u8 = undefined;
2480 \\const b: extern fn (u8) u8 = undefined;
2481 \\const c: fn (u8) callconv(.Naked) u8 = undefined;
2607 \\const b: fn (u8) callconv(.Naked) u8 = undefined;
24822608 \\const ap: fn (u8) u8 = a;
24832609 \\
24842610 );
......@@ -2500,7 +2626,7 @@ test "zig fmt: inline asm" {
25002626
25012627test "zig fmt: async functions" {
25022628 try testCanonical(
2503 \\async fn simpleAsyncFn() void {
2629 \\fn simpleAsyncFn() void {
25042630 \\ const a = async a.b();
25052631 \\ x += 1;
25062632 \\ suspend;
......@@ -2519,9 +2645,9 @@ test "zig fmt: async functions" {
25192645 );
25202646}
25212647
2522test "zig fmt: noasync" {
2648test "zig fmt: nosuspend" {
25232649 try testCanonical(
2524 \\const a = noasync foo();
2650 \\const a = nosuspend foo();
25252651 \\
25262652 );
25272653}
......@@ -2854,7 +2980,10 @@ test "zig fmt: extern without container keyword returns error" {
28542980 try testError(
28552981 \\const container = extern {};
28562982 \\
2857 );
2983 , &[_]Error{
2984 .ExpectedExpr,
2985 .ExpectedVarDeclOrFn,
2986 });
28582987}
28592988
28602989test "zig fmt: integer literals with underscore separators" {
......@@ -2926,6 +3055,40 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
29263055 );
29273056}
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
29293092const std = @import("std");
29303093const mem = std.mem;
29313094const warn = std.debug.warn;
......@@ -2972,7 +3135,6 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
29723135 anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);
29733136 return buffer.toOwnedSlice();
29743137}
2975
29763138fn testTransform(source: []const u8, expected_source: []const u8) !void {
29773139 const needed_alloc_count = x: {
29783140 // Try it once with unlimited memory, make sure it works
......@@ -3020,14 +3182,20 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
30203182 }
30213183 }
30223184}
3023
30243185fn testCanonical(source: []const u8) !void {
30253186 return testTransform(source, source);
30263187}
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 {
30293192 const tree = try std.zig.parse(std.testing.allocator, source);
30303193 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 }
30333201}
lib/std/zig/render.zig+22-30
......@@ -13,6 +13,9 @@ pub const Error = error{
1313
1414/// Returns whether anything changed
1515pub 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
1619 // make a passthrough stream that checks whether something changed
1720 const MyStream = struct {
1821 const MyStream = @This();
......@@ -391,11 +394,15 @@ fn renderExpression(
391394 try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
392395 return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
393396 },
394 .Noasync => {
395 const noasync_node = @fieldParentPtr(ast.Node.Noasync, "base", base);
396
397 try renderToken(tree, stream, noasync_node.noasync_token, indent, start_col, Space.Space);
398 return renderExpression(allocator, stream, tree, indent, start_col, noasync_node.expr, space);
397 .Nosuspend => {
398 const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base);
399 if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) {
400 // TODO: remove this
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);
399406 },
400407
401408 .Suspend => {
......@@ -1409,32 +1416,15 @@ fn renderExpression(
14091416 try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
14101417 }
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;
14151419 if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
1416 const tok = tree.tokens.at(extern_export_inline_token);
1417 if (tok.id != .Keyword_extern or fn_proto.body_node == null) {
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 }
1420 if (!fn_proto.is_extern_prototype)
1421 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export/inline
14231422 }
14241423
14251424 if (fn_proto.lib_name) |lib_name| {
14261425 try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
14271426 }
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
14381428 const lparen = if (fn_proto.name_token) |name_token| blk: {
14391429 try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
14401430 try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
......@@ -1457,6 +1447,7 @@ fn renderExpression(
14571447 else switch (fn_proto.return_type) {
14581448 .Explicit => |node| node.firstToken(),
14591449 .InferErrorSet => |node| tree.prevToken(node.firstToken()),
1450 .Invalid => unreachable,
14601451 });
14611452 assert(tree.tokens.at(rparen).id == .RParen);
14621453
......@@ -1524,20 +1515,21 @@ fn renderExpression(
15241515 try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
15251516 try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
15261517 try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
1527 } else if (cc_rewrite_str) |str| {
1528 try stream.writeAll("callconv(");
1529 try stream.writeAll(mem.spanZ(str));
1530 try stream.writeAll(") ");
1518 } else if (fn_proto.is_extern_prototype) {
1519 try stream.writeAll("callconv(.C) ");
1520 } else if (fn_proto.is_async) {
1521 try stream.writeAll("callconv(.Async) ");
15311522 }
15321523
15331524 switch (fn_proto.return_type) {
1534 ast.Node.FnProto.ReturnType.Explicit => |node| {
1525 .Explicit => |node| {
15351526 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
15361527 },
1537 ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
1528 .InferErrorSet => |node| {
15381529 try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !
15391530 return renderExpression(allocator, stream, tree, indent, start_col, node, space);
15401531 },
1532 .Invalid => unreachable,
15411533 }
15421534 },
15431535
lib/std/zig/system.zig+1
......@@ -837,6 +837,7 @@ pub const NativeTargetInfo = struct {
837837 error.BrokenPipe => return error.UnableToReadElfFile,
838838 error.Unseekable => return error.UnableToReadElfFile,
839839 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
840 error.ConnectionTimedOut => return error.UnableToReadElfFile,
840841 error.Unexpected => return error.Unexpected,
841842 error.InputOutput => return error.FileSystem,
842843 };
lib/std/zig/system/macos.zig+9-4
......@@ -39,7 +39,7 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
3939 zend += 1;
4040 }
4141 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
4444 result.patch = switch (result.minor) {
4545 // TODO: compiler complains without explicit @as() coercion
......@@ -97,7 +97,9 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
9797 4 => @as(u32, switch (y) { // Tiger: 10.4
9898 'A' => 0,
9999 'B' => 1,
100 'C', 'E', => 2,
100 'C',
101 'E',
102 => 2,
101103 'F' => 3,
102104 'G' => @as(u32, block: {
103105 if (z >= 1454) break :block 5;
......@@ -105,7 +107,10 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
105107 }),
106108 'H' => 5,
107109 'I' => 6,
108 'J', 'K', 'N', => 7,
110 'J',
111 'K',
112 'N',
113 => 7,
109114 'L' => 8,
110115 'P' => 9,
111116 'R' => 10,
......@@ -438,7 +443,7 @@ test "version_from_build" {
438443 for (known) |pair| {
439444 var buf: [32]u8 = undefined;
440445 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 });
442447 std.testing.expect(std.mem.eql(u8, sver, pair[1]));
443448 }
444449}
lib/std/zig/tokenizer.zig+481-486
......@@ -47,10 +47,10 @@ pub const Token = struct {
4747 Keyword.init("for", .Keyword_for),
4848 Keyword.init("if", .Keyword_if),
4949 Keyword.init("inline", .Keyword_inline),
50 Keyword.init("nakedcc", .Keyword_nakedcc),
5150 Keyword.init("noalias", .Keyword_noalias),
52 Keyword.init("noasync", .Keyword_noasync),
51 Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
5352 Keyword.init("noinline", .Keyword_noinline),
53 Keyword.init("nosuspend", .Keyword_nosuspend),
5454 Keyword.init("null", .Keyword_null),
5555 Keyword.init("or", .Keyword_or),
5656 Keyword.init("orelse", .Keyword_orelse),
......@@ -59,7 +59,6 @@ pub const Token = struct {
5959 Keyword.init("resume", .Keyword_resume),
6060 Keyword.init("return", .Keyword_return),
6161 Keyword.init("linksection", .Keyword_linksection),
62 Keyword.init("stdcallcc", .Keyword_stdcallcc),
6362 Keyword.init("struct", .Keyword_struct),
6463 Keyword.init("suspend", .Keyword_suspend),
6564 Keyword.init("switch", .Keyword_switch),
......@@ -180,10 +179,9 @@ pub const Token = struct {
180179 Keyword_for,
181180 Keyword_if,
182181 Keyword_inline,
183 Keyword_nakedcc,
184182 Keyword_noalias,
185 Keyword_noasync,
186183 Keyword_noinline,
184 Keyword_nosuspend,
187185 Keyword_null,
188186 Keyword_or,
189187 Keyword_orelse,
......@@ -193,7 +191,6 @@ pub const Token = struct {
193191 Keyword_resume,
194192 Keyword_return,
195193 Keyword_linksection,
196 Keyword_stdcallcc,
197194 Keyword_struct,
198195 Keyword_suspend,
199196 Keyword_switch,
......@@ -305,10 +302,9 @@ pub const Token = struct {
305302 .Keyword_for => "for",
306303 .Keyword_if => "if",
307304 .Keyword_inline => "inline",
308 .Keyword_nakedcc => "nakedcc",
309305 .Keyword_noalias => "noalias",
310 .Keyword_noasync => "noasync",
311306 .Keyword_noinline => "noinline",
307 .Keyword_nosuspend => "nosuspend",
312308 .Keyword_null => "null",
313309 .Keyword_or => "or",
314310 .Keyword_orelse => "orelse",
......@@ -317,7 +313,6 @@ pub const Token = struct {
317313 .Keyword_resume => "resume",
318314 .Keyword_return => "return",
319315 .Keyword_linksection => "linksection",
320 .Keyword_stdcallcc => "stdcallcc",
321316 .Keyword_struct => "struct",
322317 .Keyword_suspend => "suspend",
323318 .Keyword_switch => "switch",
......@@ -358,64 +353,64 @@ pub const Tokenizer = struct {
358353 }
359354
360355 const State = enum {
361 Start,
362 Identifier,
363 Builtin,
364 StringLiteral,
365 StringLiteralBackslash,
366 MultilineStringLiteralLine,
367 CharLiteral,
368 CharLiteralBackslash,
369 CharLiteralHexEscape,
370 CharLiteralUnicodeEscapeSawU,
371 CharLiteralUnicodeEscape,
372 CharLiteralUnicodeInvalid,
373 CharLiteralUnicode,
374 CharLiteralEnd,
375 Backslash,
376 Equal,
377 Bang,
378 Pipe,
379 Minus,
380 MinusPercent,
381 Asterisk,
382 AsteriskPercent,
383 Slash,
384 LineCommentStart,
385 LineComment,
386 DocCommentStart,
387 DocComment,
388 ContainerDocComment,
389 Zero,
390 IntegerLiteralDec,
391 IntegerLiteralDecNoUnderscore,
392 IntegerLiteralBin,
393 IntegerLiteralBinNoUnderscore,
394 IntegerLiteralOct,
395 IntegerLiteralOctNoUnderscore,
396 IntegerLiteralHex,
397 IntegerLiteralHexNoUnderscore,
398 NumberDotDec,
399 NumberDotHex,
400 FloatFractionDec,
401 FloatFractionDecNoUnderscore,
402 FloatFractionHex,
403 FloatFractionHexNoUnderscore,
404 FloatExponentUnsigned,
405 FloatExponentNumber,
406 FloatExponentNumberNoUnderscore,
407 Ampersand,
408 Caret,
409 Percent,
410 Plus,
411 PlusPercent,
412 AngleBracketLeft,
413 AngleBracketAngleBracketLeft,
414 AngleBracketRight,
415 AngleBracketAngleBracketRight,
416 Period,
417 Period2,
418 SawAtSign,
356 start,
357 identifier,
358 builtin,
359 string_literal,
360 string_literal_backslash,
361 multiline_string_literal_line,
362 char_literal,
363 char_literal_backslash,
364 char_literal_hex_escape,
365 char_literal_unicode_escape_saw_u,
366 char_literal_unicode_escape,
367 char_literal_unicode_invalid,
368 char_literal_unicode,
369 char_literal_end,
370 backslash,
371 equal,
372 bang,
373 pipe,
374 minus,
375 minus_percent,
376 asterisk,
377 asterisk_percent,
378 slash,
379 line_comment_start,
380 line_comment,
381 doc_comment_start,
382 doc_comment,
383 container_doc_comment,
384 zero,
385 int_literal_dec,
386 int_literal_dec_no_underscore,
387 int_literal_bin,
388 int_literal_bin_no_underscore,
389 int_literal_oct,
390 int_literal_oct_no_underscore,
391 int_literal_hex,
392 int_literal_hex_no_underscore,
393 num_dot_dec,
394 num_dot_hex,
395 float_fraction_dec,
396 float_fraction_dec_no_underscore,
397 float_fraction_hex,
398 float_fraction_hex_no_underscore,
399 float_exponent_unsigned,
400 float_exponent_num,
401 float_exponent_num_no_underscore,
402 ampersand,
403 caret,
404 percent,
405 plus,
406 plus_percent,
407 angle_bracket_left,
408 angle_bracket_angle_bracket_left,
409 angle_bracket_right,
410 angle_bracket_angle_bracket_right,
411 period,
412 period_2,
413 saw_at_sign,
419414 };
420415
421416 fn isIdentifierChar(char: u8) bool {
......@@ -428,9 +423,9 @@ pub const Tokenizer = struct {
428423 return token;
429424 }
430425 const start_index = self.index;
431 var state = State.Start;
426 var state: State = .start;
432427 var result = Token{
433 .id = Token.Id.Eof,
428 .id = .Eof,
434429 .start = self.index,
435430 .end = undefined,
436431 };
......@@ -439,40 +434,40 @@ pub const Tokenizer = struct {
439434 while (self.index < self.buffer.len) : (self.index += 1) {
440435 const c = self.buffer[self.index];
441436 switch (state) {
442 State.Start => switch (c) {
437 .start => switch (c) {
443438 ' ', '\n', '\t', '\r' => {
444439 result.start = self.index + 1;
445440 },
446441 '"' => {
447 state = State.StringLiteral;
448 result.id = Token.Id.StringLiteral;
442 state = .string_literal;
443 result.id = .StringLiteral;
449444 },
450445 '\'' => {
451 state = State.CharLiteral;
446 state = .char_literal;
452447 },
453448 'a'...'z', 'A'...'Z', '_' => {
454 state = State.Identifier;
455 result.id = Token.Id.Identifier;
449 state = .identifier;
450 result.id = .Identifier;
456451 },
457452 '@' => {
458 state = State.SawAtSign;
453 state = .saw_at_sign;
459454 },
460455 '=' => {
461 state = State.Equal;
456 state = .equal;
462457 },
463458 '!' => {
464 state = State.Bang;
459 state = .bang;
465460 },
466461 '|' => {
467 state = State.Pipe;
462 state = .pipe;
468463 },
469464 '(' => {
470 result.id = Token.Id.LParen;
465 result.id = .LParen;
471466 self.index += 1;
472467 break;
473468 },
474469 ')' => {
475 result.id = Token.Id.RParen;
470 result.id = .RParen;
476471 self.index += 1;
477472 break;
478473 },
......@@ -482,213 +477,213 @@ pub const Tokenizer = struct {
482477 break;
483478 },
484479 ']' => {
485 result.id = Token.Id.RBracket;
480 result.id = .RBracket;
486481 self.index += 1;
487482 break;
488483 },
489484 ';' => {
490 result.id = Token.Id.Semicolon;
485 result.id = .Semicolon;
491486 self.index += 1;
492487 break;
493488 },
494489 ',' => {
495 result.id = Token.Id.Comma;
490 result.id = .Comma;
496491 self.index += 1;
497492 break;
498493 },
499494 '?' => {
500 result.id = Token.Id.QuestionMark;
495 result.id = .QuestionMark;
501496 self.index += 1;
502497 break;
503498 },
504499 ':' => {
505 result.id = Token.Id.Colon;
500 result.id = .Colon;
506501 self.index += 1;
507502 break;
508503 },
509504 '%' => {
510 state = State.Percent;
505 state = .percent;
511506 },
512507 '*' => {
513 state = State.Asterisk;
508 state = .asterisk;
514509 },
515510 '+' => {
516 state = State.Plus;
511 state = .plus;
517512 },
518513 '<' => {
519 state = State.AngleBracketLeft;
514 state = .angle_bracket_left;
520515 },
521516 '>' => {
522 state = State.AngleBracketRight;
517 state = .angle_bracket_right;
523518 },
524519 '^' => {
525 state = State.Caret;
520 state = .caret;
526521 },
527522 '\\' => {
528 state = State.Backslash;
529 result.id = Token.Id.MultilineStringLiteralLine;
523 state = .backslash;
524 result.id = .MultilineStringLiteralLine;
530525 },
531526 '{' => {
532 result.id = Token.Id.LBrace;
527 result.id = .LBrace;
533528 self.index += 1;
534529 break;
535530 },
536531 '}' => {
537 result.id = Token.Id.RBrace;
532 result.id = .RBrace;
538533 self.index += 1;
539534 break;
540535 },
541536 '~' => {
542 result.id = Token.Id.Tilde;
537 result.id = .Tilde;
543538 self.index += 1;
544539 break;
545540 },
546541 '.' => {
547 state = State.Period;
542 state = .period;
548543 },
549544 '-' => {
550 state = State.Minus;
545 state = .minus;
551546 },
552547 '/' => {
553 state = State.Slash;
548 state = .slash;
554549 },
555550 '&' => {
556 state = State.Ampersand;
551 state = .ampersand;
557552 },
558553 '0' => {
559 state = State.Zero;
560 result.id = Token.Id.IntegerLiteral;
554 state = .zero;
555 result.id = .IntegerLiteral;
561556 },
562557 '1'...'9' => {
563 state = State.IntegerLiteralDec;
564 result.id = Token.Id.IntegerLiteral;
558 state = .int_literal_dec;
559 result.id = .IntegerLiteral;
565560 },
566561 else => {
567 result.id = Token.Id.Invalid;
562 result.id = .Invalid;
568563 self.index += 1;
569564 break;
570565 },
571566 },
572567
573 State.SawAtSign => switch (c) {
568 .saw_at_sign => switch (c) {
574569 '"' => {
575 result.id = Token.Id.Identifier;
576 state = State.StringLiteral;
570 result.id = .Identifier;
571 state = .string_literal;
577572 },
578573 else => {
579574 // reinterpret as a builtin
580575 self.index -= 1;
581 state = State.Builtin;
582 result.id = Token.Id.Builtin;
576 state = .builtin;
577 result.id = .Builtin;
583578 },
584579 },
585580
586 State.Ampersand => switch (c) {
581 .ampersand => switch (c) {
587582 '&' => {
588 result.id = Token.Id.Invalid_ampersands;
583 result.id = .Invalid_ampersands;
589584 self.index += 1;
590585 break;
591586 },
592587 '=' => {
593 result.id = Token.Id.AmpersandEqual;
588 result.id = .AmpersandEqual;
594589 self.index += 1;
595590 break;
596591 },
597592 else => {
598 result.id = Token.Id.Ampersand;
593 result.id = .Ampersand;
599594 break;
600595 },
601596 },
602597
603 State.Asterisk => switch (c) {
598 .asterisk => switch (c) {
604599 '=' => {
605 result.id = Token.Id.AsteriskEqual;
600 result.id = .AsteriskEqual;
606601 self.index += 1;
607602 break;
608603 },
609604 '*' => {
610 result.id = Token.Id.AsteriskAsterisk;
605 result.id = .AsteriskAsterisk;
611606 self.index += 1;
612607 break;
613608 },
614609 '%' => {
615 state = State.AsteriskPercent;
610 state = .asterisk_percent;
616611 },
617612 else => {
618 result.id = Token.Id.Asterisk;
613 result.id = .Asterisk;
619614 break;
620615 },
621616 },
622617
623 State.AsteriskPercent => switch (c) {
618 .asterisk_percent => switch (c) {
624619 '=' => {
625 result.id = Token.Id.AsteriskPercentEqual;
620 result.id = .AsteriskPercentEqual;
626621 self.index += 1;
627622 break;
628623 },
629624 else => {
630 result.id = Token.Id.AsteriskPercent;
625 result.id = .AsteriskPercent;
631626 break;
632627 },
633628 },
634629
635 State.Percent => switch (c) {
630 .percent => switch (c) {
636631 '=' => {
637 result.id = Token.Id.PercentEqual;
632 result.id = .PercentEqual;
638633 self.index += 1;
639634 break;
640635 },
641636 else => {
642 result.id = Token.Id.Percent;
637 result.id = .Percent;
643638 break;
644639 },
645640 },
646641
647 State.Plus => switch (c) {
642 .plus => switch (c) {
648643 '=' => {
649 result.id = Token.Id.PlusEqual;
644 result.id = .PlusEqual;
650645 self.index += 1;
651646 break;
652647 },
653648 '+' => {
654 result.id = Token.Id.PlusPlus;
649 result.id = .PlusPlus;
655650 self.index += 1;
656651 break;
657652 },
658653 '%' => {
659 state = State.PlusPercent;
654 state = .plus_percent;
660655 },
661656 else => {
662 result.id = Token.Id.Plus;
657 result.id = .Plus;
663658 break;
664659 },
665660 },
666661
667 State.PlusPercent => switch (c) {
662 .plus_percent => switch (c) {
668663 '=' => {
669 result.id = Token.Id.PlusPercentEqual;
664 result.id = .PlusPercentEqual;
670665 self.index += 1;
671666 break;
672667 },
673668 else => {
674 result.id = Token.Id.PlusPercent;
669 result.id = .PlusPercent;
675670 break;
676671 },
677672 },
678673
679 State.Caret => switch (c) {
674 .caret => switch (c) {
680675 '=' => {
681 result.id = Token.Id.CaretEqual;
676 result.id = .CaretEqual;
682677 self.index += 1;
683678 break;
684679 },
685680 else => {
686 result.id = Token.Id.Caret;
681 result.id = .Caret;
687682 break;
688683 },
689684 },
690685
691 State.Identifier => switch (c) {
686 .identifier => switch (c) {
692687 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
693688 else => {
694689 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
......@@ -697,19 +692,19 @@ pub const Tokenizer = struct {
697692 break;
698693 },
699694 },
700 State.Builtin => switch (c) {
695 .builtin => switch (c) {
701696 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
702697 else => break,
703698 },
704 State.Backslash => switch (c) {
699 .backslash => switch (c) {
705700 '\\' => {
706 state = State.MultilineStringLiteralLine;
701 state = .multiline_string_literal_line;
707702 },
708703 else => break,
709704 },
710 State.StringLiteral => switch (c) {
705 .string_literal => switch (c) {
711706 '\\' => {
712 state = State.StringLiteralBackslash;
707 state = .string_literal_backslash;
713708 },
714709 '"' => {
715710 self.index += 1;
......@@ -719,98 +714,98 @@ pub const Tokenizer = struct {
719714 else => self.checkLiteralCharacter(),
720715 },
721716
722 State.StringLiteralBackslash => switch (c) {
717 .string_literal_backslash => switch (c) {
723718 '\n', '\r' => break, // Look for this error later.
724719 else => {
725 state = State.StringLiteral;
720 state = .string_literal;
726721 },
727722 },
728723
729 State.CharLiteral => switch (c) {
724 .char_literal => switch (c) {
730725 '\\' => {
731 state = State.CharLiteralBackslash;
726 state = .char_literal_backslash;
732727 },
733728 '\'', 0x80...0xbf, 0xf8...0xff => {
734 result.id = Token.Id.Invalid;
729 result.id = .Invalid;
735730 break;
736731 },
737732 0xc0...0xdf => { // 110xxxxx
738733 remaining_code_units = 1;
739 state = State.CharLiteralUnicode;
734 state = .char_literal_unicode;
740735 },
741736 0xe0...0xef => { // 1110xxxx
742737 remaining_code_units = 2;
743 state = State.CharLiteralUnicode;
738 state = .char_literal_unicode;
744739 },
745740 0xf0...0xf7 => { // 11110xxx
746741 remaining_code_units = 3;
747 state = State.CharLiteralUnicode;
742 state = .char_literal_unicode;
748743 },
749744 else => {
750 state = State.CharLiteralEnd;
745 state = .char_literal_end;
751746 },
752747 },
753748
754 State.CharLiteralBackslash => switch (c) {
749 .char_literal_backslash => switch (c) {
755750 '\n' => {
756 result.id = Token.Id.Invalid;
751 result.id = .Invalid;
757752 break;
758753 },
759754 'x' => {
760 state = State.CharLiteralHexEscape;
755 state = .char_literal_hex_escape;
761756 seen_escape_digits = 0;
762757 },
763758 'u' => {
764 state = State.CharLiteralUnicodeEscapeSawU;
759 state = .char_literal_unicode_escape_saw_u;
765760 },
766761 else => {
767 state = State.CharLiteralEnd;
762 state = .char_literal_end;
768763 },
769764 },
770765
771 State.CharLiteralHexEscape => switch (c) {
766 .char_literal_hex_escape => switch (c) {
772767 '0'...'9', 'a'...'f', 'A'...'F' => {
773768 seen_escape_digits += 1;
774769 if (seen_escape_digits == 2) {
775 state = State.CharLiteralEnd;
770 state = .char_literal_end;
776771 }
777772 },
778773 else => {
779 result.id = Token.Id.Invalid;
774 result.id = .Invalid;
780775 break;
781776 },
782777 },
783778
784 State.CharLiteralUnicodeEscapeSawU => switch (c) {
779 .char_literal_unicode_escape_saw_u => switch (c) {
785780 '{' => {
786 state = State.CharLiteralUnicodeEscape;
781 state = .char_literal_unicode_escape;
787782 seen_escape_digits = 0;
788783 },
789784 else => {
790 result.id = Token.Id.Invalid;
791 state = State.CharLiteralUnicodeInvalid;
785 result.id = .Invalid;
786 state = .char_literal_unicode_invalid;
792787 },
793788 },
794789
795 State.CharLiteralUnicodeEscape => switch (c) {
790 .char_literal_unicode_escape => switch (c) {
796791 '0'...'9', 'a'...'f', 'A'...'F' => {
797792 seen_escape_digits += 1;
798793 },
799794 '}' => {
800795 if (seen_escape_digits == 0) {
801 result.id = Token.Id.Invalid;
802 state = State.CharLiteralUnicodeInvalid;
796 result.id = .Invalid;
797 state = .char_literal_unicode_invalid;
803798 } else {
804 state = State.CharLiteralEnd;
799 state = .char_literal_end;
805800 }
806801 },
807802 else => {
808 result.id = Token.Id.Invalid;
809 state = State.CharLiteralUnicodeInvalid;
803 result.id = .Invalid;
804 state = .char_literal_unicode_invalid;
810805 },
811806 },
812807
813 State.CharLiteralUnicodeInvalid => switch (c) {
808 .char_literal_unicode_invalid => switch (c) {
814809 // Keep consuming characters until an obvious stopping point.
815810 // This consolidates e.g. `u{0ab1Q}` into a single invalid token
816811 // instead of creating the tokens `u{0ab1`, `Q`, `}`
......@@ -818,32 +813,32 @@ pub const Tokenizer = struct {
818813 else => break,
819814 },
820815
821 State.CharLiteralEnd => switch (c) {
816 .char_literal_end => switch (c) {
822817 '\'' => {
823 result.id = Token.Id.CharLiteral;
818 result.id = .CharLiteral;
824819 self.index += 1;
825820 break;
826821 },
827822 else => {
828 result.id = Token.Id.Invalid;
823 result.id = .Invalid;
829824 break;
830825 },
831826 },
832827
833 State.CharLiteralUnicode => switch (c) {
828 .char_literal_unicode => switch (c) {
834829 0x80...0xbf => {
835830 remaining_code_units -= 1;
836831 if (remaining_code_units == 0) {
837 state = State.CharLiteralEnd;
832 state = .char_literal_end;
838833 }
839834 },
840835 else => {
841 result.id = Token.Id.Invalid;
836 result.id = .Invalid;
842837 break;
843838 },
844839 },
845840
846 State.MultilineStringLiteralLine => switch (c) {
841 .multiline_string_literal_line => switch (c) {
847842 '\n' => {
848843 self.index += 1;
849844 break;
......@@ -852,449 +847,449 @@ pub const Tokenizer = struct {
852847 else => self.checkLiteralCharacter(),
853848 },
854849
855 State.Bang => switch (c) {
850 .bang => switch (c) {
856851 '=' => {
857 result.id = Token.Id.BangEqual;
852 result.id = .BangEqual;
858853 self.index += 1;
859854 break;
860855 },
861856 else => {
862 result.id = Token.Id.Bang;
857 result.id = .Bang;
863858 break;
864859 },
865860 },
866861
867 State.Pipe => switch (c) {
862 .pipe => switch (c) {
868863 '=' => {
869 result.id = Token.Id.PipeEqual;
864 result.id = .PipeEqual;
870865 self.index += 1;
871866 break;
872867 },
873868 '|' => {
874 result.id = Token.Id.PipePipe;
869 result.id = .PipePipe;
875870 self.index += 1;
876871 break;
877872 },
878873 else => {
879 result.id = Token.Id.Pipe;
874 result.id = .Pipe;
880875 break;
881876 },
882877 },
883878
884 State.Equal => switch (c) {
879 .equal => switch (c) {
885880 '=' => {
886 result.id = Token.Id.EqualEqual;
881 result.id = .EqualEqual;
887882 self.index += 1;
888883 break;
889884 },
890885 '>' => {
891 result.id = Token.Id.EqualAngleBracketRight;
886 result.id = .EqualAngleBracketRight;
892887 self.index += 1;
893888 break;
894889 },
895890 else => {
896 result.id = Token.Id.Equal;
891 result.id = .Equal;
897892 break;
898893 },
899894 },
900895
901 State.Minus => switch (c) {
896 .minus => switch (c) {
902897 '>' => {
903 result.id = Token.Id.Arrow;
898 result.id = .Arrow;
904899 self.index += 1;
905900 break;
906901 },
907902 '=' => {
908 result.id = Token.Id.MinusEqual;
903 result.id = .MinusEqual;
909904 self.index += 1;
910905 break;
911906 },
912907 '%' => {
913 state = State.MinusPercent;
908 state = .minus_percent;
914909 },
915910 else => {
916 result.id = Token.Id.Minus;
911 result.id = .Minus;
917912 break;
918913 },
919914 },
920915
921 State.MinusPercent => switch (c) {
916 .minus_percent => switch (c) {
922917 '=' => {
923 result.id = Token.Id.MinusPercentEqual;
918 result.id = .MinusPercentEqual;
924919 self.index += 1;
925920 break;
926921 },
927922 else => {
928 result.id = Token.Id.MinusPercent;
923 result.id = .MinusPercent;
929924 break;
930925 },
931926 },
932927
933 State.AngleBracketLeft => switch (c) {
928 .angle_bracket_left => switch (c) {
934929 '<' => {
935 state = State.AngleBracketAngleBracketLeft;
930 state = .angle_bracket_angle_bracket_left;
936931 },
937932 '=' => {
938 result.id = Token.Id.AngleBracketLeftEqual;
933 result.id = .AngleBracketLeftEqual;
939934 self.index += 1;
940935 break;
941936 },
942937 else => {
943 result.id = Token.Id.AngleBracketLeft;
938 result.id = .AngleBracketLeft;
944939 break;
945940 },
946941 },
947942
948 State.AngleBracketAngleBracketLeft => switch (c) {
943 .angle_bracket_angle_bracket_left => switch (c) {
949944 '=' => {
950 result.id = Token.Id.AngleBracketAngleBracketLeftEqual;
945 result.id = .AngleBracketAngleBracketLeftEqual;
951946 self.index += 1;
952947 break;
953948 },
954949 else => {
955 result.id = Token.Id.AngleBracketAngleBracketLeft;
950 result.id = .AngleBracketAngleBracketLeft;
956951 break;
957952 },
958953 },
959954
960 State.AngleBracketRight => switch (c) {
955 .angle_bracket_right => switch (c) {
961956 '>' => {
962 state = State.AngleBracketAngleBracketRight;
957 state = .angle_bracket_angle_bracket_right;
963958 },
964959 '=' => {
965 result.id = Token.Id.AngleBracketRightEqual;
960 result.id = .AngleBracketRightEqual;
966961 self.index += 1;
967962 break;
968963 },
969964 else => {
970 result.id = Token.Id.AngleBracketRight;
965 result.id = .AngleBracketRight;
971966 break;
972967 },
973968 },
974969
975 State.AngleBracketAngleBracketRight => switch (c) {
970 .angle_bracket_angle_bracket_right => switch (c) {
976971 '=' => {
977 result.id = Token.Id.AngleBracketAngleBracketRightEqual;
972 result.id = .AngleBracketAngleBracketRightEqual;
978973 self.index += 1;
979974 break;
980975 },
981976 else => {
982 result.id = Token.Id.AngleBracketAngleBracketRight;
977 result.id = .AngleBracketAngleBracketRight;
983978 break;
984979 },
985980 },
986981
987 State.Period => switch (c) {
982 .period => switch (c) {
988983 '.' => {
989 state = State.Period2;
984 state = .period_2;
990985 },
991986 '*' => {
992 result.id = Token.Id.PeriodAsterisk;
987 result.id = .PeriodAsterisk;
993988 self.index += 1;
994989 break;
995990 },
996991 else => {
997 result.id = Token.Id.Period;
992 result.id = .Period;
998993 break;
999994 },
1000995 },
1001996
1002 State.Period2 => switch (c) {
997 .period_2 => switch (c) {
1003998 '.' => {
1004 result.id = Token.Id.Ellipsis3;
999 result.id = .Ellipsis3;
10051000 self.index += 1;
10061001 break;
10071002 },
10081003 else => {
1009 result.id = Token.Id.Ellipsis2;
1004 result.id = .Ellipsis2;
10101005 break;
10111006 },
10121007 },
10131008
1014 State.Slash => switch (c) {
1009 .slash => switch (c) {
10151010 '/' => {
1016 state = State.LineCommentStart;
1017 result.id = Token.Id.LineComment;
1011 state = .line_comment_start;
1012 result.id = .LineComment;
10181013 },
10191014 '=' => {
1020 result.id = Token.Id.SlashEqual;
1015 result.id = .SlashEqual;
10211016 self.index += 1;
10221017 break;
10231018 },
10241019 else => {
1025 result.id = Token.Id.Slash;
1020 result.id = .Slash;
10261021 break;
10271022 },
10281023 },
1029 State.LineCommentStart => switch (c) {
1024 .line_comment_start => switch (c) {
10301025 '/' => {
1031 state = State.DocCommentStart;
1026 state = .doc_comment_start;
10321027 },
10331028 '!' => {
1034 result.id = Token.Id.ContainerDocComment;
1035 state = State.ContainerDocComment;
1029 result.id = .ContainerDocComment;
1030 state = .container_doc_comment;
10361031 },
10371032 '\n' => break,
10381033 else => {
1039 state = State.LineComment;
1034 state = .line_comment;
10401035 self.checkLiteralCharacter();
10411036 },
10421037 },
1043 State.DocCommentStart => switch (c) {
1038 .doc_comment_start => switch (c) {
10441039 '/' => {
1045 state = State.LineComment;
1040 state = .line_comment;
10461041 },
10471042 '\n' => {
1048 result.id = Token.Id.DocComment;
1043 result.id = .DocComment;
10491044 break;
10501045 },
10511046 else => {
1052 state = State.DocComment;
1053 result.id = Token.Id.DocComment;
1047 state = .doc_comment;
1048 result.id = .DocComment;
10541049 self.checkLiteralCharacter();
10551050 },
10561051 },
1057 State.LineComment, State.DocComment, State.ContainerDocComment => switch (c) {
1052 .line_comment, .doc_comment, .container_doc_comment => switch (c) {
10581053 '\n' => break,
10591054 else => self.checkLiteralCharacter(),
10601055 },
1061 State.Zero => switch (c) {
1056 .zero => switch (c) {
10621057 'b' => {
1063 state = State.IntegerLiteralBinNoUnderscore;
1058 state = .int_literal_bin_no_underscore;
10641059 },
10651060 'o' => {
1066 state = State.IntegerLiteralOctNoUnderscore;
1061 state = .int_literal_oct_no_underscore;
10671062 },
10681063 'x' => {
1069 state = State.IntegerLiteralHexNoUnderscore;
1064 state = .int_literal_hex_no_underscore;
10701065 },
10711066 '0'...'9', '_', '.', 'e', 'E' => {
10721067 // reinterpret as a decimal number
10731068 self.index -= 1;
1074 state = State.IntegerLiteralDec;
1069 state = .int_literal_dec;
10751070 },
10761071 else => {
10771072 if (isIdentifierChar(c)) {
1078 result.id = Token.Id.Invalid;
1073 result.id = .Invalid;
10791074 }
10801075 break;
10811076 },
10821077 },
1083 State.IntegerLiteralBinNoUnderscore => switch (c) {
1078 .int_literal_bin_no_underscore => switch (c) {
10841079 '0'...'1' => {
1085 state = State.IntegerLiteralBin;
1080 state = .int_literal_bin;
10861081 },
10871082 else => {
1088 result.id = Token.Id.Invalid;
1083 result.id = .Invalid;
10891084 break;
10901085 },
10911086 },
1092 State.IntegerLiteralBin => switch (c) {
1087 .int_literal_bin => switch (c) {
10931088 '_' => {
1094 state = State.IntegerLiteralBinNoUnderscore;
1089 state = .int_literal_bin_no_underscore;
10951090 },
10961091 '0'...'1' => {},
10971092 else => {
10981093 if (isIdentifierChar(c)) {
1099 result.id = Token.Id.Invalid;
1094 result.id = .Invalid;
11001095 }
11011096 break;
11021097 },
11031098 },
1104 State.IntegerLiteralOctNoUnderscore => switch (c) {
1099 .int_literal_oct_no_underscore => switch (c) {
11051100 '0'...'7' => {
1106 state = State.IntegerLiteralOct;
1101 state = .int_literal_oct;
11071102 },
11081103 else => {
1109 result.id = Token.Id.Invalid;
1104 result.id = .Invalid;
11101105 break;
11111106 },
11121107 },
1113 State.IntegerLiteralOct => switch (c) {
1108 .int_literal_oct => switch (c) {
11141109 '_' => {
1115 state = State.IntegerLiteralOctNoUnderscore;
1110 state = .int_literal_oct_no_underscore;
11161111 },
11171112 '0'...'7' => {},
11181113 else => {
11191114 if (isIdentifierChar(c)) {
1120 result.id = Token.Id.Invalid;
1115 result.id = .Invalid;
11211116 }
11221117 break;
11231118 },
11241119 },
1125 State.IntegerLiteralDecNoUnderscore => switch (c) {
1120 .int_literal_dec_no_underscore => switch (c) {
11261121 '0'...'9' => {
1127 state = State.IntegerLiteralDec;
1122 state = .int_literal_dec;
11281123 },
11291124 else => {
1130 result.id = Token.Id.Invalid;
1125 result.id = .Invalid;
11311126 break;
11321127 },
11331128 },
1134 State.IntegerLiteralDec => switch (c) {
1129 .int_literal_dec => switch (c) {
11351130 '_' => {
1136 state = State.IntegerLiteralDecNoUnderscore;
1131 state = .int_literal_dec_no_underscore;
11371132 },
11381133 '.' => {
1139 state = State.NumberDotDec;
1140 result.id = Token.Id.FloatLiteral;
1134 state = .num_dot_dec;
1135 result.id = .FloatLiteral;
11411136 },
11421137 'e', 'E' => {
1143 state = State.FloatExponentUnsigned;
1144 result.id = Token.Id.FloatLiteral;
1138 state = .float_exponent_unsigned;
1139 result.id = .FloatLiteral;
11451140 },
11461141 '0'...'9' => {},
11471142 else => {
11481143 if (isIdentifierChar(c)) {
1149 result.id = Token.Id.Invalid;
1144 result.id = .Invalid;
11501145 }
11511146 break;
11521147 },
11531148 },
1154 State.IntegerLiteralHexNoUnderscore => switch (c) {
1149 .int_literal_hex_no_underscore => switch (c) {
11551150 '0'...'9', 'a'...'f', 'A'...'F' => {
1156 state = State.IntegerLiteralHex;
1151 state = .int_literal_hex;
11571152 },
11581153 else => {
1159 result.id = Token.Id.Invalid;
1154 result.id = .Invalid;
11601155 break;
11611156 },
11621157 },
1163 State.IntegerLiteralHex => switch (c) {
1158 .int_literal_hex => switch (c) {
11641159 '_' => {
1165 state = State.IntegerLiteralHexNoUnderscore;
1160 state = .int_literal_hex_no_underscore;
11661161 },
11671162 '.' => {
1168 state = State.NumberDotHex;
1169 result.id = Token.Id.FloatLiteral;
1163 state = .num_dot_hex;
1164 result.id = .FloatLiteral;
11701165 },
11711166 'p', 'P' => {
1172 state = State.FloatExponentUnsigned;
1173 result.id = Token.Id.FloatLiteral;
1167 state = .float_exponent_unsigned;
1168 result.id = .FloatLiteral;
11741169 },
11751170 '0'...'9', 'a'...'f', 'A'...'F' => {},
11761171 else => {
11771172 if (isIdentifierChar(c)) {
1178 result.id = Token.Id.Invalid;
1173 result.id = .Invalid;
11791174 }
11801175 break;
11811176 },
11821177 },
1183 State.NumberDotDec => switch (c) {
1178 .num_dot_dec => switch (c) {
11841179 '.' => {
11851180 self.index -= 1;
1186 state = State.Start;
1181 state = .start;
11871182 break;
11881183 },
11891184 'e', 'E' => {
1190 state = State.FloatExponentUnsigned;
1185 state = .float_exponent_unsigned;
11911186 },
11921187 '0'...'9' => {
1193 result.id = Token.Id.FloatLiteral;
1194 state = State.FloatFractionDec;
1188 result.id = .FloatLiteral;
1189 state = .float_fraction_dec;
11951190 },
11961191 else => {
11971192 if (isIdentifierChar(c)) {
1198 result.id = Token.Id.Invalid;
1193 result.id = .Invalid;
11991194 }
12001195 break;
12011196 },
12021197 },
1203 State.NumberDotHex => switch (c) {
1198 .num_dot_hex => switch (c) {
12041199 '.' => {
12051200 self.index -= 1;
1206 state = State.Start;
1201 state = .start;
12071202 break;
12081203 },
12091204 'p', 'P' => {
1210 state = State.FloatExponentUnsigned;
1205 state = .float_exponent_unsigned;
12111206 },
12121207 '0'...'9', 'a'...'f', 'A'...'F' => {
1213 result.id = Token.Id.FloatLiteral;
1214 state = State.FloatFractionHex;
1208 result.id = .FloatLiteral;
1209 state = .float_fraction_hex;
12151210 },
12161211 else => {
12171212 if (isIdentifierChar(c)) {
1218 result.id = Token.Id.Invalid;
1213 result.id = .Invalid;
12191214 }
12201215 break;
12211216 },
12221217 },
1223 State.FloatFractionDecNoUnderscore => switch (c) {
1218 .float_fraction_dec_no_underscore => switch (c) {
12241219 '0'...'9' => {
1225 state = State.FloatFractionDec;
1220 state = .float_fraction_dec;
12261221 },
12271222 else => {
1228 result.id = Token.Id.Invalid;
1223 result.id = .Invalid;
12291224 break;
12301225 },
12311226 },
1232 State.FloatFractionDec => switch (c) {
1227 .float_fraction_dec => switch (c) {
12331228 '_' => {
1234 state = State.FloatFractionDecNoUnderscore;
1229 state = .float_fraction_dec_no_underscore;
12351230 },
12361231 'e', 'E' => {
1237 state = State.FloatExponentUnsigned;
1232 state = .float_exponent_unsigned;
12381233 },
12391234 '0'...'9' => {},
12401235 else => {
12411236 if (isIdentifierChar(c)) {
1242 result.id = Token.Id.Invalid;
1237 result.id = .Invalid;
12431238 }
12441239 break;
12451240 },
12461241 },
1247 State.FloatFractionHexNoUnderscore => switch (c) {
1242 .float_fraction_hex_no_underscore => switch (c) {
12481243 '0'...'9', 'a'...'f', 'A'...'F' => {
1249 state = State.FloatFractionHex;
1244 state = .float_fraction_hex;
12501245 },
12511246 else => {
1252 result.id = Token.Id.Invalid;
1247 result.id = .Invalid;
12531248 break;
12541249 },
12551250 },
1256 State.FloatFractionHex => switch (c) {
1251 .float_fraction_hex => switch (c) {
12571252 '_' => {
1258 state = State.FloatFractionHexNoUnderscore;
1253 state = .float_fraction_hex_no_underscore;
12591254 },
12601255 'p', 'P' => {
1261 state = State.FloatExponentUnsigned;
1256 state = .float_exponent_unsigned;
12621257 },
12631258 '0'...'9', 'a'...'f', 'A'...'F' => {},
12641259 else => {
12651260 if (isIdentifierChar(c)) {
1266 result.id = Token.Id.Invalid;
1261 result.id = .Invalid;
12671262 }
12681263 break;
12691264 },
12701265 },
1271 State.FloatExponentUnsigned => switch (c) {
1266 .float_exponent_unsigned => switch (c) {
12721267 '+', '-' => {
1273 state = State.FloatExponentNumberNoUnderscore;
1268 state = .float_exponent_num_no_underscore;
12741269 },
12751270 else => {
12761271 // reinterpret as a normal exponent number
12771272 self.index -= 1;
1278 state = State.FloatExponentNumberNoUnderscore;
1273 state = .float_exponent_num_no_underscore;
12791274 },
12801275 },
1281 State.FloatExponentNumberNoUnderscore => switch (c) {
1276 .float_exponent_num_no_underscore => switch (c) {
12821277 '0'...'9' => {
1283 state = State.FloatExponentNumber;
1278 state = .float_exponent_num;
12841279 },
12851280 else => {
1286 result.id = Token.Id.Invalid;
1281 result.id = .Invalid;
12871282 break;
12881283 },
12891284 },
1290 State.FloatExponentNumber => switch (c) {
1285 .float_exponent_num => switch (c) {
12911286 '_' => {
1292 state = State.FloatExponentNumberNoUnderscore;
1287 state = .float_exponent_num_no_underscore;
12931288 },
12941289 '0'...'9' => {},
12951290 else => {
12961291 if (isIdentifierChar(c)) {
1297 result.id = Token.Id.Invalid;
1292 result.id = .Invalid;
12981293 }
12991294 break;
13001295 },
......@@ -1302,123 +1297,123 @@ pub const Tokenizer = struct {
13021297 }
13031298 } else if (self.index == self.buffer.len) {
13041299 switch (state) {
1305 State.Start,
1306 State.IntegerLiteralDec,
1307 State.IntegerLiteralBin,
1308 State.IntegerLiteralOct,
1309 State.IntegerLiteralHex,
1310 State.NumberDotDec,
1311 State.NumberDotHex,
1312 State.FloatFractionDec,
1313 State.FloatFractionHex,
1314 State.FloatExponentNumber,
1315 State.StringLiteral, // find this error later
1316 State.MultilineStringLiteralLine,
1317 State.Builtin,
1300 .start,
1301 .int_literal_dec,
1302 .int_literal_bin,
1303 .int_literal_oct,
1304 .int_literal_hex,
1305 .num_dot_dec,
1306 .num_dot_hex,
1307 .float_fraction_dec,
1308 .float_fraction_hex,
1309 .float_exponent_num,
1310 .string_literal, // find this error later
1311 .multiline_string_literal_line,
1312 .builtin,
13181313 => {},
13191314
1320 State.Identifier => {
1315 .identifier => {
13211316 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
13221317 result.id = id;
13231318 }
13241319 },
1325 State.LineCommentStart, State.LineComment => {
1326 result.id = Token.Id.LineComment;
1327 },
1328 State.DocComment, State.DocCommentStart => {
1329 result.id = Token.Id.DocComment;
1330 },
1331 State.ContainerDocComment => {
1332 result.id = Token.Id.ContainerDocComment;
1333 },
1334
1335 State.IntegerLiteralDecNoUnderscore,
1336 State.IntegerLiteralBinNoUnderscore,
1337 State.IntegerLiteralOctNoUnderscore,
1338 State.IntegerLiteralHexNoUnderscore,
1339 State.FloatFractionDecNoUnderscore,
1340 State.FloatFractionHexNoUnderscore,
1341 State.FloatExponentNumberNoUnderscore,
1342 State.FloatExponentUnsigned,
1343 State.SawAtSign,
1344 State.Backslash,
1345 State.CharLiteral,
1346 State.CharLiteralBackslash,
1347 State.CharLiteralHexEscape,
1348 State.CharLiteralUnicodeEscapeSawU,
1349 State.CharLiteralUnicodeEscape,
1350 State.CharLiteralUnicodeInvalid,
1351 State.CharLiteralEnd,
1352 State.CharLiteralUnicode,
1353 State.StringLiteralBackslash,
1320 .line_comment, .line_comment_start => {
1321 result.id = .LineComment;
1322 },
1323 .doc_comment, .doc_comment_start => {
1324 result.id = .DocComment;
1325 },
1326 .container_doc_comment => {
1327 result.id = .ContainerDocComment;
1328 },
1329
1330 .int_literal_dec_no_underscore,
1331 .int_literal_bin_no_underscore,
1332 .int_literal_oct_no_underscore,
1333 .int_literal_hex_no_underscore,
1334 .float_fraction_dec_no_underscore,
1335 .float_fraction_hex_no_underscore,
1336 .float_exponent_num_no_underscore,
1337 .float_exponent_unsigned,
1338 .saw_at_sign,
1339 .backslash,
1340 .char_literal,
1341 .char_literal_backslash,
1342 .char_literal_hex_escape,
1343 .char_literal_unicode_escape_saw_u,
1344 .char_literal_unicode_escape,
1345 .char_literal_unicode_invalid,
1346 .char_literal_end,
1347 .char_literal_unicode,
1348 .string_literal_backslash,
13541349 => {
1355 result.id = Token.Id.Invalid;
1350 result.id = .Invalid;
13561351 },
13571352
1358 State.Equal => {
1359 result.id = Token.Id.Equal;
1353 .equal => {
1354 result.id = .Equal;
13601355 },
1361 State.Bang => {
1362 result.id = Token.Id.Bang;
1356 .bang => {
1357 result.id = .Bang;
13631358 },
1364 State.Minus => {
1365 result.id = Token.Id.Minus;
1359 .minus => {
1360 result.id = .Minus;
13661361 },
1367 State.Slash => {
1368 result.id = Token.Id.Slash;
1362 .slash => {
1363 result.id = .Slash;
13691364 },
1370 State.Zero => {
1371 result.id = Token.Id.IntegerLiteral;
1365 .zero => {
1366 result.id = .IntegerLiteral;
13721367 },
1373 State.Ampersand => {
1374 result.id = Token.Id.Ampersand;
1368 .ampersand => {
1369 result.id = .Ampersand;
13751370 },
1376 State.Period => {
1377 result.id = Token.Id.Period;
1371 .period => {
1372 result.id = .Period;
13781373 },
1379 State.Period2 => {
1380 result.id = Token.Id.Ellipsis2;
1374 .period_2 => {
1375 result.id = .Ellipsis2;
13811376 },
1382 State.Pipe => {
1383 result.id = Token.Id.Pipe;
1377 .pipe => {
1378 result.id = .Pipe;
13841379 },
1385 State.AngleBracketAngleBracketRight => {
1386 result.id = Token.Id.AngleBracketAngleBracketRight;
1380 .angle_bracket_angle_bracket_right => {
1381 result.id = .AngleBracketAngleBracketRight;
13871382 },
1388 State.AngleBracketRight => {
1389 result.id = Token.Id.AngleBracketRight;
1383 .angle_bracket_right => {
1384 result.id = .AngleBracketRight;
13901385 },
1391 State.AngleBracketAngleBracketLeft => {
1392 result.id = Token.Id.AngleBracketAngleBracketLeft;
1386 .angle_bracket_angle_bracket_left => {
1387 result.id = .AngleBracketAngleBracketLeft;
13931388 },
1394 State.AngleBracketLeft => {
1395 result.id = Token.Id.AngleBracketLeft;
1389 .angle_bracket_left => {
1390 result.id = .AngleBracketLeft;
13961391 },
1397 State.PlusPercent => {
1398 result.id = Token.Id.PlusPercent;
1392 .plus_percent => {
1393 result.id = .PlusPercent;
13991394 },
1400 State.Plus => {
1401 result.id = Token.Id.Plus;
1395 .plus => {
1396 result.id = .Plus;
14021397 },
1403 State.Percent => {
1404 result.id = Token.Id.Percent;
1398 .percent => {
1399 result.id = .Percent;
14051400 },
1406 State.Caret => {
1407 result.id = Token.Id.Caret;
1401 .caret => {
1402 result.id = .Caret;
14081403 },
1409 State.AsteriskPercent => {
1410 result.id = Token.Id.AsteriskPercent;
1404 .asterisk_percent => {
1405 result.id = .AsteriskPercent;
14111406 },
1412 State.Asterisk => {
1413 result.id = Token.Id.Asterisk;
1407 .asterisk => {
1408 result.id = .Asterisk;
14141409 },
1415 State.MinusPercent => {
1416 result.id = Token.Id.MinusPercent;
1410 .minus_percent => {
1411 result.id = .MinusPercent;
14171412 },
14181413 }
14191414 }
14201415
1421 if (result.id == Token.Id.Eof) {
1416 if (result.id == .Eof) {
14221417 if (self.pending_invalid_token) |token| {
14231418 self.pending_invalid_token = null;
14241419 return token;
......@@ -1433,8 +1428,8 @@ pub const Tokenizer = struct {
14331428 if (self.pending_invalid_token != null) return;
14341429 const invalid_length = self.getInvalidCharacterLength();
14351430 if (invalid_length == 0) return;
1436 self.pending_invalid_token = Token{
1437 .id = Token.Id.Invalid,
1431 self.pending_invalid_token = .{
1432 .id = .Invalid,
14381433 .start = self.index,
14391434 .end = self.index + invalid_length,
14401435 };
......@@ -1479,7 +1474,7 @@ pub const Tokenizer = struct {
14791474};
14801475
14811476test "tokenizer" {
1482 testTokenize("test", &[_]Token.Id{Token.Id.Keyword_test});
1477 testTokenize("test", &[_]Token.Id{.Keyword_test});
14831478}
14841479
14851480test "tokenizer - unknown length pointer and then c pointer" {
......@@ -1487,15 +1482,15 @@ test "tokenizer - unknown length pointer and then c pointer" {
14871482 \\[*]u8
14881483 \\[*c]u8
14891484 , &[_]Token.Id{
1490 Token.Id.LBracket,
1491 Token.Id.Asterisk,
1492 Token.Id.RBracket,
1493 Token.Id.Identifier,
1494 Token.Id.LBracket,
1495 Token.Id.Asterisk,
1496 Token.Id.Identifier,
1497 Token.Id.RBracket,
1498 Token.Id.Identifier,
1485 .LBracket,
1486 .Asterisk,
1487 .RBracket,
1488 .Identifier,
1489 .LBracket,
1490 .Asterisk,
1491 .Identifier,
1492 .RBracket,
1493 .Identifier,
14991494 });
15001495}
15011496
......@@ -1566,125 +1561,125 @@ test "tokenizer - char literal with unicode code point" {
15661561
15671562test "tokenizer - float literal e exponent" {
15681563 testTokenize("a = 4.94065645841246544177e-324;\n", &[_]Token.Id{
1569 Token.Id.Identifier,
1570 Token.Id.Equal,
1571 Token.Id.FloatLiteral,
1572 Token.Id.Semicolon,
1564 .Identifier,
1565 .Equal,
1566 .FloatLiteral,
1567 .Semicolon,
15731568 });
15741569}
15751570
15761571test "tokenizer - float literal p exponent" {
15771572 testTokenize("a = 0x1.a827999fcef32p+1022;\n", &[_]Token.Id{
1578 Token.Id.Identifier,
1579 Token.Id.Equal,
1580 Token.Id.FloatLiteral,
1581 Token.Id.Semicolon,
1573 .Identifier,
1574 .Equal,
1575 .FloatLiteral,
1576 .Semicolon,
15821577 });
15831578}
15841579
15851580test "tokenizer - chars" {
1586 testTokenize("'c'", &[_]Token.Id{Token.Id.CharLiteral});
1581 testTokenize("'c'", &[_]Token.Id{.CharLiteral});
15871582}
15881583
15891584test "tokenizer - invalid token characters" {
1590 testTokenize("#", &[_]Token.Id{Token.Id.Invalid});
1591 testTokenize("`", &[_]Token.Id{Token.Id.Invalid});
1592 testTokenize("'c", &[_]Token.Id{Token.Id.Invalid});
1593 testTokenize("'", &[_]Token.Id{Token.Id.Invalid});
1594 testTokenize("''", &[_]Token.Id{ Token.Id.Invalid, Token.Id.Invalid });
1585 testTokenize("#", &[_]Token.Id{.Invalid});
1586 testTokenize("`", &[_]Token.Id{.Invalid});
1587 testTokenize("'c", &[_]Token.Id{.Invalid});
1588 testTokenize("'", &[_]Token.Id{.Invalid});
1589 testTokenize("''", &[_]Token.Id{ .Invalid, .Invalid });
15951590}
15961591
15971592test "tokenizer - invalid literal/comment characters" {
15981593 testTokenize("\"\x00\"", &[_]Token.Id{
1599 Token.Id.StringLiteral,
1600 Token.Id.Invalid,
1594 .StringLiteral,
1595 .Invalid,
16011596 });
16021597 testTokenize("//\x00", &[_]Token.Id{
1603 Token.Id.LineComment,
1604 Token.Id.Invalid,
1598 .LineComment,
1599 .Invalid,
16051600 });
16061601 testTokenize("//\x1f", &[_]Token.Id{
1607 Token.Id.LineComment,
1608 Token.Id.Invalid,
1602 .LineComment,
1603 .Invalid,
16091604 });
16101605 testTokenize("//\x7f", &[_]Token.Id{
1611 Token.Id.LineComment,
1612 Token.Id.Invalid,
1606 .LineComment,
1607 .Invalid,
16131608 });
16141609}
16151610
16161611test "tokenizer - utf8" {
1617 testTokenize("//\xc2\x80", &[_]Token.Id{Token.Id.LineComment});
1618 testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{Token.Id.LineComment});
1612 testTokenize("//\xc2\x80", &[_]Token.Id{.LineComment});
1613 testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{.LineComment});
16191614}
16201615
16211616test "tokenizer - invalid utf8" {
16221617 testTokenize("//\x80", &[_]Token.Id{
1623 Token.Id.LineComment,
1624 Token.Id.Invalid,
1618 .LineComment,
1619 .Invalid,
16251620 });
16261621 testTokenize("//\xbf", &[_]Token.Id{
1627 Token.Id.LineComment,
1628 Token.Id.Invalid,
1622 .LineComment,
1623 .Invalid,
16291624 });
16301625 testTokenize("//\xf8", &[_]Token.Id{
1631 Token.Id.LineComment,
1632 Token.Id.Invalid,
1626 .LineComment,
1627 .Invalid,
16331628 });
16341629 testTokenize("//\xff", &[_]Token.Id{
1635 Token.Id.LineComment,
1636 Token.Id.Invalid,
1630 .LineComment,
1631 .Invalid,
16371632 });
16381633 testTokenize("//\xc2\xc0", &[_]Token.Id{
1639 Token.Id.LineComment,
1640 Token.Id.Invalid,
1634 .LineComment,
1635 .Invalid,
16411636 });
16421637 testTokenize("//\xe0", &[_]Token.Id{
1643 Token.Id.LineComment,
1644 Token.Id.Invalid,
1638 .LineComment,
1639 .Invalid,
16451640 });
16461641 testTokenize("//\xf0", &[_]Token.Id{
1647 Token.Id.LineComment,
1648 Token.Id.Invalid,
1642 .LineComment,
1643 .Invalid,
16491644 });
16501645 testTokenize("//\xf0\x90\x80\xc0", &[_]Token.Id{
1651 Token.Id.LineComment,
1652 Token.Id.Invalid,
1646 .LineComment,
1647 .Invalid,
16531648 });
16541649}
16551650
16561651test "tokenizer - illegal unicode codepoints" {
16571652 // 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});
16591654 testTokenize("//\xc2\x85", &[_]Token.Id{
1660 Token.Id.LineComment,
1661 Token.Id.Invalid,
1655 .LineComment,
1656 .Invalid,
16621657 });
1663 testTokenize("//\xc2\x86", &[_]Token.Id{Token.Id.LineComment});
1664 testTokenize("//\xe2\x80\xa7", &[_]Token.Id{Token.Id.LineComment});
1658 testTokenize("//\xc2\x86", &[_]Token.Id{.LineComment});
1659 testTokenize("//\xe2\x80\xa7", &[_]Token.Id{.LineComment});
16651660 testTokenize("//\xe2\x80\xa8", &[_]Token.Id{
1666 Token.Id.LineComment,
1667 Token.Id.Invalid,
1661 .LineComment,
1662 .Invalid,
16681663 });
16691664 testTokenize("//\xe2\x80\xa9", &[_]Token.Id{
1670 Token.Id.LineComment,
1671 Token.Id.Invalid,
1665 .LineComment,
1666 .Invalid,
16721667 });
1673 testTokenize("//\xe2\x80\xaa", &[_]Token.Id{Token.Id.LineComment});
1668 testTokenize("//\xe2\x80\xaa", &[_]Token.Id{.LineComment});
16741669}
16751670
16761671test "tokenizer - string identifier and builtin fns" {
16771672 testTokenize(
16781673 \\const @"if" = @import("std");
16791674 , &[_]Token.Id{
1680 Token.Id.Keyword_const,
1681 Token.Id.Identifier,
1682 Token.Id.Equal,
1683 Token.Id.Builtin,
1684 Token.Id.LParen,
1685 Token.Id.StringLiteral,
1686 Token.Id.RParen,
1687 Token.Id.Semicolon,
1675 .Keyword_const,
1676 .Identifier,
1677 .Equal,
1678 .Builtin,
1679 .LParen,
1680 .StringLiteral,
1681 .RParen,
1682 .Semicolon,
16881683 });
16891684}
16901685
......@@ -1692,26 +1687,26 @@ test "tokenizer - multiline string literal with literal tab" {
16921687 testTokenize(
16931688 \\\\foo bar
16941689 , &[_]Token.Id{
1695 Token.Id.MultilineStringLiteralLine,
1690 .MultilineStringLiteralLine,
16961691 });
16971692}
16981693
16991694test "tokenizer - pipe and then invalid" {
17001695 testTokenize("||=", &[_]Token.Id{
1701 Token.Id.PipePipe,
1702 Token.Id.Equal,
1696 .PipePipe,
1697 .Equal,
17031698 });
17041699}
17051700
17061701test "tokenizer - line comment and doc comment" {
1707 testTokenize("//", &[_]Token.Id{Token.Id.LineComment});
1708 testTokenize("// a / b", &[_]Token.Id{Token.Id.LineComment});
1709 testTokenize("// /", &[_]Token.Id{Token.Id.LineComment});
1710 testTokenize("/// a", &[_]Token.Id{Token.Id.DocComment});
1711 testTokenize("///", &[_]Token.Id{Token.Id.DocComment});
1712 testTokenize("////", &[_]Token.Id{Token.Id.LineComment});
1713 testTokenize("//!", &[_]Token.Id{Token.Id.ContainerDocComment});
1714 testTokenize("//!!", &[_]Token.Id{Token.Id.ContainerDocComment});
1702 testTokenize("//", &[_]Token.Id{.LineComment});
1703 testTokenize("// a / b", &[_]Token.Id{.LineComment});
1704 testTokenize("// /", &[_]Token.Id{.LineComment});
1705 testTokenize("/// a", &[_]Token.Id{.DocComment});
1706 testTokenize("///", &[_]Token.Id{.DocComment});
1707 testTokenize("////", &[_]Token.Id{.LineComment});
1708 testTokenize("//!", &[_]Token.Id{.ContainerDocComment});
1709 testTokenize("//!!", &[_]Token.Id{.ContainerDocComment});
17151710}
17161711
17171712test "tokenizer - line comment followed by identifier" {
......@@ -1720,28 +1715,28 @@ test "tokenizer - line comment followed by identifier" {
17201715 \\ // another
17211716 \\ Another,
17221717 , &[_]Token.Id{
1723 Token.Id.Identifier,
1724 Token.Id.Comma,
1725 Token.Id.LineComment,
1726 Token.Id.Identifier,
1727 Token.Id.Comma,
1718 .Identifier,
1719 .Comma,
1720 .LineComment,
1721 .Identifier,
1722 .Comma,
17281723 });
17291724}
17301725
17311726test "tokenizer - UTF-8 BOM is recognized and skipped" {
17321727 testTokenize("\xEF\xBB\xBFa;\n", &[_]Token.Id{
1733 Token.Id.Identifier,
1734 Token.Id.Semicolon,
1728 .Identifier,
1729 .Semicolon,
17351730 });
17361731}
17371732
17381733test "correctly parse pointer assignment" {
17391734 testTokenize("b.*=3;\n", &[_]Token.Id{
1740 Token.Id.Identifier,
1741 Token.Id.PeriodAsterisk,
1742 Token.Id.Equal,
1743 Token.Id.IntegerLiteral,
1744 Token.Id.Semicolon,
1735 .Identifier,
1736 .PeriodAsterisk,
1737 .Equal,
1738 .IntegerLiteral,
1739 .Semicolon,
17451740 });
17461741}
17471742
......@@ -1984,5 +1979,5 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
19841979 }
19851980 }
19861981 const last_token = tokenizer.next();
1987 std.testing.expect(last_token.id == Token.Id.Eof);
1982 std.testing.expect(last_token.id == .Eof);
19881983}
src-self-hosted/clang.zig+1-1
......@@ -781,7 +781,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigCla
781781pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
782782pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
783783pub 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;
785785pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
786786pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClangTagDecl) bool;
787787pub 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: [
589589 error.EndOfStream => return .EndOfFile,
590590 error.IsDir => return .IsDir,
591591 error.ConnectionResetByPeer => unreachable,
592 error.ConnectionTimedOut => unreachable,
592593 error.OutOfMemory => return .OutOfMemory,
593594 error.Unseekable => unreachable,
594595 error.SharingViolation => return .SharingViolation,
src-self-hosted/translate_c.zig+60-36
......@@ -668,6 +668,31 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
668668 return transCreateNodeIdentifier(c, builtin_name);
669669}
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
671696fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
672697 if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
673698 return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
......@@ -678,54 +703,36 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
678703 // TODO https://github.com/ziglang/zig/issues/3756
679704 // TODO https://github.com/ziglang/zig/issues/1802
680705 const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
681
682 if (mem.eql(u8, checked_name, "uint8_t"))
683 return transTypeDefAsBuiltin(c, typedef_decl, "u8")
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");
706 if (checkForBuiltinTypedef(checked_name)) |builtin| {
707 return transTypeDefAsBuiltin(c, typedef_decl, builtin);
708 }
706709
707710 if (!top_level_visit) {
708711 return transCreateNodeIdentifier(c, checked_name);
709712 }
710713
711714 _ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
712 const visib_tok = try appendToken(c, .Keyword_pub, "pub");
713 const const_tok = try appendToken(c, .Keyword_const, "const");
714 const node = try transCreateNodeVarDecl(c, true, true, checked_name);
715 node.eq_token = try appendToken(c, .Equal, "=");
715 const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
716 try addTopLevelDecl(c, checked_name, &node.base);
717 return transCreateNodeIdentifier(c, checked_name);
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
717724 const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
718725 const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
719726 node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
720727 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", .{});
722729 return null;
723730 },
724731 error.OutOfMemory => |e| return e,
725732 };
726 node.semicolon_token = try appendToken(c, .Semicolon, ";");
727 try addTopLevelDecl(c, checked_name, &node.base);
728 return transCreateNodeIdentifier(c, checked_name);
733
734 node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
735 return node;
729736}
730737
731738fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {
......@@ -1394,6 +1401,26 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
13941401 node.semicolon_token = try appendToken(c, .Semicolon, ";");
13951402 try block_scope.block_node.statements.push(&node.base);
13961403 },
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 },
13971424 else => |kind| return revertAndWarn(
13981425 rp,
13991426 error.UnsupportedTranslation,
......@@ -4094,7 +4121,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
40944121 .return_type = proto_alias.return_type,
40954122 .var_args_token = null,
40964123 .extern_export_inline_token = inline_tok,
4097 .cc_token = null,
40984124 .body_node = null,
40994125 .lib_name = null,
41004126 .align_expr = null,
......@@ -4753,7 +4779,6 @@ fn finishTransFnProto(
47534779 .return_type = .{ .Explicit = return_type_node },
47544780 .var_args_token = null, // TODO this field is broken in the AST data model
47554781 .extern_export_inline_token = extern_export_inline_tok,
4756 .cc_token = null,
47574782 .body_node = null,
47584783 .lib_name = null,
47594784 .align_expr = align_expr,
......@@ -5119,7 +5144,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
51195144 .return_type = .{ .Explicit = &type_of.base },
51205145 .doc_comments = null,
51215146 .var_args_token = null,
5122 .cc_token = null,
51235147 .body_node = null,
51245148 .lib_name = null,
51255149 .align_expr = null,
src-self-hosted/zir.zig+1-1
......@@ -283,7 +283,7 @@ pub const Inst = struct {
283283 comptime_int,
284284 comptime_float,
285285
286 fn toType(self: BuiltinType) Type {
286 pub fn toType(self: BuiltinType) Type {
287287 return switch (self) {
288288 .isize => Type.initTag(.isize),
289289 .usize => Type.initTag(.usize),
src/all_types.hpp+11-12
......@@ -672,7 +672,7 @@ enum NodeType {
672672 NodeTypeSwitchProng,
673673 NodeTypeSwitchRange,
674674 NodeTypeCompTime,
675 NodeTypeNoAsync,
675 NodeTypeNoSuspend,
676676 NodeTypeBreak,
677677 NodeTypeContinue,
678678 NodeTypeAsmExpr,
......@@ -718,7 +718,6 @@ struct AstNodeFnProto {
718718 Buf doc_comments;
719719
720720 FnInline fn_inline;
721 bool is_async;
722721
723722 VisibMod visib_mod;
724723 bool auto_err_set;
......@@ -862,7 +861,7 @@ enum CallModifier {
862861 CallModifierAsync,
863862 CallModifierNeverTail,
864863 CallModifierNeverInline,
865 CallModifierNoAsync,
864 CallModifierNoSuspend,
866865 CallModifierAlwaysTail,
867866 CallModifierAlwaysInline,
868867 CallModifierCompileTime,
......@@ -1014,7 +1013,7 @@ struct AstNodeCompTime {
10141013 AstNode *expr;
10151014};
10161015
1017struct AstNodeNoAsync {
1016struct AstNodeNoSuspend {
10181017 AstNode *expr;
10191018};
10201019
......@@ -1225,7 +1224,7 @@ struct AstNode {
12251224 AstNodeSwitchProng switch_prong;
12261225 AstNodeSwitchRange switch_range;
12271226 AstNodeCompTime comptime_expr;
1228 AstNodeNoAsync noasync_expr;
1227 AstNodeNoSuspend nosuspend_expr;
12291228 AstNodeAsmExpr asm_expr;
12301229 AstNodeFieldAccessExpr field_access_expr;
12311230 AstNodePtrDerefExpr ptr_deref_expr;
......@@ -1858,7 +1857,7 @@ enum PanicMsgId {
18581857 PanicMsgIdResumedAnAwaitingFn,
18591858 PanicMsgIdFrameTooSmall,
18601859 PanicMsgIdResumedFnPendingAwait,
1861 PanicMsgIdBadNoAsyncCall,
1860 PanicMsgIdBadNoSuspendCall,
18621861 PanicMsgIdResumeNotSuspendedFn,
18631862 PanicMsgIdBadSentinel,
18641863 PanicMsgIdShxTooBigRhs,
......@@ -2376,7 +2375,7 @@ enum ScopeId {
23762375 ScopeIdRuntime,
23772376 ScopeIdTypeOf,
23782377 ScopeIdExpr,
2379 ScopeIdNoAsync,
2378 ScopeIdNoSuspend,
23802379};
23812380
23822381struct Scope {
......@@ -2510,9 +2509,9 @@ struct ScopeCompTime {
25102509 Scope base;
25112510};
25122511
2513// This scope is created for a noasync expression.
2514// NodeTypeNoAsync
2515struct ScopeNoAsync {
2512// This scope is created for a nosuspend expression.
2513// NodeTypeNoSuspend
2514struct ScopeNoSuspend {
25162515 Scope base;
25172516};
25182517
......@@ -4488,7 +4487,7 @@ struct IrInstSrcAwait {
44884487
44894488 IrInstSrc *frame;
44904489 ResultLoc *result_loc;
4491 bool is_noasync;
4490 bool is_nosuspend;
44924491};
44934492
44944493struct IrInstGenAwait {
......@@ -4497,7 +4496,7 @@ struct IrInstGenAwait {
44974496 IrInstGen *frame;
44984497 IrInstGen *result_loc;
44994498 ZigFn *target_fn;
4500 bool is_noasync;
4499 bool is_nosuspend;
45014500};
45024501
45034502struct IrInstSrcResume {
src/analyze.cpp+9-11
......@@ -106,7 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {
106106 case ScopeIdDecls:
107107 case ScopeIdFnDef:
108108 case ScopeIdCompTime:
109 case ScopeIdNoAsync:
109 case ScopeIdNoSuspend:
110110 case ScopeIdVarDecl:
111111 case ScopeIdCImport:
112112 case ScopeIdSuspend:
......@@ -227,9 +227,9 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
227227 return &scope->base;
228228}
229229
230Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) {
231 ScopeNoAsync *scope = heap::c_allocator.create<ScopeNoAsync>();
232 init_scope(g, &scope->base, ScopeIdNoAsync, node, parent);
230Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
231 ScopeNoSuspend *scope = heap::c_allocator.create<ScopeNoSuspend>();
232 init_scope(g, &scope->base, ScopeIdNoSuspend, node, parent);
233233 return &scope->base;
234234}
235235
......@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
15281528}
15291529
15301530CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
1531 if (fn_proto->is_async)
1532 return CallingConventionAsync;
15331531 // Compatible with the C ABI
15341532 if (fn_proto->is_extern || fn_proto->is_export)
15351533 return CallingConventionC;
......@@ -3771,7 +3769,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
37713769 case NodeTypeCompTime:
37723770 preview_comptime_decl(g, node, decls_scope);
37733771 break;
3774 case NodeTypeNoAsync:
3772 case NodeTypeNoSuspend:
37753773 case NodeTypeParamDecl:
37763774 case NodeTypeReturnExpr:
37773775 case NodeTypeDefer:
......@@ -4689,7 +4687,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {
46894687static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,
46904688 bool must_not_be_async, CallModifier modifier)
46914689{
4692 if (modifier == CallModifierNoAsync)
4690 if (modifier == CallModifierNoSuspend)
46934691 return ErrorNone;
46944692 bool callee_is_async = false;
46954693 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) {
48124810 }
48134811 for (size_t i = 0; i < fn->await_list.length; i += 1) {
48144812 IrInstGenAwait *await = fn->await_list.at(i);
4815 if (await->is_noasync) continue;
4813 if (await->is_nosuspend) continue;
48164814 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
48174815 CallModifierNone))
48184816 {
......@@ -6239,7 +6237,7 @@ static void mark_suspension_point(Scope *scope) {
62396237 case ScopeIdDecls:
62406238 case ScopeIdFnDef:
62416239 case ScopeIdCompTime:
6242 case ScopeIdNoAsync:
6240 case ScopeIdNoSuspend:
62436241 case ScopeIdCImport:
62446242 case ScopeIdSuspend:
62456243 case ScopeIdTypeOf:
......@@ -6472,7 +6470,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
64726470 // The funtion call result of foo() must be spilled.
64736471 for (size_t i = 0; i < fn->await_list.length; i += 1) {
64746472 IrInstGenAwait *await = fn->await_list.at(i);
6475 if (await->is_noasync) {
6473 if (await->is_nosuspend) {
64766474 continue;
64776475 }
64786476 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);
125125ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
126126ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
127127Scope *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);
129129Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
130130Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
131131ScopeExpr *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) {
220220 return "SwitchRange";
221221 case NodeTypeCompTime:
222222 return "CompTime";
223 case NodeTypeNoAsync:
224 return "NoAsync";
223 case NodeTypeNoSuspend:
224 return "NoSuspend";
225225 case NodeTypeBreak:
226226 return "Break";
227227 case NodeTypeContinue:
......@@ -709,8 +709,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
709709 switch (node->data.fn_call_expr.modifier) {
710710 case CallModifierNone:
711711 break;
712 case CallModifierNoAsync:
713 fprintf(ar->f, "noasync ");
712 case CallModifierNoSuspend:
713 fprintf(ar->f, "nosuspend ");
714714 break;
715715 case CallModifierAsync:
716716 fprintf(ar->f, "async ");
......@@ -1093,10 +1093,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
10931093 render_node_grouped(ar, node->data.comptime_expr.expr);
10941094 break;
10951095 }
1096 case NodeTypeNoAsync:
1096 case NodeTypeNoSuspend:
10971097 {
1098 fprintf(ar->f, "noasync ");
1099 render_node_grouped(ar, node->data.noasync_expr.expr);
1098 fprintf(ar->f, "nosuspend ");
1099 render_node_grouped(ar, node->data.nosuspend_expr.expr);
11001100 break;
11011101 }
11021102 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) {
243243 }
244244
245245 if (!is_signed) {
246 if(bn->is_negative) return false;
246247 size_t full_bits = bn->digit_count * 64;
247248 size_t leading_zero_count = bigint_clz(bn, full_bits);
248249 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) {
685685 case ScopeIdLoop:
686686 case ScopeIdSuspend:
687687 case ScopeIdCompTime:
688 case ScopeIdNoAsync:
688 case ScopeIdNoSuspend:
689689 case ScopeIdRuntime:
690690 case ScopeIdTypeOf:
691691 case ScopeIdExpr:
......@@ -966,8 +966,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
966966 return buf_create_from_str("frame too small");
967967 case PanicMsgIdResumedFnPendingAwait:
968968 return buf_create_from_str("resumed an async function which can only be awaited");
969 case PanicMsgIdBadNoAsyncCall:
970 return buf_create_from_str("async function called in noasync scope suspended");
969 case PanicMsgIdBadNoSuspendCall:
970 return buf_create_from_str("async function called in nosuspend scope suspended");
971971 case PanicMsgIdResumeNotSuspendedFn:
972972 return buf_create_from_str("resumed a non-suspended function");
973973 case PanicMsgIdBadSentinel:
......@@ -4071,7 +4071,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
40714071 case ScopeIdLoop:
40724072 case ScopeIdSuspend:
40734073 case ScopeIdCompTime:
4074 case ScopeIdNoAsync:
4074 case ScopeIdNoSuspend:
40754075 case ScopeIdRuntime:
40764076 case ScopeIdTypeOf:
40774077 case ScopeIdExpr:
......@@ -4222,9 +4222,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
42224222 // even if prefix_arg_err_ret_stack is true, let the async function do its own
42234223 // initialization.
42244224 } else {
4225 if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) {
4225 if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
42264226 // 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 will
4227 // This is allowed because it was called with `nosuspend` which asserts that it will
42284228 // never suspend.
42294229 awaiter_init_val = zero;
42304230 } else {
......@@ -4335,7 +4335,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
43354335 case CallModifierCompileTime:
43364336 zig_unreachable();
43374337 case CallModifierNone:
4338 case CallModifierNoAsync:
4338 case CallModifierNoSuspend:
43394339 case CallModifierAsync:
43404340 call_attr = ZigLLVM_CallAttrAuto;
43414341 break;
......@@ -4411,7 +4411,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
44114411 get_llvm_type(g, instruction->base.value->type), "");
44124412 }
44134413 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)) {
44154415 gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
44164416
44174417 if (ir_want_runtime_safety(g, &instruction->base)) {
......@@ -4422,13 +4422,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
44224422 all_ones, LLVMAtomicOrderingRelease);
44234423 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, "");
44244424
4425 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic");
4426 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk");
4425 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendPanic");
4426 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendOk");
44274427 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.
44304430 LLVMPositionBuilderAtEnd(g->builder, bad_block);
4431 gen_safety_crash(g, PanicMsgIdBadNoAsyncCall);
4431 gen_safety_crash(g, PanicMsgIdBadNoSuspendCall);
44324432
44334433 LLVMPositionBuilderAtEnd(g->builder, ok_block);
44344434 }
......@@ -6401,7 +6401,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
64016401 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
64026402 nullptr : ir_llvm_value(g, instruction->result_loc);
64036403
6404 if (instruction->is_noasync ||
6404 if (instruction->is_nosuspend ||
64056405 (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
64066406 {
64076407 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
......@@ -7928,7 +7928,7 @@ static void do_code_gen(CodeGen *g) {
79287928 }
79297929
79307930 if (!is_async) {
7931 // allocate async frames for noasync calls & awaits to async functions
7931 // allocate async frames for nosuspend calls & awaits to async functions
79327932 ZigType *largest_call_frame_type = nullptr;
79337933 IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,
79347934 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) {
79387938 continue;
79397939 if (!fn_is_async(call->fn_entry))
79407940 continue;
7941 if (call->modifier != CallModifierNoAsync)
7941 if (call->modifier != CallModifierNoSuspend)
79427942 continue;
79437943 if (call->frame_result_loc != nullptr)
79447944 continue;
src/ir.cpp+62-35
......@@ -4846,12 +4846,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins
48464846}
48474847
48484848static 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)
48504850{
48514851 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
48524852 instruction->frame = frame;
48534853 instruction->result_loc = result_loc;
4854 instruction->is_noasync = is_noasync;
4854 instruction->is_nosuspend = is_nosuspend;
48554855
48564856 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
48594859}
48604860
48614861static 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)
48634863{
48644864 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
48654865 source_instruction->scope, source_instruction->source_node);
48664866 instruction->base.value->type = result_type;
48674867 instruction->frame = frame;
48684868 instruction->result_loc = result_loc;
4869 instruction->is_noasync = is_noasync;
4869 instruction->is_nosuspend = is_nosuspend;
48704870
48714871 ir_ref_inst_gen(frame);
48724872 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_
49824982 case ScopeIdLoop:
49834983 case ScopeIdSuspend:
49844984 case ScopeIdCompTime:
4985 case ScopeIdNoAsync:
4985 case ScopeIdNoSuspend:
49864986 case ScopeIdRuntime:
49874987 case ScopeIdTypeOf:
49884988 case ScopeIdExpr:
......@@ -5072,7 +5072,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope
50725072 case ScopeIdLoop:
50735073 case ScopeIdSuspend:
50745074 case ScopeIdCompTime:
5075 case ScopeIdNoAsync:
5075 case ScopeIdNoSuspend:
50765076 case ScopeIdRuntime:
50775077 case ScopeIdTypeOf:
50785078 case ScopeIdExpr:
......@@ -7335,10 +7335,10 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
73357335 zig_unreachable();
73367336}
73377337
7338static ScopeNoAsync *get_scope_noasync(Scope *scope) {
7338static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
73397339 while (scope) {
7340 if (scope->id == ScopeIdNoAsync)
7341 return (ScopeNoAsync *)scope;
7340 if (scope->id == ScopeIdNoSuspend)
7341 return (ScopeNoSuspend *)scope;
73427342 if (scope->id == ScopeIdFnDef)
73437343 return nullptr;
73447344
......@@ -7355,15 +7355,15 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,
73557355 if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
73567356 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;
73597359 CallModifier modifier = node->data.fn_call_expr.modifier;
7360 if (is_noasync) {
7360 if (is_nosuspend) {
73617361 if (modifier == CallModifierAsync) {
73627362 add_node_error(irb->codegen, node,
7363 buf_sprintf("async call in noasync scope"));
7363 buf_sprintf("async call in nosuspend scope"));
73647364 return irb->codegen->invalid_inst_src;
73657365 }
7366 modifier = CallModifierNoAsync;
7366 modifier = CallModifierNoSuspend;
73677367 }
73687368
73697369 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
92229222 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
92239223}
92249224
9225static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
9226 assert(node->type == NodeTypeNoAsync);
9225static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
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);
92299229 // purposefully pass null for result_loc and let EndExpr handle it
92309230 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
92319231}
......@@ -9813,8 +9813,8 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
98139813
98149814static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
98159815 assert(node->type == NodeTypeResume);
9816 if (get_scope_noasync(scope) != nullptr) {
9817 add_node_error(irb->codegen, node, buf_sprintf("resume in noasync scope"));
9816 if (get_scope_nosuspend(scope) != nullptr) {
9817 add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope"));
98189818 return irb->codegen->invalid_inst_src;
98199819 }
98209820
......@@ -9830,7 +9830,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
98309830{
98319831 assert(node->type == NodeTypeAwaitExpr);
98329832
9833 bool is_noasync = get_scope_noasync(scope) != nullptr;
9833 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
98349834
98359835 AstNode *expr_node = node->data.await_expr.expr;
98369836 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
98649864 if (target_inst == irb->codegen->invalid_inst_src)
98659865 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);
98689868 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
98699869}
98709870
......@@ -9876,8 +9876,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode
98769876 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
98779877 return irb->codegen->invalid_inst_src;
98789878 }
9879 if (get_scope_noasync(parent_scope) != nullptr) {
9880 add_node_error(irb->codegen, node, buf_sprintf("suspend in noasync scope"));
9879 if (get_scope_nosuspend(parent_scope) != nullptr) {
9880 add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope"));
98819881 return irb->codegen->invalid_inst_src;
98829882 }
98839883
......@@ -10017,8 +10017,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
1001710017 return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
1001810018 case NodeTypeCompTime:
1001910019 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
10020 case NodeTypeNoAsync:
10021 return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc);
10020 case NodeTypeNoSuspend:
10021 return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc);
1002210022 case NodeTypeErrorType:
1002310023 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
1002410024 case NodeTypeBreak:
......@@ -10105,7 +10105,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco
1010510105 case NodeTypeIfOptional:
1010610106 case NodeTypeSwitchExpr:
1010710107 case NodeTypeCompTime:
10108 case NodeTypeNoAsync:
10108 case NodeTypeNoSuspend:
1010910109 case NodeTypeErrorType:
1011010110 case NodeTypeBreak:
1011110111 case NodeTypeContinue:
......@@ -12760,9 +12760,7 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
1276012760 const_val->type = new_type;
1276112761 break;
1276212762 case CastOpIntToFloat:
12763 {
12764 assert(new_type->id == ZigTypeIdFloat);
12765
12763 if (new_type->id == ZigTypeIdFloat) {
1276612764 BigFloat bigfloat;
1276712765 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint);
1276812766 switch (new_type->data.floating.bit_count) {
......@@ -12783,9 +12781,13 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
1278312781 default:
1278412782 zig_unreachable();
1278512783 }
12786 const_val->special = ConstValSpecialStatic;
12787 break;
12784 } else if (new_type->id == ZigTypeIdComptimeFloat) {
12785 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint);
12786 } else {
12787 zig_unreachable();
1278812788 }
12789 const_val->special = ConstValSpecialStatic;
12790 break;
1278912791 case CastOpFloatToInt:
1279012792 float_init_bigint(&const_val->data.x_bigint, other_val);
1279112793 if (new_type->id == ZigTypeIdInt) {
......@@ -19999,6 +20001,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
1999920001 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
2000020002 return result_loc;
2000120003 }
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
2000220009 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type);
2000320010 dummy_value->value->special = ConstValSpecialRuntime;
2000420011 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
......@@ -20025,7 +20032,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2002520032
2002620033 if (impl_fn_type_id->cc == CallingConventionAsync &&
2002720034 parent_fn_entry->inferred_async_node == nullptr &&
20028 modifier != CallModifierNoAsync)
20035 modifier != CallModifierNoSuspend)
2002920036 {
2003020037 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
2003120038 parent_fn_entry->inferred_async_fn = impl_fn;
......@@ -20123,7 +20130,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2012320130
2012420131 if (fn_type_id->cc == CallingConventionAsync &&
2012520132 parent_fn_entry->inferred_async_node == nullptr &&
20126 modifier != CallModifierNoAsync)
20133 modifier != CallModifierNoSuspend)
2012720134 {
2012820135 parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
2012920136 parent_fn_entry->inferred_async_fn = fn_entry;
......@@ -20137,6 +20144,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
2013720144 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
2013820145 return result_loc;
2013920146 }
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
2014020152 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
2014120153 dummy_value->value->special = ConstValSpecialRuntime;
2014220154 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
......@@ -20233,7 +20245,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
2023320245 case CallModifierNone:
2023420246 case CallModifierAlwaysInline:
2023520247 case CallModifierAlwaysTail:
20236 case CallModifierNoAsync:
20248 case CallModifierNoSuspend:
2023720249 modifier = CallModifierCompileTime;
2023820250 break;
2023920251 case CallModifierNeverInline:
......@@ -21614,6 +21626,15 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira,
2161421626 if (tld->resolution == TldResolutionResolving)
2161521627 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
2161721638 TldFn *tld_fn = (TldFn *)tld;
2161821639 ZigFn *fn_entry = tld_fn->fn_entry;
2161921640 assert(fn_entry != nullptr);
......@@ -21687,6 +21708,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
2168721708 if (field->is_comptime) {
2168821709 IrInstGen *elem = ir_const(ira, source_instr, field_type);
2168921710 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 }
2169021714 copy_const_val(ira->codegen, elem->value, field->init_val);
2169121715 return ir_get_ref2(ira, source_instr, elem, field_type, true, false);
2169221716 }
......@@ -25043,6 +25067,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
2504325067 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
2504425068 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;
2504525069 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 }
2504625073 set_optional_payload(inner_fields[3], struct_field->init_val);
2504725074
2504825075 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
3027730304 ir_assert(fn_entry != nullptr, &instruction->base.base);
3027830305
3027930306 // 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) {
3028130308 if (fn_entry->inferred_async_node == nullptr) {
3028230309 fn_entry->inferred_async_node = instruction->base.base.source_node;
3028330310 }
......@@ -30301,7 +30328,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
3030130328 }
3030230329
3030330330 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,
30304 instruction->is_noasync);
30331 instruction->is_nosuspend);
3030530332 result->target_fn = target_fn;
3030630333 fn_entry->await_list.append(result);
3030730334 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)
861861 switch (call_instruction->modifier) {
862862 case CallModifierNone:
863863 break;
864 case CallModifierNoAsync:
865 fprintf(irp->f, "noasync ");
864 case CallModifierNoSuspend:
865 fprintf(irp->f, "nosuspend ");
866866 break;
867867 case CallModifierAsync:
868868 fprintf(irp->f, "async ");
......@@ -906,8 +906,8 @@ static void ir_print_call_gen(IrPrintGen *irp, IrInstGenCall *call_instruction)
906906 switch (call_instruction->modifier) {
907907 case CallModifierNone:
908908 break;
909 case CallModifierNoAsync:
910 fprintf(irp->f, "noasync ");
909 case CallModifierNoSuspend:
910 fprintf(irp->f, "nosuspend ");
911911 break;
912912 case CallModifierAsync:
913913 fprintf(irp->f, "async ");
src/parser.cpp+16-73
......@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);
9393static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
9494static AstNode *ast_parse_link_section(ParseContext *pc);
9595static AstNode *ast_parse_callconv(ParseContext *pc);
96static Optional<AstNodeFnProto> ast_parse_fn_cc(ParseContext *pc);
9796static AstNode *ast_parse_param_decl(ParseContext *pc);
9897static AstNode *ast_parse_param_type(ParseContext *pc);
9998static AstNode *ast_parse_if_prefix(ParseContext *pc);
......@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
707706 fn_proto->column = first->start_column;
708707 fn_proto->data.fn_proto.visib_mod = visib_mod;
709708 fn_proto->data.fn_proto.doc_comments = *doc_comments;
710 // ast_parse_fn_cc may set it
711709 if (!fn_proto->data.fn_proto.is_extern)
712710 fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
713711 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
788786 return nullptr;
789787}
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)
792790static AstNode *ast_parse_fn_proto(ParseContext *pc) {
793 Token *first = peek_token(pc);
794 AstNodeFnProto fn_cc;
795 Token *fn;
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;
791 Token *first = eat_token_if(pc, TokenIdKeywordFn);
792 if (first == nullptr) {
793 return nullptr;
814794 }
815795
816796 Token *identifier = eat_token_if(pc, TokenIdSymbol);
......@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
830810 }
831811
832812 AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
833 res->data.fn_proto = fn_cc;
813 res->data.fn_proto = {};
834814 res->data.fn_proto.name = token_buf(identifier);
835815 res->data.fn_proto.params = params;
836816 res->data.fn_proto.align_expr = align_expr;
......@@ -913,7 +893,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
913893// Statement
914894// <- KEYWORD_comptime? VarDecl
915895// / KEYWORD_comptime BlockExprStatement
916// / KEYWORD_noasync BlockExprStatement
896// / KEYWORD_nosuspend BlockExprStatement
917897// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
918898// / KEYWORD_defer BlockExprStatement
919899// / KEYWORD_errdefer Payload? BlockExprStatement
......@@ -937,11 +917,11 @@ static AstNode *ast_parse_statement(ParseContext *pc) {
937917 return res;
938918 }
939919
940 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
941 if (noasync != nullptr) {
920 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
921 if (nosuspend != nullptr) {
942922 AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
943 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
944 res->data.noasync_expr.expr = statement;
923 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
924 res->data.nosuspend_expr.expr = statement;
945925 return res;
946926 }
947927
......@@ -1289,7 +1269,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
12891269// / IfExpr
12901270// / KEYWORD_break BreakLabel? Expr?
12911271// / KEYWORD_comptime Expr
1292// / KEYWORD_noasync Expr
1272// / KEYWORD_nosuspend Expr
12931273// / KEYWORD_continue BreakLabel?
12941274// / KEYWORD_resume Expr
12951275// / KEYWORD_return Expr?
......@@ -1324,11 +1304,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
13241304 return res;
13251305 }
13261306
1327 Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
1328 if (noasync != nullptr) {
1307 Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
1308 if (nosuspend != nullptr) {
13291309 AstNode *expr = ast_expect(pc, ast_parse_expr);
1330 AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
1331 res->data.noasync_expr.expr = expr;
1310 AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
1311 res->data.nosuspend_expr.expr = expr;
13321312 return res;
13331313 }
13341314
......@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
15241504static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
15251505 Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
15261506 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
15381507 AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
15391508 while (true) {
15401509 AstNode *suffix = ast_parse_suffix_op(pc);
......@@ -1640,7 +1609,6 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
16401609// / IfTypeExpr
16411610// / INTEGER
16421611// / KEYWORD_comptime TypeExpr
1643// / KEYWORD_noasync TypeExpr
16441612// / KEYWORD_error DOT IDENTIFIER
16451613// / KEYWORD_false
16461614// / KEYWORD_null
......@@ -1742,14 +1710,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
17421710 return res;
17431711 }
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
17531713 Token *error = eat_token_if(pc, TokenIdKeywordError);
17541714 if (error != nullptr) {
17551715 Token *dot = expect_token(pc, TokenIdDot);
......@@ -2187,23 +2147,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
21872147 return res;
21882148}
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
22072150// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
22082151static AstNode *ast_parse_param_decl(ParseContext *pc) {
22092152 Buf doc_comments = BUF_INIT;
......@@ -3189,7 +3132,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
31893132 case NodeTypeCompTime:
31903133 visit_field(&node->data.comptime_expr.expr, visit, context);
31913134 break;
3192 case NodeTypeNoAsync:
3135 case NodeTypeNoSuspend:
31933136 visit_field(&node->data.comptime_expr.expr, visit, context);
31943137 break;
31953138 case NodeTypeBreak:
src/tokenizer.cpp+2-2
......@@ -128,8 +128,8 @@ static const struct ZigKeyword zig_keywords[] = {
128128 {"if", TokenIdKeywordIf},
129129 {"inline", TokenIdKeywordInline},
130130 {"noalias", TokenIdKeywordNoAlias},
131 {"noasync", TokenIdKeywordNoAsync},
132131 {"noinline", TokenIdKeywordNoInline},
132 {"nosuspend", TokenIdKeywordNoSuspend},
133133 {"null", TokenIdKeywordNull},
134134 {"or", TokenIdKeywordOr},
135135 {"orelse", TokenIdKeywordOrElse},
......@@ -1589,8 +1589,8 @@ const char * token_name(TokenId id) {
15891589 case TokenIdKeywordIf: return "if";
15901590 case TokenIdKeywordInline: return "inline";
15911591 case TokenIdKeywordNoAlias: return "noalias";
1592 case TokenIdKeywordNoAsync: return "noasync";
15931592 case TokenIdKeywordNoInline: return "noinline";
1593 case TokenIdKeywordNoSuspend: return "nosuspend";
15941594 case TokenIdKeywordNull: return "null";
15951595 case TokenIdKeywordOr: return "or";
15961596 case TokenIdKeywordOrElse: return "orelse";
src/tokenizer.hpp+1-1
......@@ -78,7 +78,7 @@ enum TokenId {
7878 TokenIdKeywordNoInline,
7979 TokenIdKeywordLinkSection,
8080 TokenIdKeywordNoAlias,
81 TokenIdKeywordNoAsync,
81 TokenIdKeywordNoSuspend,
8282 TokenIdKeywordNull,
8383 TokenIdKeywordOr,
8484 TokenIdKeywordOrElse,
test/compile_errors.zig+105-16
......@@ -2,6 +2,29 @@ const tests = @import("tests.zig");
22const std = @import("std");
33
44pub 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
528 cases.add("invalid pointer syntax",
629 \\export fn foo() void {
730 \\ var guid: *:0 const u8 = undefined;
......@@ -243,9 +266,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
243266 "tmp.zig:17:17: error: RHS of shift is too large for LHS type",
244267 });
245268
246 cases.addTest("combination of noasync and async",
269 cases.addTest("combination of nosuspend and async",
247270 \\export fn entry() void {
248 \\ noasync {
271 \\ nosuspend {
249272 \\ const bar = async foo();
250273 \\ suspend;
251274 \\ resume bar;
......@@ -253,9 +276,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
253276 \\}
254277 \\fn foo() void {}
255278 , &[_][]const u8{
256 "tmp.zig:3:21: error: async call in noasync scope",
257 "tmp.zig:4:9: error: suspend in noasync scope",
258 "tmp.zig:5:9: error: resume in noasync scope",
279 "tmp.zig:3:21: error: async call in nosuspend scope",
280 "tmp.zig:4:9: error: suspend in nosuspend scope",
281 "tmp.zig:5:9: error: resume in nosuspend scope",
259282 });
260283
261284 cases.add("atomicrmw with bool op not .Xchg",
......@@ -779,7 +802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
779802 });
780803
781804 cases.add("exported async function",
782 \\export async fn foo() void {}
805 \\export fn foo() callconv(.Async) void {}
783806 , &[_][]const u8{
784807 "tmp.zig:1:1: error: exported function cannot be async",
785808 });
......@@ -1258,11 +1281,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
12581281
12591282 cases.add("bad alignment in @asyncCall",
12601283 \\export fn entry() void {
1261 \\ var ptr: async fn () void = func;
1284 \\ var ptr: fn () callconv(.Async) void = func;
12621285 \\ var bytes: [64]u8 = undefined;
12631286 \\ _ = @asyncCall(&bytes, {}, ptr);
12641287 \\}
1265 \\async fn func() void {}
1288 \\fn func() callconv(.Async) void {}
12661289 , &[_][]const u8{
12671290 "tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'",
12681291 });
......@@ -1408,7 +1431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14081431 \\export fn entry() void {
14091432 \\ _ = async amain();
14101433 \\}
1411 \\async fn amain() void {
1434 \\fn amain() callconv(.Async) void {
14121435 \\ other();
14131436 \\}
14141437 \\fn other() void {
......@@ -1424,7 +1447,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14241447 \\export fn entry() void {
14251448 \\ _ = async amain();
14261449 \\}
1427 \\async fn amain() void {
1450 \\fn amain() callconv(.Async) void {
14281451 \\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
14291452 \\}
14301453 , &[_][]const u8{
......@@ -1451,7 +1474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14511474 \\ var ptr = afunc;
14521475 \\ _ = ptr();
14531476 \\}
1454 \\async fn afunc() void {}
1477 \\fn afunc() callconv(.Async) void {}
14551478 , &[_][]const u8{
14561479 "tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
14571480 });
......@@ -1462,7 +1485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14621485 \\ _ = async ptr();
14631486 \\}
14641487 \\
1465 \\async fn afunc() void { }
1488 \\fn afunc() callconv(.Async) void { }
14661489 , &[_][]const u8{
14671490 "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
14681491 });
......@@ -3051,7 +3074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30513074 \\export fn entry() void {
30523075 \\ _ = async foo();
30533076 \\}
3054 \\async fn foo() void {
3077 \\fn foo() void {
30553078 \\ suspend {
30563079 \\ suspend {
30573080 \\ }
......@@ -3099,7 +3122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30993122 \\export fn entry() void {
31003123 \\ _ = async amain();
31013124 \\}
3102 \\async fn amain() void {
3125 \\fn amain() callconv(.Async) void {
31033126 \\ return error.ShouldBeCompileError;
31043127 \\}
31053128 , &[_][]const u8{
......@@ -3569,7 +3592,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35693592 });
35703593
35713594 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;
35733596 \\
35743597 \\export fn entry() void {
35753598 \\ foo(bar);
......@@ -3580,7 +3603,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
35803603 \\ bar(&{});
35813604 \\}
35823605 , &[_][]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'",
35843607 "tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
35853608 });
35863609
......@@ -5352,6 +5375,50 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
53525375 break :x tc;
53535376 });
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
53555422 cases.add("container init with non-type",
53565423 \\const zero: i32 = 0;
53575424 \\const a = zero{1};
......@@ -7330,4 +7397,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
73307397 ":3:18: error: expected type '[*:0]const u8', found '*[64]u8'",
73317398 ":3:18: note: destination pointer requires a terminating '0' sentinel",
73327399 });
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 });
73337422}
test/run_translated_c.zig+13
......@@ -243,4 +243,17 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
243243 \\ return 0;
244244 \\}
245245 , "");
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 , "");
246259}
test/runtime_safety.zig+6-6
......@@ -234,12 +234,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
234234 \\}
235235 );
236236
237 cases.addRuntimeSafety("noasync function call, callee suspends",
237 cases.addRuntimeSafety("nosuspend function call, callee suspends",
238238 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
239239 \\ @import("std").os.exit(126);
240240 \\}
241241 \\pub fn main() void {
242 \\ _ = noasync add(101, 100);
242 \\ _ = nosuspend add(101, 100);
243243 \\}
244244 \\fn add(a: i32, b: i32) i32 {
245245 \\ if (a > 100) {
......@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
282282 \\ var ptr = other;
283283 \\ var frame = @asyncCall(&bytes, {}, ptr);
284284 \\}
285 \\async fn other() void {
285 \\fn other() callconv(.Async) void {
286286 \\ suspend;
287287 \\}
288288 );
......@@ -874,16 +874,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
874874 \\ return &failing_frame;
875875 \\}
876876 \\
877 \\async fn failing() anyerror!void {
877 \\fn failing() anyerror!void {
878878 \\ suspend;
879879 \\ return second();
880880 \\}
881881 \\
882 \\async fn second() anyerror!void {
882 \\fn second() callconv(.Async) anyerror!void {
883883 \\ return error.Fail;
884884 \\}
885885 \\
886 \\async fn printTrace(p: anyframe->anyerror!void) void {
886 \\fn printTrace(p: anyframe->anyerror!void) void {
887887 \\ (await p) catch unreachable;
888888 \\}
889889 );
test/stack_traces.zig+1-1
......@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
282282 \\source.zig:10:8: [address] in main (test)
283283 \\ foo();
284284 \\ ^
285 \\start.zig:250:29: [address] in std.start.posixCallMainAndExit (test)
285 \\start.zig:249:29: [address] in std.start.posixCallMainAndExit (test)
286286 \\ return root.main();
287287 \\ ^
288288 \\start.zig:123:5: [address] in std.start._start (test)
test/stage1/behavior/async_fn.zig+33-37
......@@ -112,12 +112,12 @@ test "@frameSize" {
112112 const S = struct {
113113 fn doTheTest() void {
114114 {
115 var ptr = @ptrCast(async fn (i32) void, other);
115 var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
116116 const size = @frameSize(ptr);
117117 expect(size == @sizeOf(@Frame(other)));
118118 }
119119 {
120 var ptr = @ptrCast(async fn () void, first);
120 var ptr = @ptrCast(fn () callconv(.Async) void, first);
121121 const size = @frameSize(ptr);
122122 expect(size == @sizeOf(@Frame(first)));
123123 }
......@@ -184,7 +184,7 @@ test "coroutine suspend with block" {
184184
185185var a_promise: anyframe = undefined;
186186var global_result = false;
187async fn testSuspendBlock() void {
187fn testSuspendBlock() callconv(.Async) void {
188188 suspend {
189189 comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock));
190190 a_promise = @frame();
......@@ -209,14 +209,14 @@ test "coroutine await" {
209209 expect(await_final_result == 1234);
210210 expect(std.mem.eql(u8, &await_points, "abcdefghi"));
211211}
212async fn await_amain() void {
212fn await_amain() callconv(.Async) void {
213213 await_seq('b');
214214 var p = async await_another();
215215 await_seq('e');
216216 await_final_result = await p;
217217 await_seq('h');
218218}
219async fn await_another() i32 {
219fn await_another() callconv(.Async) i32 {
220220 await_seq('c');
221221 suspend {
222222 await_seq('d');
......@@ -243,14 +243,14 @@ test "coroutine await early return" {
243243 expect(early_final_result == 1234);
244244 expect(std.mem.eql(u8, &early_points, "abcdef"));
245245}
246async fn early_amain() void {
246fn early_amain() callconv(.Async) void {
247247 early_seq('b');
248248 var p = async early_another();
249249 early_seq('d');
250250 early_final_result = await p;
251251 early_seq('e');
252252}
253async fn early_another() i32 {
253fn early_another() callconv(.Async) i32 {
254254 early_seq('c');
255255 return 1234;
256256}
......@@ -266,7 +266,7 @@ fn early_seq(c: u8) void {
266266test "async function with dot syntax" {
267267 const S = struct {
268268 var y: i32 = 1;
269 async fn foo() void {
269 fn foo() callconv(.Async) void {
270270 y += 1;
271271 suspend;
272272 }
......@@ -278,7 +278,7 @@ test "async function with dot syntax" {
278278test "async fn pointer in a struct field" {
279279 var data: i32 = 1;
280280 const Foo = struct {
281 bar: async fn (*i32) void,
281 bar: fn (*i32) callconv(.Async) void,
282282 };
283283 var foo = Foo{ .bar = simpleAsyncFn2 };
284284 var bytes: [64]u8 align(16) = undefined;
......@@ -294,8 +294,7 @@ test "async fn pointer in a struct field" {
294294fn doTheAwait(f: anyframe->void) void {
295295 await f;
296296}
297
298async fn simpleAsyncFn2(y: *i32) void {
297fn simpleAsyncFn2(y: *i32) callconv(.Async) void {
299298 defer y.* += 2;
300299 y.* += 1;
301300 suspend;
......@@ -303,11 +302,10 @@ async fn simpleAsyncFn2(y: *i32) void {
303302
304303test "@asyncCall with return type" {
305304 const Foo = struct {
306 bar: async fn () i32,
305 bar: fn () callconv(.Async) i32,
307306
308307 var global_frame: anyframe = undefined;
309
310 async fn middle() i32 {
308 fn middle() callconv(.Async) i32 {
311309 return afunc();
312310 }
313311
......@@ -338,8 +336,7 @@ test "async fn with inferred error set" {
338336 resume global_frame;
339337 std.testing.expectError(error.Fail, result);
340338 }
341
342 async fn middle() !void {
339 fn middle() callconv(.Async) !void {
343340 var f = async middle2();
344341 return await f;
345342 }
......@@ -376,11 +373,11 @@ fn nonFailing() (anyframe->anyerror!void) {
376373 Static.frame = async suspendThenFail();
377374 return &Static.frame;
378375}
379async fn suspendThenFail() anyerror!void {
376fn suspendThenFail() callconv(.Async) anyerror!void {
380377 suspend;
381378 return error.Fail;
382379}
383async fn printTrace(p: anyframe->(anyerror!void)) void {
380fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void {
384381 (await p) catch |e| {
385382 std.testing.expect(e == error.Fail);
386383 if (@errorReturnTrace()) |trace| {
......@@ -397,7 +394,7 @@ test "break from suspend" {
397394 const p = async testBreakFromSuspend(&my_result);
398395 std.testing.expect(my_result == 2);
399396}
400async fn testBreakFromSuspend(my_result: *i32) void {
397fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void {
401398 suspend {
402399 resume @frame();
403400 }
......@@ -826,7 +823,7 @@ test "cast fn to async fn when it is inferred to be async" {
826823 var ok = false;
827824
828825 fn doTheTest() void {
829 var ptr: async fn () i32 = undefined;
826 var ptr: fn () callconv(.Async) i32 = undefined;
830827 ptr = func;
831828 var buf: [100]u8 align(16) = undefined;
832829 var result: i32 = undefined;
......@@ -854,7 +851,7 @@ test "cast fn to async fn when it is inferred to be async, awaited directly" {
854851 var ok = false;
855852
856853 fn doTheTest() void {
857 var ptr: async fn () i32 = undefined;
854 var ptr: fn () callconv(.Async) i32 = undefined;
858855 ptr = func;
859856 var buf: [100]u8 align(16) = undefined;
860857 var result: i32 = undefined;
......@@ -958,8 +955,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
958955 resume global_frame;
959956 std.testing.expectError(error.Fail, result);
960957 }
961
962 async fn middle() !void {
958 fn middle() callconv(.Async) !void {
963959 var f = async middle2();
964960 return await f;
965961 }
......@@ -993,7 +989,7 @@ test "@asyncCall with actual frame instead of byte buffer" {
993989
994990test "@asyncCall using the result location inside the frame" {
995991 const S = struct {
996 async fn simple2(y: *i32) i32 {
992 fn simple2(y: *i32) callconv(.Async) i32 {
997993 defer y.* += 2;
998994 y.* += 1;
999995 suspend;
......@@ -1005,7 +1001,7 @@ test "@asyncCall using the result location inside the frame" {
10051001 };
10061002 var data: i32 = 1;
10071003 const Foo = struct {
1008 bar: async fn (*i32) i32,
1004 bar: fn (*i32) callconv(.Async) i32,
10091005 };
10101006 var foo = Foo{ .bar = S.simple2 };
10111007 var bytes: [64]u8 align(16) = undefined;
......@@ -1090,10 +1086,10 @@ test "recursive call of await @asyncCall with struct return type" {
10901086 expect(res.z == 3);
10911087}
10921088
1093test "noasync function call" {
1089test "nosuspend function call" {
10941090 const S = struct {
10951091 fn doTheTest() void {
1096 const result = noasync add(50, 100);
1092 const result = nosuspend add(50, 100);
10971093 expect(result == 150);
10981094 }
10991095 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
11151111 const sum = (await f1) + (await f2);
11161112 expect(sum == 10);
11171113 }
1118 async fn add(a: i32, b: i32) i32 {
1114 fn add(a: i32, b: i32) callconv(.Async) i32 {
11191115 return a + b;
11201116 }
11211117 };
......@@ -1130,7 +1126,7 @@ test "await used in expression after a fn call" {
11301126 sum = foo() + await f1;
11311127 expect(sum == 8);
11321128 }
1133 async fn add(a: i32, b: i32) i32 {
1129 fn add(a: i32, b: i32) callconv(.Async) i32 {
11341130 return a + b;
11351131 }
11361132 fn foo() i32 {
......@@ -1147,7 +1143,7 @@ test "async fn call used in expression after a fn call" {
11471143 sum = foo() + add(3, 4);
11481144 expect(sum == 8);
11491145 }
1150 async fn add(a: i32, b: i32) i32 {
1146 fn add(a: i32, b: i32) callconv(.Async) i32 {
11511147 return a + b;
11521148 }
11531149 fn foo() i32 {
......@@ -1403,7 +1399,7 @@ test "async function call resolves target fn frame, runtime func" {
14031399 fn foo() anyerror!void {
14041400 const stack_size = 1000;
14051401 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;
14071403 return await @asyncCall(&stack_frame, {}, func);
14081404 }
14091405
......@@ -1511,13 +1507,13 @@ test "take address of temporary async frame" {
15111507 S.doTheTest();
15121508}
15131509
1514test "noasync await" {
1510test "nosuspend await" {
15151511 const S = struct {
15161512 var finished = false;
15171513
15181514 fn doTheTest() void {
15191515 var frame = async foo(false);
1520 expect(noasync await frame == 42);
1516 expect(nosuspend await frame == 42);
15211517 finished = true;
15221518 }
15231519
......@@ -1532,7 +1528,7 @@ test "noasync await" {
15321528 expect(S.finished);
15331529}
15341530
1535test "noasync on function calls" {
1531test "nosuspend on function calls" {
15361532 const S0 = struct {
15371533 b: i32 = 42,
15381534 };
......@@ -1544,8 +1540,8 @@ test "noasync on function calls" {
15441540 return S0{};
15451541 }
15461542 };
1547 expectEqual(@as(i32, 42), noasync S1.c().b);
1548 expectEqual(@as(i32, 42), (try noasync S1.d()).b);
1543 expectEqual(@as(i32, 42), nosuspend S1.c().b);
1544 expectEqual(@as(i32, 42), (try nosuspend S1.d()).b);
15491545}
15501546
15511547test "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" {
15611557 };
15621558 var frame = async S.foo();
15631559 resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
1564 expect(noasync await frame);
1560 expect(nosuspend await frame);
15651561}
test/stage1/behavior/await_struct.zig+2-2
......@@ -18,14 +18,14 @@ test "coroutine await struct" {
1818 expect(await_final_result.x == 1234);
1919 expect(std.mem.eql(u8, &await_points, "abcdefghi"));
2020}
21async fn await_amain() void {
21fn await_amain() callconv(.Async) void {
2222 await_seq('b');
2323 var p = async await_another();
2424 await_seq('e');
2525 await_final_result = await p;
2626 await_seq('h');
2727}
28async fn await_another() Foo {
28fn await_another() callconv(.Async) Foo {
2929 await_seq('c');
3030 suspend {
3131 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
762762
763763test "cast between [*c]T and ?[*:0]T on fn parameter" {
764764 const S = struct {
765 const Handler = ?extern fn ([*c]const u8) void;
765 const Handler = ?fn ([*c]const u8) callconv(.C) void;
766766 fn addCallback(handler: Handler) void {}
767767
768768 fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}
......@@ -823,7 +823,16 @@ test "peer type resolve array pointer and unknown pointer" {
823823
824824 comptime expect(@TypeOf(&array, const_ptr) == [*]const u8);
825825 comptime expect(@TypeOf(const_ptr, &array) == [*]const u8);
826
826
827827 comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
828828 comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
829829}
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 @@
1const Err = error {
2 Foo
3};
1const Err = error{Foo};
42
53pub fn main() !u8 {
64 return Err.Foo;
test/standalone/main_return_error/error_u8_non_zero.zig+5-2
......@@ -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
58pub fn main() !u8 {
69 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)