diff --git a/example/guess_number/main.zig b/example/guess_number/main.zig index 0090da9644..6414542362 100644 --- a/example/guess_number/main.zig +++ b/example/guess_number/main.zig @@ -3,7 +3,10 @@ export executable "guess_number"; import "std.zig"; import "rand.zig"; -pub fn main(args: [][]u8) i32 => { +%.GetRandomFail; +%.ReadInputFail; + +pub fn main(args: [][]u8) %void => { print_str("Welcome to the Guess Number Game in Zig.\n"); var seed : u32; @@ -12,7 +15,7 @@ pub fn main(args: [][]u8) i32 => { if (err != @sizeof(u32)) { // TODO full error message fprint_str(stderr_fileno, "unable to get random bytes\n"); - return 1; + return %.GetRandomFail; } var rand : Rand; @@ -28,7 +31,7 @@ pub fn main(args: [][]u8) i32 => { if (readline(line_buf, &line_len) || line_len == line_buf.len) { // TODO full error message fprint_str(stderr_fileno, "unable to read input\n"); - return 1; + return %.ReadInputFail; } var guess : u64; @@ -40,7 +43,7 @@ pub fn main(args: [][]u8) i32 => { print_str("Guess higher.\n"); } else { print_str("You win!\n"); - return 0; + return; } } } diff --git a/src/analyze.cpp b/src/analyze.cpp index a137fdb3cb..7553796ec3 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -1344,6 +1344,16 @@ static AstNode *create_ast_type_node(CodeGen *g, ImportTableEntry *import, TypeT return node; } +static AstNode *create_ast_void_node(CodeGen *g, ImportTableEntry *import, AstNode *source_node) { + AstNode *node = create_ast_node(g, import, NodeTypeContainerInitExpr); + node->data.container_init_expr.kind = ContainerInitKindArray; + node->data.container_init_expr.type = create_ast_type_node(g, import, g->builtin_types.entry_void); + node->line = source_node->line; + node->column = source_node->column; + normalize_parent_ptrs(node); + return node; +} + static TypeTableEntry *create_and_analyze_cast_node(CodeGen *g, ImportTableEntry *import, BlockContext *context, TypeTableEntry *cast_to_type, AstNode *node) { @@ -3596,25 +3606,17 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, return g->builtin_types.entry_invalid; } + if (!node->data.return_expr.expr) { + node->data.return_expr.expr = create_ast_void_node(g, import, node); + normalize_parent_ptrs(node); + } + if (node->data.return_expr.kind != ReturnKindUnconditional) { zig_panic("TODO analyze_return_expr conditional"); } TypeTableEntry *expected_return_type = get_return_type(context); - TypeTableEntry *actual_return_type; - if (node->data.return_expr.expr) { - actual_return_type = analyze_expression(g, import, context, expected_return_type, node->data.return_expr.expr); - } else { - actual_return_type = g->builtin_types.entry_void; - } - - if (actual_return_type->id == TypeTableEntryIdUnreachable) { - // "return exit(0)" should just be "exit(0)". - add_node_error(g, node, buf_sprintf("returning is unreachable")); - actual_return_type = g->builtin_types.entry_invalid; - } - - resolve_type_compatibility(g, import, context, node, expected_return_type, actual_return_type); + analyze_expression(g, import, context, expected_return_type, node->data.return_expr.expr); return g->builtin_types.entry_unreachable; } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 2af6d5d29f..e6f7d2a01e 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -1226,6 +1226,15 @@ pub fn main(args: [][]u8) %void => { } )SOURCE", "OK\n"); + add_simple_case("return with implicit cast from while loop", R"SOURCE( +import "std.zig"; +pub fn main(args: [][]u8) %void => { + while (true) { + print_str("OK\n"); + return; + } +} + )SOURCE", "OK\n"); }