| ... | ... | @@ -1980,7 +1980,7 @@ static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o |
| 1980 | 1980 | (gen_maybe_defers && defer_kind == ReturnKindMaybe)) |
| 1981 | 1981 | { |
| 1982 | 1982 | AstNode *defer_expr_node = defer_node->data.defer.expr; |
| 1983 | | ir_gen_node(irb, defer_expr_node, defer_node->data.defer.parent_scope); |
| 1983 | ir_gen_node(irb, defer_expr_node, defer_node->data.defer.expr_scope); |
| 1984 | 1984 | } |
| 1985 | 1985 | |
| 1986 | 1986 | } |
| ... | ... | @@ -1994,6 +1994,18 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { |
| 1994 | 1994 | irb->current_basic_block = basic_block; |
| 1995 | 1995 | } |
| 1996 | 1996 | |
| 1997 | static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { |
| 1998 | while (scope) { |
| 1999 | if (scope->id == ScopeIdDeferExpr) |
| 2000 | return (ScopeDeferExpr *)scope; |
| 2001 | if (scope->id == ScopeIdFnDef) |
| 2002 | return nullptr; |
| 2003 | |
| 2004 | scope = scope->parent; |
| 2005 | } |
| 2006 | return nullptr; |
| 2007 | } |
| 2008 | |
| 1997 | 2009 | static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LValPurpose lval) { |
| 1998 | 2010 | assert(node->type == NodeTypeReturnExpr); |
| 1999 | 2011 | |
| ... | ... | @@ -2003,6 +2015,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2003 | 2015 | return irb->codegen->invalid_instruction; |
| 2004 | 2016 | } |
| 2005 | 2017 | |
| 2018 | ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); |
| 2019 | if (scope_defer_expr) { |
| 2020 | if (!scope_defer_expr->reported_err) { |
| 2021 | add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); |
| 2022 | scope_defer_expr->reported_err = true; |
| 2023 | } |
| 2024 | return irb->codegen->invalid_instruction; |
| 2025 | } |
| 2026 | |
| 2006 | 2027 | Scope *outer_scope = fn_entry->child_scope; |
| 2007 | 2028 | |
| 2008 | 2029 | AstNode *expr_node = node->data.return_expr.expr; |
| ... | ... | @@ -2593,6 +2614,8 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2593 | 2614 | return irb->codegen->invalid_instruction; |
| 2594 | 2615 | } |
| 2595 | 2616 | |
| 2617 | // TODO put a variable of same name with invalid type in global scope |
| 2618 | // so that future references to this same name will find a variable with an invalid type |
| 2596 | 2619 | add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); |
| 2597 | 2620 | return irb->codegen->invalid_instruction; |
| 2598 | 2621 | } |
| ... | ... | @@ -4012,9 +4035,11 @@ static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 4012 | 4035 | static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { |
| 4013 | 4036 | assert(node->type == NodeTypeDefer); |
| 4014 | 4037 | |
| 4015 | | ScopeDefer *defer_scope = create_defer_scope(node, parent_scope); |
| 4016 | | node->data.defer.child_scope = &defer_scope->base; |
| 4017 | | node->data.defer.parent_scope = parent_scope; |
| 4038 | ScopeDefer *defer_child_scope = create_defer_scope(node, parent_scope); |
| 4039 | node->data.defer.child_scope = &defer_child_scope->base; |
| 4040 | |
| 4041 | ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(node, parent_scope); |
| 4042 | node->data.defer.expr_scope = &defer_expr_scope->base; |
| 4018 | 4043 | |
| 4019 | 4044 | return ir_build_const_void(irb, parent_scope, node); |
| 4020 | 4045 | } |
| ... | ... | @@ -4665,6 +4690,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 4665 | 4690 | ir_add_error_node(ira, source_node, |
| 4666 | 4691 | buf_sprintf("unable to make error union out of null literal")); |
| 4667 | 4692 | return ira->codegen->builtin_types.entry_invalid; |
| 4693 | } else if (prev_inst->value.type->id == TypeTableEntryIdErrorUnion) { |
| 4694 | return prev_inst->value.type; |
| 4668 | 4695 | } else { |
| 4669 | 4696 | return get_error_type(ira->codegen, prev_inst->value.type); |
| 4670 | 4697 | } |
| ... | ... | @@ -4675,6 +4702,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 4675 | 4702 | ir_add_error_node(ira, source_node, |
| 4676 | 4703 | buf_sprintf("unable to make maybe out of number literal")); |
| 4677 | 4704 | return ira->codegen->builtin_types.entry_invalid; |
| 4705 | } else if (prev_inst->value.type->id == TypeTableEntryIdMaybe) { |
| 4706 | return prev_inst->value.type; |
| 4678 | 4707 | } else { |
| 4679 | 4708 | return get_maybe_type(ira->codegen, prev_inst->value.type); |
| 4680 | 4709 | } |
| ... | ... | @@ -9955,6 +9984,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 9955 | 9984 | static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 9956 | 9985 | IrInstructionUnwrapErrPayload *instruction) |
| 9957 | 9986 | { |
| 9987 | assert(instruction->value->other); |
| 9958 | 9988 | IrInstruction *value = instruction->value->other; |
| 9959 | 9989 | if (value->value.type->id == TypeTableEntryIdInvalid) |
| 9960 | 9990 | return ira->codegen->builtin_types.entry_invalid; |