diff --git a/src/analyze.cpp b/src/analyze.cpp index f3f2a30dd8..ef23e896e3 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -4610,7 +4610,9 @@ bool resolve_inferred_error_set(CodeGen *g, ZigType *err_set_type, AstNode *sour return false; } else if (infer_fn->anal_state == FnAnalStateReady) { analyze_fn_body(g, infer_fn); - if (err_set_type->data.error_set.incomplete) { + if (infer_fn->anal_state == FnAnalStateInvalid || + err_set_type->data.error_set.incomplete) + { assert(g->errors.length != 0); return false; } diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 6bc21ce970..52e450dad4 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -571,7 +571,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { { const char *defer_str = defer_string(node->data.defer.kind); fprintf(ar->f, "%s ", defer_str); - render_node_grouped(ar, node->data.return_expr.expr); + render_node_grouped(ar, node->data.defer.expr); break; } case NodeTypeVariableDeclaration: diff --git a/src/ir.cpp b/src/ir.cpp index 2732f4e023..0ba9c605d5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5408,11 +5408,19 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * } bool is_continuation_unreachable = false; + bool found_invalid_inst = false; IrInstSrc *noreturn_return_value = nullptr; for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { AstNode *statement_node = block_node->data.block.statements.at(i); IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); + if (statement_value == irb->codegen->invalid_inst_src) { + // keep generating all the elements of the block in case of error, + // we want to collect other compile errors + found_invalid_inst = true; + continue; + } + is_continuation_unreachable = instr_is_unreachable(statement_value); if (is_continuation_unreachable) { // keep the last noreturn statement value around in case we need to return it @@ -5420,7 +5428,7 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * } // This logic must be kept in sync with // [STMT_EXPR_TEST_THING] <--- (search this token) - if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_inst_src) { + if (statement_node->type == NodeTypeDefer) { // defer starts a new scope child_scope = statement_node->data.defer.child_scope; assert(child_scope); @@ -5428,12 +5436,15 @@ static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode * // variable declarations start a new scope IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; child_scope = decl_var_instruction->var->child_scope; - } else if (statement_value != irb->codegen->invalid_inst_src && !is_continuation_unreachable) { + } else if (!is_continuation_unreachable) { // this statement's value must be void ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); } } + if (found_invalid_inst) + return irb->codegen->invalid_inst_src; + if (is_continuation_unreachable) { assert(noreturn_return_value != nullptr); if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { @@ -9905,6 +9916,8 @@ static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); Scope *child_scope = &suspend_scope->base; IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); + if (susp_res == irb->codegen->invalid_inst_src) + return irb->codegen->invalid_inst_src; ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); }