diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-23 21:12:29 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-23 21:12:29 -0700 |
| commit | fbfae832eaf520f7fcc632580b4b4a7fb171f90f (patch) | |
| tree | 1a8b34df8132e7bffc336235cfdae17f261f41c9 /src/AstGen.zig | |
| parent | 49be88859d3cef22c5cc27c908264a235c78a4d0 (diff) | |
| download | zig-fbfae832eaf520f7fcc632580b4b4a7fb171f90f.tar.gz zig-fbfae832eaf520f7fcc632580b4b4a7fb171f90f.zip | |
AstGen: emit nosuspend function calls
Inside a nosuspend block, emit function calls as nosuspend calls.
Also inside a comptime block, emit function calls as comptime calls.
Also emit `async foo()` calls as async calls.
Remove compile error for `nosuspend` block inside `suspend` block.
Instead of implicitly treating every `suspend` block also as a
`nosuspend` block (which would make sense), we leave suspension points
as compile errors, to hint to the programmer about accidents. Of course
they may then assert `nosuspend` by introducing a block within their
suspend block.
To make room in `Zir.Inst.Tag` I moved `typeof_peer` and `compile_log`
to `Extended`.
Diffstat (limited to 'src/AstGen.zig')
| -rw-r--r-- | src/AstGen.zig | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 88cddc39b9..5994ca0d7f 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -900,11 +900,6 @@ pub fn nosuspendExpr( try astgen.errNoteNode(gz.nosuspend_node, "other nosuspend block here", .{}), }); } - if (gz.suspend_node != 0) { - return astgen.failNodeNotes(node, "inside a suspend block, nosuspend is implied", .{}, &[_]u32{ - try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), - }); - } gz.nosuspend_node = node; const result = try expr(gz, scope, rl, body_node); gz.nosuspend_node = 0; @@ -1803,6 +1798,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner .bool_and, .bool_or, .call_compile_time, + .call_nosuspend, + .call_async, .cmp_lt, .cmp_lte, .cmp_eq, @@ -1876,7 +1873,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner .slice_end, .slice_sentinel, .import, - .typeof_peer, .switch_block, .switch_block_multi, .switch_block_else, @@ -2001,7 +1997,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner .ensure_result_non_error, .@"export", .set_eval_branch_quota, - .compile_log, .ensure_err_payload_void, .@"break", .break_inline, @@ -6074,11 +6069,7 @@ fn typeOf( items[param_i] = try expr(gz, scope, .none, param); } - const result = try gz.addPlNode(.typeof_peer, node, Zir.Inst.MultiOp{ - .operands_len = @intCast(u32, params.len), - }); - try gz.astgen.appendRefs(items); - + const result = try gz.addExtendedMultiOp(.typeof_peer, node, items); return rvalue(gz, scope, rl, result, node); } @@ -6138,10 +6129,7 @@ fn builtinCall( for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param); - const result = try gz.addPlNode(.compile_log, node, Zir.Inst.MultiOp{ - .operands_len = @intCast(u32, params.len), - }); - try gz.astgen.appendRefs(arg_refs); + const result = try gz.addExtendedMultiOp(.compile_log, node, arg_refs); return rvalue(gz, scope, rl, result, node); }, .field => { @@ -6745,9 +6733,6 @@ fn callExpr( call: ast.full.Call, ) InnerError!Zir.Inst.Ref { const astgen = gz.astgen; - if (call.async_token) |async_token| { - return astgen.failTok(async_token, "async and related features are not yet supported", .{}); - } const lhs = try expr(gz, scope, .none, call.ast.fn_expr); const args = try astgen.gpa.alloc(Zir.Inst.Ref, call.ast.params.len); @@ -6764,9 +6749,17 @@ fn callExpr( args[i] = try expr(gz, scope, .{ .ty = param_type }, param_node); } - const modifier: std.builtin.CallOptions.Modifier = switch (call.async_token != null) { - true => .async_kw, - false => .auto, + const modifier: std.builtin.CallOptions.Modifier = blk: { + if (gz.force_comptime) { + break :blk .compile_time; + } + if (call.async_token != null) { + break :blk .async_kw; + } + if (gz.nosuspend_node != 0) { + break :blk .no_async; + } + break :blk .auto; }; const result: Zir.Inst.Ref = res: { const tag: Zir.Inst.Tag = switch (modifier) { @@ -6774,10 +6767,10 @@ fn callExpr( true => break :res try gz.addUnNode(.call_none, lhs, node), false => .call, }, - .async_kw => return astgen.failNode(node, "async and related features are not yet supported", .{}), + .async_kw => .call_async, .never_tail => unreachable, .never_inline => unreachable, - .no_async => return astgen.failNode(node, "async and related features are not yet supported", .{}), + .no_async => .call_nosuspend, .always_tail => unreachable, .always_inline => unreachable, .compile_time => .call_compile_time, |
