| ... | @@ -2961,16 +2961,34 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco | ... | @@ -2961,16 +2961,34 @@ static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_sco |
| 2961 | results[ReturnKindUnconditional] = 0; | 2961 | results[ReturnKindUnconditional] = 0; |
| 2962 | results[ReturnKindError] = 0; | 2962 | results[ReturnKindError] = 0; |
| 2963 | | 2963 | |
| 2964 | while (inner_scope != outer_scope) { | 2964 | Scope *scope = inner_scope; |
| 2965 | assert(inner_scope); | | |
| 2966 | if (inner_scope->id == ScopeIdDefer) { | | |
| 2967 | AstNode *defer_node = inner_scope->source_node; | | |
| 2968 | assert(defer_node->type == NodeTypeDefer); | | |
| 2969 | ReturnKind defer_kind = defer_node->data.defer.kind; | | |
| 2970 | results[defer_kind] += 1; | | |
| 2971 | | 2965 | |
| | 2966 | while (scope != outer_scope) { |
| | 2967 | assert(scope); |
| | 2968 | switch (scope->id) { |
| | 2969 | case ScopeIdDefer: { |
| | 2970 | AstNode *defer_node = scope->source_node; |
| | 2971 | assert(defer_node->type == NodeTypeDefer); |
| | 2972 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| | 2973 | results[defer_kind] += 1; |
| | 2974 | scope = scope->parent; |
| | 2975 | continue; |
| | 2976 | } |
| | 2977 | case ScopeIdDecls: |
| | 2978 | case ScopeIdFnDef: |
| | 2979 | return; |
| | 2980 | case ScopeIdBlock: |
| | 2981 | case ScopeIdVarDecl: |
| | 2982 | case ScopeIdLoop: |
| | 2983 | case ScopeIdSuspend: |
| | 2984 | case ScopeIdCompTime: |
| | 2985 | scope = scope->parent; |
| | 2986 | continue; |
| | 2987 | case ScopeIdDeferExpr: |
| | 2988 | case ScopeIdCImport: |
| | 2989 | case ScopeIdCoroPrelude: |
| | 2990 | zig_unreachable(); |
| 2972 | } | 2991 | } |
| 2973 | inner_scope = inner_scope->parent; | | |
| 2974 | } | 2992 | } |
| 2975 | } | 2993 | } |
| 2976 | | 2994 | |
| ... | @@ -2986,27 +3004,43 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o | ... | @@ -2986,27 +3004,43 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o |
| 2986 | if (!scope) | 3004 | if (!scope) |
| 2987 | return is_noreturn; | 3005 | return is_noreturn; |
| 2988 | | 3006 | |
| 2989 | if (scope->id == ScopeIdDefer) { | 3007 | switch (scope->id) { |
| 2990 | AstNode *defer_node = scope->source_node; | 3008 | case ScopeIdDefer: { |
| 2991 | assert(defer_node->type == NodeTypeDefer); | 3009 | AstNode *defer_node = scope->source_node; |
| 2992 | ReturnKind defer_kind = defer_node->data.defer.kind; | 3010 | assert(defer_node->type == NodeTypeDefer); |
| 2993 | if (defer_kind == ReturnKindUnconditional || | 3011 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| 2994 | (gen_error_defers && defer_kind == ReturnKindError)) | 3012 | if (defer_kind == ReturnKindUnconditional || |
| 2995 | { | 3013 | (gen_error_defers && defer_kind == ReturnKindError)) |
| 2996 | AstNode *defer_expr_node = defer_node->data.defer.expr; | 3014 | { |
| 2997 | Scope *defer_expr_scope = defer_node->data.defer.expr_scope; | 3015 | AstNode *defer_expr_node = defer_node->data.defer.expr; |
| 2998 | IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); | 3016 | Scope *defer_expr_scope = defer_node->data.defer.expr_scope; |
| 2999 | if (defer_expr_value != irb->codegen->invalid_instruction) { | 3017 | IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); |
| 3000 | if (defer_expr_value->value.type != nullptr && defer_expr_value->value.type->id == TypeTableEntryIdUnreachable) { | 3018 | if (defer_expr_value != irb->codegen->invalid_instruction) { |
| 3001 | is_noreturn = true; | 3019 | if (defer_expr_value->value.type != nullptr && defer_expr_value->value.type->id == TypeTableEntryIdUnreachable) { |
| 3002 | } else { | 3020 | is_noreturn = true; |
| 3003 | ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, defer_expr_value)); | 3021 | } else { |
| | 3022 | ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, defer_expr_value)); |
| | 3023 | } |
| 3004 | } | 3024 | } |
| 3005 | } | 3025 | } |
| | 3026 | scope = scope->parent; |
| | 3027 | continue; |
| 3006 | } | 3028 | } |
| 3007 | | 3029 | case ScopeIdDecls: |
| | 3030 | case ScopeIdFnDef: |
| | 3031 | return is_noreturn; |
| | 3032 | case ScopeIdBlock: |
| | 3033 | case ScopeIdVarDecl: |
| | 3034 | case ScopeIdLoop: |
| | 3035 | case ScopeIdSuspend: |
| | 3036 | case ScopeIdCompTime: |
| | 3037 | scope = scope->parent; |
| | 3038 | continue; |
| | 3039 | case ScopeIdDeferExpr: |
| | 3040 | case ScopeIdCImport: |
| | 3041 | case ScopeIdCoroPrelude: |
| | 3042 | zig_unreachable(); |
| 3008 | } | 3043 | } |
| 3009 | scope = scope->parent; | | |
| 3010 | } | 3044 | } |
| 3011 | return is_noreturn; | 3045 | return is_noreturn; |
| 3012 | } | 3046 | } |