diff options
| author | gingerBill <gingerBill@users.noreply.github.com> | 2025-11-02 15:27:33 +0000 |
|---|---|---|
| committer | gingerBill <gingerBill@users.noreply.github.com> | 2025-11-02 15:27:33 +0000 |
| commit | d8f26720bba78c00d3311ad89e6a3a55de13c7f1 (patch) | |
| tree | bea5cbb63ebf3cdc526cb5ad159284a3eca51ea9 /src/check_expr.cpp | |
| parent | 2d5b431b859754666b8342f042fa98413cb4fa29 (diff) | |
Improve error handling for #5506
Diffstat (limited to 'src/check_expr.cpp')
| -rw-r--r-- | src/check_expr.cpp | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e02fee05e..8ac277917 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9200,6 +9200,52 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A return kind; } + +gb_internal void check_expr_as_value_for_ternary(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { + check_expr_base(c, o, e, type_hint); + check_not_tuple(c, o); + error_operand_no_value(o); + + switch (o->mode) { + case Addressing_Type: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "A type '%s' cannot be used as a runtime value", expr_str); + + error_line("\tSuggestion: If a runtime 'typeid' is wanted, use 'typeid_of' to convert a type\n"); + + o->mode = Addressing_Invalid; + + } break; + + case Addressing_Builtin: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "A built-in procedure '%s' cannot be used as a runtime value", expr_str); + + error_line("\tNote: Built-in procedures are implemented by the compiler and might not be actually instantiated procedures\n"); + + o->mode = Addressing_Invalid; + } break; + + case Addressing_ProcGroup: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "Cannot use overloaded procedure '%s' as a runtime value", expr_str); + + error_line("\tNote: Please specify which procedure in the procedure group to use, via cast or type inference\n"); + + o->mode = Addressing_Invalid; + } break; + } +} + gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {Addressing_Invalid}; @@ -9213,7 +9259,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n Operand x = {Addressing_Invalid}; Operand y = {Addressing_Invalid}; - check_expr_or_type(c, &x, te->x, type_hint); + check_expr_as_value_for_ternary(c, &x, te->x, type_hint); node->viral_state_flags |= te->x->viral_state_flags; if (te->y != nullptr) { @@ -9221,7 +9267,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n if (type_hint == nullptr && is_type_typed(x.type)) { th = x.type; } - check_expr_or_type(c, &y, te->y, th); + check_expr_as_value_for_ternary(c, &y, te->y, th); node->viral_state_flags |= te->y->viral_state_flags; } else { error(node, "A ternary expression must have an else clause"); |