mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 22:58:46 +00:00
Fix update_untyped_expr_type for ternary if expressions with an untyped type
This commit is contained in:
+24
-3
@@ -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);
|
GB_ASSERT(o->mode == Addressing_Constant);
|
||||||
ExactValue out_value = o->value;
|
ExactValue out_value = o->value;
|
||||||
if (is_type_constant_type(type) && check_representable_as_constant(ctx, o->value, type, &out_value)) {
|
if (is_type_constant_type(type) && check_representable_as_constant(ctx, o->value, type, &out_value)) {
|
||||||
o->value = out_value;
|
o->value = out_value;
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
o->value = out_value;
|
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);
|
error(o->expr, "Cannot convert '%s' to '%s' from '%s", a, b, c);
|
||||||
check_assignment_error_suggestion(ctx, o, type);
|
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;
|
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) {
|
void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final) {
|
||||||
GB_ASSERT(e != nullptr);
|
GB_ASSERT(e != nullptr);
|
||||||
@@ -3253,8 +3265,17 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_untyped_expr_type(c, te->x, type, final);
|
// NOTE(bill): This is a bit of a hack to get around the edge cases of ternary if expressions
|
||||||
update_untyped_expr_type(c, te->y, type, final);
|
// 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_end;
|
||||||
|
|
||||||
case_ast_node(te, TernaryWhenExpr, e);
|
case_ast_node(te, TernaryWhenExpr, e);
|
||||||
|
|||||||
Reference in New Issue
Block a user