| author | |
| committer | |
| log | fc9c1b4e4ae86c36a7ff29859cc589a9816ab7d5 |
| tree | c5472fe8e6a291831de78e0914741bf724d82b5a |
| parent | f270bef9a4d21e880826cef6b5264acdc84f0a6f |
| parent | 2d286100ef7ae87a71af1ace0002398d405e33d2 |
| signature |
stage1: allow async and resume inside nosuspend blocks3 files changed, 64 insertions(+), 13 deletions(-)
src/stage1/ir.cpp+1-10| ... | @@ -7641,12 +7641,7 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, | ... | @@ -7641,12 +7641,7 @@ static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, |
| 7641 | 7641 | ||
| 7642 | bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; | 7642 | bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; |
| 7643 | CallModifier modifier = node->data.fn_call_expr.modifier; | 7643 | CallModifier modifier = node->data.fn_call_expr.modifier; |
| 7644 | if (is_nosuspend) { | 7644 | if (is_nosuspend && modifier != CallModifierAsync) { |
| 7645 | if (modifier == CallModifierAsync) { | ||
| 7646 | add_node_error(irb->codegen, node, | ||
| 7647 | buf_sprintf("async call in nosuspend scope")); | ||
| 7648 | return irb->codegen->invalid_inst_src; | ||
| 7649 | } | ||
| 7650 | modifier = CallModifierNoSuspend; | 7645 | modifier = CallModifierNoSuspend; |
| 7651 | } | 7646 | } |
| 7652 | 7647 | ||
| ... | @@ -10129,10 +10124,6 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod | ... | @@ -10129,10 +10124,6 @@ static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNod |
| 10129 | 10124 | ||
| 10130 | static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { | 10125 | static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { |
| 10131 | assert(node->type == NodeTypeResume); | 10126 | assert(node->type == NodeTypeResume); |
| 10132 | if (get_scope_nosuspend(scope) != nullptr) { | ||
| 10133 | add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope")); | ||
| 10134 | return irb->codegen->invalid_inst_src; | ||
| 10135 | } | ||
| 10136 | 10127 | ||
| 10137 | IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); | 10128 | IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); |
| 10138 | if (target_inst == irb->codegen->invalid_inst_src) | 10129 | if (target_inst == irb->codegen->invalid_inst_src) |
test/compile_errors.zig-2| ... | @@ -1027,9 +1027,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1027,9 +1027,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1027 | \\} | 1027 | \\} |
| 1028 | \\fn foo() void {} | 1028 | \\fn foo() void {} |
| 1029 | , &[_][]const u8{ | 1029 | , &[_][]const u8{ |
| 1030 | "tmp.zig:3:21: error: async call in nosuspend scope", | ||
| 1031 | "tmp.zig:4:9: error: suspend in nosuspend scope", | 1030 | "tmp.zig:4:9: error: suspend in nosuspend scope", |
| 1032 | "tmp.zig:5:9: error: resume in nosuspend scope", | ||
| 1033 | }); | 1031 | }); |
| 1034 | 1032 | ||
| 1035 | cases.add("atomicrmw with bool op not .Xchg", | 1033 | cases.add("atomicrmw with bool op not .Xchg", |
test/stage1/behavior/async_fn.zig+63-1| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = std.builtin; |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | const expectEqual = std.testing.expectEqual; | 4 | const expectEqual = std.testing.expectEqual; |
| 5 | const expectEqualStrings = std.testing.expectEqualStrings; | 5 | const expectEqualStrings = std.testing.expectEqualStrings; |
| ... | @@ -1545,6 +1545,68 @@ test "nosuspend on function calls" { | ... | @@ -1545,6 +1545,68 @@ test "nosuspend on function calls" { |
| 1545 | expectEqual(@as(i32, 42), (try nosuspend S1.d()).b); | 1545 | expectEqual(@as(i32, 42), (try nosuspend S1.d()).b); |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | test "nosuspend on async function calls" { | ||
| 1549 | const S0 = struct { | ||
| 1550 | b: i32 = 42, | ||
| 1551 | }; | ||
| 1552 | const S1 = struct { | ||
| 1553 | fn c() S0 { | ||
| 1554 | return S0{}; | ||
| 1555 | } | ||
| 1556 | fn d() !S0 { | ||
| 1557 | return S0{}; | ||
| 1558 | } | ||
| 1559 | }; | ||
| 1560 | var frame_c = nosuspend async S1.c(); | ||
| 1561 | expectEqual(@as(i32, 42), (await frame_c).b); | ||
| 1562 | var frame_d = nosuspend async S1.d(); | ||
| 1563 | expectEqual(@as(i32, 42), (try await frame_d).b); | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | // test "resume nosuspend async function calls" { | ||
| 1567 | // const S0 = struct { | ||
| 1568 | // b: i32 = 42, | ||
| 1569 | // }; | ||
| 1570 | // const S1 = struct { | ||
| 1571 | // fn c() S0 { | ||
| 1572 | // suspend; | ||
| 1573 | // return S0{}; | ||
| 1574 | // } | ||
| 1575 | // fn d() !S0 { | ||
| 1576 | // suspend; | ||
| 1577 | // return S0{}; | ||
| 1578 | // } | ||
| 1579 | // }; | ||
| 1580 | // var frame_c = nosuspend async S1.c(); | ||
| 1581 | // resume frame_c; | ||
| 1582 | // expectEqual(@as(i32, 42), (await frame_c).b); | ||
| 1583 | // var frame_d = nosuspend async S1.d(); | ||
| 1584 | // resume frame_d; | ||
| 1585 | // expectEqual(@as(i32, 42), (try await frame_d).b); | ||
| 1586 | // } | ||
| 1587 | |||
| 1588 | test "nosuspend resume async function calls" { | ||
| 1589 | const S0 = struct { | ||
| 1590 | b: i32 = 42, | ||
| 1591 | }; | ||
| 1592 | const S1 = struct { | ||
| 1593 | fn c() S0 { | ||
| 1594 | suspend; | ||
| 1595 | return S0{}; | ||
| 1596 | } | ||
| 1597 | fn d() !S0 { | ||
| 1598 | suspend; | ||
| 1599 | return S0{}; | ||
| 1600 | } | ||
| 1601 | }; | ||
| 1602 | var frame_c = async S1.c(); | ||
| 1603 | nosuspend resume frame_c; | ||
| 1604 | expectEqual(@as(i32, 42), (await frame_c).b); | ||
| 1605 | var frame_d = async S1.d(); | ||
| 1606 | nosuspend resume frame_d; | ||
| 1607 | expectEqual(@as(i32, 42), (try await frame_d).b); | ||
| 1608 | } | ||
| 1609 | |||
| 1548 | test "avoid forcing frame alignment resolution implicit cast to *c_void" { | 1610 | test "avoid forcing frame alignment resolution implicit cast to *c_void" { |
| 1549 | const S = struct { | 1611 | const S = struct { |
| 1550 | var x: ?*c_void = null; | 1612 | var x: ?*c_void = null; |