From 92a423739d91bd0677940fc1a86b593649cafaa6 Mon Sep 17 00:00:00 2001
From: Sebastian <15335529+Sobeston@users.noreply.github.com>
Date: Wed, 1 Apr 2020 09:11:05 +0100
Subject: [PATCH 01/74] mem.zeroes - add sentinel terminated array support
---
lib/std/mem.zig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index f54eb03d65..cedb1bc27d 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -341,6 +341,9 @@ pub fn zeroes(comptime T: type) T {
}
},
.Array => |info| {
+ if (info.sentinel) |sentinel| {
+ return [_:info.sentinel]info.child{zeroes(info.child)} ** info.len;
+ }
return [_]info.child{zeroes(info.child)} ** info.len;
},
.Vector,
From ebbd137a0e90a8e78655d2a5f74cf87120b5a5a1 Mon Sep 17 00:00:00 2001
From: xackus <14938807+xackus@users.noreply.github.com>
Date: Tue, 21 Apr 2020 10:25:09 +0200
Subject: [PATCH 02/74] fix json.WriteStream.emitJson
---
lib/std/json/write_stream.zig | 55 ++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 23 deletions(-)
diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig
index 60974a207e..11f0171996 100644
--- a/lib/std/json/write_stream.zig
+++ b/lib/std/json/write_stream.zig
@@ -148,6 +148,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
self.popState();
}
+ // TODO better handling of ComptimeInt and ComptimeFloat
pub fn emitNumber(
self: *Self,
/// An integer, float, or `std.math.BigInt`. Emitted as a bare number if it fits losslessly
@@ -180,6 +181,7 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
}
pub fn emitString(self: *Self, string: []const u8) !void {
+ assert(self.state[self.state_index] == State.Value);
try self.writeEscapedString(string);
self.popState();
}
@@ -191,7 +193,9 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
/// Writes the complete json into the output stream
pub fn emitJson(self: *Self, json: std.json.Value) Stream.Error!void {
+ assert(self.state[self.state_index] == State.Value);
try self.stringify(json);
+ self.popState();
}
fn indent(self: *Self) !void {
@@ -233,7 +237,32 @@ test "json write stream" {
defer arena_allocator.deinit();
var w = std.json.writeStream(out, 10);
- try w.emitJson(try getJson(&arena_allocator.allocator));
+
+ try w.beginObject();
+
+ try w.objectField("object");
+ try w.emitJson(try getJsonObject(&arena_allocator.allocator));
+
+ try w.objectField("string");
+ try w.emitString("This is a string");
+
+ try w.objectField("array");
+ try w.beginArray();
+ try w.arrayElem();
+ try w.emitString("Another string");
+ try w.arrayElem();
+ try w.emitNumber(@as(i32, 1));
+ try w.arrayElem();
+ try w.emitNumber(@as(f32, 3.5));
+ try w.endArray();
+
+ try w.objectField("int");
+ try w.emitNumber(@as(i32, 10));
+
+ try w.objectField("float");
+ try w.emitNumber(@as(f32, 3.5));
+
+ try w.endObject();
const result = slice_stream.getWritten();
const expected =
@@ -246,38 +275,18 @@ test "json write stream" {
\\ "array": [
\\ "Another string",
\\ 1,
- \\ 3.14e+00
+ \\ 3.5e+00
\\ ],
\\ "int": 10,
- \\ "float": 3.14e+00
+ \\ "float": 3.5e+00
\\}
;
std.testing.expect(std.mem.eql(u8, expected, result));
}
-fn getJson(allocator: *std.mem.Allocator) !std.json.Value {
- var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
- _ = try value.Object.put("string", std.json.Value{ .String = "This is a string" });
- _ = try value.Object.put("int", std.json.Value{ .Integer = @intCast(i64, 10) });
- _ = try value.Object.put("float", std.json.Value{ .Float = 3.14 });
- _ = try value.Object.put("array", try getJsonArray(allocator));
- _ = try value.Object.put("object", try getJsonObject(allocator));
- return value;
-}
-
fn getJsonObject(allocator: *std.mem.Allocator) !std.json.Value {
var value = std.json.Value{ .Object = std.json.ObjectMap.init(allocator) };
_ = try value.Object.put("one", std.json.Value{ .Integer = @intCast(i64, 1) });
_ = try value.Object.put("two", std.json.Value{ .Float = 2.0 });
return value;
}
-
-fn getJsonArray(allocator: *std.mem.Allocator) !std.json.Value {
- var value = std.json.Value{ .Array = std.json.Array.init(allocator) };
- var array = &value.Array;
- _ = try array.append(std.json.Value{ .String = "Another string" });
- _ = try array.append(std.json.Value{ .Integer = @intCast(i64, 1) });
- _ = try array.append(std.json.Value{ .Float = 3.14 });
-
- return value;
-}
From 3a397795be1c0219a3a0d96082ee7d4eeddbfa7a Mon Sep 17 00:00:00 2001
From: Isaac Freund
Date: Sat, 2 May 2020 23:28:44 +0200
Subject: [PATCH 03/74] Apply naming conventions of structs to files
---
doc/langref.html.in | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 6026912893..537a0a55d3 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -9990,6 +9990,13 @@ coding style.
conventions.
+ File names fall into two categories: types and namespaces. If the file
+ (implicity a struct) has top level fields, it should be named like any
+ other struct with fields using {#syntax#}TitleCase{#endsyntax#}. Otherwise,
+ it should use {#syntax#}snake_case{#endsyntax#}. Directory names should be
+ {#syntax#}snake_case{#endsyntax#}.
+
+
These are general rules of thumb; if it makes sense to do something different,
do what makes sense. For example, if there is an established convention such as
{#syntax#}ENOENT{#endsyntax#}, follow the established convention.
@@ -9998,6 +10005,7 @@ coding style.
{#header_open|Examples#}
{#code_begin|syntax#}
const namespace_name = @import("dir_name/file_name.zig");
+const TypeName = @import("dir_name/TypeName.zig");
var global_var: i32 = undefined;
const const_name = 42;
const primitive_type_alias = f32;
From c5198bd76f96d7dab64fdd8d81fc8028187b1403 Mon Sep 17 00:00:00 2001
From: Matthew Knight
Date: Sat, 2 May 2020 20:22:43 -0700
Subject: [PATCH 04/74] added scoped typedef to translate-c
---
src-self-hosted/translate_c.zig | 18 ++++++++++++++++++
test/run_translated_c.zig | 11 +++++++++++
2 files changed, 29 insertions(+)
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 1c689e9f76..a204469b83 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -1394,6 +1394,24 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
node.semicolon_token = try appendToken(c, .Semicolon, ";");
try block_scope.block_node.statements.push(&node.base);
},
+ .Typedef => {
+ const type_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
+ const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
+ @ptrCast(*const ZigClangNamedDecl, type_decl),
+ ));
+
+ const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(type_decl);
+ const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
+
+ const mangled_name = try block_scope.makeMangledName(c, name);
+ const node = try transCreateNodeVarDecl(c, false, true, mangled_name);
+ node.eq_token = try appendToken(c, .Equal, "=");
+
+ const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt));
+ node.init_node = try transType(rp, underlying_type, loc);
+ node.semicolon_token = try appendToken(c, .Semicolon, ";");
+ try block_scope.block_node.statements.push(&node.base);
+ },
else => |kind| return revertAndWarn(
rp,
error.UnsupportedTranslation,
diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig
index ec6a11b9b4..a49fef76d1 100644
--- a/test/run_translated_c.zig
+++ b/test/run_translated_c.zig
@@ -243,4 +243,15 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
+
+ cases.add("scoped typedef",
+ \\int main(int argc, char **argv) {
+ \\ typedef int Foo;
+ \\ typedef Foo Bar;
+ \\ typedef void (*func)(int);
+ \\ Foo i;
+ \\ Bar j;
+ \\ return 0;
+ \\}
+ , "");
}
From 9b788b765c1557a414710872fa9c11fce1f8c504 Mon Sep 17 00:00:00 2001
From: Cato
Date: Sun, 3 May 2020 10:40:07 +0200
Subject: [PATCH 05/74] Pass filtered_sock_type to system.socket. Cover
PermissionDenied error
---
lib/std/net.zig | 4 ++++
lib/std/net/test.zig | 2 +-
lib/std/os.zig | 10 +++++++++-
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index b9681bc618..cc3e0d903e 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -1366,6 +1366,10 @@ pub const StreamServer = struct {
/// Firewall rules forbid connection.
BlockedByFirewall,
+
+ /// Permission to create a socket of the specified type and/or
+ /// protocol is denied.
+ PermissionDenied,
} || os.UnexpectedError;
pub const Connection = struct {
diff --git a/lib/std/net/test.zig b/lib/std/net/test.zig
index 087f965c4e..f4f97d3944 100644
--- a/lib/std/net/test.zig
+++ b/lib/std/net/test.zig
@@ -81,7 +81,7 @@ test "resolve DNS" {
test "listen on a port, send bytes, receive bytes" {
if (!std.io.is_async) return error.SkipZigTest;
- if (std.builtin.os.tag != .linux) {
+ if (std.builtin.os.tag != .linux and !std.builtin.os.tag.isDarwin()) {
// TODO build abstractions for other operating systems
return error.SkipZigTest;
}
diff --git a/lib/std/os.zig b/lib/std/os.zig
index ff7089ceb0..3b8767bdc1 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -2156,6 +2156,9 @@ pub const SocketError = error{
/// The protocol type or the specified protocol is not supported within this domain.
ProtocolNotSupported,
+
+ /// The socket type is not supported by the protocol.
+ SocketTypeNotSupported,
} || UnexpectedError;
pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
@@ -2164,7 +2167,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
socket_type & ~@as(u32, SOCK_NONBLOCK | SOCK_CLOEXEC)
else
socket_type;
- const rc = system.socket(domain, socket_type, protocol);
+ const rc = system.socket(domain, filtered_sock_type, protocol);
switch (errno(rc)) {
0 => {
const fd = @intCast(fd_t, rc);
@@ -2181,6 +2184,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
ENOBUFS => return error.SystemResources,
ENOMEM => return error.SystemResources,
EPROTONOSUPPORT => return error.ProtocolNotSupported,
+ EPROTOTYPE => return error.SocketTypeNotSupported,
else => |err| return unexpectedErrno(err),
}
}
@@ -2290,6 +2294,10 @@ pub const AcceptError = error{
/// This error occurs when no global event loop is configured,
/// and accepting from the socket would block.
WouldBlock,
+
+ /// Permission to create a socket of the specified type and/or
+ /// protocol is denied.
+ PermissionDenied,
} || UnexpectedError;
/// Accept a connection on a socket.
From adc444ceeb91c06a6ee84dc4e4874294a41dee45 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Mon, 4 May 2020 14:28:58 +0300
Subject: [PATCH 06/74] fix missing compile error on call assigned to const
---
src/ir.cpp | 10 ++++++++++
test/compile_errors.zig | 23 +++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index 4795645544..b636ac6f76 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -20000,6 +20000,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
return result_loc;
}
+ if (result_loc->value->type->data.pointer.is_const) {
+ ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type);
dummy_value->value->special = ConstValSpecialRuntime;
IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
@@ -20138,6 +20143,11 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
return result_loc;
}
+ if (result_loc->value->type->data.pointer.is_const) {
+ ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
IrInstGen *dummy_value = ir_const(ira, source_instr, return_type);
dummy_value->value->special = ConstValSpecialRuntime;
IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr,
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index fd27b8e666..3d7677ab75 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,29 @@ const tests = @import("tests.zig");
const std = @import("std");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add("call assigned to constant",
+ \\const Foo = struct {
+ \\ x: i32,
+ \\};
+ \\fn foo() Foo {
+ \\ return .{ .x = 42 };
+ \\}
+ \\fn bar(val: var) Foo {
+ \\ return .{ .x = val };
+ \\}
+ \\export fn entry() void {
+ \\ const baz: Foo = undefined;
+ \\ baz = foo();
+ \\}
+ \\export fn entry1() void {
+ \\ const baz: Foo = undefined;
+ \\ baz = bar(42);
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:12:14: error: cannot assign to constant",
+ "tmp.zig:16:14: error: cannot assign to constant",
+ });
+
cases.add("invalid pointer syntax",
\\export fn foo() void {
\\ var guid: *:0 const u8 = undefined;
From 85fd484f0778b5f158dc76bf51b820314b86292d Mon Sep 17 00:00:00 2001
From: Vexu
Date: Mon, 4 May 2020 14:45:36 +0300
Subject: [PATCH 07/74] std: fix blake3 assignment to constant
---
lib/std/crypto/blake3.zig | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/std/crypto/blake3.zig b/lib/std/crypto/blake3.zig
index 7c79ffcf55..08479d65a5 100644
--- a/lib/std/crypto/blake3.zig
+++ b/lib/std/crypto/blake3.zig
@@ -338,7 +338,7 @@ pub const Blake3 = struct {
}
// Section 5.1.2 of the BLAKE3 spec explains this algorithm in more detail.
- fn add_chunk_chaining_value(self: *Blake3, new_cv: [8]u32, total_chunks: u64) void {
+ fn add_chunk_chaining_value(self: *Blake3, first_cv: [8]u32, total_chunks: u64) void {
// This chunk might complete some subtrees. For each completed subtree,
// its left child will be the current top entry in the CV stack, and
// its right child will be the current value of `new_cv`. Pop each left
@@ -346,6 +346,7 @@ pub const Blake3 = struct {
// with the result. After all these merges, push the final value of
// `new_cv` onto the stack. The number of completed subtrees is given
// by the number of trailing 0-bits in the new total number of chunks.
+ var new_cv = first_cv;
var chunk_counter = total_chunks;
while (chunk_counter & 1 == 0) {
new_cv = parent_cv(self.pop_cv(), new_cv, self.key, self.flags);
From 75b699b2c624d62a4b6717f00bd0856b86c3f990 Mon Sep 17 00:00:00 2001
From: Jonathan Marler
Date: Mon, 4 May 2020 00:42:12 -0600
Subject: [PATCH 08/74] os.zig: add ETIMEDOUT error case to read function
According to documentation ETIMEDOUT (110) is a valid error code for the read function. I just had my long-running (been running for about 7 weeks) network program crash because it did not handle the ETIMEDOUT error code from "read".
---
lib/std/os.zig | 2 ++
lib/std/zig/system.zig | 1 +
src-self-hosted/stage2.zig | 1 +
3 files changed, 4 insertions(+)
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 3b8767bdc1..86130ed32c 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -292,6 +292,7 @@ pub const ReadError = error{
OperationAborted,
BrokenPipe,
ConnectionResetByPeer,
+ ConnectionTimedOut,
/// This error occurs when no global event loop is configured,
/// and reading from the file descriptor would block.
@@ -351,6 +352,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
ENOBUFS => return error.SystemResources,
ENOMEM => return error.SystemResources,
ECONNRESET => return error.ConnectionResetByPeer,
+ ETIMEDOUT => return error.ConnectionTimedOut,
else => |err| return unexpectedErrno(err),
}
}
diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig
index 7b05e3bcfb..92f01c4195 100644
--- a/lib/std/zig/system.zig
+++ b/lib/std/zig/system.zig
@@ -837,6 +837,7 @@ pub const NativeTargetInfo = struct {
error.BrokenPipe => return error.UnableToReadElfFile,
error.Unseekable => return error.UnableToReadElfFile,
error.ConnectionResetByPeer => return error.UnableToReadElfFile,
+ error.ConnectionTimedOut => return error.UnableToReadElfFile,
error.Unexpected => return error.Unexpected,
error.InputOutput => return error.FileSystem,
};
diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig
index 38ab49ccc4..d93d069915 100644
--- a/src-self-hosted/stage2.zig
+++ b/src-self-hosted/stage2.zig
@@ -841,6 +841,7 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [
error.EndOfStream => return .EndOfFile,
error.IsDir => return .IsDir,
error.ConnectionResetByPeer => unreachable,
+ error.ConnectionTimedOut => unreachable,
error.OutOfMemory => return .OutOfMemory,
error.Unseekable => unreachable,
error.SharingViolation => return .SharingViolation,
From db4833d4d607a91686dc37ed68e453e9538dc668 Mon Sep 17 00:00:00 2001
From: Matthew Knight
Date: Mon, 4 May 2020 23:45:31 -0700
Subject: [PATCH 09/74] moved duplicated code to common functions
---
src-self-hosted/translate_c.zig | 66 ++++++++++++++++++---------------
test/run_translated_c.zig | 2 +
2 files changed, 39 insertions(+), 29 deletions(-)
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index a204469b83..2a8817977b 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -668,17 +668,7 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
return transCreateNodeIdentifier(c, builtin_name);
}
-fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
- if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
- return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
- const rp = makeRestorePoint(c);
-
- const typedef_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl)));
-
- // TODO https://github.com/ziglang/zig/issues/3756
- // TODO https://github.com/ziglang/zig/issues/1802
- const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
-
+fn checkForBuiltinTypedef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, checked_name: []const u8) !?*ast.Node {
if (mem.eql(u8, checked_name, "uint8_t"))
return transTypeDefAsBuiltin(c, typedef_decl, "u8")
else if (mem.eql(u8, checked_name, "int8_t"))
@@ -704,28 +694,49 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
else if (mem.eql(u8, checked_name, "size_t"))
return transTypeDefAsBuiltin(c, typedef_decl, "usize");
+ return null;
+}
+
+fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_level_visit: bool) Error!?*ast.Node {
+ if (c.decl_table.get(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)))) |kv|
+ return transCreateNodeIdentifier(c, kv.value); // Avoid processing this decl twice
+ const rp = makeRestorePoint(c);
+
+ const typedef_name = try c.str(ZigClangNamedDecl_getName_bytes_begin(@ptrCast(*const ZigClangNamedDecl, typedef_decl)));
+
+ // TODO https://github.com/ziglang/zig/issues/3756
+ // TODO https://github.com/ziglang/zig/issues/1802
+ const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
+ if (try checkForBuiltinTypedef(c, typedef_decl, checked_name)) |node| {
+ return node;
+ }
+
if (!top_level_visit) {
return transCreateNodeIdentifier(c, checked_name);
}
_ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
- const visib_tok = try appendToken(c, .Keyword_pub, "pub");
- const const_tok = try appendToken(c, .Keyword_const, "const");
- const node = try transCreateNodeVarDecl(c, true, true, checked_name);
- node.eq_token = try appendToken(c, .Equal, "=");
+ const node = (try transZigTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
+ try addTopLevelDecl(c, checked_name, &node.base);
+ return transCreateNodeIdentifier(c, checked_name);
+}
+
+fn transZigTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl {
+ const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name);
+ node.eq_token = try appendToken(rp.c, .Equal, "=");
const child_qt = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
const typedef_loc = ZigClangTypedefNameDecl_getLocation(typedef_decl);
node.init_node = transQualType(rp, child_qt, typedef_loc) catch |err| switch (err) {
error.UnsupportedType => {
- try failDecl(c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});
+ try failDecl(rp.c, typedef_loc, checked_name, "unable to resolve typedef child type", .{});
return null;
},
error.OutOfMemory => |e| return e,
};
- node.semicolon_token = try appendToken(c, .Semicolon, ";");
- try addTopLevelDecl(c, checked_name, &node.base);
- return transCreateNodeIdentifier(c, checked_name);
+
+ node.semicolon_token = try appendToken(rp.c, .Semicolon, ";");
+ return node;
}
fn transRecordDecl(c: *Context, record_decl: *const ZigClangRecordDecl) Error!?*ast.Node {
@@ -1395,21 +1406,18 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
try block_scope.block_node.statements.push(&node.base);
},
.Typedef => {
- const type_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
+ const typedef_decl = @ptrCast(*const ZigClangTypedefNameDecl, it[0]);
const name = try c.str(ZigClangNamedDecl_getName_bytes_begin(
- @ptrCast(*const ZigClangNamedDecl, type_decl),
+ @ptrCast(*const ZigClangNamedDecl, typedef_decl),
));
- const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(type_decl);
- const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
-
const mangled_name = try block_scope.makeMangledName(c, name);
- const node = try transCreateNodeVarDecl(c, false, true, mangled_name);
- node.eq_token = try appendToken(c, .Equal, "=");
+ if (try checkForBuiltinTypedef(c, typedef_decl, mangled_name)) |ast_node| {
+ return ast_node;
+ }
- const loc = ZigClangStmt_getBeginLoc(@ptrCast(*const ZigClangStmt, stmt));
- node.init_node = try transType(rp, underlying_type, loc);
- node.semicolon_token = try appendToken(c, .Semicolon, ";");
+ const node = (try transZigTypedef(rp, typedef_decl, false, mangled_name))
+ orelse return error.UnsupportedTranslation;
try block_scope.block_node.statements.push(&node.base);
},
else => |kind| return revertAndWarn(
diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig
index a49fef76d1..83569f1241 100644
--- a/test/run_translated_c.zig
+++ b/test/run_translated_c.zig
@@ -245,10 +245,12 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
, "");
cases.add("scoped typedef",
+ \\#include
\\int main(int argc, char **argv) {
\\ typedef int Foo;
\\ typedef Foo Bar;
\\ typedef void (*func)(int);
+ \\ typedef uint32_t Number;
\\ Foo i;
\\ Bar j;
\\ return 0;
From 4cb4097b084d9f9df31d7cf36b5876ad51790828 Mon Sep 17 00:00:00 2001
From: Haze Booth
Date: Tue, 5 May 2020 04:14:11 -0400
Subject: [PATCH 10/74] Update ErrorUnion thread spawn result to return null
instead of 0
---
lib/std/thread.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/thread.zig b/lib/std/thread.zig
index 6d9b4bebe6..d07c41c5b0 100644
--- a/lib/std/thread.zig
+++ b/lib/std/thread.zig
@@ -280,7 +280,7 @@ pub const Thread = struct {
std.debug.dumpStackTrace(trace.*);
}
};
- return 0;
+ return null;
},
else => @compileError(bad_startfn_ret),
}
From 8d5636ebe4b1d70db14e28c67f7986fb2a1ce3cf Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Tue, 5 May 2020 05:08:46 -0600
Subject: [PATCH 11/74] Rename noasync to nosuspend in self-hosted, add
rewriter
---
doc/docgen.zig | 2 +-
lib/std/zig/ast.zig | 22 +++++++++++-----------
lib/std/zig/parse.zig | 24 ++++++++++++------------
lib/std/zig/parser_test.zig | 26 ++++++++++++++++++++------
lib/std/zig/render.zig | 14 +++++++++-----
lib/std/zig/tokenizer.zig | 7 ++++---
6 files changed, 57 insertions(+), 38 deletions(-)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 21bec3ba7e..a249a526a1 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -802,8 +802,8 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_inline,
.Keyword_nakedcc,
.Keyword_noalias,
- .Keyword_noasync,
.Keyword_noinline,
+ .Keyword_nosuspend,
.Keyword_or,
.Keyword_orelse,
.Keyword_packed,
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 91b9a704c9..50051040d9 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -438,7 +438,7 @@ pub const Node = struct {
ContainerDecl,
Asm,
Comptime,
- Noasync,
+ Nosuspend,
Block,
// Misc
@@ -569,9 +569,9 @@ pub const Node = struct {
return true;
},
- .Noasync => {
- const noasync_node = @fieldParentPtr(Noasync, "base", n);
- return noasync_node.expr.id != .Block;
+ .Nosuspend => {
+ const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);
+ return nosuspend_node.expr.id != .Block;
},
else => return true,
}
@@ -1084,12 +1084,12 @@ pub const Node = struct {
}
};
- pub const Noasync = struct {
- base: Node = Node{ .id = .Noasync },
- noasync_token: TokenIndex,
+ pub const Nosuspend = struct {
+ base: Node = Node{ .id = .Nosuspend },
+ nosuspend_token: TokenIndex,
expr: *Node,
- pub fn iterate(self: *Noasync, index: usize) ?*Node {
+ pub fn iterate(self: *Nosuspend, index: usize) ?*Node {
var i = index;
if (i < 1) return self.expr;
@@ -1098,11 +1098,11 @@ pub const Node = struct {
return null;
}
- pub fn firstToken(self: *const Noasync) TokenIndex {
- return self.noasync_token;
+ pub fn firstToken(self: *const Nosuspend) TokenIndex {
+ return self.nosuspend_token;
}
- pub fn lastToken(self: *const Noasync) TokenIndex {
+ pub fn lastToken(self: *const Nosuspend) TokenIndex {
return self.expr.lastToken();
}
};
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index fdaf0ec8f1..d7f4d76cf6 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -495,7 +495,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
/// Statement
/// <- KEYWORD_comptime? VarDecl
/// / KEYWORD_comptime BlockExprStatement
-/// / KEYWORD_noasync BlockExprStatement
+/// / KEYWORD_nosuspend BlockExprStatement
/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
/// / KEYWORD_defer BlockExprStatement
/// / KEYWORD_errdefer Payload? BlockExprStatement
@@ -527,14 +527,14 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
return &node.base;
}
- if (eatToken(it, .Keyword_noasync)) |noasync_token| {
+ if (eatToken(it, .Keyword_nosuspend)) |nosuspend_token| {
const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{
.ExpectedBlockOrAssignment = .{ .token = it.index },
});
- const node = try arena.create(Node.Noasync);
+ const node = try arena.create(Node.Nosuspend);
node.* = .{
- .noasync_token = noasync_token,
+ .nosuspend_token = nosuspend_token,
.expr = block_expr,
};
return &node.base;
@@ -908,7 +908,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / IfExpr
/// / KEYWORD_break BreakLabel? Expr?
/// / KEYWORD_comptime Expr
-/// / KEYWORD_noasync Expr
+/// / KEYWORD_nosuspend Expr
/// / KEYWORD_continue BreakLabel?
/// / KEYWORD_resume Expr
/// / KEYWORD_return Expr?
@@ -944,13 +944,13 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return &node.base;
}
- if (eatToken(it, .Keyword_noasync)) |token| {
+ if (eatToken(it, .Keyword_nosuspend)) |token| {
const expr_node = try expectNode(arena, it, tree, parseExpr, .{
.ExpectedExpr = .{ .token = it.index },
});
- const node = try arena.create(Node.Noasync);
+ const node = try arena.create(Node.Nosuspend);
node.* = .{
- .noasync_token = token,
+ .nosuspend_token = token,
.expr = expr_node,
};
return &node.base;
@@ -1288,7 +1288,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / IfTypeExpr
/// / INTEGER
/// / KEYWORD_comptime TypeExpr
-/// / KEYWORD_noasync TypeExpr
+/// / KEYWORD_nosuspend TypeExpr
/// / KEYWORD_error DOT IDENTIFIER
/// / KEYWORD_false
/// / KEYWORD_null
@@ -1327,11 +1327,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
};
return &node.base;
}
- if (eatToken(it, .Keyword_noasync)) |token| {
+ if (eatToken(it, .Keyword_nosuspend)) |token| {
const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
- const node = try arena.create(Node.Noasync);
+ const node = try arena.create(Node.Nosuspend);
node.* = .{
- .noasync_token = token,
+ .nosuspend_token = token,
.expr = expr,
};
return &node.base;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 7fca72ac70..ebc6b92b78 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -35,10 +35,10 @@ test "zig fmt: errdefer with payload" {
);
}
-test "zig fmt: noasync block" {
+test "zig fmt: nosuspend block" {
try testCanonical(
\\pub fn main() anyerror!void {
- \\ noasync {
+ \\ nosuspend {
\\ var foo: Foo = .{ .bar = 42 };
\\ }
\\}
@@ -46,10 +46,10 @@ test "zig fmt: noasync block" {
);
}
-test "zig fmt: noasync await" {
+test "zig fmt: nosuspend await" {
try testCanonical(
\\fn foo() void {
- \\ x = noasync await y;
+ \\ x = nosuspend await y;
\\}
\\
);
@@ -2519,9 +2519,9 @@ test "zig fmt: async functions" {
);
}
-test "zig fmt: noasync" {
+test "zig fmt: nosuspend" {
try testCanonical(
- \\const a = noasync foo();
+ \\const a = nosuspend foo();
\\
);
}
@@ -2926,6 +2926,20 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
);
}
+test "zig fmt: noasync to nosuspend" {
+ // TODO: remove this
+ try testTransform(
+ \\pub fn main() void {
+ \\ noasync call();
+ \\}
+ ,
+ \\pub fn main() void {
+ \\ nosuspend call();
+ \\}
+ \\
+ );
+}
+
const std = @import("std");
const mem = std.mem;
const warn = std.debug.warn;
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 1e1552dae4..441a91a28a 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -391,11 +391,15 @@ fn renderExpression(
try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space);
return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
},
- .Noasync => {
- const noasync_node = @fieldParentPtr(ast.Node.Noasync, "base", base);
-
- try renderToken(tree, stream, noasync_node.noasync_token, indent, start_col, Space.Space);
- return renderExpression(allocator, stream, tree, indent, start_col, noasync_node.expr, space);
+ .Nosuspend => {
+ const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base);
+ if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) {
+ // TODO: remove this
+ try stream.writeAll("nosuspend ");
+ } else {
+ try renderToken(tree, stream, nosuspend_node.nosuspend_token, indent, start_col, Space.Space);
+ }
+ return renderExpression(allocator, stream, tree, indent, start_col, nosuspend_node.expr, space);
},
.Suspend => {
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index 99574f2a98..b6c1a06276 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -49,8 +49,9 @@ pub const Token = struct {
Keyword.init("inline", .Keyword_inline),
Keyword.init("nakedcc", .Keyword_nakedcc),
Keyword.init("noalias", .Keyword_noalias),
- Keyword.init("noasync", .Keyword_noasync),
+ Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
Keyword.init("noinline", .Keyword_noinline),
+ Keyword.init("nosuspend", .Keyword_nosuspend),
Keyword.init("null", .Keyword_null),
Keyword.init("or", .Keyword_or),
Keyword.init("orelse", .Keyword_orelse),
@@ -182,8 +183,8 @@ pub const Token = struct {
Keyword_inline,
Keyword_nakedcc,
Keyword_noalias,
- Keyword_noasync,
Keyword_noinline,
+ Keyword_nosuspend,
Keyword_null,
Keyword_or,
Keyword_orelse,
@@ -307,8 +308,8 @@ pub const Token = struct {
.Keyword_inline => "inline",
.Keyword_nakedcc => "nakedcc",
.Keyword_noalias => "noalias",
- .Keyword_noasync => "noasync",
.Keyword_noinline => "noinline",
+ .Keyword_nosuspend => "nosuspend",
.Keyword_null => "null",
.Keyword_or => "or",
.Keyword_orelse => "orelse",
From b957dc29a4e3f025e446e717b0ae8c69602545ca Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Tue, 5 May 2020 05:11:19 -0600
Subject: [PATCH 12/74] Rename noasync to nosuspend in C++ compiler
---
src/all_types.hpp | 22 ++++++++---------
src/analyze.cpp | 18 +++++++-------
src/analyze.hpp | 2 +-
src/ast_render.cpp | 14 +++++------
src/codegen.cpp | 30 +++++++++++------------
src/ir.cpp | 60 +++++++++++++++++++++++-----------------------
src/ir_print.cpp | 8 +++----
src/parser.cpp | 32 ++++++++++++-------------
src/tokenizer.cpp | 4 ++--
src/tokenizer.hpp | 2 +-
10 files changed, 96 insertions(+), 96 deletions(-)
diff --git a/src/all_types.hpp b/src/all_types.hpp
index ade57a0a5d..aeffa440ab 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -672,7 +672,7 @@ enum NodeType {
NodeTypeSwitchProng,
NodeTypeSwitchRange,
NodeTypeCompTime,
- NodeTypeNoAsync,
+ NodeTypeNoSuspend,
NodeTypeBreak,
NodeTypeContinue,
NodeTypeAsmExpr,
@@ -862,7 +862,7 @@ enum CallModifier {
CallModifierAsync,
CallModifierNeverTail,
CallModifierNeverInline,
- CallModifierNoAsync,
+ CallModifierNoSuspend,
CallModifierAlwaysTail,
CallModifierAlwaysInline,
CallModifierCompileTime,
@@ -1014,7 +1014,7 @@ struct AstNodeCompTime {
AstNode *expr;
};
-struct AstNodeNoAsync {
+struct AstNodeNoSuspend {
AstNode *expr;
};
@@ -1225,7 +1225,7 @@ struct AstNode {
AstNodeSwitchProng switch_prong;
AstNodeSwitchRange switch_range;
AstNodeCompTime comptime_expr;
- AstNodeNoAsync noasync_expr;
+ AstNodeNoSuspend nosuspend_expr;
AstNodeAsmExpr asm_expr;
AstNodeFieldAccessExpr field_access_expr;
AstNodePtrDerefExpr ptr_deref_expr;
@@ -1858,7 +1858,7 @@ enum PanicMsgId {
PanicMsgIdResumedAnAwaitingFn,
PanicMsgIdFrameTooSmall,
PanicMsgIdResumedFnPendingAwait,
- PanicMsgIdBadNoAsyncCall,
+ PanicMsgIdBadNoSuspendCall,
PanicMsgIdResumeNotSuspendedFn,
PanicMsgIdBadSentinel,
PanicMsgIdShxTooBigRhs,
@@ -2376,7 +2376,7 @@ enum ScopeId {
ScopeIdRuntime,
ScopeIdTypeOf,
ScopeIdExpr,
- ScopeIdNoAsync,
+ ScopeIdNoSuspend,
};
struct Scope {
@@ -2510,9 +2510,9 @@ struct ScopeCompTime {
Scope base;
};
-// This scope is created for a noasync expression.
-// NodeTypeNoAsync
-struct ScopeNoAsync {
+// This scope is created for a nosuspend expression.
+// NodeTypeNoSuspend
+struct ScopeNoSuspend {
Scope base;
};
@@ -4488,7 +4488,7 @@ struct IrInstSrcAwait {
IrInstSrc *frame;
ResultLoc *result_loc;
- bool is_noasync;
+ bool is_nosuspend;
};
struct IrInstGenAwait {
@@ -4497,7 +4497,7 @@ struct IrInstGenAwait {
IrInstGen *frame;
IrInstGen *result_loc;
ZigFn *target_fn;
- bool is_noasync;
+ bool is_nosuspend;
};
struct IrInstSrcResume {
diff --git a/src/analyze.cpp b/src/analyze.cpp
index d170273808..4c3103c48c 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -106,7 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {
case ScopeIdDecls:
case ScopeIdFnDef:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdVarDecl:
case ScopeIdCImport:
case ScopeIdSuspend:
@@ -227,9 +227,9 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
return &scope->base;
}
-Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) {
- ScopeNoAsync *scope = heap::c_allocator.create();
- init_scope(g, &scope->base, ScopeIdNoAsync, node, parent);
+Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
+ ScopeNoSuspend *scope = heap::c_allocator.create();
+ init_scope(g, &scope->base, ScopeIdNoSuspend, node, parent);
return &scope->base;
}
@@ -3771,7 +3771,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeCompTime:
preview_comptime_decl(g, node, decls_scope);
break;
- case NodeTypeNoAsync:
+ case NodeTypeNoSuspend:
case NodeTypeParamDecl:
case NodeTypeReturnExpr:
case NodeTypeDefer:
@@ -4689,7 +4689,7 @@ void add_async_error_notes(CodeGen *g, ErrorMsg *msg, ZigFn *fn) {
static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,
bool must_not_be_async, CallModifier modifier)
{
- if (modifier == CallModifierNoAsync)
+ if (modifier == CallModifierNoSuspend)
return ErrorNone;
bool callee_is_async = false;
switch (callee->type_entry->data.fn.fn_type_id.cc) {
@@ -4812,7 +4812,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
}
for (size_t i = 0; i < fn->await_list.length; i += 1) {
IrInstGenAwait *await = fn->await_list.at(i);
- if (await->is_noasync) continue;
+ if (await->is_nosuspend) continue;
switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
CallModifierNone))
{
@@ -6239,7 +6239,7 @@ static void mark_suspension_point(Scope *scope) {
case ScopeIdDecls:
case ScopeIdFnDef:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdCImport:
case ScopeIdSuspend:
case ScopeIdTypeOf:
@@ -6472,7 +6472,7 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
// The funtion call result of foo() must be spilled.
for (size_t i = 0; i < fn->await_list.length; i += 1) {
IrInstGenAwait *await = fn->await_list.at(i);
- if (await->is_noasync) {
+ if (await->is_nosuspend) {
continue;
}
if (await->base.value->special != ConstValSpecialRuntime) {
diff --git a/src/analyze.hpp b/src/analyze.hpp
index ae010c87e1..abe1d938d9 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -125,7 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeSuspend *create_suspend_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeFnDef *create_fndef_scope(CodeGen *g, AstNode *node, Scope *parent, ZigFn *fn_entry);
Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent);
-Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent);
+Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent);
Scope *create_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index 52e450dad4..49fad80a40 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -220,8 +220,8 @@ static const char *node_type_str(NodeType node_type) {
return "SwitchRange";
case NodeTypeCompTime:
return "CompTime";
- case NodeTypeNoAsync:
- return "NoAsync";
+ case NodeTypeNoSuspend:
+ return "NoSuspend";
case NodeTypeBreak:
return "Break";
case NodeTypeContinue:
@@ -709,8 +709,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
switch (node->data.fn_call_expr.modifier) {
case CallModifierNone:
break;
- case CallModifierNoAsync:
- fprintf(ar->f, "noasync ");
+ case CallModifierNoSuspend:
+ fprintf(ar->f, "nosuspend ");
break;
case CallModifierAsync:
fprintf(ar->f, "async ");
@@ -1093,10 +1093,10 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
render_node_grouped(ar, node->data.comptime_expr.expr);
break;
}
- case NodeTypeNoAsync:
+ case NodeTypeNoSuspend:
{
- fprintf(ar->f, "noasync ");
- render_node_grouped(ar, node->data.noasync_expr.expr);
+ fprintf(ar->f, "nosuspend ");
+ render_node_grouped(ar, node->data.nosuspend_expr.expr);
break;
}
case NodeTypeForExpr:
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 366eac4230..bf0e004dda 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -685,7 +685,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
case ScopeIdLoop:
case ScopeIdSuspend:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdRuntime:
case ScopeIdTypeOf:
case ScopeIdExpr:
@@ -966,8 +966,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("frame too small");
case PanicMsgIdResumedFnPendingAwait:
return buf_create_from_str("resumed an async function which can only be awaited");
- case PanicMsgIdBadNoAsyncCall:
- return buf_create_from_str("async function called in noasync scope suspended");
+ case PanicMsgIdBadNoSuspendCall:
+ return buf_create_from_str("async function called in nosuspend scope suspended");
case PanicMsgIdResumeNotSuspendedFn:
return buf_create_from_str("resumed a non-suspended function");
case PanicMsgIdBadSentinel:
@@ -4061,7 +4061,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
case ScopeIdLoop:
case ScopeIdSuspend:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdRuntime:
case ScopeIdTypeOf:
case ScopeIdExpr:
@@ -4212,9 +4212,9 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
// even if prefix_arg_err_ret_stack is true, let the async function do its own
// initialization.
} else {
- if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) {
+ if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
// Async function called as a normal function, and calling function is not async.
- // This is allowed because it was called with `noasync` which asserts that it will
+ // This is allowed because it was called with `nosuspend` which asserts that it will
// never suspend.
awaiter_init_val = zero;
} else {
@@ -4325,7 +4325,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
case CallModifierCompileTime:
zig_unreachable();
case CallModifierNone:
- case CallModifierNoAsync:
+ case CallModifierNoSuspend:
case CallModifierAsync:
call_attr = ZigLLVM_CallAttrAuto;
break;
@@ -4401,7 +4401,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
get_llvm_type(g, instruction->base.value->type), "");
}
return nullptr;
- } else if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) {
+ } else if (instruction->modifier == CallModifierNoSuspend && !fn_is_async(g->cur_fn)) {
gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
if (ir_want_runtime_safety(g, &instruction->base)) {
@@ -4412,13 +4412,13 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
all_ones, LLVMAtomicOrderingRelease);
LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, "");
- LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic");
- LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk");
+ LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendPanic");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendOk");
LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
- // The async function suspended, but this noasync call asserted it wouldn't.
+ // The async function suspended, but this nosuspend call asserted it wouldn't.
LLVMPositionBuilderAtEnd(g->builder, bad_block);
- gen_safety_crash(g, PanicMsgIdBadNoAsyncCall);
+ gen_safety_crash(g, PanicMsgIdBadNoSuspendCall);
LLVMPositionBuilderAtEnd(g->builder, ok_block);
}
@@ -6391,7 +6391,7 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
nullptr : ir_llvm_value(g, instruction->result_loc);
- if (instruction->is_noasync ||
+ if (instruction->is_nosuspend ||
(instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
{
return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
@@ -7918,7 +7918,7 @@ static void do_code_gen(CodeGen *g) {
}
if (!is_async) {
- // allocate async frames for noasync calls & awaits to async functions
+ // allocate async frames for nosuspend calls & awaits to async functions
ZigType *largest_call_frame_type = nullptr;
IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base,
fn_table_entry->body_node, fn_table_entry, g->builtin_types.entry_void, "@async_call_frame");
@@ -7928,7 +7928,7 @@ static void do_code_gen(CodeGen *g) {
continue;
if (!fn_is_async(call->fn_entry))
continue;
- if (call->modifier != CallModifierNoAsync)
+ if (call->modifier != CallModifierNoSuspend)
continue;
if (call->frame_result_loc != nullptr)
continue;
diff --git a/src/ir.cpp b/src/ir.cpp
index f37f91088a..a8243b15df 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -4846,12 +4846,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins
}
static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
- IrInstSrc *frame, ResultLoc *result_loc, bool is_noasync)
+ IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend)
{
IrInstSrcAwait *instruction = ir_build_instruction(irb, scope, source_node);
instruction->frame = frame;
instruction->result_loc = result_loc;
- instruction->is_noasync = is_noasync;
+ instruction->is_nosuspend = is_nosuspend;
ir_ref_instruction(frame, irb->current_basic_block);
@@ -4859,14 +4859,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s
}
static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
- IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_noasync)
+ IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend)
{
IrInstGenAwait *instruction = ir_build_inst_gen(&ira->new_irb,
source_instruction->scope, source_instruction->source_node);
instruction->base.value->type = result_type;
instruction->frame = frame;
instruction->result_loc = result_loc;
- instruction->is_noasync = is_noasync;
+ instruction->is_nosuspend = is_nosuspend;
ir_ref_inst_gen(frame);
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_
case ScopeIdLoop:
case ScopeIdSuspend:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdRuntime:
case ScopeIdTypeOf:
case ScopeIdExpr:
@@ -5072,7 +5072,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope
case ScopeIdLoop:
case ScopeIdSuspend:
case ScopeIdCompTime:
- case ScopeIdNoAsync:
+ case ScopeIdNoSuspend:
case ScopeIdRuntime:
case ScopeIdTypeOf:
case ScopeIdExpr:
@@ -7335,10 +7335,10 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
zig_unreachable();
}
-static ScopeNoAsync *get_scope_noasync(Scope *scope) {
+static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
while (scope) {
- if (scope->id == ScopeIdNoAsync)
- return (ScopeNoAsync *)scope;
+ if (scope->id == ScopeIdNoSuspend)
+ return (ScopeNoSuspend *)scope;
if (scope->id == ScopeIdFnDef)
return nullptr;
@@ -7355,15 +7355,15 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node,
if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc);
- bool is_noasync = get_scope_noasync(scope) != nullptr;
+ bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
CallModifier modifier = node->data.fn_call_expr.modifier;
- if (is_noasync) {
+ if (is_nosuspend) {
if (modifier == CallModifierAsync) {
add_node_error(irb->codegen, node,
- buf_sprintf("async call in noasync scope"));
+ buf_sprintf("async call in nosuspend scope"));
return irb->codegen->invalid_inst_src;
}
- modifier = CallModifierNoAsync;
+ modifier = CallModifierNoSuspend;
}
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
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
}
-static IrInstSrc *ir_gen_noasync(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
- assert(node->type == NodeTypeNoAsync);
+static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
+ assert(node->type == NodeTypeNoSuspend);
- Scope *child_scope = create_noasync_scope(irb->codegen, node, parent_scope);
+ Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope);
// purposefully pass null for result_loc and let EndExpr handle it
return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr);
}
@@ -9813,8 +9813,8 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod
static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeResume);
- if (get_scope_noasync(scope) != nullptr) {
- add_node_error(irb->codegen, node, buf_sprintf("resume in noasync scope"));
+ if (get_scope_nosuspend(scope) != nullptr) {
+ add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope"));
return irb->codegen->invalid_inst_src;
}
@@ -9830,7 +9830,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
{
assert(node->type == NodeTypeAwaitExpr);
- bool is_noasync = get_scope_noasync(scope) != nullptr;
+ bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
AstNode *expr_node = node->data.await_expr.expr;
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
if (target_inst == irb->codegen->invalid_inst_src)
return irb->codegen->invalid_inst_src;
- IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_noasync);
+ IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_nosuspend);
return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
}
@@ -9876,8 +9876,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode
add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
return irb->codegen->invalid_inst_src;
}
- if (get_scope_noasync(parent_scope) != nullptr) {
- add_node_error(irb->codegen, node, buf_sprintf("suspend in noasync scope"));
+ if (get_scope_nosuspend(parent_scope) != nullptr) {
+ add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope"));
return irb->codegen->invalid_inst_src;
}
@@ -10017,8 +10017,8 @@ static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope
return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
case NodeTypeCompTime:
return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
- case NodeTypeNoAsync:
- return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc);
+ case NodeTypeNoSuspend:
+ return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc);
case NodeTypeErrorType:
return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
case NodeTypeBreak:
@@ -10105,7 +10105,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco
case NodeTypeIfOptional:
case NodeTypeSwitchExpr:
case NodeTypeCompTime:
- case NodeTypeNoAsync:
+ case NodeTypeNoSuspend:
case NodeTypeErrorType:
case NodeTypeBreak:
case NodeTypeContinue:
@@ -20025,7 +20025,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (impl_fn_type_id->cc == CallingConventionAsync &&
parent_fn_entry->inferred_async_node == nullptr &&
- modifier != CallModifierNoAsync)
+ modifier != CallModifierNoSuspend)
{
parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
parent_fn_entry->inferred_async_fn = impl_fn;
@@ -20123,7 +20123,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (fn_type_id->cc == CallingConventionAsync &&
parent_fn_entry->inferred_async_node == nullptr &&
- modifier != CallModifierNoAsync)
+ modifier != CallModifierNoSuspend)
{
parent_fn_entry->inferred_async_node = fn_ref->base.source_node;
parent_fn_entry->inferred_async_fn = fn_entry;
@@ -20233,7 +20233,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
case CallModifierNone:
case CallModifierAlwaysInline:
case CallModifierAlwaysTail:
- case CallModifierNoAsync:
+ case CallModifierNoSuspend:
modifier = CallModifierCompileTime;
break;
case CallModifierNeverInline:
@@ -30277,7 +30277,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
ir_assert(fn_entry != nullptr, &instruction->base.base);
// If it's not @Frame(func) then it's definitely a suspend point
- if (target_fn == nullptr && !instruction->is_noasync) {
+ if (target_fn == nullptr && !instruction->is_nosuspend) {
if (fn_entry->inferred_async_node == nullptr) {
fn_entry->inferred_async_node = instruction->base.base.source_node;
}
@@ -30301,7 +30301,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
}
IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,
- instruction->is_noasync);
+ instruction->is_nosuspend);
result->target_fn = target_fn;
fn_entry->await_list.append(result);
return ir_finish_anal(ira, &result->base);
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 6176aaf0ba..3e50b7304f 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -861,8 +861,8 @@ static void ir_print_call_src(IrPrintSrc *irp, IrInstSrcCall *call_instruction)
switch (call_instruction->modifier) {
case CallModifierNone:
break;
- case CallModifierNoAsync:
- fprintf(irp->f, "noasync ");
+ case CallModifierNoSuspend:
+ fprintf(irp->f, "nosuspend ");
break;
case CallModifierAsync:
fprintf(irp->f, "async ");
@@ -906,8 +906,8 @@ static void ir_print_call_gen(IrPrintGen *irp, IrInstGenCall *call_instruction)
switch (call_instruction->modifier) {
case CallModifierNone:
break;
- case CallModifierNoAsync:
- fprintf(irp->f, "noasync ");
+ case CallModifierNoSuspend:
+ fprintf(irp->f, "nosuspend ");
break;
case CallModifierAsync:
fprintf(irp->f, "async ");
diff --git a/src/parser.cpp b/src/parser.cpp
index eed1a5abb4..71f7adf7d1 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -913,7 +913,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
// Statement
// <- KEYWORD_comptime? VarDecl
// / KEYWORD_comptime BlockExprStatement
-// / KEYWORD_noasync BlockExprStatement
+// / KEYWORD_nosuspend BlockExprStatement
// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
// / KEYWORD_defer BlockExprStatement
// / KEYWORD_errdefer Payload? BlockExprStatement
@@ -937,11 +937,11 @@ static AstNode *ast_parse_statement(ParseContext *pc) {
return res;
}
- Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
- if (noasync != nullptr) {
+ Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
+ if (nosuspend != nullptr) {
AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
- AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
- res->data.noasync_expr.expr = statement;
+ AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
+ res->data.nosuspend_expr.expr = statement;
return res;
}
@@ -1289,7 +1289,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
// / IfExpr
// / KEYWORD_break BreakLabel? Expr?
// / KEYWORD_comptime Expr
-// / KEYWORD_noasync Expr
+// / KEYWORD_nosuspend Expr
// / KEYWORD_continue BreakLabel?
// / KEYWORD_resume Expr
// / KEYWORD_return Expr?
@@ -1324,11 +1324,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
return res;
}
- Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
- if (noasync != nullptr) {
+ Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
+ if (nosuspend != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_expr);
- AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
- res->data.noasync_expr.expr = expr;
+ AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
+ res->data.nosuspend_expr.expr = expr;
return res;
}
@@ -1640,7 +1640,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// / IfTypeExpr
// / INTEGER
// / KEYWORD_comptime TypeExpr
-// / KEYWORD_noasync TypeExpr
+// / KEYWORD_nosuspend TypeExpr
// / KEYWORD_error DOT IDENTIFIER
// / KEYWORD_false
// / KEYWORD_null
@@ -1742,11 +1742,11 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
return res;
}
- Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync);
- if (noasync != nullptr) {
+ Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
+ if (nosuspend != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_type_expr);
- AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync);
- res->data.noasync_expr.expr = expr;
+ AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
+ res->data.nosuspend_expr.expr = expr;
return res;
}
@@ -3189,7 +3189,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeCompTime:
visit_field(&node->data.comptime_expr.expr, visit, context);
break;
- case NodeTypeNoAsync:
+ case NodeTypeNoSuspend:
visit_field(&node->data.comptime_expr.expr, visit, context);
break;
case NodeTypeBreak:
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index 11432ecac1..f09a146f2b 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -128,8 +128,8 @@ static const struct ZigKeyword zig_keywords[] = {
{"if", TokenIdKeywordIf},
{"inline", TokenIdKeywordInline},
{"noalias", TokenIdKeywordNoAlias},
- {"noasync", TokenIdKeywordNoAsync},
{"noinline", TokenIdKeywordNoInline},
+ {"nosuspend", TokenIdKeywordNoSuspend},
{"null", TokenIdKeywordNull},
{"or", TokenIdKeywordOr},
{"orelse", TokenIdKeywordOrElse},
@@ -1589,8 +1589,8 @@ const char * token_name(TokenId id) {
case TokenIdKeywordIf: return "if";
case TokenIdKeywordInline: return "inline";
case TokenIdKeywordNoAlias: return "noalias";
- case TokenIdKeywordNoAsync: return "noasync";
case TokenIdKeywordNoInline: return "noinline";
+ case TokenIdKeywordNoSuspend: return "nosuspend";
case TokenIdKeywordNull: return "null";
case TokenIdKeywordOr: return "or";
case TokenIdKeywordOrElse: return "orelse";
diff --git a/src/tokenizer.hpp b/src/tokenizer.hpp
index 3f025ca74a..552ded4ef8 100644
--- a/src/tokenizer.hpp
+++ b/src/tokenizer.hpp
@@ -78,7 +78,7 @@ enum TokenId {
TokenIdKeywordNoInline,
TokenIdKeywordLinkSection,
TokenIdKeywordNoAlias,
- TokenIdKeywordNoAsync,
+ TokenIdKeywordNoSuspend,
TokenIdKeywordNull,
TokenIdKeywordOr,
TokenIdKeywordOrElse,
From af00afed9844b9fb17478d33840fb4a312c4f07c Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Tue, 5 May 2020 05:14:22 -0600
Subject: [PATCH 13/74] zig fmt
---
lib/std/debug.zig | 30 +++++++--------
lib/std/dwarf.zig | 38 +++++++++----------
lib/std/event/batch.zig | 4 +-
lib/std/event/loop.zig | 8 ++--
lib/std/zig/system/macos.zig | 13 +++++--
test/stage1/behavior/async_fn.zig | 10 ++---
test/stage1/behavior/cast.zig | 2 +-
.../standalone/main_return_error/error_u8.zig | 4 +-
.../main_return_error/error_u8_non_zero.zig | 7 +++-
9 files changed, 61 insertions(+), 55 deletions(-)
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index df84a8bbcb..d999de6a17 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -62,7 +62,7 @@ pub fn warn(comptime fmt: []const u8, args: var) void {
const held = stderr_mutex.acquire();
defer held.release();
const stderr = getStderrStream();
- noasync stderr.print(fmt, args) catch return;
+ nosuspend stderr.print(fmt, args) catch return;
}
pub fn getStderrStream() *File.OutStream {
@@ -112,7 +112,7 @@ pub fn detectTTYConfig() TTY.Config {
/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
- noasync {
+ nosuspend {
const stderr = getStderrStream();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
@@ -133,7 +133,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
/// unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
- noasync {
+ nosuspend {
const stderr = getStderrStream();
if (builtin.strip_debug_info) {
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
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
- noasync {
+ nosuspend {
const stderr = getStderrStream();
if (builtin.strip_debug_info) {
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
resetSegfaultHandler();
}
- noasync switch (panic_stage) {
+ nosuspend switch (panic_stage) {
0 => {
panic_stage = 1;
@@ -447,7 +447,7 @@ pub const TTY = struct {
windows_api,
fn setColor(conf: Config, out_stream: var, color: Color) void {
- noasync switch (conf) {
+ nosuspend switch (conf) {
.no_color => return,
.escape_codes => switch (color) {
.Red => out_stream.writeAll(RED) catch return,
@@ -604,7 +604,7 @@ fn printLineInfo(
tty_config: TTY.Config,
comptime printLineFromFile: var,
) !void {
- noasync {
+ nosuspend {
tty_config.setColor(out_stream, .White);
if (line_info) |*li| {
@@ -651,7 +651,7 @@ pub const OpenSelfDebugInfoError = error{
/// TODO resources https://github.com/ziglang/zig/issues/4353
pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
- noasync {
+ nosuspend {
if (builtin.strip_debug_info)
return error.MissingDebugInfo;
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 {
/// TODO resources https://github.com/ziglang/zig/issues/4353
fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {
- noasync {
+ nosuspend {
const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
errdefer coff_file.close();
@@ -853,7 +853,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
/// TODO resources https://github.com/ziglang/zig/issues/4353
pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {
- noasync {
+ nosuspend {
const mapped_mem = try mapWholeFile(elf_file_path);
const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
@@ -1056,7 +1056,7 @@ const MachoSymbol = struct {
};
fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
- noasync {
+ nosuspend {
const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
defer file.close();
@@ -1418,7 +1418,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
}
fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
- noasync {
+ nosuspend {
// Translate the VA into an address into this object
const relocated_address = address - self.base_address;
assert(relocated_address >= 0x100000000);
@@ -1643,14 +1643,14 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
// Translate the VA into an address into this object
const relocated_address = address - self.base_address;
- if (noasync self.dwarf.findCompileUnit(relocated_address)) |compile_unit| {
+ if (nosuspend self.dwarf.findCompileUnit(relocated_address)) |compile_unit| {
return SymbolInfo{
- .symbol_name = noasync self.dwarf.getSymbolName(relocated_address) orelse "???",
+ .symbol_name = nosuspend self.dwarf.getSymbolName(relocated_address) orelse "???",
.compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => "???",
else => return err,
},
- .line_info = noasync self.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) {
+ .line_info = nosuspend self.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => null,
else => return err,
},
diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig
index 42139876bb..4191d45d6d 100644
--- a/lib/std/dwarf.zig
+++ b/lib/std/dwarf.zig
@@ -252,13 +252,13 @@ fn readUnitLength(in_stream: var, endian: builtin.Endian, is_64: *bool) !u64 {
fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
const buf = try allocator.alloc(u8, size);
errdefer allocator.free(buf);
- if ((try noasync in_stream.read(buf)) < size) return error.EndOfFile;
+ if ((try nosuspend in_stream.read(buf)) < size) return error.EndOfFile;
return buf;
}
// TODO the noasyncs here are workarounds
fn readAddress(in_stream: var, endian: builtin.Endian, is_64: bool) !u64 {
- return noasync if (is_64)
+ return nosuspend if (is_64)
try in_stream.readInt(u64, endian)
else
@as(u64, try in_stream.readInt(u32, endian));
@@ -271,7 +271,7 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
// TODO the noasyncs here are workarounds
fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: usize) !FormValue {
- const block_len = try noasync in_stream.readVarInt(usize, endian, size);
+ const block_len = try nosuspend in_stream.readVarInt(usize, endian, size);
return parseFormValueBlockLen(allocator, in_stream, block_len);
}
@@ -282,16 +282,16 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
.Const = Constant{
.signed = signed,
.payload = switch (size) {
- 1 => try noasync in_stream.readInt(u8, endian),
- 2 => try noasync in_stream.readInt(u16, endian),
- 4 => try noasync in_stream.readInt(u32, endian),
- 8 => try noasync in_stream.readInt(u64, endian),
+ 1 => try nosuspend in_stream.readInt(u8, endian),
+ 2 => try nosuspend in_stream.readInt(u16, endian),
+ 4 => try nosuspend in_stream.readInt(u32, endian),
+ 8 => try nosuspend in_stream.readInt(u64, endian),
-1 => blk: {
if (signed) {
- const x = try noasync leb.readILEB128(i64, in_stream);
+ const x = try nosuspend leb.readILEB128(i64, in_stream);
break :blk @bitCast(u64, x);
} else {
- const x = try noasync leb.readULEB128(u64, in_stream);
+ const x = try nosuspend leb.readULEB128(u64, in_stream);
break :blk x;
}
},
@@ -305,11 +305,11 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {
return FormValue{
.Ref = switch (size) {
- 1 => try noasync in_stream.readInt(u8, endian),
- 2 => try noasync in_stream.readInt(u16, endian),
- 4 => try noasync in_stream.readInt(u32, endian),
- 8 => try noasync in_stream.readInt(u64, endian),
- -1 => try noasync leb.readULEB128(u64, in_stream),
+ 1 => try nosuspend in_stream.readInt(u8, endian),
+ 2 => try nosuspend in_stream.readInt(u16, endian),
+ 4 => try nosuspend in_stream.readInt(u32, endian),
+ 8 => try nosuspend in_stream.readInt(u64, endian),
+ -1 => try nosuspend leb.readULEB128(u64, in_stream),
else => unreachable,
},
};
@@ -323,7 +323,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
FORM_block => x: {
- const block_len = try noasync leb.readULEB128(usize, in_stream);
+ const block_len = try nosuspend leb.readULEB128(usize, in_stream);
return parseFormValueBlockLen(allocator, in_stream, block_len);
},
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
return parseFormValueConstant(allocator, in_stream, signed, endian, -1);
},
FORM_exprloc => {
- const size = try noasync leb.readULEB128(usize, in_stream);
+ const size = try nosuspend leb.readULEB128(usize, in_stream);
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue{ .ExprLoc = buf };
},
- FORM_flag => FormValue{ .Flag = (try noasync in_stream.readByte()) != 0 },
+ FORM_flag => FormValue{ .Flag = (try nosuspend in_stream.readByte()) != 0 },
FORM_flag_present => FormValue{ .Flag = true },
FORM_sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) },
@@ -350,12 +350,12 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
FORM_ref_udata => parseFormValueRef(allocator, in_stream, endian, -1),
FORM_ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) },
- FORM_ref_sig8 => FormValue{ .Ref = try noasync in_stream.readInt(u64, endian) },
+ FORM_ref_sig8 => FormValue{ .Ref = try nosuspend in_stream.readInt(u64, endian) },
FORM_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
FORM_indirect => {
- const child_form_id = try noasync leb.readULEB128(u64, in_stream);
+ const child_form_id = try nosuspend leb.readULEB128(u64, in_stream);
const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
var frame = try allocator.create(F);
defer allocator.destroy(frame);
diff --git a/lib/std/event/batch.zig b/lib/std/event/batch.zig
index af59b32490..26c0d5fab0 100644
--- a/lib/std/event/batch.zig
+++ b/lib/std/event/batch.zig
@@ -75,7 +75,7 @@ pub fn Batch(
const job = &self.jobs[self.next_job_index];
self.next_job_index = (self.next_job_index + 1) % max_jobs;
if (job.frame) |existing| {
- job.result = if (async_ok) await existing else noasync await existing;
+ job.result = if (async_ok) await existing else nosuspend await existing;
if (CollectedResult != void) {
job.result catch |err| {
self.collected_result = err;
@@ -94,7 +94,7 @@ pub fn Batch(
/// a time, however, it need not be the same thread.
pub fn wait(self: *Self) CollectedResult {
for (self.jobs) |*job| if (job.frame) |f| {
- job.result = if (async_ok) await f else noasync await f;
+ job.result = if (async_ok) await f else nosuspend await f;
if (CollectedResult != void) {
job.result catch |err| {
self.collected_result = err;
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 6fa65f90dd..15e7a3481c 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -195,7 +195,7 @@ pub const Loop = struct {
const wakeup_bytes = [_]u8{0x1} ** 8;
fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {
- noasync switch (builtin.os.tag) {
+ nosuspend switch (builtin.os.tag) {
.linux => {
errdefer {
while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
@@ -371,7 +371,7 @@ pub const Loop = struct {
}
fn deinitOsData(self: *Loop) void {
- noasync switch (builtin.os.tag) {
+ nosuspend switch (builtin.os.tag) {
.linux => {
os.close(self.os_data.final_eventfd);
while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd);
@@ -663,7 +663,7 @@ pub const Loop = struct {
}
pub fn finishOneEvent(self: *Loop) void {
- noasync {
+ nosuspend {
const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst);
if (prev != 1) return;
@@ -1041,7 +1041,7 @@ pub const Loop = struct {
}
fn posixFsRun(self: *Loop) void {
- noasync while (true) {
+ nosuspend while (true) {
self.fs_thread_wakeup.reset();
while (self.fs_queue.get()) |node| {
switch (node.data.msg) {
diff --git a/lib/std/zig/system/macos.zig b/lib/std/zig/system/macos.zig
index 3261fdbf4c..dd34fe26f9 100644
--- a/lib/std/zig/system/macos.zig
+++ b/lib/std/zig/system/macos.zig
@@ -39,7 +39,7 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
zend += 1;
}
if (zend == yindex + 1) return error.InvalidVersion;
- const z = std.fmt.parseUnsigned(u16, build[yindex + 1..zend], 10) catch return error.InvalidVersion;
+ const z = std.fmt.parseUnsigned(u16, build[yindex + 1 .. zend], 10) catch return error.InvalidVersion;
result.patch = switch (result.minor) {
// TODO: compiler complains without explicit @as() coercion
@@ -97,7 +97,9 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
4 => @as(u32, switch (y) { // Tiger: 10.4
'A' => 0,
'B' => 1,
- 'C', 'E', => 2,
+ 'C',
+ 'E',
+ => 2,
'F' => 3,
'G' => @as(u32, block: {
if (z >= 1454) break :block 5;
@@ -105,7 +107,10 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
}),
'H' => 5,
'I' => 6,
- 'J', 'K', 'N', => 7,
+ 'J',
+ 'K',
+ 'N',
+ => 7,
'L' => 8,
'P' => 9,
'R' => 10,
@@ -438,7 +443,7 @@ test "version_from_build" {
for (known) |pair| {
var buf: [32]u8 = undefined;
const ver = try version_from_build(pair[0]);
- const sver = try std.fmt.bufPrint(buf[0..], "{}.{}.{}", .{ver.major, ver.minor, ver.patch});
+ const sver = try std.fmt.bufPrint(buf[0..], "{}.{}.{}", .{ ver.major, ver.minor, ver.patch });
std.testing.expect(std.mem.eql(u8, sver, pair[1]));
}
}
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 958e9ea55f..4b78060664 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -1093,7 +1093,7 @@ test "recursive call of await @asyncCall with struct return type" {
test "noasync function call" {
const S = struct {
fn doTheTest() void {
- const result = noasync add(50, 100);
+ const result = nosuspend add(50, 100);
expect(result == 150);
}
fn add(a: i32, b: i32) i32 {
@@ -1517,7 +1517,7 @@ test "noasync await" {
fn doTheTest() void {
var frame = async foo(false);
- expect(noasync await frame == 42);
+ expect(nosuspend await frame == 42);
finished = true;
}
@@ -1544,8 +1544,8 @@ test "noasync on function calls" {
return S0{};
}
};
- expectEqual(@as(i32, 42), noasync S1.c().b);
- expectEqual(@as(i32, 42), (try noasync S1.d()).b);
+ expectEqual(@as(i32, 42), nosuspend S1.c().b);
+ expectEqual(@as(i32, 42), (try nosuspend S1.d()).b);
}
test "avoid forcing frame alignment resolution implicit cast to *c_void" {
@@ -1561,5 +1561,5 @@ test "avoid forcing frame alignment resolution implicit cast to *c_void" {
};
var frame = async S.foo();
resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
- expect(noasync await frame);
+ expect(nosuspend await frame);
}
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index d277590c7a..63bf055aca 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -823,7 +823,7 @@ test "peer type resolve array pointer and unknown pointer" {
comptime expect(@TypeOf(&array, const_ptr) == [*]const u8);
comptime expect(@TypeOf(const_ptr, &array) == [*]const u8);
-
+
comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
}
diff --git a/test/standalone/main_return_error/error_u8.zig b/test/standalone/main_return_error/error_u8.zig
index 4edac26afd..8fbe1e8f65 100644
--- a/test/standalone/main_return_error/error_u8.zig
+++ b/test/standalone/main_return_error/error_u8.zig
@@ -1,6 +1,4 @@
-const Err = error {
- Foo
-};
+const Err = error{Foo};
pub fn main() !u8 {
return Err.Foo;
diff --git a/test/standalone/main_return_error/error_u8_non_zero.zig b/test/standalone/main_return_error/error_u8_non_zero.zig
index 703a19b314..9f7de780ac 100644
--- a/test/standalone/main_return_error/error_u8_non_zero.zig
+++ b/test/standalone/main_return_error/error_u8_non_zero.zig
@@ -1,6 +1,9 @@
-const Err = error { Foo };
+const Err = error{Foo};
-fn foo() u8 { var x = @intCast(u8, 9); return x; }
+fn foo() u8 {
+ var x = @intCast(u8, 9);
+ return x;
+}
pub fn main() !u8 {
if (foo() == 7) return Err.Foo;
From 2c9204032d1c839d8d577113a9c4def4b9ea9b94 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Tue, 5 May 2020 05:18:29 -0600
Subject: [PATCH 14/74] update tests for nosuspend
---
test/compile_errors.zig | 10 +++++-----
test/runtime_safety.zig | 4 ++--
test/stage1/behavior/async_fn.zig | 6 +++---
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index fd27b8e666..c902e1d968 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -243,9 +243,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:17:17: error: RHS of shift is too large for LHS type",
});
- cases.addTest("combination of noasync and async",
+ cases.addTest("combination of nosuspend and async",
\\export fn entry() void {
- \\ noasync {
+ \\ nosuspend {
\\ const bar = async foo();
\\ suspend;
\\ resume bar;
@@ -253,9 +253,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\}
\\fn foo() void {}
, &[_][]const u8{
- "tmp.zig:3:21: error: async call in noasync scope",
- "tmp.zig:4:9: error: suspend in noasync scope",
- "tmp.zig:5:9: error: resume in noasync scope",
+ "tmp.zig:3:21: error: async call in nosuspend scope",
+ "tmp.zig:4:9: error: suspend in nosuspend scope",
+ "tmp.zig:5:9: error: resume in nosuspend scope",
});
cases.add("atomicrmw with bool op not .Xchg",
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 19af470e2f..6837efe2d2 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -234,12 +234,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\}
);
- cases.addRuntimeSafety("noasync function call, callee suspends",
+ cases.addRuntimeSafety("nosuspend function call, callee suspends",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() void {
- \\ _ = noasync add(101, 100);
+ \\ _ = nosuspend add(101, 100);
\\}
\\fn add(a: i32, b: i32) i32 {
\\ if (a > 100) {
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 4b78060664..4f6ace9899 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -1090,7 +1090,7 @@ test "recursive call of await @asyncCall with struct return type" {
expect(res.z == 3);
}
-test "noasync function call" {
+test "nosuspend function call" {
const S = struct {
fn doTheTest() void {
const result = nosuspend add(50, 100);
@@ -1511,7 +1511,7 @@ test "take address of temporary async frame" {
S.doTheTest();
}
-test "noasync await" {
+test "nosuspend await" {
const S = struct {
var finished = false;
@@ -1532,7 +1532,7 @@ test "noasync await" {
expect(S.finished);
}
-test "noasync on function calls" {
+test "nosuspend on function calls" {
const S0 = struct {
b: i32 = 42,
};
From fdfdac493998a180eeffdcab66e579e7af250039 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Tue, 5 May 2020 05:19:17 -0600
Subject: [PATCH 15/74] update comments for nosuspend
---
lib/std/dwarf.zig | 12 ++++++------
lib/std/event/batch.zig | 2 +-
lib/std/fs/file.zig | 4 ++--
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig
index 4191d45d6d..fe40a04b9d 100644
--- a/lib/std/dwarf.zig
+++ b/lib/std/dwarf.zig
@@ -248,7 +248,7 @@ fn readUnitLength(in_stream: var, endian: builtin.Endian, is_64: *bool) !u64 {
}
}
-// TODO the noasyncs here are workarounds
+// TODO the nosuspends here are workarounds
fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
const buf = try allocator.alloc(u8, size);
errdefer allocator.free(buf);
@@ -256,7 +256,7 @@ fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8
return buf;
}
-// TODO the noasyncs here are workarounds
+// TODO the nosuspends here are workarounds
fn readAddress(in_stream: var, endian: builtin.Endian, is_64: bool) !u64 {
return nosuspend if (is_64)
try in_stream.readInt(u64, endian)
@@ -269,7 +269,7 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
return FormValue{ .Block = buf };
}
-// TODO the noasyncs here are workarounds
+// TODO the nosuspends here are workarounds
fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: usize) !FormValue {
const block_len = try nosuspend in_stream.readVarInt(usize, endian, size);
return parseFormValueBlockLen(allocator, in_stream, block_len);
@@ -277,7 +277,7 @@ fn parseFormValueBlock(allocator: *mem.Allocator, in_stream: var, endian: builti
fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, endian: builtin.Endian, comptime size: i32) !FormValue {
// TODO: Please forgive me, I've worked around zig not properly spilling some intermediate values here.
- // `noasync` should be removed from all the function calls once it is fixed.
+ // `nosuspend` should be removed from all the function calls once it is fixed.
return FormValue{
.Const = Constant{
.signed = signed,
@@ -301,7 +301,7 @@ fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: boo
};
}
-// TODO the noasyncs here are workarounds
+// TODO the nosuspends here are workarounds
fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {
return FormValue{
.Ref = switch (size) {
@@ -315,7 +315,7 @@ fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.
};
}
-// TODO the noasyncs here are workarounds
+// TODO the nosuspends here are workarounds
fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {
return switch (form_id) {
FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },
diff --git a/lib/std/event/batch.zig b/lib/std/event/batch.zig
index 26c0d5fab0..9c424fcd2c 100644
--- a/lib/std/event/batch.zig
+++ b/lib/std/event/batch.zig
@@ -21,7 +21,7 @@ pub fn Batch(
/// usual recommended option for this parameter.
auto_async,
- /// Always uses the `noasync` keyword when using `await` on the jobs,
+ /// Always uses the `nosuspend` keyword when using `await` on the jobs,
/// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
never_async,
diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig
index b7c575a04a..383a2be12d 100644
--- a/lib/std/fs/file.zig
+++ b/lib/std/fs/file.zig
@@ -66,7 +66,7 @@ pub const File = struct {
lock_nonblocking: bool = false,
/// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even
- /// if `std.io.is_async`. It allows the use of `noasync` when calling functions
+ /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
/// related to opening the file, reading, writing, and locking.
intended_io_mode: io.ModeOverride = io.default_mode,
};
@@ -112,7 +112,7 @@ pub const File = struct {
mode: Mode = default_mode,
/// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even
- /// if `std.io.is_async`. It allows the use of `noasync` when calling functions
+ /// if `std.io.is_async`. It allows the use of `nosuspend` when calling functions
/// related to opening the file, reading, writing, and locking.
intended_io_mode: io.ModeOverride = io.default_mode,
};
From 7ada59f873738931b4d162372dff0a33442112b6 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Mon, 4 May 2020 09:06:20 -0600
Subject: [PATCH 16/74] remove nakedcc/stdcallcc/async fn/extern fn fnproto
---
doc/docgen.zig | 2 --
doc/langref.html.in | 7 +---
lib/std/zig/ast.zig | 2 --
lib/std/zig/parse.zig | 53 ++----------------------------
lib/std/zig/parser_test.zig | 16 ---------
lib/std/zig/render.zig | 24 +-------------
lib/std/zig/tokenizer.zig | 6 ----
src-self-hosted/translate_c.zig | 3 --
src/all_types.hpp | 1 -
src/analyze.cpp | 2 --
src/parser.cpp | 58 +++------------------------------
11 files changed, 9 insertions(+), 165 deletions(-)
diff --git a/doc/docgen.zig b/doc/docgen.zig
index a249a526a1..92a7353fa1 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -800,7 +800,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_for,
.Keyword_if,
.Keyword_inline,
- .Keyword_nakedcc,
.Keyword_noalias,
.Keyword_noinline,
.Keyword_nosuspend,
@@ -813,7 +812,6 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_return,
.Keyword_linksection,
.Keyword_callconv,
- .Keyword_stdcallcc,
.Keyword_struct,
.Keyword_suspend,
.Keyword_switch,
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 6026912893..b2e1f6e6f6 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -10088,7 +10088,7 @@ TopLevelDecl
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
/ KEYWORD_usingnamespace Expr SEMICOLON
-FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
+FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
@@ -10255,11 +10255,6 @@ WhileContinueExpr <- COLON LPAREN AssignExpr RPAREN
LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
-# Fn specific
-FnCC
- <- KEYWORD_extern
- / KEYWORD_async
-
ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
ParamType
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 50051040d9..220b0390f1 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -875,7 +875,6 @@ pub const Node = struct {
return_type: ReturnType,
var_args_token: ?TokenIndex,
extern_export_inline_token: ?TokenIndex,
- cc_token: ?TokenIndex,
body_node: ?*Node,
lib_name: ?*Node, // populated if this is an extern declaration
align_expr: ?*Node, // populated if align(A) is present
@@ -929,7 +928,6 @@ pub const Node = struct {
if (self.visib_token) |visib_token| return visib_token;
if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
assert(self.lib_name == null);
- if (self.cc_token) |cc_token| return cc_token;
return self.fn_token;
}
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index d7f4d76cf6..ac1c1f8b15 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -335,22 +335,9 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return use_node;
}
-/// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
+/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
- const cc = parseFnCC(arena, it, tree);
- const fn_token = eatToken(it, .Keyword_fn) orelse {
- if (cc) |fnCC| {
- if (fnCC == .Extern) {
- putBackToken(it, fnCC.Extern); // 'extern' is also used in ContainerDecl
- } else {
- try tree.errors.push(.{
- .ExpectedToken = .{ .token = it.index, .expected_id = .Keyword_fn },
- });
- return error.ParseError;
- }
- }
- return null;
- };
+ const fn_token = eatToken(it, .Keyword_fn) orelse return null;
const name_token = eatToken(it, .Identifier);
const lparen = try expectToken(it, tree, .LParen);
const params = try parseParamDeclList(arena, it, tree);
@@ -389,7 +376,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.return_type = return_type,
.var_args_token = var_args_token,
.extern_export_inline_token = null,
- .cc_token = null,
.body_node = null,
.lib_name = null,
.align_expr = align_expr,
@@ -397,13 +383,6 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.callconv_expr = callconv_expr,
};
- if (cc) |kind| {
- switch (kind) {
- .CC => |token| fn_proto_node.cc_token = token,
- .Extern => |token| fn_proto_node.extern_export_inline_token = token,
- }
- }
-
return &fn_proto_node.base;
}
@@ -1196,16 +1175,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const maybe_async = eatToken(it, .Keyword_async);
if (maybe_async) |async_token| {
const token_fn = eatToken(it, .Keyword_fn);
- if (token_fn != null) {
- // HACK: If we see the keyword `fn`, then we assume that
- // we are parsing an async fn proto, and not a call.
- // We therefore put back all tokens consumed by the async
- // prefix...
- putBackToken(it, token_fn.?);
- putBackToken(it, async_token);
- return parsePrimaryTypeExpr(arena, it, tree);
- }
- // TODO: Implement hack for parsing `async fn ...` in ast_parse_suffix_expr
var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
.ExpectedPrimaryTypeExpr = .{ .token = it.index },
});
@@ -1778,24 +1747,6 @@ fn parseCallconv(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
return expr_node;
}
-/// FnCC
-/// <- KEYWORD_nakedcc
-/// / KEYWORD_stdcallcc
-/// / KEYWORD_extern
-/// / KEYWORD_async
-fn parseFnCC(arena: *Allocator, it: *TokenIterator, tree: *Tree) ?FnCC {
- if (eatToken(it, .Keyword_nakedcc)) |token| return FnCC{ .CC = token };
- if (eatToken(it, .Keyword_stdcallcc)) |token| return FnCC{ .CC = token };
- if (eatToken(it, .Keyword_extern)) |token| return FnCC{ .Extern = token };
- if (eatToken(it, .Keyword_async)) |token| return FnCC{ .CC = token };
- return null;
-}
-
-const FnCC = union(enum) {
- CC: TokenIndex,
- Extern: TokenIndex,
-};
-
/// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
fn parseParamDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const doc_comments = try parseDocComment(arena, it, tree);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index ebc6b92b78..198ce1ad94 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -123,22 +123,6 @@ test "zig fmt: trailing comma in fn parameter list" {
);
}
-// TODO: Remove nakedcc/stdcallcc once zig 0.6.0 is released. See https://github.com/ziglang/zig/pull/3977
-test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
- try testTransform(
- \\nakedcc fn foo1() void {}
- \\stdcallcc fn foo2() void {}
- \\extern fn foo3() void {}
- \\extern "mylib" fn foo4() void {}
- ,
- \\fn foo1() callconv(.Naked) void {}
- \\fn foo2() callconv(.Stdcall) void {}
- \\fn foo3() callconv(.C) void {}
- \\fn foo4() callconv(.C) void {}
- \\
- );
-}
-
test "zig fmt: comptime struct field" {
try testCanonical(
\\const Foo = struct {
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 441a91a28a..3e2cebcd8a 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -1413,32 +1413,14 @@ fn renderExpression(
try renderToken(tree, stream, visib_token_index, indent, start_col, Space.Space); // pub
}
- // Some extra machinery is needed to rewrite the old-style cc
- // notation to the new callconv one
- var cc_rewrite_str: ?[*:0]const u8 = null;
if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
- const tok = tree.tokens.at(extern_export_inline_token);
- if (tok.id != .Keyword_extern or fn_proto.body_node == null) {
- try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
- } else {
- cc_rewrite_str = ".C";
- fn_proto.lib_name = null;
- }
+ try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
}
if (fn_proto.lib_name) |lib_name| {
try renderExpression(allocator, stream, tree, indent, start_col, lib_name, Space.Space);
}
- if (fn_proto.cc_token) |cc_token| {
- var str = tree.tokenSlicePtr(tree.tokens.at(cc_token));
- if (mem.eql(u8, str, "stdcallcc")) {
- cc_rewrite_str = ".Stdcall";
- } else if (mem.eql(u8, str, "nakedcc")) {
- cc_rewrite_str = ".Naked";
- } else try renderToken(tree, stream, cc_token, indent, start_col, Space.Space); // stdcallcc
- }
-
const lparen = if (fn_proto.name_token) |name_token| blk: {
try renderToken(tree, stream, fn_proto.fn_token, indent, start_col, Space.Space); // fn
try renderToken(tree, stream, name_token, indent, start_col, Space.None); // name
@@ -1528,10 +1510,6 @@ fn renderExpression(
try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
- } else if (cc_rewrite_str) |str| {
- try stream.writeAll("callconv(");
- try stream.writeAll(mem.spanZ(str));
- try stream.writeAll(") ");
}
switch (fn_proto.return_type) {
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index b6c1a06276..089711871e 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -47,7 +47,6 @@ pub const Token = struct {
Keyword.init("for", .Keyword_for),
Keyword.init("if", .Keyword_if),
Keyword.init("inline", .Keyword_inline),
- Keyword.init("nakedcc", .Keyword_nakedcc),
Keyword.init("noalias", .Keyword_noalias),
Keyword.init("noasync", .Keyword_nosuspend), // TODO: remove this
Keyword.init("noinline", .Keyword_noinline),
@@ -60,7 +59,6 @@ pub const Token = struct {
Keyword.init("resume", .Keyword_resume),
Keyword.init("return", .Keyword_return),
Keyword.init("linksection", .Keyword_linksection),
- Keyword.init("stdcallcc", .Keyword_stdcallcc),
Keyword.init("struct", .Keyword_struct),
Keyword.init("suspend", .Keyword_suspend),
Keyword.init("switch", .Keyword_switch),
@@ -181,7 +179,6 @@ pub const Token = struct {
Keyword_for,
Keyword_if,
Keyword_inline,
- Keyword_nakedcc,
Keyword_noalias,
Keyword_noinline,
Keyword_nosuspend,
@@ -194,7 +191,6 @@ pub const Token = struct {
Keyword_resume,
Keyword_return,
Keyword_linksection,
- Keyword_stdcallcc,
Keyword_struct,
Keyword_suspend,
Keyword_switch,
@@ -306,7 +302,6 @@ pub const Token = struct {
.Keyword_for => "for",
.Keyword_if => "if",
.Keyword_inline => "inline",
- .Keyword_nakedcc => "nakedcc",
.Keyword_noalias => "noalias",
.Keyword_noinline => "noinline",
.Keyword_nosuspend => "nosuspend",
@@ -318,7 +313,6 @@ pub const Token = struct {
.Keyword_resume => "resume",
.Keyword_return => "return",
.Keyword_linksection => "linksection",
- .Keyword_stdcallcc => "stdcallcc",
.Keyword_struct => "struct",
.Keyword_suspend => "suspend",
.Keyword_switch => "switch",
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 1c689e9f76..6bbb133bb1 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -4094,7 +4094,6 @@ fn transCreateNodeMacroFn(c: *Context, name: []const u8, ref: *ast.Node, proto_a
.return_type = proto_alias.return_type,
.var_args_token = null,
.extern_export_inline_token = inline_tok,
- .cc_token = null,
.body_node = null,
.lib_name = null,
.align_expr = null,
@@ -4753,7 +4752,6 @@ fn finishTransFnProto(
.return_type = .{ .Explicit = return_type_node },
.var_args_token = null, // TODO this field is broken in the AST data model
.extern_export_inline_token = extern_export_inline_tok,
- .cc_token = null,
.body_node = null,
.lib_name = null,
.align_expr = align_expr,
@@ -5119,7 +5117,6 @@ fn transMacroFnDefine(c: *Context, it: *CTokenList.Iterator, source: []const u8,
.return_type = .{ .Explicit = &type_of.base },
.doc_comments = null,
.var_args_token = null,
- .cc_token = null,
.body_node = null,
.lib_name = null,
.align_expr = null,
diff --git a/src/all_types.hpp b/src/all_types.hpp
index aeffa440ab..61b6cbd74a 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -718,7 +718,6 @@ struct AstNodeFnProto {
Buf doc_comments;
FnInline fn_inline;
- bool is_async;
VisibMod visib_mod;
bool auto_err_set;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 4c3103c48c..39f797a9ec 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1528,8 +1528,6 @@ ZigType *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
}
CallingConvention cc_from_fn_proto(AstNodeFnProto *fn_proto) {
- if (fn_proto->is_async)
- return CallingConventionAsync;
// Compatible with the C ABI
if (fn_proto->is_extern || fn_proto->is_export)
return CallingConventionC;
diff --git a/src/parser.cpp b/src/parser.cpp
index 71f7adf7d1..1a929cd1b1 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -93,7 +93,6 @@ static AstNode *ast_parse_field_init(ParseContext *pc);
static AstNode *ast_parse_while_continue_expr(ParseContext *pc);
static AstNode *ast_parse_link_section(ParseContext *pc);
static AstNode *ast_parse_callconv(ParseContext *pc);
-static Optional ast_parse_fn_cc(ParseContext *pc);
static AstNode *ast_parse_param_decl(ParseContext *pc);
static AstNode *ast_parse_param_type(ParseContext *pc);
static AstNode *ast_parse_if_prefix(ParseContext *pc);
@@ -707,7 +706,6 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
fn_proto->column = first->start_column;
fn_proto->data.fn_proto.visib_mod = visib_mod;
fn_proto->data.fn_proto.doc_comments = *doc_comments;
- // ast_parse_fn_cc may set it
if (!fn_proto->data.fn_proto.is_extern)
fn_proto->data.fn_proto.is_extern = first->id == TokenIdKeywordExtern;
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
return nullptr;
}
-// FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
+// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
static AstNode *ast_parse_fn_proto(ParseContext *pc) {
- Token *first = peek_token(pc);
- AstNodeFnProto fn_cc;
- Token *fn;
- if (ast_parse_fn_cc(pc).unwrap(&fn_cc)) {
- // The extern keyword for fn CC is also used for container decls.
- // We therefore put it back, as allow container decl to consume it
- // later.
- if (fn_cc.is_extern) {
- fn = eat_token_if(pc, TokenIdKeywordFn);
- if (fn == nullptr) {
- put_back_token(pc);
- return nullptr;
- }
- } else {
- fn = expect_token(pc, TokenIdKeywordFn);
- }
- } else {
- fn_cc = {};
- fn = eat_token_if(pc, TokenIdKeywordFn);
- if (fn == nullptr)
- return nullptr;
+ Token *first = eat_token_if(pc, TokenIdKeywordFn);
+ if (first == nullptr) {
+ return nullptr;
}
Token *identifier = eat_token_if(pc, TokenIdSymbol);
@@ -830,7 +810,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
}
AstNode *res = ast_create_node(pc, NodeTypeFnProto, first);
- res->data.fn_proto = fn_cc;
+ res->data.fn_proto = {};
res->data.fn_proto.name = token_buf(identifier);
res->data.fn_proto.params = params;
res->data.fn_proto.align_expr = align_expr;
@@ -1524,17 +1504,6 @@ static AstNode *ast_parse_error_union_expr(ParseContext *pc) {
static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
Token *async_token = eat_token_if(pc, TokenIdKeywordAsync);
if (async_token) {
- if (eat_token_if(pc, TokenIdKeywordFn) != nullptr) {
- // HACK: If we see the keyword `fn`, then we assume that
- // we are parsing an async fn proto, and not a call.
- // We therefore put back all tokens consumed by the async
- // prefix...
- put_back_token(pc);
- put_back_token(pc);
-
- return ast_parse_primary_type_expr(pc);
- }
-
AstNode *child = ast_expect(pc, ast_parse_primary_type_expr);
while (true) {
AstNode *suffix = ast_parse_suffix_op(pc);
@@ -2187,23 +2156,6 @@ static AstNode *ast_parse_callconv(ParseContext *pc) {
return res;
}
-// FnCC
-// <- KEYWORD_extern
-// / KEYWORD_async
-static Optional ast_parse_fn_cc(ParseContext *pc) {
- AstNodeFnProto res = {};
- if (eat_token_if(pc, TokenIdKeywordAsync) != nullptr) {
- res.is_async = true;
- return Optional::some(res);
- }
- if (eat_token_if(pc, TokenIdKeywordExtern) != nullptr) {
- res.is_extern = true;
- return Optional::some(res);
- }
-
- return Optional::none();
-}
-
// ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
static AstNode *ast_parse_param_decl(ParseContext *pc) {
Buf doc_comments = BUF_INIT;
From d0e996405bff4352c78c570b4944b369d642d058 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Mon, 4 May 2020 09:24:46 -0600
Subject: [PATCH 17/74] add zig fmt fix for async/extern fn
---
lib/std/zig/ast.zig | 2 ++
lib/std/zig/parse.zig | 32 +++++++++++++++++++++++++++-
lib/std/zig/parser_test.zig | 42 +++++++++++++++++++++----------------
lib/std/zig/render.zig | 7 ++++++-
4 files changed, 63 insertions(+), 20 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 220b0390f1..8dec2de15c 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -880,6 +880,8 @@ pub const Node = struct {
align_expr: ?*Node, // populated if align(A) is present
section_expr: ?*Node, // populated if linksection(A) is present
callconv_expr: ?*Node, // populated if callconv(A) is present
+ is_extern_prototype: bool = false, // TODO: Remove once extern fn rewriting is
+ is_async: bool = false, // TODO: remove once async fn rewriting is
pub const ParamList = SegmentedList(*Node, 2);
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index ac1c1f8b15..031fd9c160 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -337,7 +337,25 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
- const fn_token = eatToken(it, .Keyword_fn) orelse return null;
+ // TODO: Remove once extern/async fn rewriting is
+ var is_async = false;
+ var is_extern = false;
+ const cc_token: ?usize = blk: {
+ if (eatToken(it, .Keyword_extern)) |token| {
+ is_extern = true;
+ break :blk token;
+ }
+ if (eatToken(it, .Keyword_async)) |token| {
+ is_async = true;
+ break :blk token;
+ }
+ break :blk null;
+ };
+ const fn_token = eatToken(it, .Keyword_fn) orelse {
+ if (cc_token) |token|
+ putBackToken(it, token);
+ return null;
+ };
const name_token = eatToken(it, .Identifier);
const lparen = try expectToken(it, tree, .LParen);
const params = try parseParamDeclList(arena, it, tree);
@@ -381,6 +399,8 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.align_expr = align_expr,
.section_expr = section_expr,
.callconv_expr = callconv_expr,
+ .is_extern_prototype = is_extern,
+ .is_async = is_async,
};
return &fn_proto_node.base;
@@ -1175,6 +1195,16 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const maybe_async = eatToken(it, .Keyword_async);
if (maybe_async) |async_token| {
const token_fn = eatToken(it, .Keyword_fn);
+ if (token_fn != null) {
+ // TODO: remove this hack when async fn rewriting is
+ // HACK: If we see the keyword `fn`, then we assume that
+ // we are parsing an async fn proto, and not a call.
+ // We therefore put back all tokens consumed by the async
+ // prefix...
+ putBackToken(it, token_fn.?);
+ putBackToken(it, async_token);
+ return parsePrimaryTypeExpr(arena, it, tree);
+ }
var res = try expectNode(arena, it, tree, parsePrimaryTypeExpr, .{
.ExpectedPrimaryTypeExpr = .{ .token = it.index },
});
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 198ce1ad94..7ab3e86b1a 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -236,10 +236,10 @@ test "zig fmt: anon list literal syntax" {
test "zig fmt: async function" {
try testCanonical(
\\pub const Server = struct {
- \\ handleRequestFn: async fn (*Server, *const std.net.Address, File) void,
+ \\ handleRequestFn: fn (*Server, *const std.net.Address, File) callconv(.Async) void,
\\};
\\test "hi" {
- \\ var ptr = @ptrCast(async fn (i32) void, other);
+ \\ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
\\}
\\
);
@@ -435,15 +435,6 @@ test "zig fmt: aligned struct field" {
);
}
-test "zig fmt: preserve space between async fn definitions" {
- try testCanonical(
- \\async fn a() void {}
- \\
- \\async fn b() void {}
- \\
- );
-}
-
test "zig fmt: comment to disable/enable zig fmt first" {
try testCanonical(
\\// Test trailing comma syntax
@@ -1499,7 +1490,7 @@ test "zig fmt: line comments in struct initializer" {
test "zig fmt: first line comment in struct initializer" {
try testCanonical(
- \\pub async fn acquire(self: *Self) HeldLock {
+ \\pub fn acquire(self: *Self) HeldLock {
\\ return HeldLock{
\\ // guaranteed allocation elision
\\ .held = self.lock.acquire(),
@@ -2461,8 +2452,7 @@ test "zig fmt: fn type" {
\\}
\\
\\const a: fn (u8) u8 = undefined;
- \\const b: extern fn (u8) u8 = undefined;
- \\const c: fn (u8) callconv(.Naked) u8 = undefined;
+ \\const b: fn (u8) callconv(.Naked) u8 = undefined;
\\const ap: fn (u8) u8 = a;
\\
);
@@ -2484,7 +2474,7 @@ test "zig fmt: inline asm" {
test "zig fmt: async functions" {
try testCanonical(
- \\async fn simpleAsyncFn() void {
+ \\fn simpleAsyncFn() void {
\\ const a = async a.b();
\\ x += 1;
\\ suspend;
@@ -2920,6 +2910,25 @@ test "zig fmt: noasync to nosuspend" {
\\pub fn main() void {
\\ nosuspend call();
\\}
+ );
+}
+
+test "zig fmt: convert async fn into callconv(.Async)" {
+ try testTransform(
+ \\async fn foo() void {}
+ ,
+ \\fn foo() callconv(.Async) void {}
+ \\
+ );
+}
+
+test "zig fmt: convert extern fn proto into callconv(.C)" {
+ try testTransform(
+ \\extern fn foo0() void {}
+ \\const foo1 = extern fn () void;
+ ,
+ \\extern fn foo0() void {}
+ \\const foo1 = fn () callconv(.C) void;
\\
);
}
@@ -2970,7 +2979,6 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
anything_changed.* = try std.zig.render(allocator, buffer.outStream(), tree);
return buffer.toOwnedSlice();
}
-
fn testTransform(source: []const u8, expected_source: []const u8) !void {
const needed_alloc_count = x: {
// Try it once with unlimited memory, make sure it works
@@ -3018,11 +3026,9 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
}
}
}
-
fn testCanonical(source: []const u8) !void {
return testTransform(source, source);
}
-
fn testError(source: []const u8) !void {
const tree = try std.zig.parse(std.testing.allocator, source);
defer tree.deinit();
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 3e2cebcd8a..bcdc08d43a 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -1414,7 +1414,8 @@ fn renderExpression(
}
if (fn_proto.extern_export_inline_token) |extern_export_inline_token| {
- try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
+ if (!fn_proto.is_extern_prototype)
+ try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export/inline
}
if (fn_proto.lib_name) |lib_name| {
@@ -1510,6 +1511,10 @@ fn renderExpression(
try renderToken(tree, stream, callconv_lparen, indent, start_col, Space.None); // (
try renderExpression(allocator, stream, tree, indent, start_col, callconv_expr, Space.None);
try renderToken(tree, stream, callconv_rparen, indent, start_col, Space.Space); // )
+ } else if (fn_proto.is_extern_prototype) {
+ try stream.writeAll("callconv(.C) ");
+ } else if (fn_proto.is_async) {
+ try stream.writeAll("callconv(.Async) ");
}
switch (fn_proto.return_type) {
From 6745a6f6f6f2b8d4473f00bed03a6cf1af117890 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Mon, 4 May 2020 09:49:27 -0600
Subject: [PATCH 18/74] zig fmt
---
lib/std/c.zig | 2 +-
lib/std/c/dragonfly.zig | 2 +-
lib/std/c/freebsd.zig | 2 +-
lib/std/c/linux.zig | 2 +-
lib/std/c/netbsd.zig | 2 +-
lib/std/event/channel.zig | 11 ++--
lib/std/event/future.zig | 4 +-
lib/std/event/group.zig | 16 ++---
lib/std/event/lock.zig | 8 +--
lib/std/event/locked.zig | 2 +-
lib/std/event/loop.zig | 2 +-
lib/std/event/rwlock.zig | 13 ++--
lib/std/event/rwlocked.zig | 4 +-
lib/std/os/bits/darwin.zig | 2 +-
lib/std/os/bits/dragonfly.zig | 12 ++--
lib/std/os/bits/freebsd.zig | 10 +--
lib/std/os/bits/linux.zig | 10 +--
lib/std/os/linux.zig | 4 +-
lib/std/os/linux/arm-eabi.zig | 2 +-
lib/std/os/linux/arm64.zig | 2 +-
lib/std/os/linux/i386.zig | 2 +-
lib/std/os/linux/mips.zig | 2 +-
lib/std/os/linux/riscv64.zig | 2 +-
lib/std/os/linux/x86_64.zig | 2 +-
.../protocols/absolute_pointer_protocol.zig | 4 +-
.../uefi/protocols/edid_override_protocol.zig | 2 +-
lib/std/os/uefi/protocols/file_protocol.zig | 20 +++---
.../protocols/graphics_output_protocol.zig | 6 +-
.../uefi/protocols/hii_database_protocol.zig | 8 +--
.../os/uefi/protocols/hii_popup_protocol.zig | 2 +-
.../os/uefi/protocols/ip6_config_protocol.zig | 8 +--
lib/std/os/uefi/protocols/ip6_protocol.zig | 18 +++---
.../ip6_service_binding_protocol.zig | 4 +-
.../uefi/protocols/loaded_image_protocol.zig | 2 +-
.../protocols/managed_network_protocol.zig | 16 ++---
...naged_network_service_binding_protocol.zig | 4 +-
lib/std/os/uefi/protocols/rng_protocol.zig | 4 +-
.../protocols/simple_file_system_protocol.zig | 2 +-
.../protocols/simple_network_protocol.zig | 26 ++++----
.../protocols/simple_pointer_protocol.zig | 4 +-
.../simple_text_input_ex_protocol.zig | 12 ++--
.../protocols/simple_text_input_protocol.zig | 4 +-
.../protocols/simple_text_output_protocol.zig | 18 +++---
lib/std/os/uefi/protocols/udp6_protocol.zig | 14 ++--
.../udp6_service_binding_protocol.zig | 4 +-
lib/std/os/uefi/tables/boot_services.zig | 64 +++++++++----------
lib/std/os/uefi/tables/runtime_services.zig | 10 +--
lib/std/os/windows/bits.zig | 12 ++--
lib/std/os/windows/ws2_32.zig | 2 +-
lib/std/special/test_runner.zig | 2 +-
lib/std/start.zig | 3 +-
src-self-hosted/clang.zig | 2 +-
src-self-hosted/main.zig | 5 +-
test/stage1/behavior/async_fn.zig | 54 ++++++++--------
test/stage1/behavior/await_struct.zig | 4 +-
test/stage1/behavior/cast.zig | 2 +-
56 files changed, 222 insertions(+), 240 deletions(-)
diff --git a/lib/std/c.zig b/lib/std/c.zig
index 9f1114b9c1..0f166b7e59 100644
--- a/lib/std/c.zig
+++ b/lib/std/c.zig
@@ -217,7 +217,7 @@ pub extern "c" fn utimes(path: [*:0]const u8, times: *[2]timeval) c_int;
pub extern "c" fn utimensat(dirfd: fd_t, pathname: [*:0]const u8, times: *[2]timespec, flags: u32) c_int;
pub extern "c" fn futimens(fd: fd_t, times: *const [2]timespec) c_int;
-pub 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;
+pub 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;
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
pub extern "c" fn pthread_attr_setguardsize(attr: *pthread_attr_t, guardsize: usize) c_int;
diff --git a/lib/std/c/dragonfly.zig b/lib/std/c/dragonfly.zig
index a271b2e869..0c859018be 100644
--- a/lib/std/c/dragonfly.zig
+++ b/lib/std/c/dragonfly.zig
@@ -9,7 +9,7 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
-pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
+pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub const pthread_mutex_t = extern struct {
diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig
index 3a0634dbb7..ea52c05f0b 100644
--- a/lib/std/c/freebsd.zig
+++ b/lib/std/c/freebsd.zig
@@ -24,7 +24,7 @@ pub extern "c" fn sendfile(
flags: u32,
) c_int;
-pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
+pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub const pthread_mutex_t = extern struct {
diff --git a/lib/std/c/linux.zig b/lib/std/c/linux.zig
index 1da0db57d6..4ceeb5a773 100644
--- a/lib/std/c/linux.zig
+++ b/lib/std/c/linux.zig
@@ -75,7 +75,7 @@ pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32)
/// See std.elf for constants for this
pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
-pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
+pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig
index 20960b3f77..31adbb1f59 100644
--- a/lib/std/c/netbsd.zig
+++ b/lib/std/c/netbsd.zig
@@ -6,7 +6,7 @@ usingnamespace std.c;
extern "c" fn __errno() *c_int;
pub const _errno = __errno;
-pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
+pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
diff --git a/lib/std/event/channel.zig b/lib/std/event/channel.zig
index 83c77bcac5..5aef0bb3ba 100644
--- a/lib/std/event/channel.zig
+++ b/lib/std/event/channel.zig
@@ -105,7 +105,7 @@ pub fn Channel(comptime T: type) type {
/// await this function to get an item from the channel. If the buffer is empty, the frame will
/// complete when the next item is put in the channel.
- pub async fn get(self: *SelfChannel) T {
+ pub fn get(self: *SelfChannel) callconv(.Async) T {
// TODO https://github.com/ziglang/zig/issues/2765
var result: T = undefined;
var my_tick_node = Loop.NextTickNode.init(@frame());
@@ -305,8 +305,7 @@ test "std.event.Channel wraparound" {
channel.put(7);
testing.expectEqual(@as(i32, 7), channel.get());
}
-
-async fn testChannelGetter(channel: *Channel(i32)) void {
+fn testChannelGetter(channel: *Channel(i32)) callconv(.Async) void {
const value1 = channel.get();
testing.expect(value1 == 1234);
@@ -321,12 +320,10 @@ async fn testChannelGetter(channel: *Channel(i32)) void {
testing.expect(value4.? == 4444);
await last_put;
}
-
-async fn testChannelPutter(channel: *Channel(i32)) void {
+fn testChannelPutter(channel: *Channel(i32)) callconv(.Async) void {
channel.put(1234);
channel.put(4567);
}
-
-async fn testPut(channel: *Channel(i32), value: i32) void {
+fn testPut(channel: *Channel(i32), value: i32) callconv(.Async) void {
channel.put(value);
}
diff --git a/lib/std/event/future.zig b/lib/std/event/future.zig
index 51a63e90ee..5de22c574c 100644
--- a/lib/std/event/future.zig
+++ b/lib/std/event/future.zig
@@ -34,7 +34,7 @@ pub fn Future(comptime T: type) type {
/// Obtain the value. If it's not available, wait until it becomes
/// available.
/// Thread-safe.
- pub async fn get(self: *Self) *T {
+ pub fn get(self: *Self) callconv(.Async) *T {
if (@atomicLoad(Available, &self.available, .SeqCst) == .Finished) {
return &self.data;
}
@@ -59,7 +59,7 @@ pub fn Future(comptime T: type) type {
/// should start working on the data.
/// It's not required to call start() before resolve() but it can be useful since
/// this method is thread-safe.
- pub async fn start(self: *Self) ?*T {
+ pub fn start(self: *Self) callconv(.Async) ?*T {
const state = @cmpxchgStrong(Available, &self.available, .NotStarted, .Started, .SeqCst, .SeqCst) orelse return null;
switch (state) {
.Started => {
diff --git a/lib/std/event/group.zig b/lib/std/event/group.zig
index 5eebb7ffbc..155a9486b7 100644
--- a/lib/std/event/group.zig
+++ b/lib/std/event/group.zig
@@ -84,7 +84,7 @@ pub fn Group(comptime ReturnType: type) type {
/// Wait for all the calls and promises of the group to complete.
/// Thread-safe.
/// Safe to call any number of times.
- pub async fn wait(self: *Self) ReturnType {
+ pub fn wait(self: *Self) callconv(.Async) ReturnType {
const held = self.lock.acquire();
defer held.release();
@@ -127,8 +127,7 @@ test "std.event.Group" {
const handle = async testGroup(std.heap.page_allocator);
}
-
-async fn testGroup(allocator: *Allocator) void {
+fn testGroup(allocator: *Allocator) callconv(.Async) void {
var count: usize = 0;
var group = Group(void).init(allocator);
var sleep_a_little_frame = async sleepALittle(&count);
@@ -145,20 +144,17 @@ async fn testGroup(allocator: *Allocator) void {
another.add(&something_that_fails_frame) catch @panic("memory");
testing.expectError(error.ItBroke, another.wait());
}
-
-async fn sleepALittle(count: *usize) void {
+fn sleepALittle(count: *usize) callconv(.Async) void {
std.time.sleep(1 * std.time.millisecond);
_ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
}
-
-async fn increaseByTen(count: *usize) void {
+fn increaseByTen(count: *usize) callconv(.Async) void {
var i: usize = 0;
while (i < 10) : (i += 1) {
_ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
}
}
-
-async fn doSomethingThatFails() anyerror!void {}
-async fn somethingElse() anyerror!void {
+fn doSomethingThatFails() callconv(.Async) anyerror!void {}
+fn somethingElse() callconv(.Async) anyerror!void {
return error.ItBroke;
}
diff --git a/lib/std/event/lock.zig b/lib/std/event/lock.zig
index ff1f738c5e..179b881c9c 100644
--- a/lib/std/event/lock.zig
+++ b/lib/std/event/lock.zig
@@ -89,7 +89,7 @@ pub const Lock = struct {
while (self.queue.get()) |node| resume node.data;
}
- pub async fn acquire(self: *Lock) Held {
+ pub fn acquire(self: *Lock) callconv(.Async) Held {
var my_tick_node = Loop.NextTickNode.init(@frame());
errdefer _ = self.queue.remove(&my_tick_node); // TODO test canceling an acquire
@@ -134,8 +134,7 @@ test "std.event.Lock" {
const expected_result = [1]i32{3 * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
testing.expectEqualSlices(i32, &expected_result, &shared_test_data);
}
-
-async fn testLock(lock: *Lock) void {
+fn testLock(lock: *Lock) callconv(.Async) void {
var handle1 = async lockRunner(lock);
var tick_node1 = Loop.NextTickNode{
.prev = undefined,
@@ -167,8 +166,7 @@ async fn testLock(lock: *Lock) void {
var shared_test_data = [1]i32{0} ** 10;
var shared_test_index: usize = 0;
-
-async fn lockRunner(lock: *Lock) void {
+fn lockRunner(lock: *Lock) callconv(.Async) void {
suspend; // resumed by onNextTick
var i: usize = 0;
diff --git a/lib/std/event/locked.zig b/lib/std/event/locked.zig
index 5e9c0ea10e..e921803447 100644
--- a/lib/std/event/locked.zig
+++ b/lib/std/event/locked.zig
@@ -31,7 +31,7 @@ pub fn Locked(comptime T: type) type {
self.lock.deinit();
}
- pub async fn acquire(self: *Self) HeldLock {
+ pub fn acquire(self: *Self) callconv(.Async) HeldLock {
return HeldLock{
// TODO guaranteed allocation elision
.held = self.lock.acquire(),
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 15e7a3481c..e55d5116b9 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -503,7 +503,7 @@ pub const Loop = struct {
}
}
- pub async fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) void {
+ pub fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) callconv(.Async) void {
var resume_node = ResumeNode.Basic{
.base = ResumeNode{
.id = ResumeNode.Id.Basic,
diff --git a/lib/std/event/rwlock.zig b/lib/std/event/rwlock.zig
index 425088063f..7a47c27dd8 100644
--- a/lib/std/event/rwlock.zig
+++ b/lib/std/event/rwlock.zig
@@ -97,7 +97,7 @@ pub const RwLock = struct {
while (self.reader_queue.get()) |node| resume node.data;
}
- pub async fn acquireRead(self: *RwLock) HeldRead {
+ pub fn acquireRead(self: *RwLock) callconv(.Async) HeldRead {
_ = @atomicRmw(usize, &self.reader_lock_count, .Add, 1, .SeqCst);
suspend {
@@ -130,7 +130,7 @@ pub const RwLock = struct {
return HeldRead{ .lock = self };
}
- pub async fn acquireWrite(self: *RwLock) HeldWrite {
+ pub fn acquireWrite(self: *RwLock) callconv(.Async) HeldWrite {
suspend {
var my_tick_node = Loop.NextTickNode{
.data = @frame(),
@@ -225,8 +225,7 @@ test "std.event.RwLock" {
const expected_result = [1]i32{shared_it_count * @intCast(i32, shared_test_data.len)} ** shared_test_data.len;
testing.expectEqualSlices(i32, expected_result, shared_test_data);
}
-
-async fn testLock(allocator: *Allocator, lock: *RwLock) void {
+fn testLock(allocator: *Allocator, lock: *RwLock) callconv(.Async) void {
var read_nodes: [100]Loop.NextTickNode = undefined;
for (read_nodes) |*read_node| {
const frame = allocator.create(@Frame(readRunner)) catch @panic("memory");
@@ -259,8 +258,7 @@ const shared_it_count = 10;
var shared_test_data = [1]i32{0} ** 10;
var shared_test_index: usize = 0;
var shared_count: usize = 0;
-
-async fn writeRunner(lock: *RwLock) void {
+fn writeRunner(lock: *RwLock) callconv(.Async) void {
suspend; // resumed by onNextTick
var i: usize = 0;
@@ -277,8 +275,7 @@ async fn writeRunner(lock: *RwLock) void {
shared_test_index = 0;
}
}
-
-async fn readRunner(lock: *RwLock) void {
+fn readRunner(lock: *RwLock) callconv(.Async) void {
suspend; // resumed by onNextTick
std.time.sleep(1);
diff --git a/lib/std/event/rwlocked.zig b/lib/std/event/rwlocked.zig
index 3f4c6ddbf8..9a569e8f1f 100644
--- a/lib/std/event/rwlocked.zig
+++ b/lib/std/event/rwlocked.zig
@@ -40,14 +40,14 @@ pub fn RwLocked(comptime T: type) type {
self.lock.deinit();
}
- pub async fn acquireRead(self: *Self) HeldReadLock {
+ pub fn acquireRead(self: *Self) callconv(.Async) HeldReadLock {
return HeldReadLock{
.held = self.lock.acquireRead(),
.value = &self.locked_data,
};
}
- pub async fn acquireWrite(self: *Self) HeldWriteLock {
+ pub fn acquireWrite(self: *Self) callconv(.Async) HeldWriteLock {
return HeldWriteLock{
.held = self.lock.acquireWrite(),
.value = &self.locked_data,
diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig
index d116d6157a..8a596331a6 100644
--- a/lib/std/os/bits/darwin.zig
+++ b/lib/std/os/bits/darwin.zig
@@ -125,7 +125,7 @@ pub const empty_sigset = sigset_t(0);
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
pub const Sigaction = extern struct {
- handler: extern fn (c_int) void,
+ handler: fn (c_int) callconv(.C) void,
sa_mask: sigset_t,
sa_flags: c_int,
};
diff --git a/lib/std/os/bits/dragonfly.zig b/lib/std/os/bits/dragonfly.zig
index 6a6c871fc5..df22678323 100644
--- a/lib/std/os/bits/dragonfly.zig
+++ b/lib/std/os/bits/dragonfly.zig
@@ -458,9 +458,9 @@ pub const S_IFSOCK = 49152;
pub const S_IFWHT = 57344;
pub const S_IFMT = 61440;
-pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
-pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
-pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
+pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
+pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
+pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
pub const BADSIG = SIG_ERR;
pub const SIG_BLOCK = 1;
pub const SIG_UNBLOCK = 2;
@@ -519,13 +519,13 @@ pub const sigset_t = extern struct {
pub const sig_atomic_t = c_int;
pub const Sigaction = extern struct {
__sigaction_u: extern union {
- __sa_handler: ?extern fn (c_int) void,
- __sa_sigaction: ?extern fn (c_int, [*c]siginfo_t, ?*c_void) void,
+ __sa_handler: ?fn (c_int) callconv(.C) void,
+ __sa_sigaction: ?fn (c_int, [*c]siginfo_t, ?*c_void) callconv(.C) void,
},
sa_flags: c_int,
sa_mask: sigset_t,
};
-pub const sig_t = [*c]extern fn (c_int) void;
+pub const sig_t = [*c]fn (c_int) callconv(.C) void;
pub const sigvec = extern struct {
sv_handler: [*c]__sighandler_t,
diff --git a/lib/std/os/bits/freebsd.zig b/lib/std/os/bits/freebsd.zig
index 9999dca62f..eee7504366 100644
--- a/lib/std/os/bits/freebsd.zig
+++ b/lib/std/os/bits/freebsd.zig
@@ -725,16 +725,16 @@ pub const winsize = extern struct {
const NSIG = 32;
-pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
-pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
-pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
+pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize));
+pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0);
+pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1);
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
pub const Sigaction = extern struct {
/// signal handler
__sigaction_u: extern union {
- __sa_handler: extern fn (i32) void,
- __sa_sigaction: extern fn (i32, *__siginfo, usize) void,
+ __sa_handler: fn (i32) callconv(.C) void,
+ __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void,
},
/// see signal options
diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig
index 750b487754..438be2299b 100644
--- a/lib/std/os/bits/linux.zig
+++ b/lib/std/os/bits/linux.zig
@@ -813,15 +813,15 @@ pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffff
pub const k_sigaction = if (is_mips)
extern struct {
flags: usize,
- sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
+ sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
mask: [4]u32,
- restorer: extern fn () void,
+ restorer: fn () callconv(.C) void,
}
else
extern struct {
- sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
+ sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void,
flags: usize,
- restorer: extern fn () void,
+ restorer: fn () callconv(.C) void,
mask: [2]u32,
};
@@ -831,7 +831,7 @@ pub const Sigaction = extern struct {
sigaction: ?sigaction_fn,
mask: sigset_t,
flags: u32,
- restorer: ?extern fn () void = null,
+ restorer: ?fn () callconv(.C) void = null,
};
pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 15f9bf9b62..6653293e59 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -599,7 +599,7 @@ pub fn flock(fd: fd_t, operation: i32) usize {
var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime);
// We must follow the C calling convention when we call into the VDSO
-const vdso_clock_gettime_ty = extern fn (i32, *timespec) usize;
+const vdso_clock_gettime_ty = fn (i32, *timespec) callconv(.C) usize;
pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
if (@hasDecl(@This(), "VDSO_CGT_SYM")) {
@@ -791,7 +791,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
.sigaction = act.sigaction,
.flags = act.flags | SA_RESTORER,
.mask = undefined,
- .restorer = @ptrCast(extern fn () void, restorer_fn),
+ .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
};
var ksa_old: k_sigaction = undefined;
const ksa_mask_size = @sizeOf(@TypeOf(ksa_old.mask));
diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig
index c052aeab4e..352afeeb04 100644
--- a/lib/std/os/linux/arm-eabi.zig
+++ b/lib/std/os/linux/arm-eabi.zig
@@ -86,7 +86,7 @@ pub fn syscall6(
}
/// This matches the libc clone function.
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub fn restore() callconv(.Naked) void {
return asm volatile ("svc #0"
diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig
index 52ab3656e0..49548522ec 100644
--- a/lib/std/os/linux/arm64.zig
+++ b/lib/std/os/linux/arm64.zig
@@ -86,7 +86,7 @@ pub fn syscall6(
}
/// This matches the libc clone function.
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub const restore = restore_rt;
diff --git a/lib/std/os/linux/i386.zig b/lib/std/os/linux/i386.zig
index 0342f0754e..a4fdf8a346 100644
--- a/lib/std/os/linux/i386.zig
+++ b/lib/std/os/linux/i386.zig
@@ -106,7 +106,7 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
}
/// This matches the libc clone function.
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub fn restore() callconv(.Naked) void {
return asm volatile ("int $0x80"
diff --git a/lib/std/os/linux/mips.zig b/lib/std/os/linux/mips.zig
index 87c55db9f6..5b5c1e1f34 100644
--- a/lib/std/os/linux/mips.zig
+++ b/lib/std/os/linux/mips.zig
@@ -142,7 +142,7 @@ pub fn syscall6(
}
/// This matches the libc clone function.
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub fn restore() callconv(.Naked) void {
return asm volatile ("syscall"
diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig
index 3832bfbcca..39cc13f5b6 100644
--- a/lib/std/os/linux/riscv64.zig
+++ b/lib/std/os/linux/riscv64.zig
@@ -85,7 +85,7 @@ pub fn syscall6(
);
}
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub const restore = restore_rt;
diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig
index b60dcd80e9..33d2b66670 100644
--- a/lib/std/os/linux/x86_64.zig
+++ b/lib/std/os/linux/x86_64.zig
@@ -86,7 +86,7 @@ pub fn syscall6(
}
/// This matches the libc clone function.
-pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
pub const restore = restore_rt;
diff --git a/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig b/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig
index 1a46b9cf2c..a06a19c1a4 100644
--- a/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig
+++ b/lib/std/os/uefi/protocols/absolute_pointer_protocol.zig
@@ -5,8 +5,8 @@ const Status = uefi.Status;
/// Protocol for touchscreens
pub const AbsolutePointerProtocol = extern struct {
- _reset: extern fn (*const AbsolutePointerProtocol, bool) Status,
- _get_state: extern fn (*const AbsolutePointerProtocol, *AbsolutePointerState) Status,
+ _reset: fn (*const AbsolutePointerProtocol, bool) callconv(.C) Status,
+ _get_state: fn (*const AbsolutePointerProtocol, *AbsolutePointerState) callconv(.C) Status,
wait_for_input: Event,
mode: *AbsolutePointerMode,
diff --git a/lib/std/os/uefi/protocols/edid_override_protocol.zig b/lib/std/os/uefi/protocols/edid_override_protocol.zig
index 2c37baa7a4..efe73982e9 100644
--- a/lib/std/os/uefi/protocols/edid_override_protocol.zig
+++ b/lib/std/os/uefi/protocols/edid_override_protocol.zig
@@ -5,7 +5,7 @@ const Status = uefi.Status;
/// Override EDID information
pub const EdidOverrideProtocol = extern struct {
- _get_edid: extern fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) Status,
+ _get_edid: fn (*const EdidOverrideProtocol, Handle, *u32, *usize, *?[*]u8) callconv(.C) Status,
/// Returns policy information and potentially a replacement EDID for the specified video output device.
/// attributes must be align(4)
diff --git a/lib/std/os/uefi/protocols/file_protocol.zig b/lib/std/os/uefi/protocols/file_protocol.zig
index 4331d9a38c..eacd777008 100644
--- a/lib/std/os/uefi/protocols/file_protocol.zig
+++ b/lib/std/os/uefi/protocols/file_protocol.zig
@@ -5,16 +5,16 @@ const Status = uefi.Status;
pub const FileProtocol = extern struct {
revision: u64,
- _open: extern fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) Status,
- _close: extern fn (*const FileProtocol) Status,
- _delete: extern fn (*const FileProtocol) Status,
- _read: extern fn (*const FileProtocol, *usize, [*]u8) Status,
- _write: extern fn (*const FileProtocol, *usize, [*]const u8) Status,
- _get_position: extern fn (*const FileProtocol, *u64) Status,
- _set_position: extern fn (*const FileProtocol, *const u64) Status,
- _get_info: extern fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) Status,
- _set_info: extern fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) Status,
- _flush: extern fn (*const FileProtocol) Status,
+ _open: fn (*const FileProtocol, **const FileProtocol, [*:0]const u16, u64, u64) callconv(.C) Status,
+ _close: fn (*const FileProtocol) callconv(.C) Status,
+ _delete: fn (*const FileProtocol) callconv(.C) Status,
+ _read: fn (*const FileProtocol, *usize, [*]u8) callconv(.C) Status,
+ _write: fn (*const FileProtocol, *usize, [*]const u8) callconv(.C) Status,
+ _get_position: fn (*const FileProtocol, *u64) callconv(.C) Status,
+ _set_position: fn (*const FileProtocol, *const u64) callconv(.C) Status,
+ _get_info: fn (*const FileProtocol, *align(8) const Guid, *const usize, [*]u8) callconv(.C) Status,
+ _set_info: fn (*const FileProtocol, *align(8) const Guid, usize, [*]const u8) callconv(.C) Status,
+ _flush: fn (*const FileProtocol) callconv(.C) Status,
pub fn open(self: *const FileProtocol, new_handle: **const FileProtocol, file_name: [*:0]const u16, open_mode: u64, attributes: u64) Status {
return self._open(self, new_handle, file_name, open_mode, attributes);
diff --git a/lib/std/os/uefi/protocols/graphics_output_protocol.zig b/lib/std/os/uefi/protocols/graphics_output_protocol.zig
index 7370f537bf..1ceccce0bf 100644
--- a/lib/std/os/uefi/protocols/graphics_output_protocol.zig
+++ b/lib/std/os/uefi/protocols/graphics_output_protocol.zig
@@ -4,9 +4,9 @@ const Status = uefi.Status;
/// Graphics output
pub const GraphicsOutputProtocol = extern struct {
- _query_mode: extern fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) Status,
- _set_mode: extern fn (*const GraphicsOutputProtocol, u32) Status,
- _blt: extern fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) Status,
+ _query_mode: fn (*const GraphicsOutputProtocol, u32, *usize, **GraphicsOutputModeInformation) callconv(.C) Status,
+ _set_mode: fn (*const GraphicsOutputProtocol, u32) callconv(.C) Status,
+ _blt: fn (*const GraphicsOutputProtocol, ?[*]GraphicsOutputBltPixel, GraphicsOutputBltOperation, usize, usize, usize, usize, usize, usize, usize) callconv(.C) Status,
mode: *GraphicsOutputProtocolMode,
/// Returns information for an available graphics mode that the graphics device and the set of active video output devices supports.
diff --git a/lib/std/os/uefi/protocols/hii_database_protocol.zig b/lib/std/os/uefi/protocols/hii_database_protocol.zig
index c79f693f6f..e34f72c2f3 100644
--- a/lib/std/os/uefi/protocols/hii_database_protocol.zig
+++ b/lib/std/os/uefi/protocols/hii_database_protocol.zig
@@ -6,10 +6,10 @@ const hii = uefi.protocols.hii;
/// Database manager for HII-related data structures.
pub const HIIDatabaseProtocol = extern struct {
_new_package_list: Status, // TODO
- _remove_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle) Status,
- _update_package_list: extern fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) Status,
- _list_package_lists: extern fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) Status,
- _export_package_lists: extern fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) Status,
+ _remove_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle) callconv(.C) Status,
+ _update_package_list: fn (*const HIIDatabaseProtocol, hii.HIIHandle, *const hii.HIIPackageList) callconv(.C) Status,
+ _list_package_lists: fn (*const HIIDatabaseProtocol, u8, ?*const Guid, *usize, [*]hii.HIIHandle) callconv(.C) Status,
+ _export_package_lists: fn (*const HIIDatabaseProtocol, ?hii.HIIHandle, *usize, *hii.HIIPackageList) callconv(.C) Status,
_register_package_notify: Status, // TODO
_unregister_package_notify: Status, // TODO
_find_keyboard_layouts: Status, // TODO
diff --git a/lib/std/os/uefi/protocols/hii_popup_protocol.zig b/lib/std/os/uefi/protocols/hii_popup_protocol.zig
index 96afe21fbc..2e4f621b41 100644
--- a/lib/std/os/uefi/protocols/hii_popup_protocol.zig
+++ b/lib/std/os/uefi/protocols/hii_popup_protocol.zig
@@ -6,7 +6,7 @@ const hii = uefi.protocols.hii;
/// Display a popup window
pub const HIIPopupProtocol = extern struct {
revision: u64,
- _create_popup: extern fn (*const HIIPopupProtocol, HIIPopupStyle, HIIPopupType, hii.HIIHandle, u16, ?*HIIPopupSelection) Status,
+ _create_popup: fn (*const HIIPopupProtocol, HIIPopupStyle, HIIPopupType, hii.HIIHandle, u16, ?*HIIPopupSelection) callconv(.C) Status,
/// Displays a popup window.
pub fn createPopup(self: *const HIIPopupProtocol, style: HIIPopupStyle, popup_type: HIIPopupType, handle: hii.HIIHandle, msg: u16, user_selection: ?*HIIPopupSelection) Status {
diff --git a/lib/std/os/uefi/protocols/ip6_config_protocol.zig b/lib/std/os/uefi/protocols/ip6_config_protocol.zig
index 89ff39e8d1..99ba76aa17 100644
--- a/lib/std/os/uefi/protocols/ip6_config_protocol.zig
+++ b/lib/std/os/uefi/protocols/ip6_config_protocol.zig
@@ -4,10 +4,10 @@ const Event = uefi.Event;
const Status = uefi.Status;
pub const Ip6ConfigProtocol = extern struct {
- _set_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) Status,
- _get_data: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) Status,
- _register_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,
- _unregister_data_notify: extern fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) Status,
+ _set_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, usize, *const c_void) callconv(.C) Status,
+ _get_data: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, *usize, ?*const c_void) callconv(.C) Status,
+ _register_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
+ _unregister_data_notify: fn (*const Ip6ConfigProtocol, Ip6ConfigDataType, Event) callconv(.C) Status,
pub fn setData(self: *const Ip6ConfigProtocol, data_type: Ip6ConfigDataType, data_size: usize, data: *const c_void) Status {
return self._set_data(self, data_type, data_size, data);
diff --git a/lib/std/os/uefi/protocols/ip6_protocol.zig b/lib/std/os/uefi/protocols/ip6_protocol.zig
index f9a5c23d3c..b39ae60b2a 100644
--- a/lib/std/os/uefi/protocols/ip6_protocol.zig
+++ b/lib/std/os/uefi/protocols/ip6_protocol.zig
@@ -7,15 +7,15 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
pub const Ip6Protocol = extern struct {
- _get_mode_data: extern fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
- _configure: extern fn (*const Ip6Protocol, ?*const Ip6ConfigData) Status,
- _groups: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address) Status,
- _routes: extern fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) Status,
- _neighbors: extern fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) Status,
- _transmit: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,
- _receive: extern fn (*const Ip6Protocol, *Ip6CompletionToken) Status,
- _cancel: extern fn (*const Ip6Protocol, ?*Ip6CompletionToken) Status,
- _poll: extern fn (*const Ip6Protocol) Status,
+ _get_mode_data: fn (*const Ip6Protocol, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
+ _configure: fn (*const Ip6Protocol, ?*const Ip6ConfigData) callconv(.C) Status,
+ _groups: fn (*const Ip6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
+ _routes: fn (*const Ip6Protocol, bool, ?*const Ip6Address, u8, ?*const Ip6Address) callconv(.C) Status,
+ _neighbors: fn (*const Ip6Protocol, bool, *const Ip6Address, ?*const MacAddress, u32, bool) callconv(.C) Status,
+ _transmit: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
+ _receive: fn (*const Ip6Protocol, *Ip6CompletionToken) callconv(.C) Status,
+ _cancel: fn (*const Ip6Protocol, ?*Ip6CompletionToken) callconv(.C) Status,
+ _poll: fn (*const Ip6Protocol) callconv(.C) Status,
/// Gets the current operational settings for this instance of the EFI IPv6 Protocol driver.
pub fn getModeData(self: *const Ip6Protocol, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {
diff --git a/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
index 030ae5cae2..97ab1a431c 100644
--- a/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
+++ b/lib/std/os/uefi/protocols/ip6_service_binding_protocol.zig
@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
const Status = uefi.Status;
pub const Ip6ServiceBindingProtocol = extern struct {
- _create_child: extern fn (*const Ip6ServiceBindingProtocol, *?Handle) Status,
- _destroy_child: extern fn (*const Ip6ServiceBindingProtocol, Handle) Status,
+ _create_child: fn (*const Ip6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
+ _destroy_child: fn (*const Ip6ServiceBindingProtocol, Handle) callconv(.C) Status,
pub fn createChild(self: *const Ip6ServiceBindingProtocol, handle: *?Handle) Status {
return self._create_child(self, handle);
diff --git a/lib/std/os/uefi/protocols/loaded_image_protocol.zig b/lib/std/os/uefi/protocols/loaded_image_protocol.zig
index cff2bdccc0..b8afcb1063 100644
--- a/lib/std/os/uefi/protocols/loaded_image_protocol.zig
+++ b/lib/std/os/uefi/protocols/loaded_image_protocol.zig
@@ -19,7 +19,7 @@ pub const LoadedImageProtocol = extern struct {
image_size: u64,
image_code_type: MemoryType,
image_data_type: MemoryType,
- _unload: extern fn (*const LoadedImageProtocol, Handle) Status,
+ _unload: fn (*const LoadedImageProtocol, Handle) callconv(.C) Status,
/// Unloads an image from memory.
pub fn unload(self: *const LoadedImageProtocol, handle: Handle) Status {
diff --git a/lib/std/os/uefi/protocols/managed_network_protocol.zig b/lib/std/os/uefi/protocols/managed_network_protocol.zig
index 60dc6996ad..34ef6c40fa 100644
--- a/lib/std/os/uefi/protocols/managed_network_protocol.zig
+++ b/lib/std/os/uefi/protocols/managed_network_protocol.zig
@@ -7,14 +7,14 @@ const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
const MacAddress = uefi.protocols.MacAddress;
pub const ManagedNetworkProtocol = extern struct {
- _get_mode_data: extern fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
- _configure: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) Status,
- _mcast_ip_to_mac: extern fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) Status,
- _groups: extern fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) Status,
- _transmit: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,
- _receive: extern fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) Status,
- _cancel: extern fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) Status,
- _poll: extern fn (*const ManagedNetworkProtocol) usize,
+ _get_mode_data: fn (*const ManagedNetworkProtocol, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
+ _configure: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkConfigData) callconv(.C) Status,
+ _mcast_ip_to_mac: fn (*const ManagedNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
+ _groups: fn (*const ManagedNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
+ _transmit: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
+ _receive: fn (*const ManagedNetworkProtocol, *const ManagedNetworkCompletionToken) callconv(.C) Status,
+ _cancel: fn (*const ManagedNetworkProtocol, ?*const ManagedNetworkCompletionToken) callconv(.C) Status,
+ _poll: fn (*const ManagedNetworkProtocol) callconv(.C) usize,
/// Returns the operational parameters for the current MNP child driver.
/// May also support returning the underlying SNP driver mode data.
diff --git a/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
index ea8bd470c3..e9657e4456 100644
--- a/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
+++ b/lib/std/os/uefi/protocols/managed_network_service_binding_protocol.zig
@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
const Status = uefi.Status;
pub const ManagedNetworkServiceBindingProtocol = extern struct {
- _create_child: extern fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) Status,
- _destroy_child: extern fn (*const ManagedNetworkServiceBindingProtocol, Handle) Status,
+ _create_child: fn (*const ManagedNetworkServiceBindingProtocol, *?Handle) callconv(.C) Status,
+ _destroy_child: fn (*const ManagedNetworkServiceBindingProtocol, Handle) callconv(.C) Status,
pub fn createChild(self: *const ManagedNetworkServiceBindingProtocol, handle: *?Handle) Status {
return self._create_child(self, handle);
diff --git a/lib/std/os/uefi/protocols/rng_protocol.zig b/lib/std/os/uefi/protocols/rng_protocol.zig
index 4d5dd496af..a32b202f44 100644
--- a/lib/std/os/uefi/protocols/rng_protocol.zig
+++ b/lib/std/os/uefi/protocols/rng_protocol.zig
@@ -4,8 +4,8 @@ const Status = uefi.Status;
/// Random Number Generator protocol
pub const RNGProtocol = extern struct {
- _get_info: extern fn (*const RNGProtocol, *usize, [*]align(8) Guid) Status,
- _get_rng: extern fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) Status,
+ _get_info: fn (*const RNGProtocol, *usize, [*]align(8) Guid) callconv(.C) Status,
+ _get_rng: fn (*const RNGProtocol, ?*align(8) const Guid, usize, [*]u8) callconv(.C) Status,
/// Returns information about the random number generation implementation.
pub fn getInfo(self: *const RNGProtocol, list_size: *usize, list: [*]align(8) Guid) Status {
diff --git a/lib/std/os/uefi/protocols/simple_file_system_protocol.zig b/lib/std/os/uefi/protocols/simple_file_system_protocol.zig
index 31da02595a..119c1e6587 100644
--- a/lib/std/os/uefi/protocols/simple_file_system_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_file_system_protocol.zig
@@ -5,7 +5,7 @@ const Status = uefi.Status;
pub const SimpleFileSystemProtocol = extern struct {
revision: u64,
- _open_volume: extern fn (*const SimpleFileSystemProtocol, **const FileProtocol) Status,
+ _open_volume: fn (*const SimpleFileSystemProtocol, **const FileProtocol) callconv(.C) Status,
pub fn openVolume(self: *const SimpleFileSystemProtocol, root: **const FileProtocol) Status {
return self._open_volume(self, root);
diff --git a/lib/std/os/uefi/protocols/simple_network_protocol.zig b/lib/std/os/uefi/protocols/simple_network_protocol.zig
index a0d85b06d1..ac7446036e 100644
--- a/lib/std/os/uefi/protocols/simple_network_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_network_protocol.zig
@@ -5,19 +5,19 @@ const Status = uefi.Status;
pub const SimpleNetworkProtocol = extern struct {
revision: u64,
- _start: extern fn (*const SimpleNetworkProtocol) Status,
- _stop: extern fn (*const SimpleNetworkProtocol) Status,
- _initialize: extern fn (*const SimpleNetworkProtocol, usize, usize) Status,
- _reset: extern fn (*const SimpleNetworkProtocol, bool) Status,
- _shutdown: extern fn (*const SimpleNetworkProtocol) Status,
- _receive_filters: extern fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) Status,
- _station_address: extern fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) Status,
- _statistics: extern fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) Status,
- _mcast_ip_to_mac: extern fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) Status,
- _nvdata: extern fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) Status,
- _get_status: extern fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) Status,
- _transmit: extern fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) Status,
- _receive: extern fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) Status,
+ _start: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
+ _stop: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
+ _initialize: fn (*const SimpleNetworkProtocol, usize, usize) callconv(.C) Status,
+ _reset: fn (*const SimpleNetworkProtocol, bool) callconv(.C) Status,
+ _shutdown: fn (*const SimpleNetworkProtocol) callconv(.C) Status,
+ _receive_filters: fn (*const SimpleNetworkProtocol, SimpleNetworkReceiveFilter, SimpleNetworkReceiveFilter, bool, usize, ?[*]const MacAddress) callconv(.C) Status,
+ _station_address: fn (*const SimpleNetworkProtocol, bool, ?*const MacAddress) callconv(.C) Status,
+ _statistics: fn (*const SimpleNetworkProtocol, bool, ?*usize, ?*NetworkStatistics) callconv(.C) Status,
+ _mcast_ip_to_mac: fn (*const SimpleNetworkProtocol, bool, *const c_void, *MacAddress) callconv(.C) Status,
+ _nvdata: fn (*const SimpleNetworkProtocol, bool, usize, usize, [*]u8) callconv(.C) Status,
+ _get_status: fn (*const SimpleNetworkProtocol, *SimpleNetworkInterruptStatus, ?*?[*]u8) callconv(.C) Status,
+ _transmit: fn (*const SimpleNetworkProtocol, usize, usize, [*]const u8, ?*const MacAddress, ?*const MacAddress, ?*const u16) callconv(.C) Status,
+ _receive: fn (*const SimpleNetworkProtocol, ?*usize, *usize, [*]u8, ?*MacAddress, ?*MacAddress, ?*u16) callconv(.C) Status,
wait_for_packet: Event,
mode: *SimpleNetworkMode,
diff --git a/lib/std/os/uefi/protocols/simple_pointer_protocol.zig b/lib/std/os/uefi/protocols/simple_pointer_protocol.zig
index 2d1c7d4504..d217ab5930 100644
--- a/lib/std/os/uefi/protocols/simple_pointer_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_pointer_protocol.zig
@@ -5,8 +5,8 @@ const Status = uefi.Status;
/// Protocol for mice
pub const SimplePointerProtocol = struct {
- _reset: extern fn (*const SimplePointerProtocol, bool) Status,
- _get_state: extern fn (*const SimplePointerProtocol, *SimplePointerState) Status,
+ _reset: fn (*const SimplePointerProtocol, bool) callconv(.C) Status,
+ _get_state: fn (*const SimplePointerProtocol, *SimplePointerState) callconv(.C) Status,
wait_for_input: Event,
mode: *SimplePointerMode,
diff --git a/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig
index c361ffa9a1..4a2b098e61 100644
--- a/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_text_input_ex_protocol.zig
@@ -5,12 +5,12 @@ const Status = uefi.Status;
/// Character input devices, e.g. Keyboard
pub const SimpleTextInputExProtocol = extern struct {
- _reset: extern fn (*const SimpleTextInputExProtocol, bool) Status,
- _read_key_stroke_ex: extern fn (*const SimpleTextInputExProtocol, *KeyData) Status,
+ _reset: fn (*const SimpleTextInputExProtocol, bool) callconv(.C) Status,
+ _read_key_stroke_ex: fn (*const SimpleTextInputExProtocol, *KeyData) callconv(.C) Status,
wait_for_key_ex: Event,
- _set_state: extern fn (*const SimpleTextInputExProtocol, *const u8) Status,
- _register_key_notify: extern fn (*const SimpleTextInputExProtocol, *const KeyData, extern fn (*const KeyData) usize, **c_void) Status,
- _unregister_key_notify: extern fn (*const SimpleTextInputExProtocol, *const c_void) Status,
+ _set_state: fn (*const SimpleTextInputExProtocol, *const u8) callconv(.C) Status,
+ _register_key_notify: fn (*const SimpleTextInputExProtocol, *const KeyData, fn (*const KeyData) callconv(.C) usize, **c_void) callconv(.C) Status,
+ _unregister_key_notify: fn (*const SimpleTextInputExProtocol, *const c_void) callconv(.C) Status,
/// Resets the input device hardware.
pub fn reset(self: *const SimpleTextInputExProtocol, verify: bool) Status {
@@ -28,7 +28,7 @@ pub const SimpleTextInputExProtocol = extern struct {
}
/// Register a notification function for a particular keystroke for the input device.
- pub fn registerKeyNotify(self: *const SimpleTextInputExProtocol, key_data: *const KeyData, notify: extern fn (*const KeyData) usize, handle: **c_void) Status {
+ pub fn registerKeyNotify(self: *const SimpleTextInputExProtocol, key_data: *const KeyData, notify: fn (*const KeyData) callconv(.C) usize, handle: **c_void) Status {
return self._register_key_notify(self, key_data, notify, handle);
}
diff --git a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig
index fdae001145..58ed071331 100644
--- a/lib/std/os/uefi/protocols/simple_text_input_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_text_input_protocol.zig
@@ -6,8 +6,8 @@ const Status = uefi.Status;
/// Character input devices, e.g. Keyboard
pub const SimpleTextInputProtocol = extern struct {
- _reset: extern fn (*const SimpleTextInputProtocol, bool) usize,
- _read_key_stroke: extern fn (*const SimpleTextInputProtocol, *InputKey) Status,
+ _reset: fn (*const SimpleTextInputProtocol, bool) callconv(.C) usize,
+ _read_key_stroke: fn (*const SimpleTextInputProtocol, *InputKey) callconv(.C) Status,
wait_for_key: Event,
/// Resets the input device hardware.
diff --git a/lib/std/os/uefi/protocols/simple_text_output_protocol.zig b/lib/std/os/uefi/protocols/simple_text_output_protocol.zig
index 09f3cb1cd2..84f540cb78 100644
--- a/lib/std/os/uefi/protocols/simple_text_output_protocol.zig
+++ b/lib/std/os/uefi/protocols/simple_text_output_protocol.zig
@@ -4,15 +4,15 @@ const Status = uefi.Status;
/// Character output devices
pub const SimpleTextOutputProtocol = extern struct {
- _reset: extern fn (*const SimpleTextOutputProtocol, bool) Status,
- _output_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,
- _test_string: extern fn (*const SimpleTextOutputProtocol, [*:0]const u16) Status,
- _query_mode: extern fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) Status,
- _set_mode: extern fn (*const SimpleTextOutputProtocol, usize) Status,
- _set_attribute: extern fn (*const SimpleTextOutputProtocol, usize) Status,
- _clear_screen: extern fn (*const SimpleTextOutputProtocol) Status,
- _set_cursor_position: extern fn (*const SimpleTextOutputProtocol, usize, usize) Status,
- _enable_cursor: extern fn (*const SimpleTextOutputProtocol, bool) Status,
+ _reset: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
+ _output_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
+ _test_string: fn (*const SimpleTextOutputProtocol, [*:0]const u16) callconv(.C) Status,
+ _query_mode: fn (*const SimpleTextOutputProtocol, usize, *usize, *usize) callconv(.C) Status,
+ _set_mode: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
+ _set_attribute: fn (*const SimpleTextOutputProtocol, usize) callconv(.C) Status,
+ _clear_screen: fn (*const SimpleTextOutputProtocol) callconv(.C) Status,
+ _set_cursor_position: fn (*const SimpleTextOutputProtocol, usize, usize) callconv(.C) Status,
+ _enable_cursor: fn (*const SimpleTextOutputProtocol, bool) callconv(.C) Status,
mode: *SimpleTextOutputMode,
/// Resets the text output device hardware.
diff --git a/lib/std/os/uefi/protocols/udp6_protocol.zig b/lib/std/os/uefi/protocols/udp6_protocol.zig
index f0ab2789f3..46c76beaa6 100644
--- a/lib/std/os/uefi/protocols/udp6_protocol.zig
+++ b/lib/std/os/uefi/protocols/udp6_protocol.zig
@@ -9,13 +9,13 @@ const ManagedNetworkConfigData = uefi.protocols.ManagedNetworkConfigData;
const SimpleNetworkMode = uefi.protocols.SimpleNetworkMode;
pub const Udp6Protocol = extern struct {
- _get_mode_data: extern fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) Status,
- _configure: extern fn (*const Udp6Protocol, ?*const Udp6ConfigData) Status,
- _groups: extern fn (*const Udp6Protocol, bool, ?*const Ip6Address) Status,
- _transmit: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,
- _receive: extern fn (*const Udp6Protocol, *Udp6CompletionToken) Status,
- _cancel: extern fn (*const Udp6Protocol, ?*Udp6CompletionToken) Status,
- _poll: extern fn (*const Udp6Protocol) Status,
+ _get_mode_data: fn (*const Udp6Protocol, ?*Udp6ConfigData, ?*Ip6ModeData, ?*ManagedNetworkConfigData, ?*SimpleNetworkMode) callconv(.C) Status,
+ _configure: fn (*const Udp6Protocol, ?*const Udp6ConfigData) callconv(.C) Status,
+ _groups: fn (*const Udp6Protocol, bool, ?*const Ip6Address) callconv(.C) Status,
+ _transmit: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
+ _receive: fn (*const Udp6Protocol, *Udp6CompletionToken) callconv(.C) Status,
+ _cancel: fn (*const Udp6Protocol, ?*Udp6CompletionToken) callconv(.C) Status,
+ _poll: fn (*const Udp6Protocol) callconv(.C) Status,
pub fn getModeData(self: *const Udp6Protocol, udp6_config_data: ?*Udp6ConfigData, ip6_mode_data: ?*Ip6ModeData, mnp_config_data: ?*ManagedNetworkConfigData, snp_mode_data: ?*SimpleNetworkMode) Status {
return self._get_mode_data(self, udp6_config_data, ip6_mode_data, mnp_config_data, snp_mode_data);
diff --git a/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
index 9a7a67807c..811692adc3 100644
--- a/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
+++ b/lib/std/os/uefi/protocols/udp6_service_binding_protocol.zig
@@ -4,8 +4,8 @@ const Guid = uefi.Guid;
const Status = uefi.Status;
pub const Udp6ServiceBindingProtocol = extern struct {
- _create_child: extern fn (*const Udp6ServiceBindingProtocol, *?Handle) Status,
- _destroy_child: extern fn (*const Udp6ServiceBindingProtocol, Handle) Status,
+ _create_child: fn (*const Udp6ServiceBindingProtocol, *?Handle) callconv(.C) Status,
+ _destroy_child: fn (*const Udp6ServiceBindingProtocol, Handle) callconv(.C) Status,
pub fn createChild(self: *const Udp6ServiceBindingProtocol, handle: *?Handle) Status {
return self._create_child(self, handle);
diff --git a/lib/std/os/uefi/tables/boot_services.zig b/lib/std/os/uefi/tables/boot_services.zig
index 1969b46403..a1d2c1ca59 100644
--- a/lib/std/os/uefi/tables/boot_services.zig
+++ b/lib/std/os/uefi/tables/boot_services.zig
@@ -21,117 +21,117 @@ pub const BootServices = extern struct {
hdr: TableHeader,
/// Raises a task's priority level and returns its previous level.
- raiseTpl: extern fn (usize) usize,
+ raiseTpl: fn (usize) callconv(.C) usize,
/// Restores a task's priority level to its previous value.
- restoreTpl: extern fn (usize) void,
+ restoreTpl: fn (usize) callconv(.C) void,
/// Allocates memory pages from the system.
- allocatePages: extern fn (AllocateType, MemoryType, usize, *[*]align(4096) u8) Status,
+ allocatePages: fn (AllocateType, MemoryType, usize, *[*]align(4096) u8) callconv(.C) Status,
/// Frees memory pages.
- freePages: extern fn ([*]align(4096) u8, usize) Status,
+ freePages: fn ([*]align(4096) u8, usize) callconv(.C) Status,
/// Returns the current memory map.
- getMemoryMap: extern fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) Status,
+ getMemoryMap: fn (*usize, [*]MemoryDescriptor, *usize, *usize, *u32) callconv(.C) Status,
/// Allocates pool memory.
- allocatePool: extern fn (MemoryType, usize, *[*]align(8) u8) Status,
+ allocatePool: fn (MemoryType, usize, *[*]align(8) u8) callconv(.C) Status,
/// Returns pool memory to the system.
- freePool: extern fn ([*]align(8) u8) Status,
+ freePool: fn ([*]align(8) u8) callconv(.C) Status,
/// Creates an event.
- createEvent: extern fn (u32, usize, ?extern fn (Event, ?*c_void) void, ?*const c_void, *Event) Status,
+ createEvent: fn (u32, usize, ?fn (Event, ?*c_void) callconv(.C) void, ?*const c_void, *Event) callconv(.C) Status,
/// Sets the type of timer and the trigger time for a timer event.
- setTimer: extern fn (Event, TimerDelay, u64) Status,
+ setTimer: fn (Event, TimerDelay, u64) callconv(.C) Status,
/// Stops execution until an event is signaled.
- waitForEvent: extern fn (usize, [*]const Event, *usize) Status,
+ waitForEvent: fn (usize, [*]const Event, *usize) callconv(.C) Status,
/// Signals an event.
- signalEvent: extern fn (Event) Status,
+ signalEvent: fn (Event) callconv(.C) Status,
/// Closes an event.
- closeEvent: extern fn (Event) Status,
+ closeEvent: fn (Event) callconv(.C) Status,
/// Checks whether an event is in the signaled state.
- checkEvent: extern fn (Event) Status,
+ checkEvent: fn (Event) callconv(.C) Status,
installProtocolInterface: Status, // TODO
reinstallProtocolInterface: Status, // TODO
uninstallProtocolInterface: Status, // TODO
/// Queries a handle to determine if it supports a specified protocol.
- handleProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void) Status,
+ handleProtocol: fn (Handle, *align(8) const Guid, *?*c_void) callconv(.C) Status,
reserved: *c_void,
registerProtocolNotify: Status, // TODO
/// Returns an array of handles that support a specified protocol.
- locateHandle: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, [*]Handle) Status,
+ locateHandle: fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, [*]Handle) callconv(.C) Status,
locateDevicePath: Status, // TODO
installConfigurationTable: Status, // TODO
/// Loads an EFI image into memory.
- loadImage: extern fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) Status,
+ loadImage: fn (bool, Handle, ?*const DevicePathProtocol, ?[*]const u8, usize, *?Handle) callconv(.C) Status,
/// Transfers control to a loaded image's entry point.
- startImage: extern fn (Handle, ?*usize, ?*[*]u16) Status,
+ startImage: fn (Handle, ?*usize, ?*[*]u16) callconv(.C) Status,
/// Terminates a loaded EFI image and returns control to boot services.
- exit: extern fn (Handle, Status, usize, ?*const c_void) Status,
+ exit: fn (Handle, Status, usize, ?*const c_void) callconv(.C) Status,
/// Unloads an image.
- unloadImage: extern fn (Handle) Status,
+ unloadImage: fn (Handle) callconv(.C) Status,
/// Terminates all boot services.
- exitBootServices: extern fn (Handle, usize) Status,
+ exitBootServices: fn (Handle, usize) callconv(.C) Status,
/// Returns a monotonically increasing count for the platform.
- getNextMonotonicCount: extern fn (*u64) Status,
+ getNextMonotonicCount: fn (*u64) callconv(.C) Status,
/// Induces a fine-grained stall.
- stall: extern fn (usize) Status,
+ stall: fn (usize) callconv(.C) Status,
/// Sets the system's watchdog timer.
- setWatchdogTimer: extern fn (usize, u64, usize, ?[*]const u16) Status,
+ setWatchdogTimer: fn (usize, u64, usize, ?[*]const u16) callconv(.C) Status,
connectController: Status, // TODO
disconnectController: Status, // TODO
/// Queries a handle to determine if it supports a specified protocol.
- openProtocol: extern fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) Status,
+ openProtocol: fn (Handle, *align(8) const Guid, *?*c_void, ?Handle, ?Handle, OpenProtocolAttributes) callconv(.C) Status,
/// Closes a protocol on a handle that was opened using openProtocol().
- closeProtocol: extern fn (Handle, *align(8) const Guid, Handle, ?Handle) Status,
+ closeProtocol: fn (Handle, *align(8) const Guid, Handle, ?Handle) callconv(.C) Status,
/// Retrieves the list of agents that currently have a protocol interface opened.
- openProtocolInformation: extern fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) Status,
+ openProtocolInformation: fn (Handle, *align(8) const Guid, *[*]ProtocolInformationEntry, *usize) callconv(.C) Status,
/// Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated from pool.
- protocolsPerHandle: extern fn (Handle, *[*]*align(8) const Guid, *usize) Status,
+ protocolsPerHandle: fn (Handle, *[*]*align(8) const Guid, *usize) callconv(.C) Status,
/// Returns an array of handles that support the requested protocol in a buffer allocated from pool.
- locateHandleBuffer: extern fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) Status,
+ locateHandleBuffer: fn (LocateSearchType, ?*align(8) const Guid, ?*const c_void, *usize, *[*]Handle) callconv(.C) Status,
/// Returns the first protocol instance that matches the given protocol.
- locateProtocol: extern fn (*align(8) const Guid, ?*const c_void, *?*c_void) Status,
+ locateProtocol: fn (*align(8) const Guid, ?*const c_void, *?*c_void) callconv(.C) Status,
installMultipleProtocolInterfaces: Status, // TODO
uninstallMultipleProtocolInterfaces: Status, // TODO
/// Computes and returns a 32-bit CRC for a data buffer.
- calculateCrc32: extern fn ([*]const u8, usize, *u32) Status,
+ calculateCrc32: fn ([*]const u8, usize, *u32) callconv(.C) Status,
/// Copies the contents of one buffer to another buffer
- copyMem: extern fn ([*]u8, [*]const u8, usize) void,
+ copyMem: fn ([*]u8, [*]const u8, usize) callconv(.C) void,
/// Fills a buffer with a specified value
- setMem: extern fn ([*]u8, usize, u8) void,
+ setMem: fn ([*]u8, usize, u8) callconv(.C) void,
createEventEx: Status, // TODO
diff --git a/lib/std/os/uefi/tables/runtime_services.zig b/lib/std/os/uefi/tables/runtime_services.zig
index 1f0c7efad4..981e07275b 100644
--- a/lib/std/os/uefi/tables/runtime_services.zig
+++ b/lib/std/os/uefi/tables/runtime_services.zig
@@ -17,7 +17,7 @@ pub const RuntimeServices = extern struct {
hdr: TableHeader,
/// Returns the current time and date information, and the time-keeping capabilities of the hardware platform.
- getTime: extern fn (*uefi.Time, ?*TimeCapabilities) Status,
+ getTime: fn (*uefi.Time, ?*TimeCapabilities) callconv(.C) Status,
setTime: Status, // TODO
getWakeupTime: Status, // TODO
@@ -26,18 +26,18 @@ pub const RuntimeServices = extern struct {
convertPointer: Status, // TODO
/// Returns the value of a variable.
- getVariable: extern fn ([*:0]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) Status,
+ getVariable: fn ([*:0]const u16, *align(8) const Guid, ?*u32, *usize, ?*c_void) callconv(.C) Status,
/// Enumerates the current variable names.
- getNextVariableName: extern fn (*usize, [*:0]u16, *align(8) Guid) Status,
+ getNextVariableName: fn (*usize, [*:0]u16, *align(8) Guid) callconv(.C) Status,
/// Sets the value of a variable.
- setVariable: extern fn ([*:0]const u16, *align(8) const Guid, u32, usize, *c_void) Status,
+ setVariable: fn ([*:0]const u16, *align(8) const Guid, u32, usize, *c_void) callconv(.C) Status,
getNextHighMonotonicCount: Status, // TODO
/// Resets the entire platform.
- resetSystem: extern fn (ResetType, Status, usize, ?*const c_void) noreturn,
+ resetSystem: fn (ResetType, Status, usize, ?*const c_void) callconv(.C) noreturn,
updateCapsule: Status, // TODO
queryCapsuleCapabilities: Status, // TODO
diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig
index a1a60b1798..191e8deded 100644
--- a/lib/std/os/windows/bits.zig
+++ b/lib/std/os/windows/bits.zig
@@ -627,7 +627,7 @@ pub const MEM_RESERVE_PLACEHOLDERS = 0x2;
pub const MEM_DECOMMIT = 0x4000;
pub const MEM_RELEASE = 0x8000;
-pub const PTHREAD_START_ROUTINE = extern fn (LPVOID) DWORD;
+pub const PTHREAD_START_ROUTINE = fn (LPVOID) callconv(.C) DWORD;
pub const LPTHREAD_START_ROUTINE = PTHREAD_START_ROUTINE;
pub const WIN32_FIND_DATAW = extern struct {
@@ -784,7 +784,7 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {
pub const IMAGE_TLS_DIRECTORY64 = IMAGE_TLS_DIRECTORY;
pub const IMAGE_TLS_DIRECTORY32 = IMAGE_TLS_DIRECTORY;
-pub const PIMAGE_TLS_CALLBACK = ?extern fn (PVOID, DWORD, PVOID) void;
+pub const PIMAGE_TLS_CALLBACK = ?fn (PVOID, DWORD, PVOID) callconv(.C) void;
pub const PROV_RSA_FULL = 1;
@@ -810,7 +810,7 @@ pub const FILE_ACTION_MODIFIED = 0x00000003;
pub const FILE_ACTION_RENAMED_OLD_NAME = 0x00000004;
pub const FILE_ACTION_RENAMED_NEW_NAME = 0x00000005;
-pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?extern fn (DWORD, DWORD, *OVERLAPPED) void;
+pub const LPOVERLAPPED_COMPLETION_ROUTINE = ?fn (DWORD, DWORD, *OVERLAPPED) callconv(.C) void;
pub const FILE_NOTIFY_CHANGE_CREATION = 64;
pub const FILE_NOTIFY_CHANGE_SIZE = 8;
@@ -863,7 +863,7 @@ pub const RTL_CRITICAL_SECTION = extern struct {
pub const CRITICAL_SECTION = RTL_CRITICAL_SECTION;
pub const INIT_ONCE = RTL_RUN_ONCE;
pub const INIT_ONCE_STATIC_INIT = RTL_RUN_ONCE_INIT;
-pub const INIT_ONCE_FN = extern fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) BOOL;
+pub const INIT_ONCE_FN = fn (InitOnce: *INIT_ONCE, Parameter: ?*c_void, Context: ?*c_void) callconv(.C) BOOL;
pub const RTL_RUN_ONCE = extern struct {
Ptr: ?*c_void,
@@ -1418,7 +1418,7 @@ pub const RTL_DRIVE_LETTER_CURDIR = extern struct {
DosPath: UNICODE_STRING,
};
-pub const PPS_POST_PROCESS_INIT_ROUTINE = ?extern fn () void;
+pub const PPS_POST_PROCESS_INIT_ROUTINE = ?fn () callconv(.C) void;
pub const FILE_BOTH_DIR_INFORMATION = extern struct {
NextEntryOffset: ULONG,
@@ -1438,7 +1438,7 @@ pub const FILE_BOTH_DIR_INFORMATION = extern struct {
};
pub const FILE_BOTH_DIRECTORY_INFORMATION = FILE_BOTH_DIR_INFORMATION;
-pub const IO_APC_ROUTINE = extern fn (PVOID, *IO_STATUS_BLOCK, ULONG) void;
+pub const IO_APC_ROUTINE = fn (PVOID, *IO_STATUS_BLOCK, ULONG) callconv(.C) void;
pub const CURDIR = extern struct {
DosPath: UNICODE_STRING,
diff --git a/lib/std/os/windows/ws2_32.zig b/lib/std/os/windows/ws2_32.zig
index 31547036ae..d467a60d17 100644
--- a/lib/std/os/windows/ws2_32.zig
+++ b/lib/std/os/windows/ws2_32.zig
@@ -106,7 +106,7 @@ pub const WSAOVERLAPPED = extern struct {
hEvent: ?WSAEVENT,
};
-pub const WSAOVERLAPPED_COMPLETION_ROUTINE = extern fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) void;
+pub const WSAOVERLAPPED_COMPLETION_ROUTINE = fn (dwError: DWORD, cbTransferred: DWORD, lpOverlapped: *WSAOVERLAPPED, dwFlags: DWORD) callconv(.C) void;
pub const ADDRESS_FAMILY = u16;
diff --git a/lib/std/special/test_runner.zig b/lib/std/special/test_runner.zig
index 6dd208e3b4..7403cca9c2 100644
--- a/lib/std/special/test_runner.zig
+++ b/lib/std/special/test_runner.zig
@@ -34,7 +34,7 @@ pub fn main() anyerror!void {
std.heap.page_allocator.free(async_frame_buffer);
async_frame_buffer = try std.heap.page_allocator.alignedAlloc(u8, std.Target.stack_align, size);
}
- const casted_fn = @ptrCast(async fn () anyerror!void, test_fn.func);
+ const casted_fn = @ptrCast(fn () callconv(.Async) anyerror!void, test_fn.func);
break :blk await @asyncCall(async_frame_buffer, {}, casted_fn);
},
.blocking => {
diff --git a/lib/std/start.zig b/lib/std/start.zig
index 631bb2e9f8..604c22101c 100644
--- a/lib/std/start.zig
+++ b/lib/std/start.zig
@@ -224,8 +224,7 @@ inline fn initEventLoopAndCallMain() u8 {
// and we want fewer call frames in stack traces.
return @call(.{ .modifier = .always_inline }, callMain, .{});
}
-
-async fn callMainAsync(loop: *std.event.Loop) u8 {
+fn callMainAsync(loop: *std.event.Loop) callconv(.Async) u8 {
// This prevents the event loop from terminating at least until main() has returned.
loop.beginOneEvent();
defer loop.finishOneEvent();
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig
index 57c8496c6f..b3d67aab25 100644
--- a/src-self-hosted/clang.zig
+++ b/src-self-hosted/clang.zig
@@ -781,7 +781,7 @@ pub extern fn ZigClangSourceManager_getCharacterData(self: ?*const struct_ZigCla
pub extern fn ZigClangASTContext_getPointerType(self: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
pub extern fn ZigClangASTUnit_getASTContext(self: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
pub extern fn ZigClangASTUnit_getSourceManager(self: *struct_ZigClangASTUnit) *struct_ZigClangSourceManager;
-pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, *const struct_ZigClangDecl) bool) bool;
+pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(self: *struct_ZigClangASTUnit, context: ?*c_void, Fn: ?fn (?*c_void, *const struct_ZigClangDecl) callconv(.C) bool) bool;
pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) *const struct_ZigClangRecordDecl;
pub extern fn ZigClangTagDecl_isThisDeclarationADefinition(self: *const ZigClangTagDecl) bool;
pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) *const struct_ZigClangEnumDecl;
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index b7535fca6f..05eb7212dd 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -41,7 +41,7 @@ const usage =
const Command = struct {
name: []const u8,
- exec: async fn (*Allocator, []const []const u8) anyerror!void,
+ exec: fn (*Allocator, []const []const u8) callconv(.Async) anyerror!void,
};
pub fn main() !void {
@@ -713,8 +713,7 @@ const FmtError = error{
FileBusy,
CurrentWorkingDirectoryUnlinked,
} || fs.File.OpenError;
-
-async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtError!void {
+fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) callconv(.Async) FmtError!void {
const stderr_file = io.getStdErr();
const stderr = stderr_file.outStream();
diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig
index 4f6ace9899..30df7f64aa 100644
--- a/test/stage1/behavior/async_fn.zig
+++ b/test/stage1/behavior/async_fn.zig
@@ -112,12 +112,12 @@ test "@frameSize" {
const S = struct {
fn doTheTest() void {
{
- var ptr = @ptrCast(async fn (i32) void, other);
+ var ptr = @ptrCast(fn (i32) callconv(.Async) void, other);
const size = @frameSize(ptr);
expect(size == @sizeOf(@Frame(other)));
}
{
- var ptr = @ptrCast(async fn () void, first);
+ var ptr = @ptrCast(fn () callconv(.Async) void, first);
const size = @frameSize(ptr);
expect(size == @sizeOf(@Frame(first)));
}
@@ -184,7 +184,7 @@ test "coroutine suspend with block" {
var a_promise: anyframe = undefined;
var global_result = false;
-async fn testSuspendBlock() void {
+fn testSuspendBlock() callconv(.Async) void {
suspend {
comptime expect(@TypeOf(@frame()) == *@Frame(testSuspendBlock));
a_promise = @frame();
@@ -209,14 +209,14 @@ test "coroutine await" {
expect(await_final_result == 1234);
expect(std.mem.eql(u8, &await_points, "abcdefghi"));
}
-async fn await_amain() void {
+fn await_amain() callconv(.Async) void {
await_seq('b');
var p = async await_another();
await_seq('e');
await_final_result = await p;
await_seq('h');
}
-async fn await_another() i32 {
+fn await_another() callconv(.Async) i32 {
await_seq('c');
suspend {
await_seq('d');
@@ -243,14 +243,14 @@ test "coroutine await early return" {
expect(early_final_result == 1234);
expect(std.mem.eql(u8, &early_points, "abcdef"));
}
-async fn early_amain() void {
+fn early_amain() callconv(.Async) void {
early_seq('b');
var p = async early_another();
early_seq('d');
early_final_result = await p;
early_seq('e');
}
-async fn early_another() i32 {
+fn early_another() callconv(.Async) i32 {
early_seq('c');
return 1234;
}
@@ -266,7 +266,7 @@ fn early_seq(c: u8) void {
test "async function with dot syntax" {
const S = struct {
var y: i32 = 1;
- async fn foo() void {
+ fn foo() callconv(.Async) void {
y += 1;
suspend;
}
@@ -278,7 +278,7 @@ test "async function with dot syntax" {
test "async fn pointer in a struct field" {
var data: i32 = 1;
const Foo = struct {
- bar: async fn (*i32) void,
+ bar: fn (*i32) callconv(.Async) void,
};
var foo = Foo{ .bar = simpleAsyncFn2 };
var bytes: [64]u8 align(16) = undefined;
@@ -294,8 +294,7 @@ test "async fn pointer in a struct field" {
fn doTheAwait(f: anyframe->void) void {
await f;
}
-
-async fn simpleAsyncFn2(y: *i32) void {
+fn simpleAsyncFn2(y: *i32) callconv(.Async) void {
defer y.* += 2;
y.* += 1;
suspend;
@@ -303,11 +302,10 @@ async fn simpleAsyncFn2(y: *i32) void {
test "@asyncCall with return type" {
const Foo = struct {
- bar: async fn () i32,
+ bar: fn () callconv(.Async) i32,
var global_frame: anyframe = undefined;
-
- async fn middle() i32 {
+ fn middle() callconv(.Async) i32 {
return afunc();
}
@@ -338,8 +336,7 @@ test "async fn with inferred error set" {
resume global_frame;
std.testing.expectError(error.Fail, result);
}
-
- async fn middle() !void {
+ fn middle() callconv(.Async) !void {
var f = async middle2();
return await f;
}
@@ -376,11 +373,11 @@ fn nonFailing() (anyframe->anyerror!void) {
Static.frame = async suspendThenFail();
return &Static.frame;
}
-async fn suspendThenFail() anyerror!void {
+fn suspendThenFail() callconv(.Async) anyerror!void {
suspend;
return error.Fail;
}
-async fn printTrace(p: anyframe->(anyerror!void)) void {
+fn printTrace(p: anyframe->(anyerror!void)) callconv(.Async) void {
(await p) catch |e| {
std.testing.expect(e == error.Fail);
if (@errorReturnTrace()) |trace| {
@@ -397,7 +394,7 @@ test "break from suspend" {
const p = async testBreakFromSuspend(&my_result);
std.testing.expect(my_result == 2);
}
-async fn testBreakFromSuspend(my_result: *i32) void {
+fn testBreakFromSuspend(my_result: *i32) callconv(.Async) void {
suspend {
resume @frame();
}
@@ -826,7 +823,7 @@ test "cast fn to async fn when it is inferred to be async" {
var ok = false;
fn doTheTest() void {
- var ptr: async fn () i32 = undefined;
+ var ptr: fn () callconv(.Async) i32 = undefined;
ptr = func;
var buf: [100]u8 align(16) = undefined;
var result: i32 = undefined;
@@ -854,7 +851,7 @@ test "cast fn to async fn when it is inferred to be async, awaited directly" {
var ok = false;
fn doTheTest() void {
- var ptr: async fn () i32 = undefined;
+ var ptr: fn () callconv(.Async) i32 = undefined;
ptr = func;
var buf: [100]u8 align(16) = undefined;
var result: i32 = undefined;
@@ -958,8 +955,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
resume global_frame;
std.testing.expectError(error.Fail, result);
}
-
- async fn middle() !void {
+ fn middle() callconv(.Async) !void {
var f = async middle2();
return await f;
}
@@ -993,7 +989,7 @@ test "@asyncCall with actual frame instead of byte buffer" {
test "@asyncCall using the result location inside the frame" {
const S = struct {
- async fn simple2(y: *i32) i32 {
+ fn simple2(y: *i32) callconv(.Async) i32 {
defer y.* += 2;
y.* += 1;
suspend;
@@ -1005,7 +1001,7 @@ test "@asyncCall using the result location inside the frame" {
};
var data: i32 = 1;
const Foo = struct {
- bar: async fn (*i32) i32,
+ bar: fn (*i32) callconv(.Async) i32,
};
var foo = Foo{ .bar = S.simple2 };
var bytes: [64]u8 align(16) = undefined;
@@ -1115,7 +1111,7 @@ test "await used in expression and awaiting fn with no suspend but async calling
const sum = (await f1) + (await f2);
expect(sum == 10);
}
- async fn add(a: i32, b: i32) i32 {
+ fn add(a: i32, b: i32) callconv(.Async) i32 {
return a + b;
}
};
@@ -1130,7 +1126,7 @@ test "await used in expression after a fn call" {
sum = foo() + await f1;
expect(sum == 8);
}
- async fn add(a: i32, b: i32) i32 {
+ fn add(a: i32, b: i32) callconv(.Async) i32 {
return a + b;
}
fn foo() i32 {
@@ -1147,7 +1143,7 @@ test "async fn call used in expression after a fn call" {
sum = foo() + add(3, 4);
expect(sum == 8);
}
- async fn add(a: i32, b: i32) i32 {
+ fn add(a: i32, b: i32) callconv(.Async) i32 {
return a + b;
}
fn foo() i32 {
@@ -1403,7 +1399,7 @@ test "async function call resolves target fn frame, runtime func" {
fn foo() anyerror!void {
const stack_size = 1000;
var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;
- var func: async fn () anyerror!void = bar;
+ var func: fn () callconv(.Async) anyerror!void = bar;
return await @asyncCall(&stack_frame, {}, func);
}
diff --git a/test/stage1/behavior/await_struct.zig b/test/stage1/behavior/await_struct.zig
index 2d4faadc27..328f8f87fd 100644
--- a/test/stage1/behavior/await_struct.zig
+++ b/test/stage1/behavior/await_struct.zig
@@ -18,14 +18,14 @@ test "coroutine await struct" {
expect(await_final_result.x == 1234);
expect(std.mem.eql(u8, &await_points, "abcdefghi"));
}
-async fn await_amain() void {
+fn await_amain() callconv(.Async) void {
await_seq('b');
var p = async await_another();
await_seq('e');
await_final_result = await p;
await_seq('h');
}
-async fn await_another() Foo {
+fn await_another() callconv(.Async) Foo {
await_seq('c');
suspend {
await_seq('d');
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 63bf055aca..8717c8e619 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -762,7 +762,7 @@ test "variable initialization uses result locations properly with regards to the
test "cast between [*c]T and ?[*:0]T on fn parameter" {
const S = struct {
- const Handler = ?extern fn ([*c]const u8) void;
+ const Handler = ?fn ([*c]const u8) callconv(.C) void;
fn addCallback(handler: Handler) void {}
fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {}
From 54088fe6e11f193590e22a12da2cc95be38129d8 Mon Sep 17 00:00:00 2001
From: StrangeBug
Date: Tue, 5 May 2020 18:09:32 +0200
Subject: [PATCH 19/74] Add support for external links and URL to markdown
parser.
---
lib/std/special/docs/main.js | 39 ++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/lib/std/special/docs/main.js b/lib/std/special/docs/main.js
index b11e10caa7..7c4cceb31b 100644
--- a/lib/std/special/docs/main.js
+++ b/lib/std/special/docs/main.js
@@ -1498,6 +1498,22 @@
}
];
+ // Links, images and inner links don't use the same marker to wrap their content.
+ const linksFormat = [
+ {
+ prefix: "[",
+ regex: /\[([^\]]*)\]\(([^\)]*)\)/,
+ urlIndex: 2, // Index in the match that contains the link URL
+ textIndex: 1 // Index in the match that contains the link text
+ },
+ {
+ prefix: "h",
+ regex: /http[s]?:\/\/[^\s]+/,
+ urlIndex: 0,
+ textIndex: 0
+ }
+ ];
+
const stack = [];
var innerHTML = "";
@@ -1548,6 +1564,29 @@
currentRun += innerText[i];
in_code = true;
} else {
+ var foundMatches = false;
+
+ for (var j = 0; j < linksFormat.length; j++) {
+ const linkFmt = linksFormat[j];
+
+ if (linkFmt.prefix == innerText[i]) {
+ var remaining = innerText.substring(i);
+ var matches = remaining.match(linkFmt.regex);
+
+ if (matches) {
+ flushRun();
+ innerHTML += ' ' + matches[linkFmt.textIndex] + ' ';
+ i += matches[0].length; // Skip the fragment we just consumed
+ foundMatches = true;
+ break;
+ }
+ }
+ }
+
+ if (foundMatches) {
+ continue;
+ }
+
var any = false;
for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
const fmt = idx >= 0 ? formats[idx] : stack[stack.length - 1];
From 84a0a9688caea0f7cfe19bac07d5b5d46a06d470 Mon Sep 17 00:00:00 2001
From: Tadeo Kondrak
Date: Mon, 4 May 2020 10:50:11 -0600
Subject: [PATCH 20/74] update docs/tests for async/extern fn removal
---
doc/langref.html.in | 4 ++--
lib/std/zig/parser_test.zig | 1 +
test/compile_errors.zig | 22 +++++++++++-----------
test/runtime_safety.zig | 8 ++++----
test/stack_traces.zig | 2 +-
5 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index b2e1f6e6f6..91665604f7 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -6713,7 +6713,7 @@ const assert = std.debug.assert;
test "async fn pointer in a struct field" {
var data: i32 = 1;
const Foo = struct {
- bar: async fn (*i32) void,
+ bar: fn (*i32) callconv(.Async) void,
};
var foo = Foo{ .bar = func };
var bytes: [64]u8 align(@alignOf(@Frame(func))) = undefined;
@@ -6723,7 +6723,7 @@ test "async fn pointer in a struct field" {
assert(data == 4);
}
-async fn func(y: *i32) void {
+fn func(y: *i32) void {
defer y.* += 2;
y.* += 1;
suspend;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 7ab3e86b1a..b98e8c69c3 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -2910,6 +2910,7 @@ test "zig fmt: noasync to nosuspend" {
\\pub fn main() void {
\\ nosuspend call();
\\}
+ \\
);
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 19ec55d9e6..a79c8825a1 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -802,7 +802,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
});
cases.add("exported async function",
- \\export async fn foo() void {}
+ \\export fn foo() callconv(.Async) void {}
, &[_][]const u8{
"tmp.zig:1:1: error: exported function cannot be async",
});
@@ -1281,11 +1281,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add("bad alignment in @asyncCall",
\\export fn entry() void {
- \\ var ptr: async fn () void = func;
+ \\ var ptr: fn () callconv(.Async) void = func;
\\ var bytes: [64]u8 = undefined;
\\ _ = @asyncCall(&bytes, {}, ptr);
\\}
- \\async fn func() void {}
+ \\fn func() callconv(.Async) void {}
, &[_][]const u8{
"tmp.zig:4:21: error: expected type '[]align(16) u8', found '*[64]u8'",
});
@@ -1431,7 +1431,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ _ = async amain();
\\}
- \\async fn amain() void {
+ \\fn amain() callconv(.Async) void {
\\ other();
\\}
\\fn other() void {
@@ -1447,7 +1447,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ _ = async amain();
\\}
- \\async fn amain() void {
+ \\fn amain() callconv(.Async) void {
\\ var x: [@sizeOf(@Frame(amain))]u8 = undefined;
\\}
, &[_][]const u8{
@@ -1474,7 +1474,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ var ptr = afunc;
\\ _ = ptr();
\\}
- \\async fn afunc() void {}
+ \\fn afunc() callconv(.Async) void {}
, &[_][]const u8{
"tmp.zig:6:12: error: function is not comptime-known; @asyncCall required",
});
@@ -1485,7 +1485,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = async ptr();
\\}
\\
- \\async fn afunc() void { }
+ \\fn afunc() callconv(.Async) void { }
, &[_][]const u8{
"tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
});
@@ -3074,7 +3074,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ _ = async foo();
\\}
- \\async fn foo() void {
+ \\fn foo() void {
\\ suspend {
\\ suspend {
\\ }
@@ -3122,7 +3122,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\export fn entry() void {
\\ _ = async amain();
\\}
- \\async fn amain() void {
+ \\fn amain() callconv(.Async) void {
\\ return error.ShouldBeCompileError;
\\}
, &[_][]const u8{
@@ -3592,7 +3592,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
});
cases.add("attempt to use 0 bit type in extern fn",
- \\extern fn foo(ptr: extern fn(*void) void) void;
+ \\extern fn foo(ptr: fn(*void) callconv(.C) void) void;
\\
\\export fn entry() void {
\\ foo(bar);
@@ -3603,7 +3603,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ bar(&{});
\\}
, &[_][]const u8{
- "tmp.zig:1:30: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
+ "tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
"tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C'",
});
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 6837efe2d2..2e50c3a84c 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ var ptr = other;
\\ var frame = @asyncCall(&bytes, {}, ptr);
\\}
- \\async fn other() void {
+ \\fn other() callconv(.Async) void {
\\ suspend;
\\}
);
@@ -874,16 +874,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ return &failing_frame;
\\}
\\
- \\async fn failing() anyerror!void {
+ \\fn failing() anyerror!void {
\\ suspend;
\\ return second();
\\}
\\
- \\async fn second() anyerror!void {
+ \\fn second() callconv(.Async) anyerror!void {
\\ return error.Fail;
\\}
\\
- \\async fn printTrace(p: anyframe->anyerror!void) void {
+ \\fn printTrace(p: anyframe->anyerror!void) void {
\\ (await p) catch unreachable;
\\}
);
diff --git a/test/stack_traces.zig b/test/stack_traces.zig
index 2f7201e71d..616136b9ee 100644
--- a/test/stack_traces.zig
+++ b/test/stack_traces.zig
@@ -282,7 +282,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
\\source.zig:10:8: [address] in main (test)
\\ foo();
\\ ^
- \\start.zig:250:29: [address] in std.start.posixCallMainAndExit (test)
+ \\start.zig:249:29: [address] in std.start.posixCallMainAndExit (test)
\\ return root.main();
\\ ^
\\start.zig:123:5: [address] in std.start._start (test)
From 0a2104689b4c3c686f2268b5053ad38fd01c1d55 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 5 May 2020 12:45:39 -0400
Subject: [PATCH 21/74] fix incorrect flags being set in os.setSockFlags
fixes networking stuff on darwin
---
lib/std/os.zig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 86130ed32c..74d7ec8d81 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -3283,7 +3283,7 @@ fn setSockFlags(fd: fd_t, flags: u32) !void {
error.Locked => unreachable,
else => |e| return e,
};
- if ((flags & SOCK_NONBLOCK) != 0) fd_flags |= FD_CLOEXEC;
+ if ((flags & SOCK_CLOEXEC) != 0) fd_flags |= FD_CLOEXEC;
_ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
@@ -3296,7 +3296,7 @@ fn setSockFlags(fd: fd_t, flags: u32) !void {
error.Locked => unreachable,
else => |e| return e,
};
- if ((flags & SOCK_CLOEXEC) != 0) fl_flags |= O_NONBLOCK;
+ if ((flags & SOCK_NONBLOCK) != 0) fl_flags |= O_NONBLOCK;
_ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
From b13a02ed1aaab407a29b37bb5559639bf3a69715 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 5 May 2020 12:50:50 -0400
Subject: [PATCH 22/74] avoid unnecessary fcntl syscalls when setting socket
flags
---
lib/std/os.zig | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 74d7ec8d81..7e50ad256a 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -2173,7 +2173,7 @@ pub fn socket(domain: u32, socket_type: u32, protocol: u32) SocketError!fd_t {
switch (errno(rc)) {
0 => {
const fd = @intCast(fd_t, rc);
- if (!have_sock_flags and filtered_sock_type != socket_type) {
+ if (!have_sock_flags) {
try setSockFlags(fd, socket_type);
}
return fd;
@@ -2341,7 +2341,7 @@ pub fn accept(
switch (errno(rc)) {
0 => {
const fd = @intCast(fd_t, rc);
- if (!have_accept4 and flags != 0) {
+ if (!have_accept4) {
try setSockFlags(fd, flags);
}
return fd;
@@ -3277,26 +3277,26 @@ pub fn fcntl(fd: fd_t, cmd: i32, arg: usize) FcntlError!usize {
}
fn setSockFlags(fd: fd_t, flags: u32) !void {
- {
+ if ((flags & SOCK_CLOEXEC) != 0) {
var fd_flags = fcntl(fd, F_GETFD, 0) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
else => |e| return e,
};
- if ((flags & SOCK_CLOEXEC) != 0) fd_flags |= FD_CLOEXEC;
+ fd_flags |= FD_CLOEXEC;
_ = fcntl(fd, F_SETFD, fd_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
else => |e| return e,
};
}
- {
+ if ((flags & SOCK_NONBLOCK) != 0) {
var fl_flags = fcntl(fd, F_GETFL, 0) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
else => |e| return e,
};
- if ((flags & SOCK_NONBLOCK) != 0) fl_flags |= O_NONBLOCK;
+ fl_flags |= O_NONBLOCK;
_ = fcntl(fd, F_SETFL, fl_flags) catch |err| switch (err) {
error.FileBusy => unreachable,
error.Locked => unreachable,
From a39cb034ea0ae4f608ebcd7fa98df5d58d638668 Mon Sep 17 00:00:00 2001
From: Haze Booth
Date: Tue, 5 May 2020 11:49:33 -0400
Subject: [PATCH 23/74] Add setUseTestEventedIO for test steps in build.zig
---
lib/std/build.zig | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 85a65393ec..2b7eb254ee 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -1132,6 +1132,7 @@ pub const LibExeObjStep = struct {
name_prefix: []const u8,
filter: ?[]const u8,
single_threaded: bool,
+ evented_io: bool = false,
code_model: builtin.CodeModel = .default,
root_src: ?FileSource,
@@ -1559,6 +1560,11 @@ pub const LibExeObjStep = struct {
self.filter = text;
}
+ pub fn setUseTestEventedIo(self: *LibExeObjStep, use_evented_io: bool) void {
+ assert(self.kind == Kind.Test);
+ self.evented_io = use_evented_io;
+ }
+
pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, args: []const []const u8) void {
self.addCSourceFileSource(.{
.args = args,
@@ -1864,6 +1870,10 @@ pub const LibExeObjStep = struct {
try zig_args.append(filter);
}
+ if (self.evented_io) {
+ try zig_args.append("--test-evented-io");
+ }
+
if (self.name_prefix.len != 0) {
try zig_args.append("--test-name-prefix");
try zig_args.append(self.name_prefix);
From 6f3d76f61ef7f94598c77907e5083608d223a616 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Tue, 5 May 2020 15:18:04 -0400
Subject: [PATCH 24/74] simplify test-evented-io build setting
---
lib/std/build.zig | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 2b7eb254ee..8a38383e87 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -1132,7 +1132,7 @@ pub const LibExeObjStep = struct {
name_prefix: []const u8,
filter: ?[]const u8,
single_threaded: bool,
- evented_io: bool = false,
+ test_evented_io: bool = false,
code_model: builtin.CodeModel = .default,
root_src: ?FileSource,
@@ -1560,11 +1560,6 @@ pub const LibExeObjStep = struct {
self.filter = text;
}
- pub fn setUseTestEventedIo(self: *LibExeObjStep, use_evented_io: bool) void {
- assert(self.kind == Kind.Test);
- self.evented_io = use_evented_io;
- }
-
pub fn addCSourceFile(self: *LibExeObjStep, file: []const u8, args: []const []const u8) void {
self.addCSourceFileSource(.{
.args = args,
@@ -1870,7 +1865,7 @@ pub const LibExeObjStep = struct {
try zig_args.append(filter);
}
- if (self.evented_io) {
+ if (self.test_evented_io) {
try zig_args.append("--test-evented-io");
}
From eb4fa63d3d7f7bb04ce20f0545d5d4f14aa05c89 Mon Sep 17 00:00:00 2001
From: Lann
Date: Tue, 5 May 2020 19:13:35 -0400
Subject: [PATCH 25/74] Remove reference to import type (#5279)
* Remove reference to import type
* Improve language in `@This()` doc
---
doc/langref.html.in | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 6026912893..2103a0e9e7 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -8189,9 +8189,7 @@ fn List(comptime T: type) type {
{#code_end#}
When {#syntax#}@This(){#endsyntax#} is used at global scope, it returns a reference to the
- current import. There is a proposal to remove the import type and use an empty struct
- type instead. See
- #1047 for details.
+ struct that corresponds to the current file.
{#header_close#}
From 52f0adb3052b284102f2a96c083c5dd28b7941d8 Mon Sep 17 00:00:00 2001
From: Matthew Knight
Date: Tue, 5 May 2020 23:26:00 -0700
Subject: [PATCH 26/74] checkForBuiltinTypedef now returns a string
---
src-self-hosted/translate_c.zig | 74 +++++++++++++++++----------------
1 file changed, 38 insertions(+), 36 deletions(-)
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 2a8817977b..f7b080a749 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -668,31 +668,27 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
return transCreateNodeIdentifier(c, builtin_name);
}
-fn checkForBuiltinTypedef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, checked_name: []const u8) !?*ast.Node {
- if (mem.eql(u8, checked_name, "uint8_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "u8")
- else if (mem.eql(u8, checked_name, "int8_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "i8")
- else if (mem.eql(u8, checked_name, "uint16_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "u16")
- else if (mem.eql(u8, checked_name, "int16_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "i16")
- else if (mem.eql(u8, checked_name, "uint32_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "u32")
- else if (mem.eql(u8, checked_name, "int32_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "i32")
- else if (mem.eql(u8, checked_name, "uint64_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "u64")
- else if (mem.eql(u8, checked_name, "int64_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "i64")
- else if (mem.eql(u8, checked_name, "intptr_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "isize")
- else if (mem.eql(u8, checked_name, "uintptr_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "usize")
- else if (mem.eql(u8, checked_name, "ssize_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "isize")
- else if (mem.eql(u8, checked_name, "size_t"))
- return transTypeDefAsBuiltin(c, typedef_decl, "usize");
+fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 {
+ const table = comptime [_][2][]const u8{
+ .{ "uint8_t", "u8" },
+ .{ "int8_t", "i8" },
+ .{ "uint16_t", "u16" },
+ .{ "int16_t", "i16" },
+ .{ "uint32_t", "u32" },
+ .{ "int32_t", "i32" },
+ .{ "uint64_t", "u64" },
+ .{ "int64_t", "i64" },
+ .{ "intptr_t", "isize" },
+ .{ "uintptr_t", "usize" },
+ .{ "ssize_t", "isize" },
+ .{ "size_t", "usize" },
+ };
+
+ for (table) |entry| {
+ if (mem.eql(u8, checked_name, entry[0])) {
+ return entry[1];
+ }
+ }
return null;
}
@@ -707,8 +703,8 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
// TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802
const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
- if (try checkForBuiltinTypedef(c, typedef_decl, checked_name)) |node| {
- return node;
+ if (try checkForBuiltinTypedef(checked_name)) |builtin| {
+ return transTypeDefAsBuiltin(c, typedef_decl, builtin);
}
if (!top_level_visit) {
@@ -716,12 +712,12 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
}
_ = try c.decl_table.put(@ptrToInt(ZigClangTypedefNameDecl_getCanonicalDecl(typedef_decl)), checked_name);
- const node = (try transZigTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
+ const node = (try transCreateNodeTypedef(rp, typedef_decl, true, checked_name)) orelse return null;
try addTopLevelDecl(c, checked_name, &node.base);
return transCreateNodeIdentifier(c, checked_name);
}
-fn transZigTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl {
+fn transCreateNodeTypedef(rp: RestorePoint, typedef_decl: *const ZigClangTypedefNameDecl, toplevel: bool, checked_name: []const u8) Error!?*ast.Node.VarDecl {
const node = try transCreateNodeVarDecl(rp.c, toplevel, true, checked_name);
node.eq_token = try appendToken(rp.c, .Equal, "=");
@@ -1411,14 +1407,20 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
@ptrCast(*const ZigClangNamedDecl, typedef_decl),
));
- const mangled_name = try block_scope.makeMangledName(c, name);
- if (try checkForBuiltinTypedef(c, typedef_decl, mangled_name)) |ast_node| {
- return ast_node;
- }
+ const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
+ const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
+ const underlying_name = try c.str(ZigClangType_getTypeClassName(underlying_type));
- const node = (try transZigTypedef(rp, typedef_decl, false, mangled_name))
- orelse return error.UnsupportedTranslation;
- try block_scope.block_node.statements.push(&node.base);
+ const mangled_name = try block_scope.makeMangledName(c, name);
+ if (try checkForBuiltinTypedef(underlying_name)) |builtin| {
+ try block_scope.variables.push(.{
+ .alias = builtin,
+ .name = mangled_name,
+ });
+ } else {
+ const node = (try transCreateNodeTypedef(rp, typedef_decl, false, mangled_name)) orelse return error.UnsupportedTranslation;
+ try block_scope.block_node.statements.push(&node.base);
+ }
},
else => |kind| return revertAndWarn(
rp,
From c0b269bf46d6257112f08a3c48904dd5654c97e8 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 6 May 2020 11:48:46 +0300
Subject: [PATCH 27/74] translate-c: small patch to fix bultin type detection
---
src-self-hosted/translate_c.zig | 5 ++---
test/run_translated_c.zig | 4 ++--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index f7b080a749..b515791f77 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -669,7 +669,7 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
}
fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 {
- const table = comptime [_][2][]const u8{
+ const table = [_][2][]const u8{
.{ "uint8_t", "u8" },
.{ "int8_t", "i8" },
.{ "uint16_t", "u16" },
@@ -1409,10 +1409,9 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
const underlying_qual = ZigClangTypedefNameDecl_getUnderlyingType(typedef_decl);
const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
- const underlying_name = try c.str(ZigClangType_getTypeClassName(underlying_type));
const mangled_name = try block_scope.makeMangledName(c, name);
- if (try checkForBuiltinTypedef(underlying_name)) |builtin| {
+ if (try checkForBuiltinTypedef(name)) |builtin| {
try block_scope.variables.push(.{
.alias = builtin,
.name = mangled_name,
diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig
index 83569f1241..7dc64f068f 100644
--- a/test/run_translated_c.zig
+++ b/test/run_translated_c.zig
@@ -245,12 +245,12 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
, "");
cases.add("scoped typedef",
- \\#include
\\int main(int argc, char **argv) {
\\ typedef int Foo;
\\ typedef Foo Bar;
\\ typedef void (*func)(int);
- \\ typedef uint32_t Number;
+ \\ typedef int uint32_t;
+ \\ uint32_t a;
\\ Foo i;
\\ Bar j;
\\ return 0;
From 0e30edd8d099f005e3d1ee4de1d130c6e5c69295 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 6 May 2020 12:52:26 +0300
Subject: [PATCH 28/74] std: handle ConnectionTimedOut in switch
regression from #5266
closes #5270
---
lib/std/elf.zig | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/std/elf.zig b/lib/std/elf.zig
index 7b415f675a..f02cb33969 100644
--- a/lib/std/elf.zig
+++ b/lib/std/elf.zig
@@ -548,6 +548,7 @@ fn preadNoEof(file: std.fs.File, buf: []u8, offset: u64) !void {
error.BrokenPipe => return error.UnableToReadElfFile,
error.Unseekable => return error.UnableToReadElfFile,
error.ConnectionResetByPeer => return error.UnableToReadElfFile,
+ error.ConnectionTimedOut => return error.UnableToReadElfFile,
error.InputOutput => return error.FileSystem,
error.Unexpected => return error.Unexpected,
error.WouldBlock => return error.Unexpected,
From 3c4abacba67830f368f0d22de796a9b531044a15 Mon Sep 17 00:00:00 2001
From: data-man
Date: Wed, 6 May 2020 17:08:49 +0500
Subject: [PATCH 29/74] Optimization of vectors hashing
---
lib/std/hash/auto_hash.zig | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig
index 70c858098d..a33b23354b 100644
--- a/lib/std/hash/auto_hash.zig
+++ b/lib/std/hash/auto_hash.zig
@@ -113,11 +113,9 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
hasher.update(mem.asBytes(&key));
} else {
// Otherwise, hash every element.
- // TODO remove the copy to an array once field access is done.
- const array: [info.len]info.child = key;
comptime var i = 0;
inline while (i < info.len) : (i += 1) {
- hash(hasher, array[i], strat);
+ hash(hasher, key[i], strat);
}
}
},
From b336dda0765ba345253ed4b25113a5db4386c3f0 Mon Sep 17 00:00:00 2001
From: Timon Kruiper
Date: Wed, 6 May 2020 15:36:52 +0200
Subject: [PATCH 30/74] Standard library: Fix a regression in
loop.waitUntilFdWritableOrReadable
This broke async io on linux.
Regressed in 8ebcca6734e07aea29098ca4c63c0216b3099d0e
---
lib/std/event/loop.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 15e7a3481c..04859b6205 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -493,7 +493,7 @@ pub const Loop = struct {
pub fn waitUntilFdWritableOrReadable(self: *Loop, fd: os.fd_t) void {
switch (builtin.os.tag) {
.linux => {
- self.linuxWaitFd(@intCast(usize, fd), os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
+ self.linuxWaitFd(fd, os.EPOLLET | os.EPOLLONESHOT | os.EPOLLOUT | os.EPOLLIN);
},
.macosx, .freebsd, .netbsd, .dragonfly => {
self.bsdWaitKev(@intCast(usize, fd), os.EVFILT_READ, os.EV_ONESHOT);
From 0c7397b49f8c434cf1f714c08ab37d1429ab1be7 Mon Sep 17 00:00:00 2001
From: Jonathan Marler
Date: Wed, 6 May 2020 23:08:08 -0600
Subject: [PATCH 31/74] fix copy/paste error in AllocWithOptionaPayload
---
lib/std/mem.zig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index a40334e587..210b5cc108 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -124,9 +124,9 @@ pub const Allocator = struct {
fn AllocWithOptionsPayload(comptime Elem: type, comptime alignment: ?u29, comptime sentinel: ?Elem) type {
if (sentinel) |s| {
- return [:s]align(alignment orelse @alignOf(T)) Elem;
+ return [:s]align(alignment orelse @alignOf(Elem)) Elem;
} else {
- return []align(alignment orelse @alignOf(T)) Elem;
+ return []align(alignment orelse @alignOf(Elem)) Elem;
}
}
From 0a76e11617a76d884a52bf49c7b2b9a706e7bc8c Mon Sep 17 00:00:00 2001
From: Jonathan Marler
Date: Wed, 6 May 2020 23:56:48 -0600
Subject: [PATCH 32/74] add failAllocator to enable some regression tests
---
lib/std/mem.zig | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index 210b5cc108..13fd3d05f3 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -281,6 +281,22 @@ pub const Allocator = struct {
}
};
+var failAllocator = Allocator {
+ .reallocFn = failAllocatorRealloc,
+ .shrinkFn = failAllocatorShrink,
+};
+fn failAllocatorRealloc(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) ![]u8 {
+ return error.OutOfMemory;
+}
+fn failAllocatorShrink(self: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
+ @panic("failAllocatorShrink should never be called because it cannot allocate");
+}
+
+test "mem.Allocator basics" {
+ testing.expectError(error.OutOfMemory, failAllocator.alloc(u8, 1));
+ testing.expectError(error.OutOfMemory, failAllocator.allocSentinel(u8, 1, 0));
+}
+
/// Copy all of source into dest at position 0.
/// dest.len must be >= source.len.
/// dest.ptr must be <= src.ptr.
From 25810bc1e662014185a74282abd5881778d7a55e Mon Sep 17 00:00:00 2001
From: Jens Goldberg
Date: Wed, 6 May 2020 15:45:28 +0000
Subject: [PATCH 33/74] Removed duplicate WM_ACTIVATE
---
lib/std/os/windows/user32.zig | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig
index bda1fdffb6..7b82922469 100644
--- a/lib/std/os/windows/user32.zig
+++ b/lib/std/os/windows/user32.zig
@@ -73,7 +73,6 @@ pub const WM_XBUTTONDBLCLK = 0x020D;
// WA
pub const WA_INACTIVE = 0;
pub const WA_ACTIVE = 0x0006;
-pub const WM_ACTIVATE = 0x0006;
// WS
pub const WS_OVERLAPPED = 0x00000000;
From 20c1696865fc859e4f02a1f7a3e2e4bf4177a2d8 Mon Sep 17 00:00:00 2001
From: Jens Goldberg
Date: Thu, 7 May 2020 11:25:09 +0000
Subject: [PATCH 34/74] Removed GetModuleHandleA from user32
GetModuleHandleA is an kernel32 function and already defined there, it doesn't belong in user32.
---
lib/std/os/windows/user32.zig | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/std/os/windows/user32.zig b/lib/std/os/windows/user32.zig
index 7b82922469..3877e19ad8 100644
--- a/lib/std/os/windows/user32.zig
+++ b/lib/std/os/windows/user32.zig
@@ -146,7 +146,6 @@ pub extern "user32" fn CreateWindowExA(
pub extern "user32" fn RegisterClassExA(*const WNDCLASSEXA) callconv(.Stdcall) c_ushort;
pub extern "user32" fn DefWindowProcA(HWND, Msg: UINT, WPARAM, LPARAM) callconv(.Stdcall) LRESULT;
-pub extern "user32" fn GetModuleHandleA(lpModuleName: ?LPCSTR) callconv(.Stdcall) HMODULE;
pub extern "user32" fn ShowWindow(hWnd: ?HWND, nCmdShow: i32) callconv(.Stdcall) bool;
pub extern "user32" fn UpdateWindow(hWnd: ?HWND) callconv(.Stdcall) bool;
pub extern "user32" fn GetDC(hWnd: ?HWND) callconv(.Stdcall) ?HDC;
From 79bf4003da5fad5046b34d6256eeb8a575890ea5 Mon Sep 17 00:00:00 2001
From: xackus <14938807+xackus@users.noreply.github.com>
Date: Wed, 6 May 2020 22:08:04 +0200
Subject: [PATCH 35/74] stage1: add ZigList gdb pretty printing
---
tools/zig-gdb.py | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 tools/zig-gdb.py
diff --git a/tools/zig-gdb.py b/tools/zig-gdb.py
new file mode 100644
index 0000000000..f0efef9d2f
--- /dev/null
+++ b/tools/zig-gdb.py
@@ -0,0 +1,39 @@
+# pretty printing for stage1
+# put "source /path/to/zig-gdb.py" in ~/.gdbinit to load it automatically
+
+import gdb.printing
+
+class ZigListPrinter:
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return '%s of length %d, capacity %d' % (self.val.type.name, int(self.val['length']), int(self.val['capacity']))
+
+ def children(self):
+ def it(ziglist):
+ for i in range(int(ziglist.val['length'])):
+ item = ziglist.val['items'] + i
+ yield ('[%d]' % i, item.dereference())
+ return it(self)
+
+ def display_hint(self):
+ return 'array'
+
+# handle both Buf and ZigList because Buf* doesn't work otherwise (gdb bug?)
+class BufPrinter:
+ def __init__(self, val):
+ self.val = val['list'] if val.type.name == 'Buf' else val
+
+ def to_string(self):
+ return self.val['items'].string(length=int(self.val['length']))
+
+ def display_hint(self):
+ return 'string'
+
+pp = gdb.printing.RegexpCollectionPrettyPrinter('zig')
+pp.add_printer('Buf', '^Buf$', BufPrinter)
+pp.add_printer('ZigList', '^ZigList$', BufPrinter)
+pp.add_printer('ZigList', '^ZigList<.*>$', ZigListPrinter)
+
+gdb.printing.register_pretty_printer(gdb.current_objfile(), pp)
From a78ac96134a28d9e8208728bc8affb99122ff4fa Mon Sep 17 00:00:00 2001
From: Loris Cro
Date: Thu, 7 May 2020 01:49:38 +0200
Subject: [PATCH 36/74] fix crash in single-threaded builds
---
lib/std/event/loop.zig | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index 8ef5f1d8e4..cbaa156d0e 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -616,14 +616,16 @@ pub const Loop = struct {
self.workerRun();
- switch (builtin.os.tag) {
- .linux,
- .macosx,
- .freebsd,
- .netbsd,
- .dragonfly,
- => self.fs_thread.wait(),
- else => {},
+ if (!builtin.single_threaded) {
+ switch (builtin.os.tag) {
+ .linux,
+ .macosx,
+ .freebsd,
+ .netbsd,
+ .dragonfly,
+ => self.fs_thread.wait(),
+ else => {},
+ }
}
for (self.extra_threads) |extra_thread| {
From 7e8b859095a00cca8d102f0738a43e86fb4fb5f2 Mon Sep 17 00:00:00 2001
From: Loris Cro
Date: Thu, 7 May 2020 01:55:19 +0200
Subject: [PATCH 37/74] fix oneshot flag erroneusly set as filter_flag
---
lib/std/event/loop.zig | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/lib/std/event/loop.zig b/lib/std/event/loop.zig
index cbaa156d0e..607e2f24ca 100644
--- a/lib/std/event/loop.zig
+++ b/lib/std/event/loop.zig
@@ -503,7 +503,7 @@ pub const Loop = struct {
}
}
- pub fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, fflags: u32) callconv(.Async) void {
+ pub fn bsdWaitKev(self: *Loop, ident: usize, filter: i16, flags: u16) void {
var resume_node = ResumeNode.Basic{
.base = ResumeNode{
.id = ResumeNode.Id.Basic,
@@ -512,21 +512,28 @@ pub const Loop = struct {
},
.kev = undefined,
};
- defer self.bsdRemoveKev(ident, filter);
+
+ defer {
+ // If the kevent was set to be ONESHOT, it doesn't need to be deleted manually.
+ if (flags & os.EV_ONESHOT != 0) {
+ self.bsdRemoveKev(ident, filter);
+ }
+ }
+
suspend {
- self.bsdAddKev(&resume_node, ident, filter, fflags) catch unreachable;
+ self.bsdAddKev(&resume_node, ident, filter, flags) catch unreachable;
}
}
/// resume_node must live longer than the anyframe that it holds a reference to.
- pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, fflags: u32) !void {
+ pub fn bsdAddKev(self: *Loop, resume_node: *ResumeNode.Basic, ident: usize, filter: i16, flags: u16) !void {
self.beginOneEvent();
errdefer self.finishOneEvent();
var kev = [1]os.Kevent{os.Kevent{
.ident = ident,
.filter = filter,
- .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR,
- .fflags = fflags,
+ .flags = os.EV_ADD | os.EV_ENABLE | os.EV_CLEAR | flags,
+ .fflags = 0,
.data = 0,
.udata = @ptrToInt(&resume_node.base),
}};
From 35a59b5b0f3d827a7b3ed785be3155b72d15e682 Mon Sep 17 00:00:00 2001
From: Loris Cro
Date: Thu, 7 May 2020 02:00:39 +0200
Subject: [PATCH 38/74] remove readable check when opening a socket connection
---
lib/std/os.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 7e50ad256a..1eab9affe7 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -2549,7 +2549,7 @@ pub fn connect(sockfd: fd_t, sock_addr: *const sockaddr, len: socklen_t) Connect
EAFNOSUPPORT => return error.AddressFamilyNotSupported,
EAGAIN, EINPROGRESS => {
const loop = std.event.Loop.instance orelse return error.WouldBlock;
- loop.waitUntilFdWritableOrReadable(sockfd);
+ loop.waitUntilFdWritable(sockfd);
return getsockoptError(sockfd);
},
EALREADY => unreachable, // The socket is nonblocking and a previous connection attempt has not yet been completed.
From 2c9effc101f2359f6233fefb47eb850001634b42 Mon Sep 17 00:00:00 2001
From: xackus <14938807+xackus@users.noreply.github.com>
Date: Thu, 7 May 2020 01:31:18 +0200
Subject: [PATCH 39/74] stage1: handle all cases of invalid struct field
default value
---
src/ir.cpp | 6 ++++++
test/compile_errors.zig | 14 ++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index 4a0fc55d74..bcd05553ed 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21697,6 +21697,9 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
if (field->is_comptime) {
IrInstGen *elem = ir_const(ira, source_instr, field_type);
memoize_field_init_val(ira->codegen, struct_type, field);
+ if(field->init_val != nullptr && type_is_invalid(field->init_val->type)){
+ return ira->codegen->invalid_inst_gen;
+ }
copy_const_val(ira->codegen, elem->value, field->init_val);
return ir_get_ref2(ira, source_instr, elem, field_type, true, false);
}
@@ -25053,6 +25056,9 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry);
if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail;
memoize_field_init_val(ira->codegen, type_entry, struct_field);
+ if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){
+ return ErrorSemanticAnalyzeFail;
+ }
set_optional_payload(inner_fields[3], struct_field->init_val);
ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index a79c8825a1..e85538e0ba 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -7353,4 +7353,18 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
":3:18: error: expected type '[*:0]const u8', found '*[64]u8'",
":3:18: note: destination pointer requires a terminating '0' sentinel",
});
+
+ cases.add("issue #5221: invalid struct init type referenced by @typeInfo and passed into function",
+ \\fn ignore(comptime param: var) void {}
+ \\
+ \\export fn foo() void {
+ \\ const MyStruct = struct {
+ \\ wrong_type: []u8 = "foo",
+ \\ };
+ \\
+ \\ comptime ignore(@typeInfo(MyStruct).Struct.fields[0]);
+ \\}
+ , &[_][]const u8{
+ ":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
+ });
}
From fbf081a3066b4a438e53b58ad2aa564022dfa88d Mon Sep 17 00:00:00 2001
From: Josh Junon
Date: Sat, 4 Apr 2020 04:03:06 +0200
Subject: [PATCH 40/74] add failing test for #4909
---
test/compile_errors.zig | 44 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 19ec55d9e6..c7a771abf1 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -5375,6 +5375,50 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
break :x tc;
});
+ cases.addCase(x: {
+ const tc = cases.create("multiple files with private member instance function (canonical invocation) error",
+ \\const Foo = @import("foo.zig",).Foo;
+ \\
+ \\export fn callPrivFunction() void {
+ \\ var foo = Foo{};
+ \\ Foo.privateFunction(foo);
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:5:8: error: 'privateFunction' is private",
+ "foo.zig:2:5: note: declared here",
+ });
+
+ tc.addSourceFile("foo.zig",
+ \\pub const Foo = struct {
+ \\ fn privateFunction(self: *Foo) void { }
+ \\};
+ );
+
+ break :x tc;
+ });
+
+ cases.addCase(x: {
+ const tc = cases.create("multiple files with private member instance function error",
+ \\const Foo = @import("foo.zig",).Foo;
+ \\
+ \\export fn callPrivFunction() void {
+ \\ var foo = Foo{};
+ \\ foo.privateFunction();
+ \\}
+ , &[_][]const u8{
+ "tmp.zig:5:8: error: 'privateFunction' is private",
+ "foo.zig:2:5: note: declared here",
+ });
+
+ tc.addSourceFile("foo.zig",
+ \\pub const Foo = struct {
+ \\ fn privateFunction(self: *Foo) void { }
+ \\};
+ );
+
+ break :x tc;
+ });
+
cases.add("container init with non-type",
\\const zero: i32 = 0;
\\const a = zero{1};
From 4a5c58dd354b84af821a6c257cc15489fc827f75 Mon Sep 17 00:00:00 2001
From: Josh Junon
Date: Sat, 4 Apr 2020 04:04:00 +0200
Subject: [PATCH 41/74] fix private member checking for non-canonical
invocations (fixes #4909)
---
src/ir.cpp | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/ir.cpp b/src/ir.cpp
index 4a0fc55d74..8373ebfa70 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21624,6 +21624,15 @@ static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira,
if (tld->resolution == TldResolutionResolving)
return ir_error_dependency_loop(ira, source_instr);
+ if (tld->visib_mod == VisibModPrivate &&
+ tld->import != get_scope_import(source_instr->scope))
+ {
+ ErrorMsg *msg = ir_add_error(ira, source_instr,
+ buf_sprintf("'%s' is private", buf_ptr(field_name)));
+ add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here"));
+ return ira->codegen->invalid_inst_gen;
+ }
+
TldFn *tld_fn = (TldFn *)tld;
ZigFn *fn_entry = tld_fn->fn_entry;
assert(fn_entry != nullptr);
From b6dc7fc9ffddebce6f04a5349c8f2252c457adf7 Mon Sep 17 00:00:00 2001
From: Josh Junon
Date: Sat, 4 Apr 2020 04:04:40 +0200
Subject: [PATCH 42/74] publicize member functions affected by #4909
---
lib/std/build.zig | 10 +++++-----
lib/std/dwarf.zig | 8 ++++----
lib/std/dynamic_library.zig | 4 ++--
lib/std/json.zig | 2 +-
lib/std/pdb.zig | 2 +-
lib/std/zig/cross_target.zig | 2 +-
6 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index 8a38383e87..a7615292ce 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -284,11 +284,11 @@ pub const Builder = struct {
return run_step;
}
- fn dupe(self: *Builder, bytes: []const u8) []u8 {
+ pub fn dupe(self: *Builder, bytes: []const u8) []u8 {
return mem.dupe(self.allocator, u8, bytes) catch unreachable;
}
- fn dupePath(self: *Builder, bytes: []const u8) []u8 {
+ pub fn dupePath(self: *Builder, bytes: []const u8) []u8 {
const the_copy = self.dupe(bytes);
for (the_copy) |*byte| {
switch (byte.*) {
@@ -717,7 +717,7 @@ pub const Builder = struct {
return self.invalid_user_input;
}
- fn spawnChild(self: *Builder, argv: []const []const u8) !void {
+ pub fn spawnChild(self: *Builder, argv: []const []const u8) !void {
return self.spawnChildEnvMap(null, self.env_map, argv);
}
@@ -843,7 +843,7 @@ pub const Builder = struct {
}) catch unreachable;
}
- fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
+ pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
if (self.verbose) {
warn("cp {} {} ", .{ source_path, dest_path });
}
@@ -855,7 +855,7 @@ pub const Builder = struct {
};
}
- fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
+ pub fn pathFromRoot(self: *Builder, rel_path: []const u8) []u8 {
return fs.path.resolve(self.allocator, &[_][]const u8{ self.build_root, rel_path }) catch unreachable;
}
diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig
index fe40a04b9d..ebb4c096f8 100644
--- a/lib/std/dwarf.zig
+++ b/lib/std/dwarf.zig
@@ -121,7 +121,7 @@ const Die = struct {
};
}
- fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
+ pub fn getAttrString(self: *const Die, di: *DwarfInfo, id: u64) ![]const u8 {
const form_value = self.getAttr(id) orelse return error.MissingDebugInfo;
return switch (form_value.*) {
FormValue.String => |value| value,
@@ -389,7 +389,7 @@ pub const DwarfInfo = struct {
return self.abbrev_table_list.allocator;
}
- fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {
+ pub fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 {
for (di.func_list.span()) |*func| {
if (func.pc_range) |range| {
if (address >= range.start and address < range.end) {
@@ -578,7 +578,7 @@ pub const DwarfInfo = struct {
}
}
- fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
+ pub fn findCompileUnit(di: *DwarfInfo, target_address: u64) !*const CompileUnit {
for (di.compile_unit_list.span()) |*compile_unit| {
if (compile_unit.pc_range) |range| {
if (target_address >= range.start and target_address < range.end) return compile_unit;
@@ -690,7 +690,7 @@ pub const DwarfInfo = struct {
return result;
}
- fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo {
+ pub fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo {
var stream = io.fixedBufferStream(di.debug_line);
const in = &stream.inStream();
const seekable = &stream.seekableStream();
diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig
index 70e26cc71c..65c65292bc 100644
--- a/lib/std/dynamic_library.zig
+++ b/lib/std/dynamic_library.zig
@@ -33,11 +33,11 @@ const LinkMap = extern struct {
pub const Iterator = struct {
current: ?*LinkMap,
- fn end(self: *Iterator) bool {
+ pub fn end(self: *Iterator) bool {
return self.current == null;
}
- fn next(self: *Iterator) ?*LinkMap {
+ pub fn next(self: *Iterator) ?*LinkMap {
if (self.current) |it| {
self.current = it.l_next;
return it;
diff --git a/lib/std/json.zig b/lib/std/json.zig
index b2b2db6493..1e220d6708 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -2336,7 +2336,7 @@ pub const StringifyOptions = struct {
/// After a colon, should whitespace be inserted?
separator: bool = true,
- fn outputIndent(
+ pub fn outputIndent(
whitespace: @This(),
out_stream: var,
) @TypeOf(out_stream).Error!void {
diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig
index 75589b71ff..cd0106034e 100644
--- a/lib/std/pdb.zig
+++ b/lib/std/pdb.zig
@@ -708,7 +708,7 @@ const MsfStream = struct {
return block * self.block_size + offset;
}
- fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {
+ pub fn inStream(self: *MsfStream) std.io.InStream(*MsfStream, Error, read) {
return .{ .context = self };
}
};
diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig
index 8783ddcb6d..1909a07df0 100644
--- a/lib/std/zig/cross_target.zig
+++ b/lib/std/zig/cross_target.zig
@@ -660,7 +660,7 @@ pub const CrossTarget = struct {
return Target.getObjectFormatSimple(self.getOsTag(), self.getCpuArch());
}
- fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
+ pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
set.removeFeatureSet(self.cpu_features_sub);
set.addFeatureSet(self.cpu_features_add);
set.populateDependencies(self.getCpuArch().allFeaturesList());
From 10abffcd98f2f1ac9e8532c53820d7c1eea6d88f Mon Sep 17 00:00:00 2001
From: Vexu
Date: Fri, 8 May 2020 14:52:09 +0300
Subject: [PATCH 43/74] fix more private member access
---
lib/std/net.zig | 2 +-
lib/std/pdb.zig | 6 +++---
src-self-hosted/ir/text.zig | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index cc3e0d903e..aa38aeae08 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -386,7 +386,7 @@ pub const AddressList = struct {
addrs: []Address,
canon_name: ?[]u8,
- fn deinit(self: *AddressList) void {
+ pub fn deinit(self: *AddressList) void {
// Here we copy the arena allocator into stack memory, because
// otherwise it would destroy itself while it was still working.
var arena = self.arena;
diff --git a/lib/std/pdb.zig b/lib/std/pdb.zig
index cd0106034e..e4180717e9 100644
--- a/lib/std/pdb.zig
+++ b/lib/std/pdb.zig
@@ -644,7 +644,7 @@ const MsfStream = struct {
return stream;
}
- fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {
+ pub fn readNullTermString(self: *MsfStream, allocator: *mem.Allocator) ![]u8 {
var list = ArrayList(u8).init(allocator);
while (true) {
const byte = try self.inStream().readByte();
@@ -684,13 +684,13 @@ const MsfStream = struct {
return buffer.len;
}
- fn seekBy(self: *MsfStream, len: i64) !void {
+ pub fn seekBy(self: *MsfStream, len: i64) !void {
self.pos = @intCast(u64, @intCast(i64, self.pos) + len);
if (self.pos >= self.blocks.len * self.block_size)
return error.EOF;
}
- fn seekTo(self: *MsfStream, len: u64) !void {
+ pub fn seekTo(self: *MsfStream, len: u64) !void {
self.pos = len;
if (self.pos >= self.blocks.len * self.block_size)
return error.EOF;
diff --git a/src-self-hosted/ir/text.zig b/src-self-hosted/ir/text.zig
index e1efb40fe5..1efcd6f599 100644
--- a/src-self-hosted/ir/text.zig
+++ b/src-self-hosted/ir/text.zig
@@ -236,7 +236,7 @@ pub const Inst = struct {
@"comptime_int",
@"comptime_float",
- fn toType(self: BuiltinType) Type {
+ pub fn toType(self: BuiltinType) Type {
return switch (self) {
.@"isize" => Type.initTag(.@"isize"),
.@"usize" => Type.initTag(.@"usize"),
From 45f7c78bfcfe1ddef54ee2de05e9425b990de553 Mon Sep 17 00:00:00 2001
From: daurnimator
Date: Fri, 8 May 2020 22:11:03 +1000
Subject: [PATCH 44/74] std: fix RTLD_ constants on OSX
---
lib/std/os/bits/darwin.zig | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/std/os/bits/darwin.zig b/lib/std/os/bits/darwin.zig
index 8a596331a6..8e4682b3f4 100644
--- a/lib/std/os/bits/darwin.zig
+++ b/lib/std/os/bits/darwin.zig
@@ -1263,10 +1263,10 @@ pub const RTLD_NOLOAD = 0x10;
pub const RTLD_NODELETE = 0x80;
pub const RTLD_FIRST = 0x100;
-pub const RTLD_NEXT = @intToPtr(*c_void, ~maxInt(usize));
-pub const RTLD_DEFAULT = @intToPtr(*c_void, ~maxInt(usize) - 1);
-pub const RTLD_SELF = @intToPtr(*c_void, ~maxInt(usize) - 2);
-pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, ~maxInt(usize) - 4);
+pub const RTLD_NEXT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -1)));
+pub const RTLD_DEFAULT = @intToPtr(*c_void, @bitCast(usize, @as(isize, -2)));
+pub const RTLD_SELF = @intToPtr(*c_void, @bitCast(usize, @as(isize, -3)));
+pub const RTLD_MAIN_ONLY = @intToPtr(*c_void, @bitCast(usize, @as(isize, -5)));
/// duplicate file descriptor
pub const F_DUPFD = 0;
From 336ddb5b7656367d074ab7d8a6899321a041452c Mon Sep 17 00:00:00 2001
From: Vexu
Date: Fri, 8 May 2020 19:02:15 +0300
Subject: [PATCH 45/74] std: add test for mem.zeroes on sentinel terminated
arrays
---
lib/std/mem.zig | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/lib/std/mem.zig b/lib/std/mem.zig
index cedb1bc27d..63db3d58b2 100644
--- a/lib/std/mem.zig
+++ b/lib/std/mem.zig
@@ -341,8 +341,8 @@ pub fn zeroes(comptime T: type) T {
}
},
.Array => |info| {
- if (info.sentinel) |sentinel| {
- return [_:info.sentinel]info.child{zeroes(info.child)} ** info.len;
+ if (info.sentinel) |sentinel| {
+ return [_:sentinel]info.child{zeroes(info.child)} ** info.len;
}
return [_]info.child{zeroes(info.child)} ** info.len;
},
@@ -407,6 +407,7 @@ test "mem.zeroes" {
array: [2]u32,
optional_int: ?u8,
empty: void,
+ sentinel: [3:0]u8,
};
const b = zeroes(ZigStruct);
@@ -431,6 +432,9 @@ test "mem.zeroes" {
testing.expectEqual(@as(u32, 0), e);
}
testing.expectEqual(@as(?u8, null), b.optional_int);
+ for (b.sentinel) |e| {
+ testing.expectEqual(@as(u8, 0), e);
+ }
}
pub fn secureZero(comptime T: type, s: []T) void {
@@ -504,7 +508,7 @@ pub const toSlice = @compileError("deprecated; use std.mem.spanZ");
/// the constness of the input type. `[*c]` pointers are assumed to be 0-terminated,
/// and assumed to not allow null.
pub fn Span(comptime T: type) type {
- switch(@typeInfo(T)) {
+ switch (@typeInfo(T)) {
.Optional => |optional_info| {
return ?Span(optional_info.child);
},
From d4d509090b47a3860831a0fb6fb7fae02f5f7857 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Sat, 9 May 2020 00:31:11 +0300
Subject: [PATCH 46/74] make std.build.getInstallPath public
Closes #5299
---
lib/std/build.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/build.zig b/lib/std/build.zig
index a7615292ce..67f2af1047 100644
--- a/lib/std/build.zig
+++ b/lib/std/build.zig
@@ -985,7 +985,7 @@ pub const Builder = struct {
self.search_prefixes.append(search_prefix) catch unreachable;
}
- fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
+ pub fn getInstallPath(self: *Builder, dir: InstallDir, dest_rel_path: []const u8) []const u8 {
const base_dir = switch (dir) {
.Prefix => self.install_path,
.Bin => self.exe_dir,
From e79d7e0deda9e74dbaad1aa77db3e041f92f4f71 Mon Sep 17 00:00:00 2001
From: Haze Booth
Date: Sat, 9 May 2020 08:09:55 -0400
Subject: [PATCH 47/74] Remove fs.File artifact from connectUnixSocket
---
lib/std/net.zig | 1 -
1 file changed, 1 deletion(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index aa38aeae08..4e6bd03186 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -377,7 +377,6 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
return fs.File{
.handle = sockfd,
- .io_mode = std.io.mode,
};
}
From 0363f3c6f3017e8340ec466ef615a4bb9a08baec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=86=8A=E9=91=AB?= <1781189926@qq.com>
Date: Sun, 10 May 2020 20:35:21 +0800
Subject: [PATCH 48/74] mem.eql need slice type
---
doc/langref.html.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 00f82cd379..5bf91ca70f 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -1565,7 +1565,7 @@ value == null{#endsyntax#}
const array1 = [_]u32{1,2};
const array2 = [_]u32{3,4};
const together = array1 ++ array2;
-mem.eql(u32, together, &[_]u32{1,2,3,4}){#endsyntax#}
+mem.eql(u32, &together, &[_]u32{1,2,3,4}){#endsyntax#}
From 204f8daeeda02738479e0d586e6426e23f78e6cc Mon Sep 17 00:00:00 2001
From: xackus <14938807+xackus@users.noreply.github.com>
Date: Mon, 11 May 2020 14:06:37 +0200
Subject: [PATCH 49/74] stage1: detect underflow in bigint_fits_in_bits
---
src/bigint.cpp | 1 +
test/compile_errors.zig | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/src/bigint.cpp b/src/bigint.cpp
index dd04363e82..79a05e95a5 100644
--- a/src/bigint.cpp
+++ b/src/bigint.cpp
@@ -243,6 +243,7 @@ bool bigint_fits_in_bits(const BigInt *bn, size_t bit_count, bool is_signed) {
}
if (!is_signed) {
+ if(bn->is_negative) return false;
size_t full_bits = bn->digit_count * 64;
size_t leading_zero_count = bigint_clz(bn, full_bits);
return bit_count >= full_bits - leading_zero_count;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 5eb009dafa..a6e2d0b98f 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -7411,4 +7411,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
, &[_][]const u8{
":5:28: error: expected type '[]u8', found '*const [3:0]u8'",
});
+
+ cases.add("integer underflow error",
+ \\export fn entry() void {
+ \\ _ = @intToPtr(*c_void, ~@as(usize, @import("std").math.maxInt(usize)) - 1);
+ \\}
+ , &[_][]const u8{
+ ":2:75: error: operation caused overflow",
+ });
}
From 832f6c122877b2fd6aeb45b3417e2641bd9aaec7 Mon Sep 17 00:00:00 2001
From: Jonathan Marler
Date: Mon, 11 May 2020 09:11:05 -0600
Subject: [PATCH 50/74] make Address.getOsSockLen pub
---
lib/std/net.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/net.zig b/lib/std/net.zig
index 4e6bd03186..96c95fc497 100644
--- a/lib/std/net.zig
+++ b/lib/std/net.zig
@@ -341,7 +341,7 @@ pub const Address = extern union {
return mem.eql(u8, a_bytes, b_bytes);
}
- fn getOsSockLen(self: Address) os.socklen_t {
+ pub fn getOsSockLen(self: Address) os.socklen_t {
switch (self.any.family) {
os.AF_INET => return @sizeOf(os.sockaddr_in),
os.AF_INET6 => return @sizeOf(os.sockaddr_in6),
From 0847b47bf83c699d27c903e51b20f863d47c5790 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Tue, 12 May 2020 00:24:09 +0300
Subject: [PATCH 51/74] fix `@intToFloat` on comptime_floats
---
src/ir.cpp | 12 +++++++-----
test/stage1/behavior/cast.zig | 9 +++++++++
2 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/src/ir.cpp b/src/ir.cpp
index b5c4212ca5..6bd4e9b805 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -12760,9 +12760,7 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
const_val->type = new_type;
break;
case CastOpIntToFloat:
- {
- assert(new_type->id == ZigTypeIdFloat);
-
+ if (new_type->id == ZigTypeIdFloat) {
BigFloat bigfloat;
bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint);
switch (new_type->data.floating.bit_count) {
@@ -12783,9 +12781,13 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr,
default:
zig_unreachable();
}
- const_val->special = ConstValSpecialStatic;
- break;
+ } else if (new_type->id == ZigTypeIdComptimeFloat) {
+ bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint);
+ } else {
+ zig_unreachable();
}
+ const_val->special = ConstValSpecialStatic;
+ break;
case CastOpFloatToInt:
float_init_bigint(&const_val->data.x_bigint, other_val);
if (new_type->id == ZigTypeIdInt) {
diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig
index 8717c8e619..77cdacc307 100644
--- a/test/stage1/behavior/cast.zig
+++ b/test/stage1/behavior/cast.zig
@@ -827,3 +827,12 @@ test "peer type resolve array pointer and unknown pointer" {
comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
}
+
+test "comptime float casts" {
+ const a = @intToFloat(comptime_float, 1);
+ expect(a == 1);
+ expect(@TypeOf(a) == comptime_float);
+ const b = @floatToInt(comptime_int, 2);
+ expect(b == 2);
+ expect(@TypeOf(b) == comptime_int);
+}
From 9f496c077766172465a065eafba56dd5280021a6 Mon Sep 17 00:00:00 2001
From: Greg Anders
Date: Mon, 11 May 2020 19:36:41 -0600
Subject: [PATCH 52/74] Add helper functions and docstrings to ascii.zig
* Add an upper case variant of `allocLowerString`
* Add case-sensitive variants of `eqlIgnoreCase`, `indexOfIgnoreCase`,
and `indexOfIgnoreCasePos`
* Add and update docstrings on functions
---
lib/std/ascii.zig | 71 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 5 deletions(-)
diff --git a/lib/std/ascii.zig b/lib/std/ascii.zig
index 8bd959b46d..37cb1e461c 100644
--- a/lib/std/ascii.zig
+++ b/lib/std/ascii.zig
@@ -227,6 +227,8 @@ test "ascii character classes" {
testing.expect(isSpace(' '));
}
+/// Allocates a lower case copy of `ascii_string`.
+/// Caller owns returned string and must free with `allocator`.
pub fn allocLowerString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {
const result = try allocator.alloc(u8, ascii_string.len);
for (result) |*c, i| {
@@ -241,6 +243,23 @@ test "allocLowerString" {
std.testing.expect(std.mem.eql(u8, "abcdefghijklmnopqrst0234+💩!", result));
}
+/// Allocates an upper case copy of `ascii_string`.
+/// Caller owns returned string and must free with `allocator`.
+pub fn allocUpperString(allocator: *std.mem.Allocator, ascii_string: []const u8) ![]u8 {
+ const result = try allocator.alloc(u8, ascii_string.len);
+ for (result) |*c, i| {
+ c.* = toUpper(ascii_string[i]);
+ }
+ return result;
+}
+
+test "allocUpperString" {
+ const result = try allocUpperString(std.testing.allocator, "aBcDeFgHiJkLmNOPqrst0234+💩!");
+ defer std.testing.allocator.free(result);
+ std.testing.expect(std.mem.eql(u8, "ABCDEFGHIJKLMNOPQRST0234+💩!", result));
+}
+
+/// Return `true` if `a` and `b` are equal, case insensitive.
pub fn eqlIgnoreCase(a: []const u8, b: []const u8) bool {
if (a.len != b.len) return false;
for (a) |a_c, i| {
@@ -255,20 +274,43 @@ test "eqlIgnoreCase" {
std.testing.expect(!eqlIgnoreCase("hElLo!", "helro!"));
}
-/// Finds `substr` in `container`, starting at `start_index`.
-/// TODO boyer-moore algorithm
-pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
+/// Return `true` if `a` and `b` are equal, case sensitive.
+pub fn eqlMatchCase(a: []const u8, b: []const u8) bool {
+ if (a.len != b.len) return false;
+ for (a) |a_c, i| {
+ if (a_c != b[i]) return false;
+ }
+ return true;
+}
+
+test "eqlMatchCase" {
+ std.testing.expect(!eqlMatchCase("HEl💩Lo!", "hel💩lo!"));
+ std.testing.expect(eqlMatchCase("Hello! ", "Hello! "));
+ std.testing.expect(eqlMatchCase("hElLo!", "hElLo!"));
+}
+
+fn indexOfPos(container: []const u8, start_index: usize, substr: []const u8, comptime case_sensitive: bool) ?usize {
if (substr.len > container.len) return null;
var i: usize = start_index;
const end = container.len - substr.len;
while (i <= end) : (i += 1) {
- if (eqlIgnoreCase(container[i .. i + substr.len], substr)) return i;
+ if (case_sensitive) {
+ if (eqlMatchCase(container[i .. i + substr.len], substr)) return i;
+ } else {
+ if (eqlIgnoreCase(container[i .. i + substr.len], substr)) return i;
+ }
}
return null;
}
-/// Finds `substr` in `container`, starting at `start_index`.
+/// Finds `substr` in `container`, case insensitive, starting at `start_index`.
+/// TODO boyer-moore algorithm
+pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
+ return indexOfPos(container, start_index, substr, false);
+}
+
+/// Finds `substr` in `container`, case insensitive, starting at index 0.
pub fn indexOfIgnoreCase(container: []const u8, substr: []const u8) ?usize {
return indexOfIgnoreCasePos(container, 0, substr);
}
@@ -281,3 +323,22 @@ test "indexOfIgnoreCase" {
std.testing.expect(indexOfIgnoreCase("FOO foo", "fOo").? == 0);
}
+
+/// Finds `substr` in `container`, case sensitive, starting at `start_index`.
+pub fn indexOfMatchCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
+ return indexOfPos(container, start_index, substr, true);
+}
+
+/// Finds `substr` in `container`, case sensitive, starting at index 0.
+pub fn indexOfMatchCase(container: []const u8, substr: []const u8) ?usize {
+ return indexOfMatchCasePos(container, 0, substr);
+}
+
+test "indexOfMatchCase" {
+ std.testing.expect(indexOfMatchCase("one Two Three Four", "Four").? == 14);
+ std.testing.expect(indexOfMatchCase("one two three FouR", "fOur") == null);
+ std.testing.expect(indexOfMatchCase("foO", "foO").? == 0);
+ std.testing.expect(indexOfMatchCase("foo", "fool") == null);
+
+ std.testing.expect(indexOfMatchCase("FOO foo", "FOO").? == 0);
+}
From b1ebaba40811a6131152b9fc2eb8fb533e9fe5f3 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Tue, 12 May 2020 15:15:21 +0300
Subject: [PATCH 53/74] std.json properly handle comptime int/float
---
lib/std/json.zig | 4 ++--
lib/std/json/write_stream.zig | 8 +++++---
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/lib/std/json.zig b/lib/std/json.zig
index 1784f44a4d..c4a5ec75d9 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -2194,7 +2194,7 @@ test "write json then parse it" {
try jw.emitBool(true);
try jw.objectField("int");
- try jw.emitNumber(@as(i32, 1234));
+ try jw.emitNumber(1234);
try jw.objectField("array");
try jw.beginArray();
@@ -2203,7 +2203,7 @@ test "write json then parse it" {
try jw.emitNull();
try jw.arrayElem();
- try jw.emitNumber(@as(f64, 12.34));
+ try jw.emitNumber(12.34);
try jw.endArray();
diff --git a/lib/std/json/write_stream.zig b/lib/std/json/write_stream.zig
index 11f0171996..6dd02a03cf 100644
--- a/lib/std/json/write_stream.zig
+++ b/lib/std/json/write_stream.zig
@@ -148,7 +148,6 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
self.popState();
}
- // TODO better handling of ComptimeInt and ComptimeFloat
pub fn emitNumber(
self: *Self,
/// An integer, float, or `std.math.BigInt`. Emitted as a bare number if it fits losslessly
@@ -169,8 +168,11 @@ pub fn WriteStream(comptime OutStream: type, comptime max_depth: usize) type {
return;
}
},
- .Float => if (@floatCast(f64, value) == value) {
- try self.stream.print("{}", .{value});
+ .ComptimeInt => {
+ return self.emitNumber(@as(std.math.IntFittingRange(value, value), value));
+ },
+ .Float, .ComptimeFloat => if (@floatCast(f64, value) == value) {
+ try self.stream.print("{}", .{@floatCast(f64, value)});
self.popState();
return;
},
From c6420820b0aa5df8db801c9511305b009c8920e9 Mon Sep 17 00:00:00 2001
From: Greg Anders
Date: Tue, 12 May 2020 07:14:50 -0600
Subject: [PATCH 54/74] Remove redundant ASCII functions
The `matchCase` variants are simply duplicates of the `eql` and
`indexOf` functions found in std.mem.
---
lib/std/ascii.zig | 54 ++++++-----------------------------------------
1 file changed, 6 insertions(+), 48 deletions(-)
diff --git a/lib/std/ascii.zig b/lib/std/ascii.zig
index 37cb1e461c..102be18bec 100644
--- a/lib/std/ascii.zig
+++ b/lib/std/ascii.zig
@@ -259,7 +259,7 @@ test "allocUpperString" {
std.testing.expect(std.mem.eql(u8, "ABCDEFGHIJKLMNOPQRST0234+💩!", result));
}
-/// Return `true` if `a` and `b` are equal, case insensitive.
+/// Compares strings `a` and `b` case insensitively and returns whether they are equal.
pub fn eqlIgnoreCase(a: []const u8, b: []const u8) bool {
if (a.len != b.len) return false;
for (a) |a_c, i| {
@@ -274,43 +274,20 @@ test "eqlIgnoreCase" {
std.testing.expect(!eqlIgnoreCase("hElLo!", "helro!"));
}
-/// Return `true` if `a` and `b` are equal, case sensitive.
-pub fn eqlMatchCase(a: []const u8, b: []const u8) bool {
- if (a.len != b.len) return false;
- for (a) |a_c, i| {
- if (a_c != b[i]) return false;
- }
- return true;
-}
-
-test "eqlMatchCase" {
- std.testing.expect(!eqlMatchCase("HEl💩Lo!", "hel💩lo!"));
- std.testing.expect(eqlMatchCase("Hello! ", "Hello! "));
- std.testing.expect(eqlMatchCase("hElLo!", "hElLo!"));
-}
-
-fn indexOfPos(container: []const u8, start_index: usize, substr: []const u8, comptime case_sensitive: bool) ?usize {
+/// Finds `substr` in `container`, ignoring case, starting at `start_index`.
+/// TODO boyer-moore algorithm
+pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
if (substr.len > container.len) return null;
var i: usize = start_index;
const end = container.len - substr.len;
while (i <= end) : (i += 1) {
- if (case_sensitive) {
- if (eqlMatchCase(container[i .. i + substr.len], substr)) return i;
- } else {
- if (eqlIgnoreCase(container[i .. i + substr.len], substr)) return i;
- }
+ if (eqlIgnoreCase(container[i .. i + substr.len], substr)) return i;
}
return null;
}
-/// Finds `substr` in `container`, case insensitive, starting at `start_index`.
-/// TODO boyer-moore algorithm
-pub fn indexOfIgnoreCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
- return indexOfPos(container, start_index, substr, false);
-}
-
-/// Finds `substr` in `container`, case insensitive, starting at index 0.
+/// Finds `substr` in `container`, ignoring case, starting at index 0.
pub fn indexOfIgnoreCase(container: []const u8, substr: []const u8) ?usize {
return indexOfIgnoreCasePos(container, 0, substr);
}
@@ -323,22 +300,3 @@ test "indexOfIgnoreCase" {
std.testing.expect(indexOfIgnoreCase("FOO foo", "fOo").? == 0);
}
-
-/// Finds `substr` in `container`, case sensitive, starting at `start_index`.
-pub fn indexOfMatchCasePos(container: []const u8, start_index: usize, substr: []const u8) ?usize {
- return indexOfPos(container, start_index, substr, true);
-}
-
-/// Finds `substr` in `container`, case sensitive, starting at index 0.
-pub fn indexOfMatchCase(container: []const u8, substr: []const u8) ?usize {
- return indexOfMatchCasePos(container, 0, substr);
-}
-
-test "indexOfMatchCase" {
- std.testing.expect(indexOfMatchCase("one Two Three Four", "Four").? == 14);
- std.testing.expect(indexOfMatchCase("one two three FouR", "fOur") == null);
- std.testing.expect(indexOfMatchCase("foO", "foO").? == 0);
- std.testing.expect(indexOfMatchCase("foo", "fool") == null);
-
- std.testing.expect(indexOfMatchCase("FOO foo", "FOO").? == 0);
-}
From fa57463bb9c09ee1e50012d7e50d120e1599fb81 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Tue, 12 May 2020 21:44:08 +0300
Subject: [PATCH 55/74] make parser testError take a list of expected errors
---
lib/std/zig/parser_test.zig | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index b98e8c69c3..749fd1e832 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -19,7 +19,9 @@ test "zig fmt: decl between fields" {
\\ const baz1 = 2;
\\ b: usize,
\\};
- );
+ , &[_]Error{
+ .DeclBetweenFields,
+ });
}
test "zig fmt: errdefer with payload" {
@@ -2828,7 +2830,9 @@ test "zig fmt: extern without container keyword returns error" {
try testError(
\\const container = extern {};
\\
- );
+ , &[_]Error{
+ .ExpectedExpr,
+ });
}
test "zig fmt: integer literals with underscore separators" {
@@ -3030,9 +3034,17 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
fn testCanonical(source: []const u8) !void {
return testTransform(source, source);
}
-fn testError(source: []const u8) !void {
+
+const Error = @TagType(std.zig.ast.Error);
+
+fn testError(source: []const u8, expected_errors: []const Error) !void {
const tree = try std.zig.parse(std.testing.allocator, source);
defer tree.deinit();
- std.testing.expect(tree.errors.len != 0);
+ std.testing.expect(tree.errors.len == expected_errors.len);
+ for (expected_errors) |expected, i| {
+ const err = tree.errors.at(i);
+
+ std.testing.expect(expected == err.*);
+ }
}
From df22c7dfef7312474865c868a633c8e9bbaa63fa Mon Sep 17 00:00:00 2001
From: Vexu
Date: Tue, 12 May 2020 22:37:39 +0300
Subject: [PATCH 56/74] std.zig attempt to continue parsing on error
---
lib/std/zig/parse.zig | 99 ++++++++++++++++++++++++++++---------
lib/std/zig/parser_test.zig | 10 ++++
2 files changed, 86 insertions(+), 23 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 031fd9c160..eec1765002 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -48,31 +48,21 @@ pub fn parse(allocator: *Allocator, source: []const u8) Allocator.Error!*Tree {
while (it.peek().?.id == .LineComment) _ = it.next();
- tree.root_node = parseRoot(arena, &it, tree) catch |err| blk: {
- switch (err) {
- error.ParseError => {
- assert(tree.errors.len != 0);
- break :blk undefined;
- },
- error.OutOfMemory => {
- return error.OutOfMemory;
- },
- }
- };
+ tree.root_node = try parseRoot(arena, &it, tree);
return tree;
}
/// Root <- skip ContainerMembers eof
-fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!*Node.Root {
+fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!*Node.Root {
const node = try arena.create(Node.Root);
node.* = .{
.decls = try parseContainerMembers(arena, it, tree),
- .eof_token = eatToken(it, .Eof) orelse {
+ .eof_token = eatToken(it, .Eof) orelse blk: {
try tree.errors.push(.{
.ExpectedContainerMembers = .{ .token = it.index },
});
- return error.ParseError;
+ break :blk undefined;
},
};
return node;
@@ -85,7 +75,7 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!*Node.Roo
/// / KEYWORD_pub? ContainerField COMMA ContainerMembers
/// / KEYWORD_pub? ContainerField
/// /
-fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
+fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!Node.Root.DeclList {
var list = Node.Root.DeclList.init(arena);
var field_state: union(enum) {
@@ -108,7 +98,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
const doc_comments = try parseDocComment(arena, it, tree);
- if (try parseTestDecl(arena, it, tree)) |node| {
+ if (parseTestDecl(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ findEndOfBlock(it);
+ continue;
+ },
+ }) |node| {
if (field_state == .seen) {
field_state = .{ .end = node.firstToken() };
}
@@ -117,7 +113,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
continue;
}
- if (try parseTopLevelComptime(arena, it, tree)) |node| {
+ if (parseTopLevelComptime(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ findEndOfBlock(it);
+ continue;
+ },
+ }) |node| {
if (field_state == .seen) {
field_state = .{ .end = node.firstToken() };
}
@@ -128,7 +130,15 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
const visib_token = eatToken(it, .Keyword_pub);
- if (try parseTopLevelDecl(arena, it, tree)) |node| {
+ if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // attempt to recover by finding a semicolon
+ // TODO if this was a function with a body we should use findEndOfBlock
+ findToken(it, .Semicolon);
+ continue;
+ },
+ }) |node| {
if (field_state == .seen) {
field_state = .{ .end = visib_token orelse node.firstToken() };
}
@@ -163,10 +173,17 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
try tree.errors.push(.{
.ExpectedPubItem = .{ .token = it.index },
});
- return error.ParseError;
+ // ignore this pub
}
- if (try parseContainerField(arena, it, tree)) |node| {
+ if (parseContainerField(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // attempt to recover by finding a comma
+ findToken(it, .Comma);
+ continue;
+ },
+ }) |node| {
switch (field_state) {
.none => field_state = .seen,
.err, .seen => {},
@@ -200,8 +217,39 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !No
return list;
}
+/// Attempts to find a closing brace, assumes the opening brace was found.
+fn findEndOfBlock(it: *TokenIterator) void {
+ var count: u32 = 1;
+ while (it.next()) |tok| switch (tok.id) {
+ .LBrace => count += 1,
+ .RBrace => {
+ count -= 1;
+ if (count == 0) return;
+ },
+ else => {},
+ };
+}
+
+/// Attempts to find `wanted` token, keeps track of parentheses.
+fn findToken(it: *TokenIterator, wanted: Token.Id) void {
+ var count: u32 = 0;
+ while (it.next()) |tok| switch (tok.id) {
+ .LParen, .LBracket, .LBrace => count += 1,
+ .RParen, .RBracket, .RBrace => {
+ if (count == 0) {
+ _ = it.prev();
+ return;
+ }
+ count -= 1;
+ },
+ else => {
+ if (tok.id == wanted and count == 0) return;
+ },
+ };
+}
+
/// Eat a multiline container doc comment
-fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!?*Node {
var lines = Node.DocComment.LineList.init(arena);
while (eatToken(it, .ContainerDocComment)) |line| {
try lines.push(line);
@@ -687,8 +735,13 @@ fn parseLoopStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Nod
node.cast(Node.While).?.inline_token = inline_token;
return node;
}
+ if (inline_token == null) return null;
- return null;
+ // If we've seen "inline", there should have been a "for" or "while"
+ try tree.errors.push(.{
+ .ExpectedInlinable = .{ .token = it.index },
+ });
+ return error.ParseError;
}
/// ForStatement
@@ -2925,7 +2978,7 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D
}
/// Eat a single-line doc comment on the same line as another node
-fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) !?*Node.DocComment {
+fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) Allocator.Error!?*Node.DocComment {
const comment_token = eatToken(it, .DocComment) orelse return null;
if (tree.tokensOnSameLine(after_token, comment_token)) {
const node = try arena.create(Node.DocComment);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 749fd1e832..a925aacc0b 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,3 +1,13 @@
+test "zig fmt: fault tolerant parsing" {
+ try testError(
+ \\test "" {inline}
+ \\test "" {inline}
+ , &[_]Error{
+ .ExpectedInlinable,
+ .ExpectedInlinable,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
From 706311cad9feff5d8bdf70c6775813f096ea1a85 Mon Sep 17 00:00:00 2001
From: Jason Merrill
Date: Tue, 12 May 2020 19:11:05 -0700
Subject: [PATCH 57/74] Fix comment typo RFC8529 -> RFC8259
Ref: https://tools.ietf.org/html/rfc8259
---
lib/std/json.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/json.zig b/lib/std/json.zig
index 74f384946b..fc205d2279 100644
--- a/lib/std/json.zig
+++ b/lib/std/json.zig
@@ -136,7 +136,7 @@ pub const Token = union(enum) {
/// they are encountered. No copies or allocations are performed during parsing and the entire
/// parsing state requires ~40-50 bytes of stack space.
///
-/// Conforms strictly to RFC8529.
+/// Conforms strictly to RFC8259.
///
/// For a non-byte based wrapper, consider using TokenStream instead.
pub const StreamingParser = struct {
From 91358f3092fb2004bb46572d44a0e377ed400565 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 16:51:23 +0300
Subject: [PATCH 58/74] continue parsing on extra qualifier errors
---
lib/std/zig/parse.zig | 53 +++++++++++++++++++++++++++++++++++--------
1 file changed, 43 insertions(+), 10 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index eec1765002..586af02194 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -226,6 +226,10 @@ fn findEndOfBlock(it: *TokenIterator) void {
count -= 1;
if (count == 0) return;
},
+ .Eof => {
+ _ = it.prev();
+ return;
+ },
else => {},
};
}
@@ -242,8 +246,12 @@ fn findToken(it: *TokenIterator, wanted: Token.Id) void {
}
count -= 1;
},
+ .Eof => {
+ _ = it.prev();
+ return;
+ },
else => {
- if (tok.id == wanted and count == 0) return;
+ if (tok.id == wanted and count == 0) return;
},
};
}
@@ -2324,7 +2332,7 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
const node = try arena.create(Node.AnyFrameType);
node.* = .{
.anyframe_token = token,
- .result = Node.AnyFrameType.Result{
+ .result = .{
.arrow_token = arrow,
.return_type = undefined, // set by caller
},
@@ -2365,6 +2373,13 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
} else null;
_ = try expectToken(it, tree, .RParen);
+ if (ptr_info.align_info != null) {
+ try tree.errors.push(.{
+ .ExtraAlignQualifier = .{ .token = it.index - 1 },
+ });
+ continue;
+ }
+
ptr_info.align_info = Node.PrefixOp.PtrInfo.Align{
.node = expr_node,
.bit_range = bit_range,
@@ -2373,14 +2388,32 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
continue;
}
if (eatToken(it, .Keyword_const)) |const_token| {
+ if (ptr_info.const_token != null) {
+ try tree.errors.push(.{
+ .ExtraConstQualifier = .{ .token = it.index - 1 },
+ });
+ continue;
+ }
ptr_info.const_token = const_token;
continue;
}
if (eatToken(it, .Keyword_volatile)) |volatile_token| {
+ if (ptr_info.volatile_token != null) {
+ try tree.errors.push(.{
+ .ExtraVolatileQualifier = .{ .token = it.index - 1 },
+ });
+ continue;
+ }
ptr_info.volatile_token = volatile_token;
continue;
}
if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
+ if (ptr_info.allowzero_token != null) {
+ try tree.errors.push(.{
+ .ExtraAllowZeroQualifier = .{ .token = it.index - 1 },
+ });
+ continue;
+ }
ptr_info.allowzero_token = allowzero_token;
continue;
}
@@ -2399,9 +2432,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
if (try parseByteAlign(arena, it, tree)) |align_expr| {
if (slice_type.align_info != null) {
try tree.errors.push(.{
- .ExtraAlignQualifier = .{ .token = it.index },
+ .ExtraAlignQualifier = .{ .token = it.index - 1 },
});
- return error.ParseError;
+ continue;
}
slice_type.align_info = Node.PrefixOp.PtrInfo.Align{
.node = align_expr,
@@ -2412,9 +2445,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
if (eatToken(it, .Keyword_const)) |const_token| {
if (slice_type.const_token != null) {
try tree.errors.push(.{
- .ExtraConstQualifier = .{ .token = it.index },
+ .ExtraConstQualifier = .{ .token = it.index - 1 },
});
- return error.ParseError;
+ continue;
}
slice_type.const_token = const_token;
continue;
@@ -2422,9 +2455,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
if (eatToken(it, .Keyword_volatile)) |volatile_token| {
if (slice_type.volatile_token != null) {
try tree.errors.push(.{
- .ExtraVolatileQualifier = .{ .token = it.index },
+ .ExtraVolatileQualifier = .{ .token = it.index - 1 },
});
- return error.ParseError;
+ continue;
}
slice_type.volatile_token = volatile_token;
continue;
@@ -2432,9 +2465,9 @@ fn parsePrefixTypeOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
if (eatToken(it, .Keyword_allowzero)) |allowzero_token| {
if (slice_type.allowzero_token != null) {
try tree.errors.push(.{
- .ExtraAllowZeroQualifier = .{ .token = it.index },
+ .ExtraAllowZeroQualifier = .{ .token = it.index - 1 },
});
- return error.ParseError;
+ continue;
}
slice_type.allowzero_token = allowzero_token;
continue;
From be392777b763028a02866342b12915a1e69ebdf1 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 17:21:27 +0300
Subject: [PATCH 59/74] continue parsing after missing commas and invalid
statements
---
lib/std/zig/ast.zig | 4 ++++
lib/std/zig/parse.zig | 28 ++++++++++++++++++++++++++--
lib/std/zig/parser_test.zig | 24 ++++++++++++++++++++++++
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 8dec2de15c..dd9abe61ac 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -165,6 +165,7 @@ pub const Error = union(enum) {
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
ExpectedSuffixOp: ExpectedSuffixOp,
DeclBetweenFields: DeclBetweenFields,
+ MissingComma: MissingComma,
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
switch (self.*) {
@@ -213,6 +214,7 @@ pub const Error = union(enum) {
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
.DeclBetweenFields => |*x| return x.render(tokens, stream),
+ .MissingComma => |*x| return x.render(tokens, stream),
}
}
@@ -263,6 +265,7 @@ pub const Error = union(enum) {
.ExpectedDerefOrUnwrap => |x| return x.token,
.ExpectedSuffixOp => |x| return x.token,
.DeclBetweenFields => |x| return x.token,
+ .MissingComma => |x| return x.token,
}
}
@@ -308,6 +311,7 @@ pub const Error = union(enum) {
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
+ pub const MissingComma = SimpleError("Expected comma between items");
pub const ExpectedCall = struct {
node: *Node,
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 586af02194..ad4f5e1242 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -1083,7 +1083,14 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
var statements = Node.Block.StatementList.init(arena);
while (true) {
- const statement = (try parseStatement(arena, it, tree)) orelse break;
+ const statement = (parseStatement(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // try to skip to the next statement
+ findToken(it, .Semicolon);
+ continue;
+ },
+ }) orelse break;
try statements.push(statement);
}
@@ -2816,7 +2823,24 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
var list = L.init(arena);
while (try nodeParseFn(arena, it, tree)) |node| {
try list.push(node);
- if (eatToken(it, .Comma) == null) break;
+
+ const token = nextToken(it);
+ switch (token.ptr.id) {
+ .Comma => {},
+ // all possible delimiters
+ .Colon, .RParen, .RBrace, .RBracket => {
+ putBackToken(it, token.index);
+ break;
+ },
+ else => {
+ // this is likely just a missing comma,
+ // continue parsing this list and give an error
+ try tree.errors.push(.{
+ .MissingComma = .{ .token = token.index },
+ });
+ putBackToken(it, token.index);
+ },
+ }
}
return list;
}
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index a925aacc0b..2c8b53f7f0 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -6,6 +6,30 @@ test "zig fmt: fault tolerant parsing" {
.ExpectedInlinable,
.ExpectedInlinable,
});
+ try testError(
+ \\test "" {
+ \\ foo + +;
+ \\ inline;
+ \\}
+ , &[_]Error{
+ .InvalidToken,
+ .ExpectedInlinable,
+ });
+ try testError(
+ \\test "" {
+ \\ switch (foo) {
+ \\ 2 => {}
+ \\ 3 => {}
+ \\ else => {
+ \\ inline;
+ \\ }
+ \\ }
+ \\}
+ , &[_]Error{
+ .MissingComma,
+ .MissingComma,
+ .ExpectedInlinable,
+ });
}
test "zig fmt: top-level fields" {
From cefc04348e79f85118ad3c7b7fd15a4a5d635d50 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 17:36:06 +0300
Subject: [PATCH 60/74] continue parsing on invalid and token
---
lib/std/zig/ast.zig | 7 ++++---
lib/std/zig/parse.zig | 25 +++++++++++++++----------
lib/std/zig/parser_test.zig | 5 +++--
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index dd9abe61ac..339927d636 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -166,6 +166,7 @@ pub const Error = union(enum) {
ExpectedSuffixOp: ExpectedSuffixOp,
DeclBetweenFields: DeclBetweenFields,
MissingComma: MissingComma,
+ InvalidAnd: InvalidAnd,
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
switch (self.*) {
@@ -215,6 +216,7 @@ pub const Error = union(enum) {
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
.DeclBetweenFields => |*x| return x.render(tokens, stream),
.MissingComma => |*x| return x.render(tokens, stream),
+ .InvalidAnd => |*x| return x.render(tokens, stream),
}
}
@@ -266,6 +268,7 @@ pub const Error = union(enum) {
.ExpectedSuffixOp => |x| return x.token,
.DeclBetweenFields => |x| return x.token,
.MissingComma => |x| return x.token,
+ .InvalidAnd => |x| return x.token,
}
}
@@ -312,6 +315,7 @@ pub const Error = union(enum) {
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
pub const MissingComma = SimpleError("Expected comma between items");
+ pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
pub const ExpectedCall = struct {
node: *Node,
@@ -339,9 +343,6 @@ pub const Error = union(enum) {
pub fn render(self: *const ExpectedToken, tokens: *Tree.TokenList, stream: var) !void {
const found_token = tokens.at(self.token);
switch (found_token.id) {
- .Invalid_ampersands => {
- return stream.print("`&&` is invalid. Note that `and` is boolean AND.", .{});
- },
.Invalid => {
return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
},
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index ad4f5e1242..af501cd8a4 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -2824,21 +2824,16 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
while (try nodeParseFn(arena, it, tree)) |node| {
try list.push(node);
- const token = nextToken(it);
- switch (token.ptr.id) {
- .Comma => {},
+ switch (it.peek().?.id) {
+ .Comma => _ = nextToken(it),
// all possible delimiters
- .Colon, .RParen, .RBrace, .RBracket => {
- putBackToken(it, token.index);
- break;
- },
+ .Colon, .RParen, .RBrace, .RBracket => break,
else => {
// this is likely just a missing comma,
// continue parsing this list and give an error
try tree.errors.push(.{
- .MissingComma = .{ .token = token.index },
+ .MissingComma = .{ .token = it.index },
});
- putBackToken(it, token.index);
},
}
}
@@ -2850,7 +2845,17 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
fn SimpleBinOpParseFn(comptime token: Token.Id, comptime op: Node.InfixOp.Op) NodeParseFn {
return struct {
pub fn parse(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
- const op_token = eatToken(it, token) orelse return null;
+ const op_token = if (token == .Keyword_and) switch (it.peek().?.id) {
+ .Keyword_and => nextToken(it).index,
+ .Invalid_ampersands => blk: {
+ try tree.errors.push(.{
+ .InvalidAnd = .{ .token = it.index },
+ });
+ break :blk nextToken(it).index;
+ },
+ else => return null,
+ } else eatToken(it, token) orelse return null;
+
const node = try arena.create(Node.InfixOp);
node.* = .{
.op_token = op_token,
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 2c8b53f7f0..b92ce1ea23 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -21,14 +21,15 @@ test "zig fmt: fault tolerant parsing" {
\\ 2 => {}
\\ 3 => {}
\\ else => {
- \\ inline;
+ \\ foo && bar +;
\\ }
\\ }
\\}
, &[_]Error{
.MissingComma,
.MissingComma,
- .ExpectedInlinable,
+ .InvalidAnd,
+ .InvalidToken,
});
}
From afab095b6115e189ea2c5e0947a21e55a82c9f99 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 17:53:15 +0300
Subject: [PATCH 61/74] translate-c remove error set from
`checkForBuiltinTypedef`
---
src-self-hosted/translate_c.zig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index 7da6f402af..0b4854dcdc 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -668,7 +668,7 @@ fn transTypeDefAsBuiltin(c: *Context, typedef_decl: *const ZigClangTypedefNameDe
return transCreateNodeIdentifier(c, builtin_name);
}
-fn checkForBuiltinTypedef(checked_name: []const u8) !?[]const u8 {
+fn checkForBuiltinTypedef(checked_name: []const u8) ?[]const u8 {
const table = [_][2][]const u8{
.{ "uint8_t", "u8" },
.{ "int8_t", "i8" },
@@ -703,7 +703,7 @@ fn transTypeDef(c: *Context, typedef_decl: *const ZigClangTypedefNameDecl, top_l
// TODO https://github.com/ziglang/zig/issues/3756
// TODO https://github.com/ziglang/zig/issues/1802
const checked_name = if (isZigPrimitiveType(typedef_name)) try std.fmt.allocPrint(c.a(), "{}_{}", .{ typedef_name, c.getMangle() }) else typedef_name;
- if (try checkForBuiltinTypedef(checked_name)) |builtin| {
+ if (checkForBuiltinTypedef(checked_name)) |builtin| {
return transTypeDefAsBuiltin(c, typedef_decl, builtin);
}
@@ -1411,7 +1411,7 @@ fn transDeclStmt(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangDeclStmt)
const underlying_type = ZigClangQualType_getTypePtr(underlying_qual);
const mangled_name = try block_scope.makeMangledName(c, name);
- if (try checkForBuiltinTypedef(name)) |builtin| {
+ if (checkForBuiltinTypedef(name)) |builtin| {
try block_scope.variables.push(.{
.alias = builtin,
.name = mangled_name,
From 2589f7207baef686dff969ccf2bd596a16b5012e Mon Sep 17 00:00:00 2001
From: DrDeano
Date: Wed, 13 May 2020 16:21:15 +0100
Subject: [PATCH 62/74] Make StackIterator next public
---
lib/std/debug.zig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index d999de6a17..3e52770932 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -357,7 +357,7 @@ pub const StackIterator = struct {
else
0;
- fn next(self: *StackIterator) ?usize {
+ pub fn next(self: *StackIterator) ?usize {
var address = self.next_internal() orelse return null;
if (self.first_address) |first_address| {
From 76681e6b9689c4df78b6451da1aa857dc08a84d2 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 18:38:03 +0300
Subject: [PATCH 63/74] Make PriorityQueue.Iterator public
The `iterator` function was already public but these seem to have been forgotten.
---
lib/std/priority_queue.zig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/std/priority_queue.zig b/lib/std/priority_queue.zig
index e726a07a88..dfd2379da2 100644
--- a/lib/std/priority_queue.zig
+++ b/lib/std/priority_queue.zig
@@ -185,18 +185,18 @@ pub fn PriorityQueue(comptime T: type) type {
self.len = new_len;
}
- const Iterator = struct {
+ pub const Iterator = struct {
queue: *PriorityQueue(T),
count: usize,
- fn next(it: *Iterator) ?T {
+ pub fn next(it: *Iterator) ?T {
if (it.count > it.queue.len - 1) return null;
const out = it.count;
it.count += 1;
return it.queue.items[out];
}
- fn reset(it: *Iterator) void {
+ pub fn reset(it: *Iterator) void {
it.count = 0;
}
};
From 23c5ff94e9dda07694762fcc829dbac006bb00a1 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 20:42:18 +0300
Subject: [PATCH 64/74] improve recovery on top level declarations
---
lib/std/zig/ast.zig | 2 +
lib/std/zig/parse.zig | 157 +++++++++++++++++++++---------------
lib/std/zig/parser_test.zig | 31 ++++++-
lib/std/zig/render.zig | 6 +-
4 files changed, 127 insertions(+), 69 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 339927d636..afb7fce23e 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -893,6 +893,7 @@ pub const Node = struct {
pub const ReturnType = union(enum) {
Explicit: *Node,
InferErrorSet: *Node,
+ Invalid,
};
pub fn iterate(self: *FnProto, index: usize) ?*Node {
@@ -942,6 +943,7 @@ pub const Node = struct {
if (self.body_node) |body_node| return body_node.lastToken();
switch (self.return_type) {
.Explicit, .InferErrorSet => |node| return node.lastToken(),
+ .Invalid => unreachable,
}
}
};
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index af501cd8a4..6052d92d6a 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -130,15 +130,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
const visib_token = eatToken(it, .Keyword_pub);
- if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.ParseError => {
- // attempt to recover by finding a semicolon
- // TODO if this was a function with a body we should use findEndOfBlock
- findToken(it, .Semicolon);
- continue;
- },
- }) |node| {
+ if (try parseTopLevelDecl(arena, it, tree)) |node| {
if (field_state == .seen) {
field_state = .{ .end = visib_token orelse node.firstToken() };
}
@@ -217,43 +209,49 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
return list;
}
-/// Attempts to find a closing brace, assumes the opening brace was found.
+/// Attempts to find a closing brace.
fn findEndOfBlock(it: *TokenIterator) void {
- var count: u32 = 1;
- while (it.next()) |tok| switch (tok.id) {
- .LBrace => count += 1,
- .RBrace => {
- count -= 1;
- if (count == 0) return;
- },
- .Eof => {
- _ = it.prev();
- return;
- },
- else => {},
- };
+ var count: u32 = 0;
+ while (true) {
+ const tok = nextToken(it);
+ switch (tok.ptr.id) {
+ .LBrace => count += 1,
+ .RBrace => {
+ if (count <= 1) return;
+ count -= 1;
+ },
+ .Eof => {
+ putBackToken(it, tok.index);
+ return;
+ },
+ else => {},
+ }
+ }
}
/// Attempts to find `wanted` token, keeps track of parentheses.
fn findToken(it: *TokenIterator, wanted: Token.Id) void {
var count: u32 = 0;
- while (it.next()) |tok| switch (tok.id) {
- .LParen, .LBracket, .LBrace => count += 1,
- .RParen, .RBracket, .RBrace => {
- if (count == 0) {
- _ = it.prev();
+ while (true) {
+ const tok = nextToken(it);
+ switch (tok.ptr.id) {
+ .LParen, .LBracket, .LBrace => count += 1,
+ .RParen, .RBracket, .RBrace => {
+ if (count == 0) {
+ putBackToken(it, tok.index);
+ return;
+ }
+ count -= 1;
+ },
+ .Eof => {
+ putBackToken(it, tok.index);
return;
- }
- count -= 1;
- },
- .Eof => {
- _ = it.prev();
- return;
- },
- else => {
- if (tok.id == wanted and count == 0) return;
- },
- };
+ },
+ else => {
+ if (tok.ptr.id == wanted and count == 0) return;
+ },
+ }
+ }
}
/// Eat a multiline container doc comment
@@ -317,7 +315,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
/// / KEYWORD_usingnamespace Expr SEMICOLON
-fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
+fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!?*Node {
var lib_name: ?*Node = null;
const extern_export_inline_token = blk: {
if (eatToken(it, .Keyword_export)) |token| break :blk token;
@@ -330,12 +328,26 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
break :blk null;
};
- if (try parseFnProto(arena, it, tree)) |node| {
+ if (parseFnProto(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // this fn will likely have a body so we
+ // use findEndOfBlock instead of findToken.
+ findEndOfBlock(it);
+ return null;
+ },
+ }) |node| {
const fn_node = node.cast(Node.FnProto).?;
fn_node.*.extern_export_inline_token = extern_export_inline_token;
fn_node.*.lib_name = lib_name;
if (eatToken(it, .Semicolon)) |_| return node;
- if (try parseBlock(arena, it, tree)) |body_node| {
+ if (parseBlock(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ // since parseBlock only return error.ParseError on
+ // a missing '}' we can assume this function was
+ // supposed to end here.
+ error.ParseError => null,
+ }) |body_node| {
fn_node.body_node = body_node;
return node;
}
@@ -356,7 +368,14 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
const thread_local_token = eatToken(it, .Keyword_threadlocal);
- if (try parseVarDecl(arena, it, tree)) |node| {
+ if (parseVarDecl(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // try to skip to next decl
+ findToken(it, .Semicolon);
+ return null;
+ },
+ }) |node| {
var var_decl = node.cast(Node.VarDecl).?;
var_decl.*.thread_local_token = thread_local_token;
var_decl.*.comptime_token = null;
@@ -369,7 +388,8 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
try tree.errors.push(.{
.ExpectedVarDecl = .{ .token = it.index },
});
- return error.ParseError;
+ // ignore this, try to find next decl by skipping the next block
+ findEndOfBlock(it);
}
if (extern_export_inline_token) |token| {
@@ -379,16 +399,14 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return null;
}
- const use_node = (try parseUse(arena, it, tree)) orelse return null;
- const expr_node = try expectNode(arena, it, tree, parseExpr, .{
- .ExpectedExpr = .{ .token = it.index },
- });
- const semicolon_token = try expectToken(it, tree, .Semicolon);
- const use_node_raw = use_node.cast(Node.Use).?;
- use_node_raw.*.expr = expr_node;
- use_node_raw.*.semicolon_token = semicolon_token;
-
- return use_node;
+ return parseUse(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // try to skip to next decl
+ findToken(it, .Semicolon);
+ return null;
+ },
+ };
}
/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
@@ -422,18 +440,23 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
const exclamation_token = eatToken(it, .Bang);
const return_type_expr = (try parseVarType(arena, it, tree)) orelse
- try expectNode(arena, it, tree, parseTypeExpr, .{
- .ExpectedReturnType = .{ .token = it.index },
- });
+ (try parseTypeExpr(arena, it, tree)) orelse blk: {
+ try tree.errors.push(.{
+ .ExpectedReturnType = .{ .token = it.index },
+ });
+ // most likely the user forgot to specify the return type.
+ // Mark return type as invalid and try to continue.
+ break :blk null;
+ };
- const return_type: Node.FnProto.ReturnType = if (exclamation_token != null)
- .{
- .InferErrorSet = return_type_expr,
- }
+ // TODO https://github.com/ziglang/zig/issues/3750
+ const R = Node.FnProto.ReturnType;
+ const return_type = if (return_type_expr == null)
+ R{ .Invalid = {} }
+ else if (exclamation_token != null)
+ R{ .InferErrorSet = return_type_expr.? }
else
- .{
- .Explicit = return_type_expr,
- };
+ R{ .Explicit = return_type_expr.? };
const var_args_token = if (params.len > 0)
params.at(params.len - 1).*.cast(Node.ParamDecl).?.var_args_token
@@ -2992,8 +3015,10 @@ fn parseUse(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
.doc_comments = null,
.visib_token = null,
.use_token = token,
- .expr = undefined, // set by caller
- .semicolon_token = undefined, // set by caller
+ .expr = try expectNode(arena, it, tree, parseExpr, .{
+ .ExpectedExpr = .{ .token = it.index },
+ }),
+ .semicolon_token = try expectToken(it, tree, .Semicolon),
};
return &node.base;
}
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index b92ce1ea23..e3bc20bd10 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,4 +1,4 @@
-test "zig fmt: fault tolerant parsing" {
+test "recovery: top level" {
try testError(
\\test "" {inline}
\\test "" {inline}
@@ -6,6 +6,9 @@ test "zig fmt: fault tolerant parsing" {
.ExpectedInlinable,
.ExpectedInlinable,
});
+}
+
+test "recovery: block statements" {
try testError(
\\test "" {
\\ foo + +;
@@ -15,6 +18,9 @@ test "zig fmt: fault tolerant parsing" {
.InvalidToken,
.ExpectedInlinable,
});
+}
+
+test "recovery: missing comma" {
try testError(
\\test "" {
\\ switch (foo) {
@@ -33,6 +39,29 @@ test "zig fmt: fault tolerant parsing" {
});
}
+test "recovery: extra qualifier" {
+ try testError(
+ \\const a: *const const u8;
+ \\test ""
+ , &[_]Error{
+ .ExtraConstQualifier,
+ .ExpectedLBrace,
+ });
+}
+
+test "recovery: missing return type" {
+ try testError(
+ \\fn foo() {
+ \\ a && b;
+ \\}
+ \\test ""
+ , &[_]Error{
+ .ExpectedReturnType,
+ .InvalidAnd,
+ .ExpectedLBrace,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index bcdc08d43a..64f2f77f6c 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -1444,6 +1444,7 @@ fn renderExpression(
else switch (fn_proto.return_type) {
.Explicit => |node| node.firstToken(),
.InferErrorSet => |node| tree.prevToken(node.firstToken()),
+ .Invalid => unreachable,
});
assert(tree.tokens.at(rparen).id == .RParen);
@@ -1518,13 +1519,14 @@ fn renderExpression(
}
switch (fn_proto.return_type) {
- ast.Node.FnProto.ReturnType.Explicit => |node| {
+ .Explicit => |node| {
return renderExpression(allocator, stream, tree, indent, start_col, node, space);
},
- ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
+ .InferErrorSet => |node| {
try renderToken(tree, stream, tree.prevToken(node.firstToken()), indent, start_col, Space.None); // !
return renderExpression(allocator, stream, tree, indent, start_col, node, space);
},
+ .Invalid => unreachable,
}
},
From 2296906e2ad54c387b4b19784148c47a26969cdc Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 23:08:42 +0300
Subject: [PATCH 65/74] modernize std.zig.tokenizer
---
lib/std/zig/tokenizer.zig | 946 +++++++++++++++++++-------------------
1 file changed, 473 insertions(+), 473 deletions(-)
diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig
index 089711871e..160530f459 100644
--- a/lib/std/zig/tokenizer.zig
+++ b/lib/std/zig/tokenizer.zig
@@ -353,64 +353,64 @@ pub const Tokenizer = struct {
}
const State = enum {
- Start,
- Identifier,
- Builtin,
- StringLiteral,
- StringLiteralBackslash,
- MultilineStringLiteralLine,
- CharLiteral,
- CharLiteralBackslash,
- CharLiteralHexEscape,
- CharLiteralUnicodeEscapeSawU,
- CharLiteralUnicodeEscape,
- CharLiteralUnicodeInvalid,
- CharLiteralUnicode,
- CharLiteralEnd,
- Backslash,
- Equal,
- Bang,
- Pipe,
- Minus,
- MinusPercent,
- Asterisk,
- AsteriskPercent,
- Slash,
- LineCommentStart,
- LineComment,
- DocCommentStart,
- DocComment,
- ContainerDocComment,
- Zero,
- IntegerLiteralDec,
- IntegerLiteralDecNoUnderscore,
- IntegerLiteralBin,
- IntegerLiteralBinNoUnderscore,
- IntegerLiteralOct,
- IntegerLiteralOctNoUnderscore,
- IntegerLiteralHex,
- IntegerLiteralHexNoUnderscore,
- NumberDotDec,
- NumberDotHex,
- FloatFractionDec,
- FloatFractionDecNoUnderscore,
- FloatFractionHex,
- FloatFractionHexNoUnderscore,
- FloatExponentUnsigned,
- FloatExponentNumber,
- FloatExponentNumberNoUnderscore,
- Ampersand,
- Caret,
- Percent,
- Plus,
- PlusPercent,
- AngleBracketLeft,
- AngleBracketAngleBracketLeft,
- AngleBracketRight,
- AngleBracketAngleBracketRight,
- Period,
- Period2,
- SawAtSign,
+ start,
+ identifier,
+ builtin,
+ string_literal,
+ string_literal_backslash,
+ multiline_string_literal_line,
+ char_literal,
+ char_literal_backslash,
+ char_literal_hex_escape,
+ char_literal_unicode_escape_saw_u,
+ char_literal_unicode_escape,
+ char_literal_unicode_invalid,
+ char_literal_unicode,
+ char_literal_end,
+ backslash,
+ equal,
+ bang,
+ pipe,
+ minus,
+ minus_percent,
+ asterisk,
+ asterisk_percent,
+ slash,
+ line_comment_start,
+ line_comment,
+ doc_comment_start,
+ doc_comment,
+ container_doc_comment,
+ zero,
+ int_literal_dec,
+ int_literal_dec_no_underscore,
+ int_literal_bin,
+ int_literal_bin_no_underscore,
+ int_literal_oct,
+ int_literal_oct_no_underscore,
+ int_literal_hex,
+ int_literal_hex_no_underscore,
+ num_dot_dec,
+ num_dot_hex,
+ float_fraction_dec,
+ float_fraction_dec_no_underscore,
+ float_fraction_hex,
+ float_fraction_hex_no_underscore,
+ float_exponent_unsigned,
+ float_exponent_num,
+ float_exponent_num_no_underscore,
+ ampersand,
+ caret,
+ percent,
+ plus,
+ plus_percent,
+ angle_bracket_left,
+ angle_bracket_angle_bracket_left,
+ angle_bracket_right,
+ angle_bracket_angle_bracket_right,
+ period,
+ period_2,
+ saw_at_sign,
};
fn isIdentifierChar(char: u8) bool {
@@ -423,9 +423,9 @@ pub const Tokenizer = struct {
return token;
}
const start_index = self.index;
- var state = State.Start;
+ var state: State = .start;
var result = Token{
- .id = Token.Id.Eof,
+ .id = .Eof,
.start = self.index,
.end = undefined,
};
@@ -434,40 +434,40 @@ pub const Tokenizer = struct {
while (self.index < self.buffer.len) : (self.index += 1) {
const c = self.buffer[self.index];
switch (state) {
- State.Start => switch (c) {
+ .start => switch (c) {
' ', '\n', '\t', '\r' => {
result.start = self.index + 1;
},
'"' => {
- state = State.StringLiteral;
- result.id = Token.Id.StringLiteral;
+ state = .string_literal;
+ result.id = .StringLiteral;
},
'\'' => {
- state = State.CharLiteral;
+ state = .char_literal;
},
'a'...'z', 'A'...'Z', '_' => {
- state = State.Identifier;
- result.id = Token.Id.Identifier;
+ state = .identifier;
+ result.id = .Identifier;
},
'@' => {
- state = State.SawAtSign;
+ state = .saw_at_sign;
},
'=' => {
- state = State.Equal;
+ state = .equal;
},
'!' => {
- state = State.Bang;
+ state = .bang;
},
'|' => {
- state = State.Pipe;
+ state = .pipe;
},
'(' => {
- result.id = Token.Id.LParen;
+ result.id = .LParen;
self.index += 1;
break;
},
')' => {
- result.id = Token.Id.RParen;
+ result.id = .RParen;
self.index += 1;
break;
},
@@ -477,213 +477,213 @@ pub const Tokenizer = struct {
break;
},
']' => {
- result.id = Token.Id.RBracket;
+ result.id = .RBracket;
self.index += 1;
break;
},
';' => {
- result.id = Token.Id.Semicolon;
+ result.id = .Semicolon;
self.index += 1;
break;
},
',' => {
- result.id = Token.Id.Comma;
+ result.id = .Comma;
self.index += 1;
break;
},
'?' => {
- result.id = Token.Id.QuestionMark;
+ result.id = .QuestionMark;
self.index += 1;
break;
},
':' => {
- result.id = Token.Id.Colon;
+ result.id = .Colon;
self.index += 1;
break;
},
'%' => {
- state = State.Percent;
+ state = .percent;
},
'*' => {
- state = State.Asterisk;
+ state = .asterisk;
},
'+' => {
- state = State.Plus;
+ state = .plus;
},
'<' => {
- state = State.AngleBracketLeft;
+ state = .angle_bracket_left;
},
'>' => {
- state = State.AngleBracketRight;
+ state = .angle_bracket_right;
},
'^' => {
- state = State.Caret;
+ state = .caret;
},
'\\' => {
- state = State.Backslash;
- result.id = Token.Id.MultilineStringLiteralLine;
+ state = .backslash;
+ result.id = .MultilineStringLiteralLine;
},
'{' => {
- result.id = Token.Id.LBrace;
+ result.id = .LBrace;
self.index += 1;
break;
},
'}' => {
- result.id = Token.Id.RBrace;
+ result.id = .RBrace;
self.index += 1;
break;
},
'~' => {
- result.id = Token.Id.Tilde;
+ result.id = .Tilde;
self.index += 1;
break;
},
'.' => {
- state = State.Period;
+ state = .period;
},
'-' => {
- state = State.Minus;
+ state = .minus;
},
'/' => {
- state = State.Slash;
+ state = .slash;
},
'&' => {
- state = State.Ampersand;
+ state = .ampersand;
},
'0' => {
- state = State.Zero;
- result.id = Token.Id.IntegerLiteral;
+ state = .zero;
+ result.id = .IntegerLiteral;
},
'1'...'9' => {
- state = State.IntegerLiteralDec;
- result.id = Token.Id.IntegerLiteral;
+ state = .int_literal_dec;
+ result.id = .IntegerLiteral;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
self.index += 1;
break;
},
},
- State.SawAtSign => switch (c) {
+ .saw_at_sign => switch (c) {
'"' => {
- result.id = Token.Id.Identifier;
- state = State.StringLiteral;
+ result.id = .Identifier;
+ state = .string_literal;
},
else => {
// reinterpret as a builtin
self.index -= 1;
- state = State.Builtin;
- result.id = Token.Id.Builtin;
+ state = .builtin;
+ result.id = .Builtin;
},
},
- State.Ampersand => switch (c) {
+ .ampersand => switch (c) {
'&' => {
- result.id = Token.Id.Invalid_ampersands;
+ result.id = .Invalid_ampersands;
self.index += 1;
break;
},
'=' => {
- result.id = Token.Id.AmpersandEqual;
+ result.id = .AmpersandEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Ampersand;
+ result.id = .Ampersand;
break;
},
},
- State.Asterisk => switch (c) {
+ .asterisk => switch (c) {
'=' => {
- result.id = Token.Id.AsteriskEqual;
+ result.id = .AsteriskEqual;
self.index += 1;
break;
},
'*' => {
- result.id = Token.Id.AsteriskAsterisk;
+ result.id = .AsteriskAsterisk;
self.index += 1;
break;
},
'%' => {
- state = State.AsteriskPercent;
+ state = .asterisk_percent;
},
else => {
- result.id = Token.Id.Asterisk;
+ result.id = .Asterisk;
break;
},
},
- State.AsteriskPercent => switch (c) {
+ .asterisk_percent => switch (c) {
'=' => {
- result.id = Token.Id.AsteriskPercentEqual;
+ result.id = .AsteriskPercentEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.AsteriskPercent;
+ result.id = .AsteriskPercent;
break;
},
},
- State.Percent => switch (c) {
+ .percent => switch (c) {
'=' => {
- result.id = Token.Id.PercentEqual;
+ result.id = .PercentEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Percent;
+ result.id = .Percent;
break;
},
},
- State.Plus => switch (c) {
+ .plus => switch (c) {
'=' => {
- result.id = Token.Id.PlusEqual;
+ result.id = .PlusEqual;
self.index += 1;
break;
},
'+' => {
- result.id = Token.Id.PlusPlus;
+ result.id = .PlusPlus;
self.index += 1;
break;
},
'%' => {
- state = State.PlusPercent;
+ state = .plus_percent;
},
else => {
- result.id = Token.Id.Plus;
+ result.id = .Plus;
break;
},
},
- State.PlusPercent => switch (c) {
+ .plus_percent => switch (c) {
'=' => {
- result.id = Token.Id.PlusPercentEqual;
+ result.id = .PlusPercentEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.PlusPercent;
+ result.id = .PlusPercent;
break;
},
},
- State.Caret => switch (c) {
+ .caret => switch (c) {
'=' => {
- result.id = Token.Id.CaretEqual;
+ result.id = .CaretEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Caret;
+ result.id = .Caret;
break;
},
},
- State.Identifier => switch (c) {
+ .identifier => switch (c) {
'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
else => {
if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
@@ -692,19 +692,19 @@ pub const Tokenizer = struct {
break;
},
},
- State.Builtin => switch (c) {
+ .builtin => switch (c) {
'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
else => break,
},
- State.Backslash => switch (c) {
+ .backslash => switch (c) {
'\\' => {
- state = State.MultilineStringLiteralLine;
+ state = .multiline_string_literal_line;
},
else => break,
},
- State.StringLiteral => switch (c) {
+ .string_literal => switch (c) {
'\\' => {
- state = State.StringLiteralBackslash;
+ state = .string_literal_backslash;
},
'"' => {
self.index += 1;
@@ -714,98 +714,98 @@ pub const Tokenizer = struct {
else => self.checkLiteralCharacter(),
},
- State.StringLiteralBackslash => switch (c) {
+ .string_literal_backslash => switch (c) {
'\n', '\r' => break, // Look for this error later.
else => {
- state = State.StringLiteral;
+ state = .string_literal;
},
},
- State.CharLiteral => switch (c) {
+ .char_literal => switch (c) {
'\\' => {
- state = State.CharLiteralBackslash;
+ state = .char_literal_backslash;
},
'\'', 0x80...0xbf, 0xf8...0xff => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
0xc0...0xdf => { // 110xxxxx
remaining_code_units = 1;
- state = State.CharLiteralUnicode;
+ state = .char_literal_unicode;
},
0xe0...0xef => { // 1110xxxx
remaining_code_units = 2;
- state = State.CharLiteralUnicode;
+ state = .char_literal_unicode;
},
0xf0...0xf7 => { // 11110xxx
remaining_code_units = 3;
- state = State.CharLiteralUnicode;
+ state = .char_literal_unicode;
},
else => {
- state = State.CharLiteralEnd;
+ state = .char_literal_end;
},
},
- State.CharLiteralBackslash => switch (c) {
+ .char_literal_backslash => switch (c) {
'\n' => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
'x' => {
- state = State.CharLiteralHexEscape;
+ state = .char_literal_hex_escape;
seen_escape_digits = 0;
},
'u' => {
- state = State.CharLiteralUnicodeEscapeSawU;
+ state = .char_literal_unicode_escape_saw_u;
},
else => {
- state = State.CharLiteralEnd;
+ state = .char_literal_end;
},
},
- State.CharLiteralHexEscape => switch (c) {
+ .char_literal_hex_escape => switch (c) {
'0'...'9', 'a'...'f', 'A'...'F' => {
seen_escape_digits += 1;
if (seen_escape_digits == 2) {
- state = State.CharLiteralEnd;
+ state = .char_literal_end;
}
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.CharLiteralUnicodeEscapeSawU => switch (c) {
+ .char_literal_unicode_escape_saw_u => switch (c) {
'{' => {
- state = State.CharLiteralUnicodeEscape;
+ state = .char_literal_unicode_escape;
seen_escape_digits = 0;
},
else => {
- result.id = Token.Id.Invalid;
- state = State.CharLiteralUnicodeInvalid;
+ result.id = .Invalid;
+ state = .char_literal_unicode_invalid;
},
},
- State.CharLiteralUnicodeEscape => switch (c) {
+ .char_literal_unicode_escape => switch (c) {
'0'...'9', 'a'...'f', 'A'...'F' => {
seen_escape_digits += 1;
},
'}' => {
if (seen_escape_digits == 0) {
- result.id = Token.Id.Invalid;
- state = State.CharLiteralUnicodeInvalid;
+ result.id = .Invalid;
+ state = .char_literal_unicode_invalid;
} else {
- state = State.CharLiteralEnd;
+ state = .char_literal_end;
}
},
else => {
- result.id = Token.Id.Invalid;
- state = State.CharLiteralUnicodeInvalid;
+ result.id = .Invalid;
+ state = .char_literal_unicode_invalid;
},
},
- State.CharLiteralUnicodeInvalid => switch (c) {
+ .char_literal_unicode_invalid => switch (c) {
// Keep consuming characters until an obvious stopping point.
// This consolidates e.g. `u{0ab1Q}` into a single invalid token
// instead of creating the tokens `u{0ab1`, `Q`, `}`
@@ -813,32 +813,32 @@ pub const Tokenizer = struct {
else => break,
},
- State.CharLiteralEnd => switch (c) {
+ .char_literal_end => switch (c) {
'\'' => {
- result.id = Token.Id.CharLiteral;
+ result.id = .CharLiteral;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.CharLiteralUnicode => switch (c) {
+ .char_literal_unicode => switch (c) {
0x80...0xbf => {
remaining_code_units -= 1;
if (remaining_code_units == 0) {
- state = State.CharLiteralEnd;
+ state = .char_literal_end;
}
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.MultilineStringLiteralLine => switch (c) {
+ .multiline_string_literal_line => switch (c) {
'\n' => {
self.index += 1;
break;
@@ -847,449 +847,449 @@ pub const Tokenizer = struct {
else => self.checkLiteralCharacter(),
},
- State.Bang => switch (c) {
+ .bang => switch (c) {
'=' => {
- result.id = Token.Id.BangEqual;
+ result.id = .BangEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Bang;
+ result.id = .Bang;
break;
},
},
- State.Pipe => switch (c) {
+ .pipe => switch (c) {
'=' => {
- result.id = Token.Id.PipeEqual;
+ result.id = .PipeEqual;
self.index += 1;
break;
},
'|' => {
- result.id = Token.Id.PipePipe;
+ result.id = .PipePipe;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Pipe;
+ result.id = .Pipe;
break;
},
},
- State.Equal => switch (c) {
+ .equal => switch (c) {
'=' => {
- result.id = Token.Id.EqualEqual;
+ result.id = .EqualEqual;
self.index += 1;
break;
},
'>' => {
- result.id = Token.Id.EqualAngleBracketRight;
+ result.id = .EqualAngleBracketRight;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Equal;
+ result.id = .Equal;
break;
},
},
- State.Minus => switch (c) {
+ .minus => switch (c) {
'>' => {
- result.id = Token.Id.Arrow;
+ result.id = .Arrow;
self.index += 1;
break;
},
'=' => {
- result.id = Token.Id.MinusEqual;
+ result.id = .MinusEqual;
self.index += 1;
break;
},
'%' => {
- state = State.MinusPercent;
+ state = .minus_percent;
},
else => {
- result.id = Token.Id.Minus;
+ result.id = .Minus;
break;
},
},
- State.MinusPercent => switch (c) {
+ .minus_percent => switch (c) {
'=' => {
- result.id = Token.Id.MinusPercentEqual;
+ result.id = .MinusPercentEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.MinusPercent;
+ result.id = .MinusPercent;
break;
},
},
- State.AngleBracketLeft => switch (c) {
+ .angle_bracket_left => switch (c) {
'<' => {
- state = State.AngleBracketAngleBracketLeft;
+ state = .angle_bracket_angle_bracket_left;
},
'=' => {
- result.id = Token.Id.AngleBracketLeftEqual;
+ result.id = .AngleBracketLeftEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.AngleBracketLeft;
+ result.id = .AngleBracketLeft;
break;
},
},
- State.AngleBracketAngleBracketLeft => switch (c) {
+ .angle_bracket_angle_bracket_left => switch (c) {
'=' => {
- result.id = Token.Id.AngleBracketAngleBracketLeftEqual;
+ result.id = .AngleBracketAngleBracketLeftEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.AngleBracketAngleBracketLeft;
+ result.id = .AngleBracketAngleBracketLeft;
break;
},
},
- State.AngleBracketRight => switch (c) {
+ .angle_bracket_right => switch (c) {
'>' => {
- state = State.AngleBracketAngleBracketRight;
+ state = .angle_bracket_angle_bracket_right;
},
'=' => {
- result.id = Token.Id.AngleBracketRightEqual;
+ result.id = .AngleBracketRightEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.AngleBracketRight;
+ result.id = .AngleBracketRight;
break;
},
},
- State.AngleBracketAngleBracketRight => switch (c) {
+ .angle_bracket_angle_bracket_right => switch (c) {
'=' => {
- result.id = Token.Id.AngleBracketAngleBracketRightEqual;
+ result.id = .AngleBracketAngleBracketRightEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.AngleBracketAngleBracketRight;
+ result.id = .AngleBracketAngleBracketRight;
break;
},
},
- State.Period => switch (c) {
+ .period => switch (c) {
'.' => {
- state = State.Period2;
+ state = .period_2;
},
'*' => {
- result.id = Token.Id.PeriodAsterisk;
+ result.id = .PeriodAsterisk;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Period;
+ result.id = .Period;
break;
},
},
- State.Period2 => switch (c) {
+ .period_2 => switch (c) {
'.' => {
- result.id = Token.Id.Ellipsis3;
+ result.id = .Ellipsis3;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Ellipsis2;
+ result.id = .Ellipsis2;
break;
},
},
- State.Slash => switch (c) {
+ .slash => switch (c) {
'/' => {
- state = State.LineCommentStart;
- result.id = Token.Id.LineComment;
+ state = .line_comment_start;
+ result.id = .LineComment;
},
'=' => {
- result.id = Token.Id.SlashEqual;
+ result.id = .SlashEqual;
self.index += 1;
break;
},
else => {
- result.id = Token.Id.Slash;
+ result.id = .Slash;
break;
},
},
- State.LineCommentStart => switch (c) {
+ .line_comment_start => switch (c) {
'/' => {
- state = State.DocCommentStart;
+ state = .doc_comment_start;
},
'!' => {
- result.id = Token.Id.ContainerDocComment;
- state = State.ContainerDocComment;
+ result.id = .ContainerDocComment;
+ state = .container_doc_comment;
},
'\n' => break,
else => {
- state = State.LineComment;
+ state = .line_comment;
self.checkLiteralCharacter();
},
},
- State.DocCommentStart => switch (c) {
+ .doc_comment_start => switch (c) {
'/' => {
- state = State.LineComment;
+ state = .line_comment;
},
'\n' => {
- result.id = Token.Id.DocComment;
+ result.id = .DocComment;
break;
},
else => {
- state = State.DocComment;
- result.id = Token.Id.DocComment;
+ state = .doc_comment;
+ result.id = .DocComment;
self.checkLiteralCharacter();
},
},
- State.LineComment, State.DocComment, State.ContainerDocComment => switch (c) {
+ .line_comment, .doc_comment, .container_doc_comment => switch (c) {
'\n' => break,
else => self.checkLiteralCharacter(),
},
- State.Zero => switch (c) {
+ .zero => switch (c) {
'b' => {
- state = State.IntegerLiteralBinNoUnderscore;
+ state = .int_literal_bin_no_underscore;
},
'o' => {
- state = State.IntegerLiteralOctNoUnderscore;
+ state = .int_literal_oct_no_underscore;
},
'x' => {
- state = State.IntegerLiteralHexNoUnderscore;
+ state = .int_literal_hex_no_underscore;
},
'0'...'9', '_', '.', 'e', 'E' => {
// reinterpret as a decimal number
self.index -= 1;
- state = State.IntegerLiteralDec;
+ state = .int_literal_dec;
},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.IntegerLiteralBinNoUnderscore => switch (c) {
+ .int_literal_bin_no_underscore => switch (c) {
'0'...'1' => {
- state = State.IntegerLiteralBin;
+ state = .int_literal_bin;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.IntegerLiteralBin => switch (c) {
+ .int_literal_bin => switch (c) {
'_' => {
- state = State.IntegerLiteralBinNoUnderscore;
+ state = .int_literal_bin_no_underscore;
},
'0'...'1' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.IntegerLiteralOctNoUnderscore => switch (c) {
+ .int_literal_oct_no_underscore => switch (c) {
'0'...'7' => {
- state = State.IntegerLiteralOct;
+ state = .int_literal_oct;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.IntegerLiteralOct => switch (c) {
+ .int_literal_oct => switch (c) {
'_' => {
- state = State.IntegerLiteralOctNoUnderscore;
+ state = .int_literal_oct_no_underscore;
},
'0'...'7' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.IntegerLiteralDecNoUnderscore => switch (c) {
+ .int_literal_dec_no_underscore => switch (c) {
'0'...'9' => {
- state = State.IntegerLiteralDec;
+ state = .int_literal_dec;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.IntegerLiteralDec => switch (c) {
+ .int_literal_dec => switch (c) {
'_' => {
- state = State.IntegerLiteralDecNoUnderscore;
+ state = .int_literal_dec_no_underscore;
},
'.' => {
- state = State.NumberDotDec;
- result.id = Token.Id.FloatLiteral;
+ state = .num_dot_dec;
+ result.id = .FloatLiteral;
},
'e', 'E' => {
- state = State.FloatExponentUnsigned;
- result.id = Token.Id.FloatLiteral;
+ state = .float_exponent_unsigned;
+ result.id = .FloatLiteral;
},
'0'...'9' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.IntegerLiteralHexNoUnderscore => switch (c) {
+ .int_literal_hex_no_underscore => switch (c) {
'0'...'9', 'a'...'f', 'A'...'F' => {
- state = State.IntegerLiteralHex;
+ state = .int_literal_hex;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.IntegerLiteralHex => switch (c) {
+ .int_literal_hex => switch (c) {
'_' => {
- state = State.IntegerLiteralHexNoUnderscore;
+ state = .int_literal_hex_no_underscore;
},
'.' => {
- state = State.NumberDotHex;
- result.id = Token.Id.FloatLiteral;
+ state = .num_dot_hex;
+ result.id = .FloatLiteral;
},
'p', 'P' => {
- state = State.FloatExponentUnsigned;
- result.id = Token.Id.FloatLiteral;
+ state = .float_exponent_unsigned;
+ result.id = .FloatLiteral;
},
'0'...'9', 'a'...'f', 'A'...'F' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.NumberDotDec => switch (c) {
+ .num_dot_dec => switch (c) {
'.' => {
self.index -= 1;
- state = State.Start;
+ state = .start;
break;
},
'e', 'E' => {
- state = State.FloatExponentUnsigned;
+ state = .float_exponent_unsigned;
},
'0'...'9' => {
- result.id = Token.Id.FloatLiteral;
- state = State.FloatFractionDec;
+ result.id = .FloatLiteral;
+ state = .float_fraction_dec;
},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.NumberDotHex => switch (c) {
+ .num_dot_hex => switch (c) {
'.' => {
self.index -= 1;
- state = State.Start;
+ state = .start;
break;
},
'p', 'P' => {
- state = State.FloatExponentUnsigned;
+ state = .float_exponent_unsigned;
},
'0'...'9', 'a'...'f', 'A'...'F' => {
- result.id = Token.Id.FloatLiteral;
- state = State.FloatFractionHex;
+ result.id = .FloatLiteral;
+ state = .float_fraction_hex;
},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.FloatFractionDecNoUnderscore => switch (c) {
+ .float_fraction_dec_no_underscore => switch (c) {
'0'...'9' => {
- state = State.FloatFractionDec;
+ state = .float_fraction_dec;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.FloatFractionDec => switch (c) {
+ .float_fraction_dec => switch (c) {
'_' => {
- state = State.FloatFractionDecNoUnderscore;
+ state = .float_fraction_dec_no_underscore;
},
'e', 'E' => {
- state = State.FloatExponentUnsigned;
+ state = .float_exponent_unsigned;
},
'0'...'9' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.FloatFractionHexNoUnderscore => switch (c) {
+ .float_fraction_hex_no_underscore => switch (c) {
'0'...'9', 'a'...'f', 'A'...'F' => {
- state = State.FloatFractionHex;
+ state = .float_fraction_hex;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.FloatFractionHex => switch (c) {
+ .float_fraction_hex => switch (c) {
'_' => {
- state = State.FloatFractionHexNoUnderscore;
+ state = .float_fraction_hex_no_underscore;
},
'p', 'P' => {
- state = State.FloatExponentUnsigned;
+ state = .float_exponent_unsigned;
},
'0'...'9', 'a'...'f', 'A'...'F' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
},
- State.FloatExponentUnsigned => switch (c) {
+ .float_exponent_unsigned => switch (c) {
'+', '-' => {
- state = State.FloatExponentNumberNoUnderscore;
+ state = .float_exponent_num_no_underscore;
},
else => {
// reinterpret as a normal exponent number
self.index -= 1;
- state = State.FloatExponentNumberNoUnderscore;
+ state = .float_exponent_num_no_underscore;
},
},
- State.FloatExponentNumberNoUnderscore => switch (c) {
+ .float_exponent_num_no_underscore => switch (c) {
'0'...'9' => {
- state = State.FloatExponentNumber;
+ state = .float_exponent_num;
},
else => {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
break;
},
},
- State.FloatExponentNumber => switch (c) {
+ .float_exponent_num => switch (c) {
'_' => {
- state = State.FloatExponentNumberNoUnderscore;
+ state = .float_exponent_num_no_underscore;
},
'0'...'9' => {},
else => {
if (isIdentifierChar(c)) {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
}
break;
},
@@ -1297,123 +1297,123 @@ pub const Tokenizer = struct {
}
} else if (self.index == self.buffer.len) {
switch (state) {
- State.Start,
- State.IntegerLiteralDec,
- State.IntegerLiteralBin,
- State.IntegerLiteralOct,
- State.IntegerLiteralHex,
- State.NumberDotDec,
- State.NumberDotHex,
- State.FloatFractionDec,
- State.FloatFractionHex,
- State.FloatExponentNumber,
- State.StringLiteral, // find this error later
- State.MultilineStringLiteralLine,
- State.Builtin,
+ .start,
+ .int_literal_dec,
+ .int_literal_bin,
+ .int_literal_oct,
+ .int_literal_hex,
+ .num_dot_dec,
+ .num_dot_hex,
+ .float_fraction_dec,
+ .float_fraction_hex,
+ .float_exponent_num,
+ .string_literal, // find this error later
+ .multiline_string_literal_line,
+ .builtin,
=> {},
- State.Identifier => {
+ .identifier => {
if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
result.id = id;
}
},
- State.LineCommentStart, State.LineComment => {
- result.id = Token.Id.LineComment;
+ .line_comment, .line_comment_start => {
+ result.id = .LineComment;
},
- State.DocComment, State.DocCommentStart => {
- result.id = Token.Id.DocComment;
+ .doc_comment, .doc_comment_start => {
+ result.id = .DocComment;
},
- State.ContainerDocComment => {
- result.id = Token.Id.ContainerDocComment;
+ .container_doc_comment => {
+ result.id = .ContainerDocComment;
},
- State.IntegerLiteralDecNoUnderscore,
- State.IntegerLiteralBinNoUnderscore,
- State.IntegerLiteralOctNoUnderscore,
- State.IntegerLiteralHexNoUnderscore,
- State.FloatFractionDecNoUnderscore,
- State.FloatFractionHexNoUnderscore,
- State.FloatExponentNumberNoUnderscore,
- State.FloatExponentUnsigned,
- State.SawAtSign,
- State.Backslash,
- State.CharLiteral,
- State.CharLiteralBackslash,
- State.CharLiteralHexEscape,
- State.CharLiteralUnicodeEscapeSawU,
- State.CharLiteralUnicodeEscape,
- State.CharLiteralUnicodeInvalid,
- State.CharLiteralEnd,
- State.CharLiteralUnicode,
- State.StringLiteralBackslash,
+ .int_literal_dec_no_underscore,
+ .int_literal_bin_no_underscore,
+ .int_literal_oct_no_underscore,
+ .int_literal_hex_no_underscore,
+ .float_fraction_dec_no_underscore,
+ .float_fraction_hex_no_underscore,
+ .float_exponent_num_no_underscore,
+ .float_exponent_unsigned,
+ .saw_at_sign,
+ .backslash,
+ .char_literal,
+ .char_literal_backslash,
+ .char_literal_hex_escape,
+ .char_literal_unicode_escape_saw_u,
+ .char_literal_unicode_escape,
+ .char_literal_unicode_invalid,
+ .char_literal_end,
+ .char_literal_unicode,
+ .string_literal_backslash,
=> {
- result.id = Token.Id.Invalid;
+ result.id = .Invalid;
},
- State.Equal => {
- result.id = Token.Id.Equal;
+ .equal => {
+ result.id = .Equal;
},
- State.Bang => {
- result.id = Token.Id.Bang;
+ .bang => {
+ result.id = .Bang;
},
- State.Minus => {
- result.id = Token.Id.Minus;
+ .minus => {
+ result.id = .Minus;
},
- State.Slash => {
- result.id = Token.Id.Slash;
+ .slash => {
+ result.id = .Slash;
},
- State.Zero => {
- result.id = Token.Id.IntegerLiteral;
+ .zero => {
+ result.id = .IntegerLiteral;
},
- State.Ampersand => {
- result.id = Token.Id.Ampersand;
+ .ampersand => {
+ result.id = .Ampersand;
},
- State.Period => {
- result.id = Token.Id.Period;
+ .period => {
+ result.id = .Period;
},
- State.Period2 => {
- result.id = Token.Id.Ellipsis2;
+ .period_2 => {
+ result.id = .Ellipsis2;
},
- State.Pipe => {
- result.id = Token.Id.Pipe;
+ .pipe => {
+ result.id = .Pipe;
},
- State.AngleBracketAngleBracketRight => {
- result.id = Token.Id.AngleBracketAngleBracketRight;
+ .angle_bracket_angle_bracket_right => {
+ result.id = .AngleBracketAngleBracketRight;
},
- State.AngleBracketRight => {
- result.id = Token.Id.AngleBracketRight;
+ .angle_bracket_right => {
+ result.id = .AngleBracketRight;
},
- State.AngleBracketAngleBracketLeft => {
- result.id = Token.Id.AngleBracketAngleBracketLeft;
+ .angle_bracket_angle_bracket_left => {
+ result.id = .AngleBracketAngleBracketLeft;
},
- State.AngleBracketLeft => {
- result.id = Token.Id.AngleBracketLeft;
+ .angle_bracket_left => {
+ result.id = .AngleBracketLeft;
},
- State.PlusPercent => {
- result.id = Token.Id.PlusPercent;
+ .plus_percent => {
+ result.id = .PlusPercent;
},
- State.Plus => {
- result.id = Token.Id.Plus;
+ .plus => {
+ result.id = .Plus;
},
- State.Percent => {
- result.id = Token.Id.Percent;
+ .percent => {
+ result.id = .Percent;
},
- State.Caret => {
- result.id = Token.Id.Caret;
+ .caret => {
+ result.id = .Caret;
},
- State.AsteriskPercent => {
- result.id = Token.Id.AsteriskPercent;
+ .asterisk_percent => {
+ result.id = .AsteriskPercent;
},
- State.Asterisk => {
- result.id = Token.Id.Asterisk;
+ .asterisk => {
+ result.id = .Asterisk;
},
- State.MinusPercent => {
- result.id = Token.Id.MinusPercent;
+ .minus_percent => {
+ result.id = .MinusPercent;
},
}
}
- if (result.id == Token.Id.Eof) {
+ if (result.id == .Eof) {
if (self.pending_invalid_token) |token| {
self.pending_invalid_token = null;
return token;
@@ -1428,8 +1428,8 @@ pub const Tokenizer = struct {
if (self.pending_invalid_token != null) return;
const invalid_length = self.getInvalidCharacterLength();
if (invalid_length == 0) return;
- self.pending_invalid_token = Token{
- .id = Token.Id.Invalid,
+ self.pending_invalid_token = .{
+ .id = .Invalid,
.start = self.index,
.end = self.index + invalid_length,
};
@@ -1474,7 +1474,7 @@ pub const Tokenizer = struct {
};
test "tokenizer" {
- testTokenize("test", &[_]Token.Id{Token.Id.Keyword_test});
+ testTokenize("test", &[_]Token.Id{.Keyword_test});
}
test "tokenizer - unknown length pointer and then c pointer" {
@@ -1482,15 +1482,15 @@ test "tokenizer - unknown length pointer and then c pointer" {
\\[*]u8
\\[*c]u8
, &[_]Token.Id{
- Token.Id.LBracket,
- Token.Id.Asterisk,
- Token.Id.RBracket,
- Token.Id.Identifier,
- Token.Id.LBracket,
- Token.Id.Asterisk,
- Token.Id.Identifier,
- Token.Id.RBracket,
- Token.Id.Identifier,
+ .LBracket,
+ .Asterisk,
+ .RBracket,
+ .Identifier,
+ .LBracket,
+ .Asterisk,
+ .Identifier,
+ .RBracket,
+ .Identifier,
});
}
@@ -1561,125 +1561,125 @@ test "tokenizer - char literal with unicode code point" {
test "tokenizer - float literal e exponent" {
testTokenize("a = 4.94065645841246544177e-324;\n", &[_]Token.Id{
- Token.Id.Identifier,
- Token.Id.Equal,
- Token.Id.FloatLiteral,
- Token.Id.Semicolon,
+ .Identifier,
+ .Equal,
+ .FloatLiteral,
+ .Semicolon,
});
}
test "tokenizer - float literal p exponent" {
testTokenize("a = 0x1.a827999fcef32p+1022;\n", &[_]Token.Id{
- Token.Id.Identifier,
- Token.Id.Equal,
- Token.Id.FloatLiteral,
- Token.Id.Semicolon,
+ .Identifier,
+ .Equal,
+ .FloatLiteral,
+ .Semicolon,
});
}
test "tokenizer - chars" {
- testTokenize("'c'", &[_]Token.Id{Token.Id.CharLiteral});
+ testTokenize("'c'", &[_]Token.Id{.CharLiteral});
}
test "tokenizer - invalid token characters" {
- testTokenize("#", &[_]Token.Id{Token.Id.Invalid});
- testTokenize("`", &[_]Token.Id{Token.Id.Invalid});
- testTokenize("'c", &[_]Token.Id{Token.Id.Invalid});
- testTokenize("'", &[_]Token.Id{Token.Id.Invalid});
- testTokenize("''", &[_]Token.Id{ Token.Id.Invalid, Token.Id.Invalid });
+ testTokenize("#", &[_]Token.Id{.Invalid});
+ testTokenize("`", &[_]Token.Id{.Invalid});
+ testTokenize("'c", &[_]Token.Id{.Invalid});
+ testTokenize("'", &[_]Token.Id{.Invalid});
+ testTokenize("''", &[_]Token.Id{ .Invalid, .Invalid });
}
test "tokenizer - invalid literal/comment characters" {
testTokenize("\"\x00\"", &[_]Token.Id{
- Token.Id.StringLiteral,
- Token.Id.Invalid,
+ .StringLiteral,
+ .Invalid,
});
testTokenize("//\x00", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\x1f", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\x7f", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
}
test "tokenizer - utf8" {
- testTokenize("//\xc2\x80", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{Token.Id.LineComment});
+ testTokenize("//\xc2\x80", &[_]Token.Id{.LineComment});
+ testTokenize("//\xf4\x8f\xbf\xbf", &[_]Token.Id{.LineComment});
}
test "tokenizer - invalid utf8" {
testTokenize("//\x80", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xbf", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xf8", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xff", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xc2\xc0", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xe0", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xf0", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xf0\x90\x80\xc0", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
}
test "tokenizer - illegal unicode codepoints" {
// unicode newline characters.U+0085, U+2028, U+2029
- testTokenize("//\xc2\x84", &[_]Token.Id{Token.Id.LineComment});
+ testTokenize("//\xc2\x84", &[_]Token.Id{.LineComment});
testTokenize("//\xc2\x85", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
- testTokenize("//\xc2\x86", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("//\xe2\x80\xa7", &[_]Token.Id{Token.Id.LineComment});
+ testTokenize("//\xc2\x86", &[_]Token.Id{.LineComment});
+ testTokenize("//\xe2\x80\xa7", &[_]Token.Id{.LineComment});
testTokenize("//\xe2\x80\xa8", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
testTokenize("//\xe2\x80\xa9", &[_]Token.Id{
- Token.Id.LineComment,
- Token.Id.Invalid,
+ .LineComment,
+ .Invalid,
});
- testTokenize("//\xe2\x80\xaa", &[_]Token.Id{Token.Id.LineComment});
+ testTokenize("//\xe2\x80\xaa", &[_]Token.Id{.LineComment});
}
test "tokenizer - string identifier and builtin fns" {
testTokenize(
\\const @"if" = @import("std");
, &[_]Token.Id{
- Token.Id.Keyword_const,
- Token.Id.Identifier,
- Token.Id.Equal,
- Token.Id.Builtin,
- Token.Id.LParen,
- Token.Id.StringLiteral,
- Token.Id.RParen,
- Token.Id.Semicolon,
+ .Keyword_const,
+ .Identifier,
+ .Equal,
+ .Builtin,
+ .LParen,
+ .StringLiteral,
+ .RParen,
+ .Semicolon,
});
}
@@ -1687,26 +1687,26 @@ test "tokenizer - multiline string literal with literal tab" {
testTokenize(
\\\\foo bar
, &[_]Token.Id{
- Token.Id.MultilineStringLiteralLine,
+ .MultilineStringLiteralLine,
});
}
test "tokenizer - pipe and then invalid" {
testTokenize("||=", &[_]Token.Id{
- Token.Id.PipePipe,
- Token.Id.Equal,
+ .PipePipe,
+ .Equal,
});
}
test "tokenizer - line comment and doc comment" {
- testTokenize("//", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("// a / b", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("// /", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("/// a", &[_]Token.Id{Token.Id.DocComment});
- testTokenize("///", &[_]Token.Id{Token.Id.DocComment});
- testTokenize("////", &[_]Token.Id{Token.Id.LineComment});
- testTokenize("//!", &[_]Token.Id{Token.Id.ContainerDocComment});
- testTokenize("//!!", &[_]Token.Id{Token.Id.ContainerDocComment});
+ testTokenize("//", &[_]Token.Id{.LineComment});
+ testTokenize("// a / b", &[_]Token.Id{.LineComment});
+ testTokenize("// /", &[_]Token.Id{.LineComment});
+ testTokenize("/// a", &[_]Token.Id{.DocComment});
+ testTokenize("///", &[_]Token.Id{.DocComment});
+ testTokenize("////", &[_]Token.Id{.LineComment});
+ testTokenize("//!", &[_]Token.Id{.ContainerDocComment});
+ testTokenize("//!!", &[_]Token.Id{.ContainerDocComment});
}
test "tokenizer - line comment followed by identifier" {
@@ -1715,28 +1715,28 @@ test "tokenizer - line comment followed by identifier" {
\\ // another
\\ Another,
, &[_]Token.Id{
- Token.Id.Identifier,
- Token.Id.Comma,
- Token.Id.LineComment,
- Token.Id.Identifier,
- Token.Id.Comma,
+ .Identifier,
+ .Comma,
+ .LineComment,
+ .Identifier,
+ .Comma,
});
}
test "tokenizer - UTF-8 BOM is recognized and skipped" {
testTokenize("\xEF\xBB\xBFa;\n", &[_]Token.Id{
- Token.Id.Identifier,
- Token.Id.Semicolon,
+ .Identifier,
+ .Semicolon,
});
}
test "correctly parse pointer assignment" {
testTokenize("b.*=3;\n", &[_]Token.Id{
- Token.Id.Identifier,
- Token.Id.PeriodAsterisk,
- Token.Id.Equal,
- Token.Id.IntegerLiteral,
- Token.Id.Semicolon,
+ .Identifier,
+ .PeriodAsterisk,
+ .Equal,
+ .IntegerLiteral,
+ .Semicolon,
});
}
@@ -1979,5 +1979,5 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
}
}
const last_token = tokenizer.next();
- std.testing.expect(last_token.id == Token.Id.Eof);
+ std.testing.expect(last_token.id == .Eof);
}
From ad71d959d7d1b5f3a771dc2c1eaf37dbd7cd0852 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 23:28:04 +0300
Subject: [PATCH 66/74] correctly recover from invalid top level declarations
---
lib/std/zig/parse.zig | 20 +++++++++++++-------
lib/std/zig/parser_test.zig | 22 ++++++++++++++++++++++
2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 6052d92d6a..d8d1d4b427 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -130,7 +130,13 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
const visib_token = eatToken(it, .Keyword_pub);
- if (try parseTopLevelDecl(arena, it, tree)) |node| {
+ if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
+ error.OutOfMemory => return error.OutOfMemory,
+ error.ParseError => {
+ // try again
+ continue;
+ },
+ }) |node| {
if (field_state == .seen) {
field_state = .{ .end = visib_token orelse node.firstToken() };
}
@@ -315,7 +321,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
/// / KEYWORD_usingnamespace Expr SEMICOLON
-fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!?*Node {
+fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
var lib_name: ?*Node = null;
const extern_export_inline_token = blk: {
if (eatToken(it, .Keyword_export)) |token| break :blk token;
@@ -334,7 +340,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocat
// this fn will likely have a body so we
// use findEndOfBlock instead of findToken.
findEndOfBlock(it);
- return null;
+ return error.ParseError;
},
}) |node| {
const fn_node = node.cast(Node.FnProto).?;
@@ -373,7 +379,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocat
error.ParseError => {
// try to skip to next decl
findToken(it, .Semicolon);
- return null;
+ return error.ParseError;
},
}) |node| {
var var_decl = node.cast(Node.VarDecl).?;
@@ -388,8 +394,8 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocat
try tree.errors.push(.{
.ExpectedVarDecl = .{ .token = it.index },
});
- // ignore this, try to find next decl by skipping the next block
- findEndOfBlock(it);
+ // ignore this and try again;
+ return error.ParseError;
}
if (extern_export_inline_token) |token| {
@@ -404,7 +410,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocat
error.ParseError => {
// try to skip to next decl
findToken(it, .Semicolon);
- return null;
+ return error.ParseError;
},
};
}
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index e3bc20bd10..7ddf9cc9c8 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -62,6 +62,28 @@ test "recovery: missing return type" {
});
}
+test "recovery: continue after invalid decl" {
+ try testError(
+ \\fn foo {
+ \\ inline;
+ \\}
+ \\test "" {
+ \\ a && b;
+ \\}
+ , &[_]Error{
+ .ExpectedToken,
+ .InvalidAnd,
+ });
+ try testError(
+ \\threadlocal test "" {
+ \\ a && b;
+ \\}
+ , &[_]Error{
+ .ExpectedVarDecl,
+ .InvalidAnd,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
From 1f81887a7863545d8b89bff6cc7d31941da0abf0 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Wed, 13 May 2020 23:35:58 +0300
Subject: [PATCH 67/74] recover after invalid inline/extern
---
lib/std/zig/ast.zig | 4 ++++
lib/std/zig/parse.zig | 17 ++++++++++-------
lib/std/zig/parser_test.zig | 15 +++++++++++++++
3 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index afb7fce23e..26bff31bbd 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -129,6 +129,7 @@ pub const Error = union(enum) {
ExpectedStatement: ExpectedStatement,
ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
ExpectedVarDecl: ExpectedVarDecl,
+ ExpectedFn: ExpectedFn,
ExpectedReturnType: ExpectedReturnType,
ExpectedAggregateKw: ExpectedAggregateKw,
UnattachedDocComment: UnattachedDocComment,
@@ -179,6 +180,7 @@ pub const Error = union(enum) {
.ExpectedStatement => |*x| return x.render(tokens, stream),
.ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
.ExpectedVarDecl => |*x| return x.render(tokens, stream),
+ .ExpectedFn => |*x| return x.render(tokens, stream),
.ExpectedReturnType => |*x| return x.render(tokens, stream),
.ExpectedAggregateKw => |*x| return x.render(tokens, stream),
.UnattachedDocComment => |*x| return x.render(tokens, stream),
@@ -231,6 +233,7 @@ pub const Error = union(enum) {
.ExpectedStatement => |x| return x.token,
.ExpectedVarDeclOrFn => |x| return x.token,
.ExpectedVarDecl => |x| return x.token,
+ .ExpectedFn => |x| return x.token,
.ExpectedReturnType => |x| return x.token,
.ExpectedAggregateKw => |x| return x.token,
.UnattachedDocComment => |x| return x.token,
@@ -280,6 +283,7 @@ pub const Error = union(enum) {
pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
+ pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index d8d1d4b427..cbd5336ca2 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -360,15 +360,17 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
try tree.errors.push(.{
.ExpectedSemiOrLBrace = .{ .token = it.index },
});
- return null;
+ return error.ParseError;
}
if (extern_export_inline_token) |token| {
if (tree.tokens.at(token).id == .Keyword_inline or
tree.tokens.at(token).id == .Keyword_noinline)
{
- putBackToken(it, token);
- return null;
+ try tree.errors.push(.{
+ .ExpectedFn = .{ .token = it.index },
+ });
+ return error.ParseError;
}
}
@@ -399,10 +401,11 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
}
if (extern_export_inline_token) |token| {
- if (lib_name) |string_literal_node|
- putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);
- putBackToken(it, token);
- return null;
+ try tree.errors.push(.{
+ .ExpectedVarDeclOrFn = .{ .token = it.index },
+ });
+ // ignore this and try again;
+ return error.ParseError;
}
return parseUse(arena, it, tree) catch |err| switch (err) {
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 7ddf9cc9c8..d837769802 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -84,6 +84,21 @@ test "recovery: continue after invalid decl" {
});
}
+test "recovery: invalid extern/inline" {
+ try testError(
+ \\inline test "" { a && b; }
+ , &[_]Error{
+ .ExpectedFn,
+ .InvalidAnd,
+ });
+ try testError(
+ \\extern "" test "" { a && b; }
+ , &[_]Error{
+ .ExpectedVarDeclOrFn,
+ .InvalidAnd,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
From c3b76d091337ba60d2ccb3632b525e5a42d1f2c5 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 00:16:56 +0300
Subject: [PATCH 68/74] recover from invalid builtin/async call
---
lib/std/zig/ast.zig | 1 +
lib/std/zig/parse.zig | 18 +++++++++++++-----
lib/std/zig/parser_test.zig | 9 ++++++---
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 26bff31bbd..6fb1ce012b 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -926,6 +926,7 @@ pub const Node = struct {
if (i < 1) return node;
i -= 1;
},
+ .Invalid => unreachable,
}
if (self.body_node) |body_node| {
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index cbd5336ca2..6c664bbda2 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -172,6 +172,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
.ExpectedPubItem = .{ .token = it.index },
});
// ignore this pub
+ continue;
}
if (parseContainerField(arena, it, tree) catch |err| switch (err) {
@@ -1017,7 +1018,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
const node = try arena.create(Node.ControlFlowExpression);
node.* = .{
.ltoken = token,
- .kind = Node.ControlFlowExpression.Kind{ .Break = label },
+ .kind = .{ .Break = label },
.rhs = expr_node,
};
return &node.base;
@@ -1053,7 +1054,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
const node = try arena.create(Node.ControlFlowExpression);
node.* = .{
.ltoken = token,
- .kind = Node.ControlFlowExpression.Kind{ .Continue = label },
+ .kind = .{ .Continue = label },
.rhs = null,
};
return &node.base;
@@ -1077,7 +1078,7 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
const node = try arena.create(Node.ControlFlowExpression);
node.* = .{
.ltoken = token,
- .kind = Node.ControlFlowExpression.Kind.Return,
+ .kind = .Return,
.rhs = expr_node,
};
return &node.base;
@@ -1322,7 +1323,8 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
try tree.errors.push(.{
.ExpectedParamList = .{ .token = it.index },
});
- return null;
+ // ignore this, continue parsing
+ return res;
};
const node = try arena.create(Node.SuffixOp);
node.* = .{
@@ -2908,7 +2910,13 @@ fn parseBuiltinCall(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
try tree.errors.push(.{
.ExpectedParamList = .{ .token = it.index },
});
- return error.ParseError;
+
+ // lets pretend this was an identifier so we can continue parsing
+ const node = try arena.create(Node.Identifier);
+ node.* = .{
+ .token = token,
+ };
+ return &node.base;
};
const node = try arena.create(Node.BuiltinCall);
node.* = .{
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index d837769802..34c61b6bb4 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -67,19 +67,22 @@ test "recovery: continue after invalid decl" {
\\fn foo {
\\ inline;
\\}
- \\test "" {
- \\ a && b;
+ \\pub test "" {
+ \\ async a && b;
\\}
, &[_]Error{
.ExpectedToken,
+ .ExpectedPubItem,
+ .ExpectedParamList,
.InvalidAnd,
});
try testError(
\\threadlocal test "" {
- \\ a && b;
+ \\ @a && b;
\\}
, &[_]Error{
.ExpectedVarDecl,
+ .ExpectedParamList,
.InvalidAnd,
});
}
From ac319b27348f60e37f3f1b478fee00202280715f Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 11:19:14 +0300
Subject: [PATCH 69/74] remove useless nosuspend parsing
nosuspend cannot be used in a type expression and
all other use casesare covered by PrimaryExpr
---
doc/langref.html.in | 3 +++
lib/std/zig/parse.zig | 10 ----------
src/parser.cpp | 9 ---------
3 files changed, 3 insertions(+), 19 deletions(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 5bf91ca70f..0733540478 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -10096,6 +10096,7 @@ ContainerField <- IDENTIFIER (COLON TypeExpr)? (EQUAL Expr)?
Statement
<- KEYWORD_comptime? VarDecl
/ KEYWORD_comptime BlockExprStatement
+ / KEYWORD_nosuspend BlockExprStatement
/ KEYWORD_suspend (SEMICOLON / BlockExprStatement)
/ KEYWORD_defer BlockExprStatement
/ KEYWORD_errdefer BlockExprStatement
@@ -10152,6 +10153,7 @@ PrimaryExpr
/ IfExpr
/ KEYWORD_break BreakLabel? Expr?
/ KEYWORD_comptime Expr
+ / KEYWORD_nosuspend Expr
/ KEYWORD_continue BreakLabel?
/ KEYWORD_resume Expr
/ KEYWORD_return Expr?
@@ -10514,6 +10516,7 @@ KEYWORD_for <- 'for' end_of_word
KEYWORD_if <- 'if' end_of_word
KEYWORD_inline <- 'inline' end_of_word
KEYWORD_noalias <- 'noalias' end_of_word
+KEYWORD_nosuspend <- 'nosuspend' end_of_word
KEYWORD_null <- 'null' end_of_word
KEYWORD_or <- 'or' end_of_word
KEYWORD_orelse <- 'orelse' end_of_word
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 6c664bbda2..c16dba4a11 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -1389,7 +1389,6 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / IfTypeExpr
/// / INTEGER
/// / KEYWORD_comptime TypeExpr
-/// / KEYWORD_nosuspend TypeExpr
/// / KEYWORD_error DOT IDENTIFIER
/// / KEYWORD_false
/// / KEYWORD_null
@@ -1428,15 +1427,6 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
};
return &node.base;
}
- if (eatToken(it, .Keyword_nosuspend)) |token| {
- const expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
- const node = try arena.create(Node.Nosuspend);
- node.* = .{
- .nosuspend_token = token,
- .expr = expr,
- };
- return &node.base;
- }
if (eatToken(it, .Keyword_error)) |token| {
const period = try expectToken(it, tree, .Period);
const identifier = try expectNode(arena, it, tree, parseIdentifier, .{
diff --git a/src/parser.cpp b/src/parser.cpp
index 1a929cd1b1..fc9814f393 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1609,7 +1609,6 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// / IfTypeExpr
// / INTEGER
// / KEYWORD_comptime TypeExpr
-// / KEYWORD_nosuspend TypeExpr
// / KEYWORD_error DOT IDENTIFIER
// / KEYWORD_false
// / KEYWORD_null
@@ -1711,14 +1710,6 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
return res;
}
- Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
- if (nosuspend != nullptr) {
- AstNode *expr = ast_expect(pc, ast_parse_type_expr);
- AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
- res->data.nosuspend_expr.expr = expr;
- return res;
- }
-
Token *error = eat_token_if(pc, TokenIdKeywordError);
if (error != nullptr) {
Token *dot = expect_token(pc, TokenIdDot);
From 89f2923a8aad5119b1506c3b8e08464e132c228e Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 11:19:50 +0300
Subject: [PATCH 70/74] recover from missing semicolon
---
lib/std/zig/parse.zig | 16 +++++++++++++---
lib/std/zig/parser_test.zig | 17 +++++++++++++++++
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index c16dba4a11..24bb164685 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -667,7 +667,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
if (try parseLabeledStatement(arena, it, tree)) |node| return node;
if (try parseSwitchExpr(arena, it, tree)) |node| return node;
if (try parseAssignExpr(arena, it, tree)) |node| {
- _ = try expectToken(it, tree, .Semicolon);
+ _ = eatToken(it, .Semicolon) orelse {
+ try tree.errors.push(.{
+ .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
+ });
+ // pretend we saw a semicolon and continue parsing
+ };
return node;
}
@@ -911,7 +916,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
if (try parseBlockExpr(arena, it, tree)) |node| return node;
if (try parseAssignExpr(arena, it, tree)) |node| {
- _ = try expectToken(it, tree, .Semicolon);
+ _ = eatToken(it, .Semicolon) orelse {
+ try tree.errors.push(.{
+ .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
+ });
+ // pretend we saw a semicolon and continue parsing
+ };
return node;
}
return null;
@@ -3072,7 +3082,7 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D
}
/// Eat a single-line doc comment on the same line as another node
-fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) Allocator.Error!?*Node.DocComment {
+fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) !?*Node.DocComment {
const comment_token = eatToken(it, .DocComment) orelse return null;
if (tree.tokensOnSameLine(after_token, comment_token)) {
const node = try arena.create(Node.DocComment);
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 34c61b6bb4..a367c2ff0b 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -102,6 +102,23 @@ test "recovery: invalid extern/inline" {
});
}
+test "recovery: missing semicolon" {
+ try testError(
+ \\test "" {
+ \\ comptime a && b
+ \\ c && d
+ \\ @foo
+ \\}
+ , &[_]Error{
+ .InvalidAnd,
+ .ExpectedToken,
+ .InvalidAnd,
+ .ExpectedToken,
+ .ExpectedParamList,
+ .ExpectedToken,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
From a32e240540895af536fdeb98db448ee745def59a Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 12:09:40 +0300
Subject: [PATCH 71/74] improve recovery from invalid container members
Instead of trying to find the end of the block or the next comma/semicolon
we no try to find the next token that can start a container member.
---
lib/std/zig/parse.zig | 98 +++++++++++++++++++++++++++++--------
lib/std/zig/parser_test.zig | 21 ++++++++
2 files changed, 99 insertions(+), 20 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 24bb164685..b4b80669a1 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -59,10 +59,13 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
node.* = .{
.decls = try parseContainerMembers(arena, it, tree),
.eof_token = eatToken(it, .Eof) orelse blk: {
+ // parseContainerMembers will try to skip as much
+ // invalid tokens as it can so this can only be a '}'
+ const tok = eatToken(it, .RBrace).?;
try tree.errors.push(.{
- .ExpectedContainerMembers = .{ .token = it.index },
+ .ExpectedContainerMembers = .{ .token = tok },
});
- break :blk undefined;
+ break :blk tok;
},
};
return node;
@@ -101,7 +104,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
if (parseTestDecl(arena, it, tree) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
- findEndOfBlock(it);
+ findNextContainerMember(it);
continue;
},
}) |node| {
@@ -116,7 +119,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
if (parseTopLevelComptime(arena, it, tree) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
- findEndOfBlock(it);
+ findNextContainerMember(it);
continue;
},
}) |node| {
@@ -178,8 +181,8 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
if (parseContainerField(arena, it, tree) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
- // attempt to recover by finding a comma
- findToken(it, .Comma);
+ // attempt to recover
+ findNextContainerMember(it);
continue;
},
}) |node| {
@@ -198,7 +201,21 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
const field = node.cast(Node.ContainerField).?;
field.doc_comments = doc_comments;
try list.push(node);
- const comma = eatToken(it, .Comma) orelse break;
+ const comma = eatToken(it, .Comma) orelse {
+ // try to continue parsing
+ const index = it.index;
+ findNextContainerMember(it);
+ switch (it.peek().?.id) {
+ .Eof, .RBrace => break,
+ else => {
+ // add error and continue
+ try tree.errors.push(.{
+ .ExpectedToken = .{ .token = index, .expected_id = .Comma },
+ });
+ continue;
+ }
+ }
+ };
if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|
field.doc_comments = appended_comment;
continue;
@@ -210,22 +227,63 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
.UnattachedDocComment = .{ .token = doc_comments.?.firstToken() },
});
}
- break;
+
+ switch (it.peek().?.id) {
+ .Eof, .RBrace => break,
+ else => {
+ // this was likely not supposed to end yet,
+ // try to find the next declaration
+ const index = it.index;
+ findNextContainerMember(it);
+ try tree.errors.push(.{
+ .ExpectedContainerMembers = .{ .token = index },
+ });
+ },
+ }
}
return list;
}
-/// Attempts to find a closing brace.
-fn findEndOfBlock(it: *TokenIterator) void {
- var count: u32 = 0;
+fn findNextContainerMember(it: *TokenIterator) void {
+ var level: u32 = 0;
while (true) {
const tok = nextToken(it);
switch (tok.ptr.id) {
- .LBrace => count += 1,
- .RBrace => {
- if (count <= 1) return;
- count -= 1;
+ // any of these can start a new top level declaration
+ .Keyword_test,
+ .Keyword_comptime,
+ .Keyword_pub,
+ .Keyword_export,
+ .Keyword_extern,
+ .Keyword_inline,
+ .Keyword_noinline,
+ .Keyword_usingnamespace,
+ .Keyword_threadlocal,
+ .Keyword_const,
+ .Keyword_var,
+ .Keyword_fn,
+ .Identifier,
+ => {
+ if (level == 0) {
+ putBackToken(it, tok.index);
+ return;
+ }
+ },
+ .Comma, .Semicolon => {
+ // this decl was likely meant to end here
+ if (level == 0) {
+ return;
+ }
+ },
+ .LParen, .LBracket, .LBrace => level += 1,
+ .RParen, .RBracket, .RBrace => {
+ if (level == 0) {
+ // end of container, exit
+ putBackToken(it, tok.index);
+ return;
+ }
+ level -= 1;
},
.Eof => {
putBackToken(it, tok.index);
@@ -338,9 +396,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
if (parseFnProto(arena, it, tree) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
- // this fn will likely have a body so we
- // use findEndOfBlock instead of findToken.
- findEndOfBlock(it);
+ findNextContainerMember(it);
return error.ParseError;
},
}) |node| {
@@ -381,7 +437,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
// try to skip to next decl
- findToken(it, .Semicolon);
+ findNextContainerMember(it);
return error.ParseError;
},
}) |node| {
@@ -413,7 +469,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
// try to skip to next decl
- findToken(it, .Semicolon);
+ findNextContainerMember(it);
return error.ParseError;
},
};
@@ -3215,6 +3271,8 @@ fn expectToken(it: *TokenIterator, tree: *Tree, id: Token.Id) Error!TokenIndex {
try tree.errors.push(.{
.ExpectedToken = .{ .token = token.index, .expected_id = id },
});
+ // go back so that we can recover properly
+ putBackToken(it, token.index);
return error.ParseError;
}
return token.index;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index a367c2ff0b..8cbf2d4610 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -119,6 +119,25 @@ test "recovery: missing semicolon" {
});
}
+test "recovery: invalid container members" {
+ try testError(
+ \\usingnamespace;
+ \\foo+
+ \\bar@,
+ \\while (a == 2) { test "" {}}
+ \\test "" {
+ \\ a && b
+ \\}
+ , &[_]Error{
+ .ExpectedExpr,
+ .ExpectedToken,
+ .ExpectedToken,
+ .ExpectedContainerMembers,
+ .InvalidAnd,
+ .ExpectedToken,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
@@ -2953,6 +2972,8 @@ test "zig fmt: extern without container keyword returns error" {
\\
, &[_]Error{
.ExpectedExpr,
+ .ExpectedVarDeclOrFn,
+ .ExpectedContainerMembers,
});
}
From c4552ee8edec961defb161e1b828a818f8d407bb Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 17:18:14 +0300
Subject: [PATCH 72/74] store rparen in ReturnType.Invalid
This is useful for getting a partial function signature
---
lib/std/zig/ast.zig | 2 +-
lib/std/zig/parse.zig | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 6fb1ce012b..351162bec0 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -897,7 +897,7 @@ pub const Node = struct {
pub const ReturnType = union(enum) {
Explicit: *Node,
InferErrorSet: *Node,
- Invalid,
+ Invalid: TokenIndex,
};
pub fn iterate(self: *FnProto, index: usize) ?*Node {
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index b4b80669a1..98b1e9d329 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -518,7 +518,7 @@ fn parseFnProto(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
// TODO https://github.com/ziglang/zig/issues/3750
const R = Node.FnProto.ReturnType;
const return_type = if (return_type_expr == null)
- R{ .Invalid = {} }
+ R{ .Invalid = rparen }
else if (exclamation_token != null)
R{ .InferErrorSet = return_type_expr.? }
else
From c77fee03448817366a2cda98915bc31ba8f2b451 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Thu, 14 May 2020 19:56:55 +0300
Subject: [PATCH 73/74] fix infinite loop
findToken wasn't as generic as I thought it was
---
lib/std/zig/parse.zig | 28 ++++++++++++++++------------
lib/std/zig/parser_test.zig | 10 ++++++++++
2 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 98b1e9d329..74945b1b33 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -213,7 +213,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
.ExpectedToken = .{ .token = index, .expected_id = .Comma },
});
continue;
- }
+ },
}
};
if (try parseAppendedDocComment(arena, it, tree, comma)) |appended_comment|
@@ -245,6 +245,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
return list;
}
+/// Attempts to find next container member by searching for certain tokens
fn findNextContainerMember(it: *TokenIterator) void {
var level: u32 = 0;
while (true) {
@@ -294,27 +295,30 @@ fn findNextContainerMember(it: *TokenIterator) void {
}
}
-/// Attempts to find `wanted` token, keeps track of parentheses.
-fn findToken(it: *TokenIterator, wanted: Token.Id) void {
- var count: u32 = 0;
+/// Attempts to find the next statement by searching for a semicolon
+fn findNextStmt(it: *TokenIterator) void {
+ var level: u32 = 0;
while (true) {
const tok = nextToken(it);
switch (tok.ptr.id) {
- .LParen, .LBracket, .LBrace => count += 1,
- .RParen, .RBracket, .RBrace => {
- if (count == 0) {
+ .LBrace => level += 1,
+ .RBrace => {
+ if (level == 0) {
putBackToken(it, tok.index);
return;
}
- count -= 1;
+ level -= 1;
+ },
+ .Semicolon => {
+ if (level == 0) {
+ return;
+ }
},
.Eof => {
putBackToken(it, tok.index);
return;
},
- else => {
- if (tok.ptr.id == wanted and count == 0) return;
- },
+ else => {},
}
}
}
@@ -1186,7 +1190,7 @@ fn parseBlock(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
// try to skip to the next statement
- findToken(it, .Semicolon);
+ findNextStmt(it);
continue;
},
}) orelse break;
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index 8cbf2d4610..f92cc5a222 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -138,6 +138,16 @@ test "recovery: invalid container members" {
});
}
+test "recovery: invalid parameter" {
+ try testError(
+ \\fn main() void {
+ \\ a(comptime T: type)
+ \\}
+ , &[_]Error{
+ .ExpectedToken,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,
From 440189a04ae4baa4a20114fe1d30f0eb585bacc4 Mon Sep 17 00:00:00 2001
From: Vexu
Date: Fri, 15 May 2020 11:06:34 +0300
Subject: [PATCH 74/74] cleanup* remove unecessary error* properly handle
ReturnTypeInvalid in ast.zig functions* assert that the tree is clean in
render.zig* simplify parser recovery with top level decls
---
lib/std/zig/ast.zig | 8 ++------
lib/std/zig/parse.zig | 38 +++++++++----------------------------
lib/std/zig/parser_test.zig | 5 ++---
lib/std/zig/render.zig | 3 +++
4 files changed, 16 insertions(+), 38 deletions(-)
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 351162bec0..b1441d5b25 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -166,7 +166,6 @@ pub const Error = union(enum) {
ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
ExpectedSuffixOp: ExpectedSuffixOp,
DeclBetweenFields: DeclBetweenFields,
- MissingComma: MissingComma,
InvalidAnd: InvalidAnd,
pub fn render(self: *const Error, tokens: *Tree.TokenList, stream: var) !void {
@@ -217,7 +216,6 @@ pub const Error = union(enum) {
.ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),
.ExpectedSuffixOp => |*x| return x.render(tokens, stream),
.DeclBetweenFields => |*x| return x.render(tokens, stream),
- .MissingComma => |*x| return x.render(tokens, stream),
.InvalidAnd => |*x| return x.render(tokens, stream),
}
}
@@ -270,7 +268,6 @@ pub const Error = union(enum) {
.ExpectedDerefOrUnwrap => |x| return x.token,
.ExpectedSuffixOp => |x| return x.token,
.DeclBetweenFields => |x| return x.token,
- .MissingComma => |x| return x.token,
.InvalidAnd => |x| return x.token,
}
}
@@ -318,7 +315,6 @@ pub const Error = union(enum) {
pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
- pub const MissingComma = SimpleError("Expected comma between items");
pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
pub const ExpectedCall = struct {
@@ -926,7 +922,7 @@ pub const Node = struct {
if (i < 1) return node;
i -= 1;
},
- .Invalid => unreachable,
+ .Invalid => {},
}
if (self.body_node) |body_node| {
@@ -948,7 +944,7 @@ pub const Node = struct {
if (self.body_node) |body_node| return body_node.lastToken();
switch (self.return_type) {
.Explicit, .InferErrorSet => |node| return node.lastToken(),
- .Invalid => unreachable,
+ .Invalid => |tok| return tok,
}
}
};
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 74945b1b33..a269dc616c 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -78,7 +78,7 @@ fn parseRoot(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error
/// / KEYWORD_pub? ContainerField COMMA ContainerMembers
/// / KEYWORD_pub? ContainerField
/// /
-fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!Node.Root.DeclList {
+fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) !Node.Root.DeclList {
var list = Node.Root.DeclList.init(arena);
var field_state: union(enum) {
@@ -136,7 +136,7 @@ fn parseContainerMembers(arena: *Allocator, it: *TokenIterator, tree: *Tree) All
if (parseTopLevelDecl(arena, it, tree) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
error.ParseError => {
- // try again
+ findNextContainerMember(it);
continue;
},
}) |node| {
@@ -324,7 +324,7 @@ fn findNextStmt(it: *TokenIterator) void {
}
/// Eat a multiline container doc comment
-fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) Allocator.Error!?*Node {
+fn parseContainerDocComments(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
var lines = Node.DocComment.LineList.init(arena);
while (eatToken(it, .ContainerDocComment)) |line| {
try lines.push(line);
@@ -384,7 +384,7 @@ fn parseTopLevelComptime(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*
/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / (KEYWORD_inline / KEYWORD_noinline))? FnProto (SEMICOLON / Block)
/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
/// / KEYWORD_usingnamespace Expr SEMICOLON
-fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*Node {
+fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
var lib_name: ?*Node = null;
const extern_export_inline_token = blk: {
if (eatToken(it, .Keyword_export)) |token| break :blk token;
@@ -397,13 +397,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
break :blk null;
};
- if (parseFnProto(arena, it, tree) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.ParseError => {
- findNextContainerMember(it);
- return error.ParseError;
- },
- }) |node| {
+ if (try parseFnProto(arena, it, tree)) |node| {
const fn_node = node.cast(Node.FnProto).?;
fn_node.*.extern_export_inline_token = extern_export_inline_token;
fn_node.*.lib_name = lib_name;
@@ -413,7 +407,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
// since parseBlock only return error.ParseError on
// a missing '}' we can assume this function was
// supposed to end here.
- error.ParseError => null,
+ error.ParseError => return node,
}) |body_node| {
fn_node.body_node = body_node;
return node;
@@ -437,14 +431,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
const thread_local_token = eatToken(it, .Keyword_threadlocal);
- if (parseVarDecl(arena, it, tree) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.ParseError => {
- // try to skip to next decl
- findNextContainerMember(it);
- return error.ParseError;
- },
- }) |node| {
+ if (try parseVarDecl(arena, it, tree)) |node| {
var var_decl = node.cast(Node.VarDecl).?;
var_decl.*.thread_local_token = thread_local_token;
var_decl.*.comptime_token = null;
@@ -469,14 +456,7 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
return error.ParseError;
}
- return parseUse(arena, it, tree) catch |err| switch (err) {
- error.OutOfMemory => return error.OutOfMemory,
- error.ParseError => {
- // try to skip to next decl
- findNextContainerMember(it);
- return error.ParseError;
- },
- };
+ return try parseUse(arena, it, tree);
}
/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
@@ -2926,7 +2906,7 @@ fn ListParseFn(comptime L: type, comptime nodeParseFn: var) ParseFn(L) {
// this is likely just a missing comma,
// continue parsing this list and give an error
try tree.errors.push(.{
- .MissingComma = .{ .token = it.index },
+ .ExpectedToken = .{ .token = it.index, .expected_id = .Comma },
});
},
}
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index f92cc5a222..6adc44a5b7 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -32,8 +32,8 @@ test "recovery: missing comma" {
\\ }
\\}
, &[_]Error{
- .MissingComma,
- .MissingComma,
+ .ExpectedToken,
+ .ExpectedToken,
.InvalidAnd,
.InvalidToken,
});
@@ -2983,7 +2983,6 @@ test "zig fmt: extern without container keyword returns error" {
, &[_]Error{
.ExpectedExpr,
.ExpectedVarDeclOrFn,
- .ExpectedContainerMembers,
});
}
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index 64f2f77f6c..9ca6d4450c 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -13,6 +13,9 @@ pub const Error = error{
/// Returns whether anything changed
pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Error || Error)!bool {
+ // cannot render an invalid tree
+ std.debug.assert(tree.errors.len == 0);
+
// make a passthrough stream that checks whether something changed
const MyStream = struct {
const MyStream = @This();