diff --git a/doc/langref.md b/doc/langref.md index dcbf3b03df..040acf2eca 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -85,9 +85,9 @@ ForExpression(body) = "for" "(" Expression ")" option("|" option("*") Symbol opt BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression -ReturnExpression = option("%" | "?") "return" option(Expression) +ReturnExpression = option("%") "return" option(Expression) -Defer(body) = option("%" | "?") "defer" body +Defer(body) = option("%") "defer" body IfExpression(body) = IfVarExpression(body) | IfBoolExpression(body) diff --git a/example/README.md b/example/README.md index 5b53f596b8..f36ec7e531 100644 --- a/example/README.md +++ b/example/README.md @@ -11,8 +11,6 @@ libc. * **cat** - implementation of the `cat` UNIX utility in Zig, with no dependency on libc. - -## Work-In-Progress Examples - * **shared_library** - demonstration of building a shared library and generating - a header file and documentation for interop with C code. + a header file for interop with C code. + * **mix_o_files** - how to mix .zig and .c files together as object files diff --git a/src/all_types.hpp b/src/all_types.hpp index fc5b6efb1a..2e21cdc86d 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -408,7 +408,6 @@ struct AstNodeBlock { enum ReturnKind { ReturnKindUnconditional, - ReturnKindMaybe, ReturnKindError, }; diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 17f285008b..fb9a25eaa2 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -92,7 +92,6 @@ static const char *return_string(ReturnKind kind) { switch (kind) { case ReturnKindUnconditional: return "return"; case ReturnKindError: return "%return"; - case ReturnKindMaybe: return "?return"; } zig_unreachable(); } @@ -101,7 +100,6 @@ static const char *defer_string(ReturnKind kind) { switch (kind) { case ReturnKindUnconditional: return "defer"; case ReturnKindError: return "%defer"; - case ReturnKindMaybe: return "?defer"; } zig_unreachable(); } diff --git a/src/ir.cpp b/src/ir.cpp index b1de817499..f4e2673030 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3091,7 +3091,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { results[ReturnKindUnconditional] = 0; results[ReturnKindError] = 0; - results[ReturnKindMaybe] = 0; while (inner_scope != outer_scope) { assert(inner_scope); @@ -3111,9 +3110,7 @@ static IrInstruction *ir_mark_gen(IrInstruction *instruction) { return instruction; } -static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, - bool gen_error_defers, bool gen_maybe_defers) -{ +static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { Scope *scope = inner_scope; while (scope != outer_scope) { if (!scope) @@ -3124,8 +3121,7 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o assert(defer_node->type == NodeTypeDefer); ReturnKind defer_kind = defer_node->data.defer.kind; if (defer_kind == ReturnKindUnconditional || - (gen_error_defers && defer_kind == ReturnKindError) || - (gen_maybe_defers && defer_kind == ReturnKindMaybe)) + (gen_error_defers && defer_kind == ReturnKindError)) { AstNode *defer_expr_node = defer_node->data.defer.expr; ir_gen_node(irb, defer_expr_node, defer_node->data.defer.expr_scope); @@ -3188,7 +3184,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, return_value = ir_build_const_void(irb, scope, node); } - size_t defer_counts[3]; + size_t defer_counts[2]; ir_count_defers(irb, scope, outer_scope, defer_counts); if (defer_counts[ReturnKindError] > 0) { IrBasicBlock *err_block = ir_build_basic_block(irb, scope, "ErrRetErr"); @@ -3206,37 +3202,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); ir_set_cursor_at_end(irb, err_block); - ir_gen_defers_for_block(irb, scope, outer_scope, true, false); + ir_gen_defers_for_block(irb, scope, outer_scope, true); ir_build_return(irb, scope, node, return_value); ir_set_cursor_at_end(irb, ok_block); - ir_gen_defers_for_block(irb, scope, outer_scope, false, false); - return ir_build_return(irb, scope, node, return_value); - } else if (defer_counts[ReturnKindMaybe] > 0) { - IrBasicBlock *null_block = ir_build_basic_block(irb, scope, "MaybeRetNull"); - IrBasicBlock *ok_block = ir_build_basic_block(irb, scope, "MaybeRetOk"); - - IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, return_value); - - IrInstruction *is_comptime; - if (ir_should_inline(irb->exec, scope)) { - is_comptime = ir_build_const_bool(irb, scope, node, true); - } else { - is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); - } - - ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime)); - - ir_set_cursor_at_end(irb, null_block); - ir_gen_defers_for_block(irb, scope, outer_scope, false, true); - ir_build_return(irb, scope, node, return_value); - - ir_set_cursor_at_end(irb, ok_block); - ir_gen_defers_for_block(irb, scope, outer_scope, false, false); + ir_gen_defers_for_block(irb, scope, outer_scope, false); return ir_build_return(irb, scope, node, return_value); } else { // generate unconditional defers - ir_gen_defers_for_block(irb, scope, outer_scope, false, false); + ir_gen_defers_for_block(irb, scope, outer_scope, false); return ir_build_return(irb, scope, node, return_value); } } @@ -3255,7 +3229,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); ir_set_cursor_at_end(irb, return_block); - ir_gen_defers_for_block(irb, scope, outer_scope, true, false); + ir_gen_defers_for_block(irb, scope, outer_scope, true); IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); ir_build_return(irb, scope, node, err_val); @@ -3266,32 +3240,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, else return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); } - case ReturnKindMaybe: - { - assert(expr_node); - IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); - if (maybe_val_ptr == irb->codegen->invalid_instruction) - return irb->codegen->invalid_instruction; - IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); - IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); - - IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "MaybeRetReturn"); - IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "MaybeRetContinue"); - IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb->exec, scope)); - ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime)); - - ir_set_cursor_at_end(irb, return_block); - ir_gen_defers_for_block(irb, scope, outer_scope, false, true); - IrInstruction *null = ir_build_const_null(irb, scope, node); - ir_build_return(irb, scope, node, null); - - ir_set_cursor_at_end(irb, continue_block); - IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_val_ptr, false); - if (lval.is_ptr) - return unwrapped_ptr; - else - return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); - } } zig_unreachable(); } @@ -3490,7 +3438,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); } - ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false, false); + ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); } assert(return_value != nullptr); @@ -5420,7 +5368,7 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *scope, AstNode *node) } IrBasicBlock *dest_block = loop_stack_item->break_block; - ir_gen_defers_for_block(irb, scope, dest_block->scope, false, false); + ir_gen_defers_for_block(irb, scope, dest_block->scope, false); return ir_build_br(irb, scope, node, dest_block, is_comptime); } @@ -5443,7 +5391,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod } IrBasicBlock *dest_block = loop_stack_item->continue_block; - ir_gen_defers_for_block(irb, scope, dest_block->scope, false, false); + ir_gen_defers_for_block(irb, scope, dest_block->scope, false); return ir_build_br(irb, scope, node, dest_block, is_comptime); } @@ -5784,7 +5732,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { IrInstruction *is_comptime = ir_build_const_bool(irb, goto_item->scope, source_node, ir_should_inline(irb->exec, goto_item->scope) || source_node->data.goto_expr.is_inline); - if (!ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false, false)) { + if (!ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false)) { add_node_error(irb->codegen, source_node, buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); return false; diff --git a/src/parser.cpp b/src/parser.cpp index a4e8e3c464..5349154a39 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1483,7 +1483,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma } /* -ReturnExpression : option("%" | "?") "return" option(Expression) +ReturnExpression : option("%") "return" option(Expression) */ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { Token *token = &pc->tokens->at(*token_index); @@ -1500,15 +1500,6 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { } else { return nullptr; } - } else if (token->id == TokenIdMaybe) { - Token *next_token = &pc->tokens->at(*token_index + 1); - if (next_token->id == TokenIdKeywordReturn) { - kind = ReturnKindMaybe; - node_type = NodeTypeReturnExpr; - *token_index += 2; - } else { - return nullptr; - } } else if (token->id == TokenIdKeywordReturn) { kind = ReturnKindUnconditional; node_type = NodeTypeReturnExpr; @@ -1525,7 +1516,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) { } /* -Defer(body) = option("%" | "?") "defer" body +Defer(body) = option("%") "defer" body */ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) { Token *token = &pc->tokens->at(*token_index); @@ -1542,15 +1533,6 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) { } else { return nullptr; } - } else if (token->id == TokenIdMaybe) { - Token *next_token = &pc->tokens->at(*token_index + 1); - if (next_token->id == TokenIdKeywordDefer) { - kind = ReturnKindMaybe; - node_type = NodeTypeDefer; - *token_index += 2; - } else { - return nullptr; - } } else if (token->id == TokenIdKeywordDefer) { kind = ReturnKindUnconditional; node_type = NodeTypeDefer; diff --git a/test/cases/defer.zig b/test/cases/defer.zig index ecee63bf89..90f3b35d50 100644 --- a/test/cases/defer.zig +++ b/test/cases/defer.zig @@ -13,14 +13,6 @@ fn runSomeErrorDefers(x: bool) -> %bool { return if (x) x else error.FalseNotAllowed; } -fn runSomeMaybeDefers(x: bool) -> ?bool { - index = 0; - defer {result[index] = 'a'; index += 1;}; - ?defer {result[index] = 'b'; index += 1;}; - defer {result[index] = 'c'; index += 1;}; - return if (x) x else null; -} - test "mixingNormalAndErrorDefers" { assert(%%runSomeErrorDefers(true)); assert(result[0] == 'c'); @@ -35,15 +27,3 @@ test "mixingNormalAndErrorDefers" { assert(result[1] == 'b'); assert(result[2] == 'a'); } - -test "mixingNormalAndMaybeDefers" { - assert(??runSomeMaybeDefers(true)); - assert(result[0] == 'c'); - assert(result[1] == 'a'); - - const ok = runSomeMaybeDefers(false) ?? true; - assert(ok); - assert(result[0] == 'c'); - assert(result[1] == 'b'); - assert(result[2] == 'a'); -} diff --git a/test/cases/null.zig b/test/cases/null.zig index 94852f1555..ad0b53ddec 100644 --- a/test/cases/null.zig +++ b/test/cases/null.zig @@ -42,7 +42,7 @@ test "rhsMaybeUnwrapReturn" { } -test "maybeReturn" { +test "maybe return" { maybeReturnImpl(); comptime maybeReturnImpl(); } @@ -54,7 +54,7 @@ fn maybeReturnImpl() { } fn foo(x: ?i32) -> ?bool { - const value = ?return x; + const value = x ?? return null; return value > 1234; }