authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-27 17:27:03-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-27 17:27:03-04:00
log02c5bda704d30e95e6af23804f9a552e9d8ca2d7
treebb7ebbd3bfd59dbf5ac9a97364feb57868a45281
parent442e244b4dd371d674436a163d62efdcd4e17a00

remove ability to break from suspend blocks

closes #803

5 files changed, 5 insertions(+), 42 deletions(-)

doc/langref.html.in+1-1
......@@ -7336,7 +7336,7 @@ Defer(body) = ("defer" | "deferror") body
73367336
73377337IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
73387338
7339SuspendExpression(body) = option(Symbol ":") "suspend" option(("|" Symbol "|" body))
7339SuspendExpression(body) = "suspend" option(("|" Symbol "|" body))
73407340
73417341IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)
73427342
src/all_types.hpp-2
......@@ -898,7 +898,6 @@ struct AstNodeAwaitExpr {
898898};
899899
900900struct AstNodeSuspend {
901 Buf *name;
902901 AstNode *block;
903902 AstNode *promise_symbol;
904903};
......@@ -1929,7 +1928,6 @@ struct ScopeLoop {
19291928struct ScopeSuspend {
19301929 Scope base;
19311930
1932 Buf *name;
19331931 IrBasicBlock *resume_block;
19341932 bool reported_err;
19351933};
src/analyze.cpp-1
......@@ -161,7 +161,6 @@ ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) {
161161 assert(node->type == NodeTypeSuspend);
162162 ScopeSuspend *scope = allocate<ScopeSuspend>(1);
163163 init_scope(&scope->base, ScopeIdSuspend, node, parent);
164 scope->name = node->data.suspend.name;
165164 return scope;
166165}
167166
src/ir.cpp+2-15
......@@ -6186,15 +6186,6 @@ static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scop
61866186 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
61876187}
61886188
6189static IrInstruction *ir_gen_break_from_suspend(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeSuspend *suspend_scope) {
6190 IrInstruction *is_comptime = ir_build_const_bool(irb, break_scope, node, false);
6191
6192 IrBasicBlock *dest_block = suspend_scope->resume_block;
6193 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false);
6194
6195 return ir_build_br(irb, break_scope, node, dest_block, is_comptime);
6196}
6197
61986189static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) {
61996190 assert(node->type == NodeTypeBreak);
62006191
......@@ -6235,12 +6226,8 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *
62356226 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope);
62366227 }
62376228 } else if (search_scope->id == ScopeIdSuspend) {
6238 ScopeSuspend *this_suspend_scope = (ScopeSuspend *)search_scope;
6239 if (node->data.break_expr.name != nullptr &&
6240 (this_suspend_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_suspend_scope->name)))
6241 {
6242 return ir_gen_break_from_suspend(irb, break_scope, node, this_suspend_scope);
6243 }
6229 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block"));
6230 return irb->codegen->invalid_instruction;
62446231 }
62456232 search_scope = search_scope->parent;
62466233 }
src/parser.cpp+2-23
......@@ -648,30 +648,12 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
648648}
649649
650650/*
651SuspendExpression(body) = option(Symbol ":") "suspend" option(("|" Symbol "|" body))
651SuspendExpression(body) = "suspend" option(("|" Symbol "|" body))
652652*/
653653static AstNode *ast_parse_suspend_block(ParseContext *pc, size_t *token_index, bool mandatory) {
654654 size_t orig_token_index = *token_index;
655655
656 Token *name_token = nullptr;
657 Token *token = &pc->tokens->at(*token_index);
658 if (token->id == TokenIdSymbol) {
659 *token_index += 1;
660 Token *colon_token = &pc->tokens->at(*token_index);
661 if (colon_token->id == TokenIdColon) {
662 *token_index += 1;
663 name_token = token;
664 token = &pc->tokens->at(*token_index);
665 } else if (mandatory) {
666 ast_expect_token(pc, colon_token, TokenIdColon);
667 zig_unreachable();
668 } else {
669 *token_index = orig_token_index;
670 return nullptr;
671 }
672 }
673
674 Token *suspend_token = token;
656 Token *suspend_token = &pc->tokens->at(*token_index);
675657 if (suspend_token->id == TokenIdKeywordSuspend) {
676658 *token_index += 1;
677659 } else if (mandatory) {
......@@ -693,9 +675,6 @@ static AstNode *ast_parse_suspend_block(ParseContext *pc, size_t *token_index, b
693675 }
694676
695677 AstNode *node = ast_create_node(pc, NodeTypeSuspend, suspend_token);
696 if (name_token != nullptr) {
697 node->data.suspend.name = token_buf(name_token);
698 }
699678 node->data.suspend.promise_symbol = ast_parse_symbol(pc, token_index);
700679 ast_eat_token(pc, token_index, TokenIdBinOr);
701680 node->data.suspend.block = ast_parse_block(pc, token_index, true);