diff options
| author | gingerBill <bill@gingerbill.org> | 2022-08-05 12:19:57 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-08-05 12:19:57 +0100 |
| commit | a58e4d035964275ade5e09fa6bcafb5d46cc46e2 (patch) | |
| tree | 85c404591463f4a19d46af638939a92b22ac28db /src/check_expr.cpp | |
| parent | 576914aee1565618d8448a2bbc3cbef0c4acc4d1 (diff) | |
Allow for `foo() or_else unreachable()` and other diverging procedures
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index cf9f2f751..96adde013 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -119,6 +119,7 @@ void check_or_else_split_types(CheckerContext *c, Operand *x, String const &name void check_or_else_expr_no_value_error(CheckerContext *c, String const &name, Operand const &x, Type *type_hint); void check_or_return_split_types(CheckerContext *c, Operand *x, String const &name, Type **left_type_, Type **right_type_); +bool is_diverging_expr(Ast *expr); void check_did_you_mean_print(DidYouMeanAnswers *d, char const *prefix = "") { auto results = did_you_mean_results(d); @@ -7399,8 +7400,25 @@ ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type return Expr_Expr; } - check_multi_expr_with_type_hint(c, &y, default_value, x.type); - error_operand_no_value(&y); + bool y_is_diverging = false; + check_expr_base(c, &y, default_value, x.type); + switch (y.mode) { + case Addressing_NoValue: + if (is_diverging_expr(y.expr)) { + // Allow + y.mode = Addressing_Value; + y_is_diverging = true; + } else { + error_operand_no_value(&y); + y.mode = Addressing_Invalid; + } + break; + case Addressing_Type: + error_operand_not_expression(&y); + y.mode = Addressing_Invalid; + break; + } + if (y.mode == Addressing_Invalid) { o->mode = Addressing_Value; o->type = t_invalid; @@ -7414,7 +7432,9 @@ ExprKind check_or_else_expr(CheckerContext *c, Operand *o, Ast *node, Type *type add_type_and_value(&c->checker->info, arg, x.mode, x.type, x.value); if (left_type != nullptr) { - check_assignment(c, &y, left_type, name); + if (!y_is_diverging) { + check_assignment(c, &y, left_type, name); + } } else { check_or_else_expr_no_value_error(c, name, x, type_hint); } |