diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 3c884d117..560e5e607 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1837,11 +1837,12 @@ void check_cast_error_suggestion(CheckerContext *c, Operand *o, Type *type) { } -void check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { +bool check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { GB_ASSERT(o->mode == Addressing_Constant); ExactValue out_value = o->value; if (is_type_constant_type(type) && check_representable_as_constant(ctx, o->value, type, &out_value)) { o->value = out_value; + return true; } else { o->value = out_value; @@ -1866,6 +1867,7 @@ void check_is_expressible(CheckerContext *ctx, Operand *o, Type *type) { error(o->expr, "Cannot convert '%s' to '%s' from '%s", a, b, c); check_assignment_error_suggestion(ctx, o, type); } + return false; } } @@ -3204,6 +3206,16 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint x->mode = Addressing_Value; } +Operand make_operand_from_node(Ast *node) { + GB_ASSERT(node != nullptr); + Operand x = {}; + x.expr = node; + x.mode = node->tav.mode; + x.type = node->tav.type; + x.value = node->tav.value; + return x; +} + void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) { GB_ASSERT(e != nullptr); @@ -3252,9 +3264,18 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) // See above note in UnaryExpr case break; } - - update_untyped_expr_type(c, te->x, type, final); - update_untyped_expr_type(c, te->y, type, final); + + // NOTE(bill): This is a bit of a hack to get around the edge cases of ternary if expressions + // having an untyped value + Operand x = make_operand_from_node(te->x); + Operand y = make_operand_from_node(te->y); + if (x.mode != Addressing_Constant || check_is_expressible(c, &x, type)) { + update_untyped_expr_type(c, te->x, type, final); + } + if (y.mode != Addressing_Constant || check_is_expressible(c, &y, type)) { + update_untyped_expr_type(c, te->y, type, final); + } + case_end; case_ast_node(te, TernaryWhenExpr, e);