Merge pull request #5272 from tadeokondrak/noasync-to-nosuspend

Noasync to nosuspend
This commit is contained in:
Andrew Kelley 2020-05-05 11:21:02 -04:00 committed by GitHub
commit e6955688ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 233 additions and 208 deletions

View File

@ -802,8 +802,8 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
.Keyword_inline, .Keyword_inline,
.Keyword_nakedcc, .Keyword_nakedcc,
.Keyword_noalias, .Keyword_noalias,
.Keyword_noasync,
.Keyword_noinline, .Keyword_noinline,
.Keyword_nosuspend,
.Keyword_or, .Keyword_or,
.Keyword_orelse, .Keyword_orelse,
.Keyword_packed, .Keyword_packed,

View File

@ -62,7 +62,7 @@ pub fn warn(comptime fmt: []const u8, args: var) void {
const held = stderr_mutex.acquire(); const held = stderr_mutex.acquire();
defer held.release(); defer held.release();
const stderr = getStderrStream(); const stderr = getStderrStream();
noasync stderr.print(fmt, args) catch return; nosuspend stderr.print(fmt, args) catch return;
} }
pub fn getStderrStream() *File.OutStream { 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. /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness /// TODO multithreaded awareness
pub fn dumpCurrentStackTrace(start_addr: ?usize) void { pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
noasync { nosuspend {
const stderr = getStderrStream(); const stderr = getStderrStream();
if (builtin.strip_debug_info) { if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; 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. /// unbuffered, and ignores any error returned.
/// TODO multithreaded awareness /// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
noasync { nosuspend {
const stderr = getStderrStream(); const stderr = getStderrStream();
if (builtin.strip_debug_info) { if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; 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. /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
/// TODO multithreaded awareness /// TODO multithreaded awareness
pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
noasync { nosuspend {
const stderr = getStderrStream(); const stderr = getStderrStream();
if (builtin.strip_debug_info) { if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; 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(); resetSegfaultHandler();
} }
noasync switch (panic_stage) { nosuspend switch (panic_stage) {
0 => { 0 => {
panic_stage = 1; panic_stage = 1;
@ -447,7 +447,7 @@ pub const TTY = struct {
windows_api, windows_api,
fn setColor(conf: Config, out_stream: var, color: Color) void { fn setColor(conf: Config, out_stream: var, color: Color) void {
noasync switch (conf) { nosuspend switch (conf) {
.no_color => return, .no_color => return,
.escape_codes => switch (color) { .escape_codes => switch (color) {
.Red => out_stream.writeAll(RED) catch return, .Red => out_stream.writeAll(RED) catch return,
@ -604,7 +604,7 @@ fn printLineInfo(
tty_config: TTY.Config, tty_config: TTY.Config,
comptime printLineFromFile: var, comptime printLineFromFile: var,
) !void { ) !void {
noasync { nosuspend {
tty_config.setColor(out_stream, .White); tty_config.setColor(out_stream, .White);
if (line_info) |*li| { if (line_info) |*li| {
@ -651,7 +651,7 @@ pub const OpenSelfDebugInfoError = error{
/// TODO resources https://github.com/ziglang/zig/issues/4353 /// TODO resources https://github.com/ziglang/zig/issues/4353
pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo { pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
noasync { nosuspend {
if (builtin.strip_debug_info) if (builtin.strip_debug_info)
return error.MissingDebugInfo; return error.MissingDebugInfo;
if (@hasDecl(root, "os") and @hasDecl(root.os, "debug") and @hasDecl(root.os.debug, "openSelfDebugInfo")) { 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 /// TODO resources https://github.com/ziglang/zig/issues/4353
fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo { 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 }); const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
errdefer coff_file.close(); 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 /// TODO resources https://github.com/ziglang/zig/issues/4353
pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo { pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {
noasync { nosuspend {
const mapped_mem = try mapWholeFile(elf_file_path); const mapped_mem = try mapWholeFile(elf_file_path);
const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]); const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic; 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 { fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
noasync { nosuspend {
const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking }); const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
defer file.close(); defer file.close();
@ -1418,7 +1418,7 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
} }
fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo { fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
noasync { nosuspend {
// Translate the VA into an address into this object // Translate the VA into an address into this object
const relocated_address = address - self.base_address; const relocated_address = address - self.base_address;
assert(relocated_address >= 0x100000000); assert(relocated_address >= 0x100000000);
@ -1643,14 +1643,14 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
// Translate the VA into an address into this object // Translate the VA into an address into this object
const relocated_address = address - self.base_address; 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{ 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) { .compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => "???", error.MissingDebugInfo, error.InvalidDebugInfo => "???",
else => return err, 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, error.MissingDebugInfo, error.InvalidDebugInfo => null,
else => return err, else => return err,
}, },

View File

@ -248,17 +248,17 @@ 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 { fn readAllocBytes(allocator: *mem.Allocator, in_stream: var, size: usize) ![]u8 {
const buf = try allocator.alloc(u8, size); const buf = try allocator.alloc(u8, size);
errdefer allocator.free(buf); 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; 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 { 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) try in_stream.readInt(u64, endian)
else else
@as(u64, try in_stream.readInt(u32, endian)); @as(u64, try in_stream.readInt(u32, endian));
@ -269,29 +269,29 @@ fn parseFormValueBlockLen(allocator: *mem.Allocator, in_stream: var, size: usize
return FormValue{ .Block = buf }; 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 { 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); return parseFormValueBlockLen(allocator, in_stream, block_len);
} }
fn parseFormValueConstant(allocator: *mem.Allocator, in_stream: var, signed: bool, endian: builtin.Endian, comptime size: i32) !FormValue { 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. // 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{ return FormValue{
.Const = Constant{ .Const = Constant{
.signed = signed, .signed = signed,
.payload = switch (size) { .payload = switch (size) {
1 => try noasync in_stream.readInt(u8, endian), 1 => try nosuspend in_stream.readInt(u8, endian),
2 => try noasync in_stream.readInt(u16, endian), 2 => try nosuspend in_stream.readInt(u16, endian),
4 => try noasync in_stream.readInt(u32, endian), 4 => try nosuspend in_stream.readInt(u32, endian),
8 => try noasync in_stream.readInt(u64, endian), 8 => try nosuspend in_stream.readInt(u64, endian),
-1 => blk: { -1 => blk: {
if (signed) { 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); break :blk @bitCast(u64, x);
} else { } else {
const x = try noasync leb.readULEB128(u64, in_stream); const x = try nosuspend leb.readULEB128(u64, in_stream);
break :blk x; break :blk x;
} }
}, },
@ -301,21 +301,21 @@ 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 { fn parseFormValueRef(allocator: *mem.Allocator, in_stream: var, endian: builtin.Endian, size: i32) !FormValue {
return FormValue{ return FormValue{
.Ref = switch (size) { .Ref = switch (size) {
1 => try noasync in_stream.readInt(u8, endian), 1 => try nosuspend in_stream.readInt(u8, endian),
2 => try noasync in_stream.readInt(u16, endian), 2 => try nosuspend in_stream.readInt(u16, endian),
4 => try noasync in_stream.readInt(u32, endian), 4 => try nosuspend in_stream.readInt(u32, endian),
8 => try noasync in_stream.readInt(u64, endian), 8 => try nosuspend in_stream.readInt(u64, endian),
-1 => try noasync leb.readULEB128(u64, in_stream), -1 => try nosuspend leb.readULEB128(u64, in_stream),
else => unreachable, else => unreachable,
}, },
}; };
} }
// 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 { fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endian: builtin.Endian, is_64: bool) anyerror!FormValue {
return switch (form_id) { return switch (form_id) {
FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) }, FORM_addr => FormValue{ .Address = try readAddress(in_stream, endian, @sizeOf(usize) == 8) },
@ -323,7 +323,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, endia
FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2), FORM_block2 => parseFormValueBlock(allocator, in_stream, endian, 2),
FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4), FORM_block4 => parseFormValueBlock(allocator, in_stream, endian, 4),
FORM_block => x: { 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); return parseFormValueBlockLen(allocator, in_stream, block_len);
}, },
FORM_data1 => parseFormValueConstant(allocator, in_stream, false, endian, 1), 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); return parseFormValueConstant(allocator, in_stream, signed, endian, -1);
}, },
FORM_exprloc => { 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); const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue{ .ExprLoc = buf }; 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_flag_present => FormValue{ .Flag = true },
FORM_sec_offset => FormValue{ .SecOffset = try readAddress(in_stream, endian, is_64) }, 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_udata => parseFormValueRef(allocator, in_stream, endian, -1),
FORM_ref_addr => FormValue{ .RefAddr = try readAddress(in_stream, endian, is_64) }, 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_string => FormValue{ .String = try in_stream.readUntilDelimiterAlloc(allocator, 0, math.maxInt(usize)) },
FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) }, FORM_strp => FormValue{ .StrPtr = try readAddress(in_stream, endian, is_64) },
FORM_indirect => { 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)); const F = @TypeOf(async parseFormValue(allocator, in_stream, child_form_id, endian, is_64));
var frame = try allocator.create(F); var frame = try allocator.create(F);
defer allocator.destroy(frame); defer allocator.destroy(frame);

View File

@ -21,7 +21,7 @@ pub fn Batch(
/// usual recommended option for this parameter. /// usual recommended option for this parameter.
auto_async, 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. /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
never_async, never_async,
@ -75,7 +75,7 @@ pub fn Batch(
const job = &self.jobs[self.next_job_index]; const job = &self.jobs[self.next_job_index];
self.next_job_index = (self.next_job_index + 1) % max_jobs; self.next_job_index = (self.next_job_index + 1) % max_jobs;
if (job.frame) |existing| { 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) { if (CollectedResult != void) {
job.result catch |err| { job.result catch |err| {
self.collected_result = err; self.collected_result = err;
@ -94,7 +94,7 @@ pub fn Batch(
/// a time, however, it need not be the same thread. /// a time, however, it need not be the same thread.
pub fn wait(self: *Self) CollectedResult { pub fn wait(self: *Self) CollectedResult {
for (self.jobs) |*job| if (job.frame) |f| { 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) { if (CollectedResult != void) {
job.result catch |err| { job.result catch |err| {
self.collected_result = err; self.collected_result = err;

View File

@ -195,7 +195,7 @@ pub const Loop = struct {
const wakeup_bytes = [_]u8{0x1} ** 8; const wakeup_bytes = [_]u8{0x1} ** 8;
fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void { fn initOsData(self: *Loop, extra_thread_count: usize) InitOsDataError!void {
noasync switch (builtin.os.tag) { nosuspend switch (builtin.os.tag) {
.linux => { .linux => {
errdefer { errdefer {
while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.eventfd); 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 { fn deinitOsData(self: *Loop) void {
noasync switch (builtin.os.tag) { nosuspend switch (builtin.os.tag) {
.linux => { .linux => {
os.close(self.os_data.final_eventfd); os.close(self.os_data.final_eventfd);
while (self.available_eventfd_resume_nodes.pop()) |node| os.close(node.data.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 { pub fn finishOneEvent(self: *Loop) void {
noasync { nosuspend {
const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst); const prev = @atomicRmw(usize, &self.pending_event_count, .Sub, 1, .SeqCst);
if (prev != 1) return; if (prev != 1) return;
@ -1041,7 +1041,7 @@ pub const Loop = struct {
} }
fn posixFsRun(self: *Loop) void { fn posixFsRun(self: *Loop) void {
noasync while (true) { nosuspend while (true) {
self.fs_thread_wakeup.reset(); self.fs_thread_wakeup.reset();
while (self.fs_queue.get()) |node| { while (self.fs_queue.get()) |node| {
switch (node.data.msg) { switch (node.data.msg) {

View File

@ -66,7 +66,7 @@ pub const File = struct {
lock_nonblocking: bool = false, lock_nonblocking: bool = false,
/// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even /// 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. /// related to opening the file, reading, writing, and locking.
intended_io_mode: io.ModeOverride = io.default_mode, intended_io_mode: io.ModeOverride = io.default_mode,
}; };
@ -112,7 +112,7 @@ pub const File = struct {
mode: Mode = default_mode, mode: Mode = default_mode,
/// Setting this to `.blocking` prevents `O_NONBLOCK` from being passed even /// 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. /// related to opening the file, reading, writing, and locking.
intended_io_mode: io.ModeOverride = io.default_mode, intended_io_mode: io.ModeOverride = io.default_mode,
}; };

View File

@ -438,7 +438,7 @@ pub const Node = struct {
ContainerDecl, ContainerDecl,
Asm, Asm,
Comptime, Comptime,
Noasync, Nosuspend,
Block, Block,
// Misc // Misc
@ -569,9 +569,9 @@ pub const Node = struct {
return true; return true;
}, },
.Noasync => { .Nosuspend => {
const noasync_node = @fieldParentPtr(Noasync, "base", n); const nosuspend_node = @fieldParentPtr(Nosuspend, "base", n);
return noasync_node.expr.id != .Block; return nosuspend_node.expr.id != .Block;
}, },
else => return true, else => return true,
} }
@ -1084,12 +1084,12 @@ pub const Node = struct {
} }
}; };
pub const Noasync = struct { pub const Nosuspend = struct {
base: Node = Node{ .id = .Noasync }, base: Node = Node{ .id = .Nosuspend },
noasync_token: TokenIndex, nosuspend_token: TokenIndex,
expr: *Node, expr: *Node,
pub fn iterate(self: *Noasync, index: usize) ?*Node { pub fn iterate(self: *Nosuspend, index: usize) ?*Node {
var i = index; var i = index;
if (i < 1) return self.expr; if (i < 1) return self.expr;
@ -1098,11 +1098,11 @@ pub const Node = struct {
return null; return null;
} }
pub fn firstToken(self: *const Noasync) TokenIndex { pub fn firstToken(self: *const Nosuspend) TokenIndex {
return self.noasync_token; return self.nosuspend_token;
} }
pub fn lastToken(self: *const Noasync) TokenIndex { pub fn lastToken(self: *const Nosuspend) TokenIndex {
return self.expr.lastToken(); return self.expr.lastToken();
} }
}; };

View File

@ -495,7 +495,7 @@ fn parseContainerField(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
/// Statement /// Statement
/// <- KEYWORD_comptime? VarDecl /// <- KEYWORD_comptime? VarDecl
/// / KEYWORD_comptime BlockExprStatement /// / KEYWORD_comptime BlockExprStatement
/// / KEYWORD_noasync BlockExprStatement /// / KEYWORD_nosuspend BlockExprStatement
/// / KEYWORD_suspend (SEMICOLON / BlockExprStatement) /// / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
/// / KEYWORD_defer BlockExprStatement /// / KEYWORD_defer BlockExprStatement
/// / KEYWORD_errdefer Payload? BlockExprStatement /// / KEYWORD_errdefer Payload? BlockExprStatement
@ -527,14 +527,14 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
return &node.base; 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, .{ const block_expr = try expectNode(arena, it, tree, parseBlockExprStatement, .{
.ExpectedBlockOrAssignment = .{ .token = it.index }, .ExpectedBlockOrAssignment = .{ .token = it.index },
}); });
const node = try arena.create(Node.Noasync); const node = try arena.create(Node.Nosuspend);
node.* = .{ node.* = .{
.noasync_token = noasync_token, .nosuspend_token = nosuspend_token,
.expr = block_expr, .expr = block_expr,
}; };
return &node.base; return &node.base;
@ -908,7 +908,7 @@ fn parsePrefixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / IfExpr /// / IfExpr
/// / KEYWORD_break BreakLabel? Expr? /// / KEYWORD_break BreakLabel? Expr?
/// / KEYWORD_comptime Expr /// / KEYWORD_comptime Expr
/// / KEYWORD_noasync Expr /// / KEYWORD_nosuspend Expr
/// / KEYWORD_continue BreakLabel? /// / KEYWORD_continue BreakLabel?
/// / KEYWORD_resume Expr /// / KEYWORD_resume Expr
/// / KEYWORD_return Expr? /// / KEYWORD_return Expr?
@ -944,13 +944,13 @@ fn parsePrimaryExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node
return &node.base; return &node.base;
} }
if (eatToken(it, .Keyword_noasync)) |token| { if (eatToken(it, .Keyword_nosuspend)) |token| {
const expr_node = try expectNode(arena, it, tree, parseExpr, .{ const expr_node = try expectNode(arena, it, tree, parseExpr, .{
.ExpectedExpr = .{ .token = it.index }, .ExpectedExpr = .{ .token = it.index },
}); });
const node = try arena.create(Node.Noasync); const node = try arena.create(Node.Nosuspend);
node.* = .{ node.* = .{
.noasync_token = token, .nosuspend_token = token,
.expr = expr_node, .expr = expr_node,
}; };
return &node.base; return &node.base;
@ -1288,7 +1288,7 @@ fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
/// / IfTypeExpr /// / IfTypeExpr
/// / INTEGER /// / INTEGER
/// / KEYWORD_comptime TypeExpr /// / KEYWORD_comptime TypeExpr
/// / KEYWORD_noasync TypeExpr /// / KEYWORD_nosuspend TypeExpr
/// / KEYWORD_error DOT IDENTIFIER /// / KEYWORD_error DOT IDENTIFIER
/// / KEYWORD_false /// / KEYWORD_false
/// / KEYWORD_null /// / KEYWORD_null
@ -1327,11 +1327,11 @@ fn parsePrimaryTypeExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*N
}; };
return &node.base; 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 expr = (try parseTypeExpr(arena, it, tree)) orelse return null;
const node = try arena.create(Node.Noasync); const node = try arena.create(Node.Nosuspend);
node.* = .{ node.* = .{
.noasync_token = token, .nosuspend_token = token,
.expr = expr, .expr = expr,
}; };
return &node.base; return &node.base;

View File

@ -35,10 +35,10 @@ test "zig fmt: errdefer with payload" {
); );
} }
test "zig fmt: noasync block" { test "zig fmt: nosuspend block" {
try testCanonical( try testCanonical(
\\pub fn main() anyerror!void { \\pub fn main() anyerror!void {
\\ noasync { \\ nosuspend {
\\ var foo: Foo = .{ .bar = 42 }; \\ 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( try testCanonical(
\\fn foo() void { \\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( 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 std = @import("std");
const mem = std.mem; const mem = std.mem;
const warn = std.debug.warn; const warn = std.debug.warn;

View File

@ -391,11 +391,15 @@ fn renderExpression(
try renderToken(tree, stream, comptime_node.comptime_token, indent, start_col, Space.Space); 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); return renderExpression(allocator, stream, tree, indent, start_col, comptime_node.expr, space);
}, },
.Noasync => { .Nosuspend => {
const noasync_node = @fieldParentPtr(ast.Node.Noasync, "base", base); const nosuspend_node = @fieldParentPtr(ast.Node.Nosuspend, "base", base);
if (mem.eql(u8, tree.tokenSlice(nosuspend_node.nosuspend_token), "noasync")) {
try renderToken(tree, stream, noasync_node.noasync_token, indent, start_col, Space.Space); // TODO: remove this
return renderExpression(allocator, stream, tree, indent, start_col, noasync_node.expr, space); 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 => { .Suspend => {

View File

@ -39,7 +39,7 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
zend += 1; zend += 1;
} }
if (zend == yindex + 1) return error.InvalidVersion; 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) { result.patch = switch (result.minor) {
// TODO: compiler complains without explicit @as() coercion // 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 4 => @as(u32, switch (y) { // Tiger: 10.4
'A' => 0, 'A' => 0,
'B' => 1, 'B' => 1,
'C', 'E', => 2, 'C',
'E',
=> 2,
'F' => 3, 'F' => 3,
'G' => @as(u32, block: { 'G' => @as(u32, block: {
if (z >= 1454) break :block 5; if (z >= 1454) break :block 5;
@ -105,7 +107,10 @@ pub fn version_from_build(build: []const u8) !std.builtin.Version {
}), }),
'H' => 5, 'H' => 5,
'I' => 6, 'I' => 6,
'J', 'K', 'N', => 7, 'J',
'K',
'N',
=> 7,
'L' => 8, 'L' => 8,
'P' => 9, 'P' => 9,
'R' => 10, 'R' => 10,
@ -438,7 +443,7 @@ test "version_from_build" {
for (known) |pair| { for (known) |pair| {
var buf: [32]u8 = undefined; var buf: [32]u8 = undefined;
const ver = try version_from_build(pair[0]); 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])); std.testing.expect(std.mem.eql(u8, sver, pair[1]));
} }
} }

View File

@ -49,8 +49,9 @@ pub const Token = struct {
Keyword.init("inline", .Keyword_inline), Keyword.init("inline", .Keyword_inline),
Keyword.init("nakedcc", .Keyword_nakedcc), Keyword.init("nakedcc", .Keyword_nakedcc),
Keyword.init("noalias", .Keyword_noalias), 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("noinline", .Keyword_noinline),
Keyword.init("nosuspend", .Keyword_nosuspend),
Keyword.init("null", .Keyword_null), Keyword.init("null", .Keyword_null),
Keyword.init("or", .Keyword_or), Keyword.init("or", .Keyword_or),
Keyword.init("orelse", .Keyword_orelse), Keyword.init("orelse", .Keyword_orelse),
@ -182,8 +183,8 @@ pub const Token = struct {
Keyword_inline, Keyword_inline,
Keyword_nakedcc, Keyword_nakedcc,
Keyword_noalias, Keyword_noalias,
Keyword_noasync,
Keyword_noinline, Keyword_noinline,
Keyword_nosuspend,
Keyword_null, Keyword_null,
Keyword_or, Keyword_or,
Keyword_orelse, Keyword_orelse,
@ -307,8 +308,8 @@ pub const Token = struct {
.Keyword_inline => "inline", .Keyword_inline => "inline",
.Keyword_nakedcc => "nakedcc", .Keyword_nakedcc => "nakedcc",
.Keyword_noalias => "noalias", .Keyword_noalias => "noalias",
.Keyword_noasync => "noasync",
.Keyword_noinline => "noinline", .Keyword_noinline => "noinline",
.Keyword_nosuspend => "nosuspend",
.Keyword_null => "null", .Keyword_null => "null",
.Keyword_or => "or", .Keyword_or => "or",
.Keyword_orelse => "orelse", .Keyword_orelse => "orelse",

View File

@ -672,7 +672,7 @@ enum NodeType {
NodeTypeSwitchProng, NodeTypeSwitchProng,
NodeTypeSwitchRange, NodeTypeSwitchRange,
NodeTypeCompTime, NodeTypeCompTime,
NodeTypeNoAsync, NodeTypeNoSuspend,
NodeTypeBreak, NodeTypeBreak,
NodeTypeContinue, NodeTypeContinue,
NodeTypeAsmExpr, NodeTypeAsmExpr,
@ -862,7 +862,7 @@ enum CallModifier {
CallModifierAsync, CallModifierAsync,
CallModifierNeverTail, CallModifierNeverTail,
CallModifierNeverInline, CallModifierNeverInline,
CallModifierNoAsync, CallModifierNoSuspend,
CallModifierAlwaysTail, CallModifierAlwaysTail,
CallModifierAlwaysInline, CallModifierAlwaysInline,
CallModifierCompileTime, CallModifierCompileTime,
@ -1014,7 +1014,7 @@ struct AstNodeCompTime {
AstNode *expr; AstNode *expr;
}; };
struct AstNodeNoAsync { struct AstNodeNoSuspend {
AstNode *expr; AstNode *expr;
}; };
@ -1225,7 +1225,7 @@ struct AstNode {
AstNodeSwitchProng switch_prong; AstNodeSwitchProng switch_prong;
AstNodeSwitchRange switch_range; AstNodeSwitchRange switch_range;
AstNodeCompTime comptime_expr; AstNodeCompTime comptime_expr;
AstNodeNoAsync noasync_expr; AstNodeNoSuspend nosuspend_expr;
AstNodeAsmExpr asm_expr; AstNodeAsmExpr asm_expr;
AstNodeFieldAccessExpr field_access_expr; AstNodeFieldAccessExpr field_access_expr;
AstNodePtrDerefExpr ptr_deref_expr; AstNodePtrDerefExpr ptr_deref_expr;
@ -1858,7 +1858,7 @@ enum PanicMsgId {
PanicMsgIdResumedAnAwaitingFn, PanicMsgIdResumedAnAwaitingFn,
PanicMsgIdFrameTooSmall, PanicMsgIdFrameTooSmall,
PanicMsgIdResumedFnPendingAwait, PanicMsgIdResumedFnPendingAwait,
PanicMsgIdBadNoAsyncCall, PanicMsgIdBadNoSuspendCall,
PanicMsgIdResumeNotSuspendedFn, PanicMsgIdResumeNotSuspendedFn,
PanicMsgIdBadSentinel, PanicMsgIdBadSentinel,
PanicMsgIdShxTooBigRhs, PanicMsgIdShxTooBigRhs,
@ -2376,7 +2376,7 @@ enum ScopeId {
ScopeIdRuntime, ScopeIdRuntime,
ScopeIdTypeOf, ScopeIdTypeOf,
ScopeIdExpr, ScopeIdExpr,
ScopeIdNoAsync, ScopeIdNoSuspend,
}; };
struct Scope { struct Scope {
@ -2510,9 +2510,9 @@ struct ScopeCompTime {
Scope base; Scope base;
}; };
// This scope is created for a noasync expression. // This scope is created for a nosuspend expression.
// NodeTypeNoAsync // NodeTypeNoSuspend
struct ScopeNoAsync { struct ScopeNoSuspend {
Scope base; Scope base;
}; };
@ -4488,7 +4488,7 @@ struct IrInstSrcAwait {
IrInstSrc *frame; IrInstSrc *frame;
ResultLoc *result_loc; ResultLoc *result_loc;
bool is_noasync; bool is_nosuspend;
}; };
struct IrInstGenAwait { struct IrInstGenAwait {
@ -4497,7 +4497,7 @@ struct IrInstGenAwait {
IrInstGen *frame; IrInstGen *frame;
IrInstGen *result_loc; IrInstGen *result_loc;
ZigFn *target_fn; ZigFn *target_fn;
bool is_noasync; bool is_nosuspend;
}; };
struct IrInstSrcResume { struct IrInstSrcResume {

View File

@ -106,7 +106,7 @@ static ScopeExpr *find_expr_scope(Scope *scope) {
case ScopeIdDecls: case ScopeIdDecls:
case ScopeIdFnDef: case ScopeIdFnDef:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdVarDecl: case ScopeIdVarDecl:
case ScopeIdCImport: case ScopeIdCImport:
case ScopeIdSuspend: case ScopeIdSuspend:
@ -227,9 +227,9 @@ Scope *create_comptime_scope(CodeGen *g, AstNode *node, Scope *parent) {
return &scope->base; return &scope->base;
} }
Scope *create_noasync_scope(CodeGen *g, AstNode *node, Scope *parent) { Scope *create_nosuspend_scope(CodeGen *g, AstNode *node, Scope *parent) {
ScopeNoAsync *scope = heap::c_allocator.create<ScopeNoAsync>(); ScopeNoSuspend *scope = heap::c_allocator.create<ScopeNoSuspend>();
init_scope(g, &scope->base, ScopeIdNoAsync, node, parent); init_scope(g, &scope->base, ScopeIdNoSuspend, node, parent);
return &scope->base; return &scope->base;
} }
@ -3771,7 +3771,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeCompTime: case NodeTypeCompTime:
preview_comptime_decl(g, node, decls_scope); preview_comptime_decl(g, node, decls_scope);
break; break;
case NodeTypeNoAsync: case NodeTypeNoSuspend:
case NodeTypeParamDecl: case NodeTypeParamDecl:
case NodeTypeReturnExpr: case NodeTypeReturnExpr:
case NodeTypeDefer: 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, static Error analyze_callee_async(CodeGen *g, ZigFn *fn, ZigFn *callee, AstNode *call_node,
bool must_not_be_async, CallModifier modifier) bool must_not_be_async, CallModifier modifier)
{ {
if (modifier == CallModifierNoAsync) if (modifier == CallModifierNoSuspend)
return ErrorNone; return ErrorNone;
bool callee_is_async = false; bool callee_is_async = false;
switch (callee->type_entry->data.fn.fn_type_id.cc) { 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) { for (size_t i = 0; i < fn->await_list.length; i += 1) {
IrInstGenAwait *await = fn->await_list.at(i); 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, switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
CallModifierNone)) CallModifierNone))
{ {
@ -6239,7 +6239,7 @@ static void mark_suspension_point(Scope *scope) {
case ScopeIdDecls: case ScopeIdDecls:
case ScopeIdFnDef: case ScopeIdFnDef:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdCImport: case ScopeIdCImport:
case ScopeIdSuspend: case ScopeIdSuspend:
case ScopeIdTypeOf: 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. // The funtion call result of foo() must be spilled.
for (size_t i = 0; i < fn->await_list.length; i += 1) { for (size_t i = 0; i < fn->await_list.length; i += 1) {
IrInstGenAwait *await = fn->await_list.at(i); IrInstGenAwait *await = fn->await_list.at(i);
if (await->is_noasync) { if (await->is_nosuspend) {
continue; continue;
} }
if (await->base.value->special != ConstValSpecialRuntime) { if (await->base.value->special != ConstValSpecialRuntime) {

View File

@ -125,7 +125,7 @@ ScopeLoop *create_loop_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeSuspend *create_suspend_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); 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_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_runtime_scope(CodeGen *g, AstNode *node, Scope *parent, IrInstSrc *is_comptime);
Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent); Scope *create_typeof_scope(CodeGen *g, AstNode *node, Scope *parent);
ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent); ScopeExpr *create_expr_scope(CodeGen *g, AstNode *node, Scope *parent);

View File

@ -220,8 +220,8 @@ static const char *node_type_str(NodeType node_type) {
return "SwitchRange"; return "SwitchRange";
case NodeTypeCompTime: case NodeTypeCompTime:
return "CompTime"; return "CompTime";
case NodeTypeNoAsync: case NodeTypeNoSuspend:
return "NoAsync"; return "NoSuspend";
case NodeTypeBreak: case NodeTypeBreak:
return "Break"; return "Break";
case NodeTypeContinue: case NodeTypeContinue:
@ -709,8 +709,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
switch (node->data.fn_call_expr.modifier) { switch (node->data.fn_call_expr.modifier) {
case CallModifierNone: case CallModifierNone:
break; break;
case CallModifierNoAsync: case CallModifierNoSuspend:
fprintf(ar->f, "noasync "); fprintf(ar->f, "nosuspend ");
break; break;
case CallModifierAsync: case CallModifierAsync:
fprintf(ar->f, "async "); 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); render_node_grouped(ar, node->data.comptime_expr.expr);
break; break;
} }
case NodeTypeNoAsync: case NodeTypeNoSuspend:
{ {
fprintf(ar->f, "noasync "); fprintf(ar->f, "nosuspend ");
render_node_grouped(ar, node->data.noasync_expr.expr); render_node_grouped(ar, node->data.nosuspend_expr.expr);
break; break;
} }
case NodeTypeForExpr: case NodeTypeForExpr:

View File

@ -685,7 +685,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
case ScopeIdLoop: case ScopeIdLoop:
case ScopeIdSuspend: case ScopeIdSuspend:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdRuntime: case ScopeIdRuntime:
case ScopeIdTypeOf: case ScopeIdTypeOf:
case ScopeIdExpr: case ScopeIdExpr:
@ -966,8 +966,8 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
return buf_create_from_str("frame too small"); return buf_create_from_str("frame too small");
case PanicMsgIdResumedFnPendingAwait: case PanicMsgIdResumedFnPendingAwait:
return buf_create_from_str("resumed an async function which can only be awaited"); return buf_create_from_str("resumed an async function which can only be awaited");
case PanicMsgIdBadNoAsyncCall: case PanicMsgIdBadNoSuspendCall:
return buf_create_from_str("async function called in noasync scope suspended"); return buf_create_from_str("async function called in nosuspend scope suspended");
case PanicMsgIdResumeNotSuspendedFn: case PanicMsgIdResumeNotSuspendedFn:
return buf_create_from_str("resumed a non-suspended function"); return buf_create_from_str("resumed a non-suspended function");
case PanicMsgIdBadSentinel: case PanicMsgIdBadSentinel:
@ -4061,7 +4061,7 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) {
case ScopeIdLoop: case ScopeIdLoop:
case ScopeIdSuspend: case ScopeIdSuspend:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdRuntime: case ScopeIdRuntime:
case ScopeIdTypeOf: case ScopeIdTypeOf:
case ScopeIdExpr: 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 // even if prefix_arg_err_ret_stack is true, let the async function do its own
// initialization. // initialization.
} else { } 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. // 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. // never suspend.
awaiter_init_val = zero; awaiter_init_val = zero;
} else { } else {
@ -4325,7 +4325,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
case CallModifierCompileTime: case CallModifierCompileTime:
zig_unreachable(); zig_unreachable();
case CallModifierNone: case CallModifierNone:
case CallModifierNoAsync: case CallModifierNoSuspend:
case CallModifierAsync: case CallModifierAsync:
call_attr = ZigLLVM_CallAttrAuto; call_attr = ZigLLVM_CallAttrAuto;
break; break;
@ -4401,7 +4401,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutableGen *executable, IrIn
get_llvm_type(g, instruction->base.value->type), ""); get_llvm_type(g, instruction->base.value->type), "");
} }
return nullptr; 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); gen_resume(g, fn_val, frame_result_loc, ResumeIdCall);
if (ir_want_runtime_safety(g, &instruction->base)) { 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); all_ones, LLVMAtomicOrderingRelease);
LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, ""); LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, "");
LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic"); LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendPanic");
LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk"); LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoSuspendOk");
LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block); 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); LLVMPositionBuilderAtEnd(g->builder, bad_block);
gen_safety_crash(g, PanicMsgIdBadNoAsyncCall); gen_safety_crash(g, PanicMsgIdBadNoSuspendCall);
LLVMPositionBuilderAtEnd(g->builder, ok_block); 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) ? LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
nullptr : ir_llvm_value(g, instruction->result_loc); 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))) (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
{ {
return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, 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) { 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; ZigType *largest_call_frame_type = nullptr;
IrInstGen *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base, 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"); 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; continue;
if (!fn_is_async(call->fn_entry)) if (!fn_is_async(call->fn_entry))
continue; continue;
if (call->modifier != CallModifierNoAsync) if (call->modifier != CallModifierNoSuspend)
continue; continue;
if (call->frame_result_loc != nullptr) if (call->frame_result_loc != nullptr)
continue; continue;

View File

@ -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, 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<IrInstSrcAwait>(irb, scope, source_node); IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
instruction->frame = frame; instruction->frame = frame;
instruction->result_loc = result_loc; instruction->result_loc = result_loc;
instruction->is_noasync = is_noasync; instruction->is_nosuspend = is_nosuspend;
ir_ref_instruction(frame, irb->current_basic_block); 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, 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<IrInstGenAwait>(&ira->new_irb, IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
source_instruction->scope, source_instruction->source_node); source_instruction->scope, source_instruction->source_node);
instruction->base.value->type = result_type; instruction->base.value->type = result_type;
instruction->frame = frame; instruction->frame = frame;
instruction->result_loc = result_loc; instruction->result_loc = result_loc;
instruction->is_noasync = is_noasync; instruction->is_nosuspend = is_nosuspend;
ir_ref_inst_gen(frame); ir_ref_inst_gen(frame);
if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 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 ScopeIdLoop:
case ScopeIdSuspend: case ScopeIdSuspend:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdRuntime: case ScopeIdRuntime:
case ScopeIdTypeOf: case ScopeIdTypeOf:
case ScopeIdExpr: case ScopeIdExpr:
@ -5072,7 +5072,7 @@ static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope
case ScopeIdLoop: case ScopeIdLoop:
case ScopeIdSuspend: case ScopeIdSuspend:
case ScopeIdCompTime: case ScopeIdCompTime:
case ScopeIdNoAsync: case ScopeIdNoSuspend:
case ScopeIdRuntime: case ScopeIdRuntime:
case ScopeIdTypeOf: case ScopeIdTypeOf:
case ScopeIdExpr: case ScopeIdExpr:
@ -7335,10 +7335,10 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
zig_unreachable(); zig_unreachable();
} }
static ScopeNoAsync *get_scope_noasync(Scope *scope) { static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
while (scope) { while (scope) {
if (scope->id == ScopeIdNoAsync) if (scope->id == ScopeIdNoSuspend)
return (ScopeNoAsync *)scope; return (ScopeNoSuspend *)scope;
if (scope->id == ScopeIdFnDef) if (scope->id == ScopeIdFnDef)
return nullptr; 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) if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 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; CallModifier modifier = node->data.fn_call_expr.modifier;
if (is_noasync) { if (is_nosuspend) {
if (modifier == CallModifierAsync) { if (modifier == CallModifierAsync) {
add_node_error(irb->codegen, node, 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; return irb->codegen->invalid_inst_src;
} }
modifier = CallModifierNoAsync; modifier = CallModifierNoSuspend;
} }
AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 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); 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) { static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) {
assert(node->type == NodeTypeNoAsync); 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 // 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); 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) { static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeResume); assert(node->type == NodeTypeResume);
if (get_scope_noasync(scope) != nullptr) { if (get_scope_nosuspend(scope) != nullptr) {
add_node_error(irb->codegen, node, buf_sprintf("resume in noasync scope")); add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope"));
return irb->codegen->invalid_inst_src; 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); 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; AstNode *expr_node = node->data.await_expr.expr;
if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { 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) if (target_inst == irb->codegen->invalid_inst_src)
return 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); 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")); add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition"));
return irb->codegen->invalid_inst_src; return irb->codegen->invalid_inst_src;
} }
if (get_scope_noasync(parent_scope) != nullptr) { if (get_scope_nosuspend(parent_scope) != nullptr) {
add_node_error(irb->codegen, node, buf_sprintf("suspend in noasync scope")); add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope"));
return irb->codegen->invalid_inst_src; 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); return ir_gen_switch_expr(irb, scope, node, lval, result_loc);
case NodeTypeCompTime: case NodeTypeCompTime:
return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc);
case NodeTypeNoAsync: case NodeTypeNoSuspend:
return ir_expr_wrap(irb, scope, ir_gen_noasync(irb, scope, node, lval), result_loc); return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc);
case NodeTypeErrorType: case NodeTypeErrorType:
return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc);
case NodeTypeBreak: case NodeTypeBreak:
@ -10105,7 +10105,7 @@ static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *sco
case NodeTypeIfOptional: case NodeTypeIfOptional:
case NodeTypeSwitchExpr: case NodeTypeSwitchExpr:
case NodeTypeCompTime: case NodeTypeCompTime:
case NodeTypeNoAsync: case NodeTypeNoSuspend:
case NodeTypeErrorType: case NodeTypeErrorType:
case NodeTypeBreak: case NodeTypeBreak:
case NodeTypeContinue: case NodeTypeContinue:
@ -20030,7 +20030,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (impl_fn_type_id->cc == CallingConventionAsync && if (impl_fn_type_id->cc == CallingConventionAsync &&
parent_fn_entry->inferred_async_node == nullptr && 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_node = fn_ref->base.source_node;
parent_fn_entry->inferred_async_fn = impl_fn; parent_fn_entry->inferred_async_fn = impl_fn;
@ -20128,7 +20128,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
if (fn_type_id->cc == CallingConventionAsync && if (fn_type_id->cc == CallingConventionAsync &&
parent_fn_entry->inferred_async_node == nullptr && 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_node = fn_ref->base.source_node;
parent_fn_entry->inferred_async_fn = fn_entry; parent_fn_entry->inferred_async_fn = fn_entry;
@ -20243,7 +20243,7 @@ static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr,
case CallModifierNone: case CallModifierNone:
case CallModifierAlwaysInline: case CallModifierAlwaysInline:
case CallModifierAlwaysTail: case CallModifierAlwaysTail:
case CallModifierNoAsync: case CallModifierNoSuspend:
modifier = CallModifierCompileTime; modifier = CallModifierCompileTime;
break; break;
case CallModifierNeverInline: case CallModifierNeverInline:
@ -30287,7 +30287,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
ir_assert(fn_entry != nullptr, &instruction->base.base); ir_assert(fn_entry != nullptr, &instruction->base.base);
// If it's not @Frame(func) then it's definitely a suspend point // 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) { if (fn_entry->inferred_async_node == nullptr) {
fn_entry->inferred_async_node = instruction->base.base.source_node; fn_entry->inferred_async_node = instruction->base.base.source_node;
} }
@ -30311,7 +30311,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, 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; result->target_fn = target_fn;
fn_entry->await_list.append(result); fn_entry->await_list.append(result);
return ir_finish_anal(ira, &result->base); return ir_finish_anal(ira, &result->base);

View File

@ -861,8 +861,8 @@ static void ir_print_call_src(IrPrintSrc *irp, IrInstSrcCall *call_instruction)
switch (call_instruction->modifier) { switch (call_instruction->modifier) {
case CallModifierNone: case CallModifierNone:
break; break;
case CallModifierNoAsync: case CallModifierNoSuspend:
fprintf(irp->f, "noasync "); fprintf(irp->f, "nosuspend ");
break; break;
case CallModifierAsync: case CallModifierAsync:
fprintf(irp->f, "async "); fprintf(irp->f, "async ");
@ -906,8 +906,8 @@ static void ir_print_call_gen(IrPrintGen *irp, IrInstGenCall *call_instruction)
switch (call_instruction->modifier) { switch (call_instruction->modifier) {
case CallModifierNone: case CallModifierNone:
break; break;
case CallModifierNoAsync: case CallModifierNoSuspend:
fprintf(irp->f, "noasync "); fprintf(irp->f, "nosuspend ");
break; break;
case CallModifierAsync: case CallModifierAsync:
fprintf(irp->f, "async "); fprintf(irp->f, "async ");

View File

@ -913,7 +913,7 @@ static AstNode *ast_parse_container_field(ParseContext *pc) {
// Statement // Statement
// <- KEYWORD_comptime? VarDecl // <- KEYWORD_comptime? VarDecl
// / KEYWORD_comptime BlockExprStatement // / KEYWORD_comptime BlockExprStatement
// / KEYWORD_noasync BlockExprStatement // / KEYWORD_nosuspend BlockExprStatement
// / KEYWORD_suspend (SEMICOLON / BlockExprStatement) // / KEYWORD_suspend (SEMICOLON / BlockExprStatement)
// / KEYWORD_defer BlockExprStatement // / KEYWORD_defer BlockExprStatement
// / KEYWORD_errdefer Payload? BlockExprStatement // / KEYWORD_errdefer Payload? BlockExprStatement
@ -937,11 +937,11 @@ static AstNode *ast_parse_statement(ParseContext *pc) {
return res; return res;
} }
Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync); Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
if (noasync != nullptr) { if (nosuspend != nullptr) {
AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement); AstNode *statement = ast_expect(pc, ast_parse_block_expr_statement);
AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync); AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
res->data.noasync_expr.expr = statement; res->data.nosuspend_expr.expr = statement;
return res; return res;
} }
@ -1289,7 +1289,7 @@ static AstNode *ast_parse_prefix_expr(ParseContext *pc) {
// / IfExpr // / IfExpr
// / KEYWORD_break BreakLabel? Expr? // / KEYWORD_break BreakLabel? Expr?
// / KEYWORD_comptime Expr // / KEYWORD_comptime Expr
// / KEYWORD_noasync Expr // / KEYWORD_nosuspend Expr
// / KEYWORD_continue BreakLabel? // / KEYWORD_continue BreakLabel?
// / KEYWORD_resume Expr // / KEYWORD_resume Expr
// / KEYWORD_return Expr? // / KEYWORD_return Expr?
@ -1324,11 +1324,11 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
return res; return res;
} }
Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync); Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
if (noasync != nullptr) { if (nosuspend != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_expr); AstNode *expr = ast_expect(pc, ast_parse_expr);
AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync); AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
res->data.noasync_expr.expr = expr; res->data.nosuspend_expr.expr = expr;
return res; return res;
} }
@ -1640,7 +1640,7 @@ static AstNode *ast_parse_suffix_expr(ParseContext *pc) {
// / IfTypeExpr // / IfTypeExpr
// / INTEGER // / INTEGER
// / KEYWORD_comptime TypeExpr // / KEYWORD_comptime TypeExpr
// / KEYWORD_noasync TypeExpr // / KEYWORD_nosuspend TypeExpr
// / KEYWORD_error DOT IDENTIFIER // / KEYWORD_error DOT IDENTIFIER
// / KEYWORD_false // / KEYWORD_false
// / KEYWORD_null // / KEYWORD_null
@ -1742,11 +1742,11 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
return res; return res;
} }
Token *noasync = eat_token_if(pc, TokenIdKeywordNoAsync); Token *nosuspend = eat_token_if(pc, TokenIdKeywordNoSuspend);
if (noasync != nullptr) { if (nosuspend != nullptr) {
AstNode *expr = ast_expect(pc, ast_parse_type_expr); AstNode *expr = ast_expect(pc, ast_parse_type_expr);
AstNode *res = ast_create_node(pc, NodeTypeNoAsync, noasync); AstNode *res = ast_create_node(pc, NodeTypeNoSuspend, nosuspend);
res->data.noasync_expr.expr = expr; res->data.nosuspend_expr.expr = expr;
return res; return res;
} }
@ -3189,7 +3189,7 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
case NodeTypeCompTime: case NodeTypeCompTime:
visit_field(&node->data.comptime_expr.expr, visit, context); visit_field(&node->data.comptime_expr.expr, visit, context);
break; break;
case NodeTypeNoAsync: case NodeTypeNoSuspend:
visit_field(&node->data.comptime_expr.expr, visit, context); visit_field(&node->data.comptime_expr.expr, visit, context);
break; break;
case NodeTypeBreak: case NodeTypeBreak:

View File

@ -128,8 +128,8 @@ static const struct ZigKeyword zig_keywords[] = {
{"if", TokenIdKeywordIf}, {"if", TokenIdKeywordIf},
{"inline", TokenIdKeywordInline}, {"inline", TokenIdKeywordInline},
{"noalias", TokenIdKeywordNoAlias}, {"noalias", TokenIdKeywordNoAlias},
{"noasync", TokenIdKeywordNoAsync},
{"noinline", TokenIdKeywordNoInline}, {"noinline", TokenIdKeywordNoInline},
{"nosuspend", TokenIdKeywordNoSuspend},
{"null", TokenIdKeywordNull}, {"null", TokenIdKeywordNull},
{"or", TokenIdKeywordOr}, {"or", TokenIdKeywordOr},
{"orelse", TokenIdKeywordOrElse}, {"orelse", TokenIdKeywordOrElse},
@ -1589,8 +1589,8 @@ const char * token_name(TokenId id) {
case TokenIdKeywordIf: return "if"; case TokenIdKeywordIf: return "if";
case TokenIdKeywordInline: return "inline"; case TokenIdKeywordInline: return "inline";
case TokenIdKeywordNoAlias: return "noalias"; case TokenIdKeywordNoAlias: return "noalias";
case TokenIdKeywordNoAsync: return "noasync";
case TokenIdKeywordNoInline: return "noinline"; case TokenIdKeywordNoInline: return "noinline";
case TokenIdKeywordNoSuspend: return "nosuspend";
case TokenIdKeywordNull: return "null"; case TokenIdKeywordNull: return "null";
case TokenIdKeywordOr: return "or"; case TokenIdKeywordOr: return "or";
case TokenIdKeywordOrElse: return "orelse"; case TokenIdKeywordOrElse: return "orelse";

View File

@ -78,7 +78,7 @@ enum TokenId {
TokenIdKeywordNoInline, TokenIdKeywordNoInline,
TokenIdKeywordLinkSection, TokenIdKeywordLinkSection,
TokenIdKeywordNoAlias, TokenIdKeywordNoAlias,
TokenIdKeywordNoAsync, TokenIdKeywordNoSuspend,
TokenIdKeywordNull, TokenIdKeywordNull,
TokenIdKeywordOr, TokenIdKeywordOr,
TokenIdKeywordOrElse, TokenIdKeywordOrElse,

View File

@ -266,9 +266,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:17:17: error: RHS of shift is too large for LHS type", "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 { \\export fn entry() void {
\\ noasync { \\ nosuspend {
\\ const bar = async foo(); \\ const bar = async foo();
\\ suspend; \\ suspend;
\\ resume bar; \\ resume bar;
@ -276,9 +276,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\} \\}
\\fn foo() void {} \\fn foo() void {}
, &[_][]const u8{ , &[_][]const u8{
"tmp.zig:3:21: error: async call in noasync scope", "tmp.zig:3:21: error: async call in nosuspend scope",
"tmp.zig:4:9: error: suspend in noasync scope", "tmp.zig:4:9: error: suspend in nosuspend scope",
"tmp.zig:5:9: error: resume in noasync scope", "tmp.zig:5:9: error: resume in nosuspend scope",
}); });
cases.add("atomicrmw with bool op not .Xchg", cases.add("atomicrmw with bool op not .Xchg",

View File

@ -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 { \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126); \\ @import("std").os.exit(126);
\\} \\}
\\pub fn main() void { \\pub fn main() void {
\\ _ = noasync add(101, 100); \\ _ = nosuspend add(101, 100);
\\} \\}
\\fn add(a: i32, b: i32) i32 { \\fn add(a: i32, b: i32) i32 {
\\ if (a > 100) { \\ if (a > 100) {

View File

@ -1090,10 +1090,10 @@ test "recursive call of await @asyncCall with struct return type" {
expect(res.z == 3); expect(res.z == 3);
} }
test "noasync function call" { test "nosuspend function call" {
const S = struct { const S = struct {
fn doTheTest() void { fn doTheTest() void {
const result = noasync add(50, 100); const result = nosuspend add(50, 100);
expect(result == 150); expect(result == 150);
} }
fn add(a: i32, b: i32) i32 { fn add(a: i32, b: i32) i32 {
@ -1511,13 +1511,13 @@ test "take address of temporary async frame" {
S.doTheTest(); S.doTheTest();
} }
test "noasync await" { test "nosuspend await" {
const S = struct { const S = struct {
var finished = false; var finished = false;
fn doTheTest() void { fn doTheTest() void {
var frame = async foo(false); var frame = async foo(false);
expect(noasync await frame == 42); expect(nosuspend await frame == 42);
finished = true; finished = true;
} }
@ -1532,7 +1532,7 @@ test "noasync await" {
expect(S.finished); expect(S.finished);
} }
test "noasync on function calls" { test "nosuspend on function calls" {
const S0 = struct { const S0 = struct {
b: i32 = 42, b: i32 = 42,
}; };
@ -1544,8 +1544,8 @@ test "noasync on function calls" {
return S0{}; return S0{};
} }
}; };
expectEqual(@as(i32, 42), noasync S1.c().b); expectEqual(@as(i32, 42), nosuspend S1.c().b);
expectEqual(@as(i32, 42), (try noasync S1.d()).b); expectEqual(@as(i32, 42), (try nosuspend S1.d()).b);
} }
test "avoid forcing frame alignment resolution implicit cast to *c_void" { 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(); var frame = async S.foo();
resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x)); resume @ptrCast(anyframe->bool, @alignCast(@alignOf(@Frame(S.foo)), S.x));
expect(noasync await frame); expect(nosuspend await frame);
} }

View File

@ -823,7 +823,7 @@ test "peer type resolve array pointer and unknown pointer" {
comptime expect(@TypeOf(&array, const_ptr) == [*]const u8); comptime expect(@TypeOf(&array, const_ptr) == [*]const u8);
comptime expect(@TypeOf(const_ptr, &array) == [*]const u8); comptime expect(@TypeOf(const_ptr, &array) == [*]const u8);
comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8); comptime expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8); comptime expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
} }

View File

@ -1,6 +1,4 @@
const Err = error { const Err = error{Foo};
Foo
};
pub fn main() !u8 { pub fn main() !u8 {
return Err.Foo; return Err.Foo;

View File

@ -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 { pub fn main() !u8 {
if (foo() == 7) return Err.Foo; if (foo() == 7) return Err.Foo;