fix optional-presence comparison

This commit is contained in:
2026-07-20 15:28:00 +02:00
parent deab47e75e
commit ec36b6b861
5 changed files with 138 additions and 17 deletions
+26
View File
@@ -1287,6 +1287,20 @@ ct_eval_expr :: proc(
types.is_concrete_integer(expected) {
left_expected = expected
}
left_expr := checker.ast_module.exprs[expr.left]
right_expr := checker.ast_module.exprs[expr.right]
if left_expr.kind == .None && right_expr.kind != .None &&
(expr.kind == .Eq || expr.kind == .Ne) {
right, right_flow, right_ok := ct_eval_expr(state, expr.right, types.INVALID, depth+1)
if !right_ok || right_flow.kind != .Normal {
return INVALID_CT_VALUE, right_flow, right_ok
}
left, flow, ok := ct_eval_expr(state, expr.left, state.values[right].type, depth+1)
if !ok || flow.kind != .Normal {
return INVALID_CT_VALUE, flow, ok
}
return ct_eval_binary(state, expr.kind, left, right, expr.span)
}
left, flow, ok := ct_eval_expr(state, expr.left, left_expected, depth+1)
if !ok || flow.kind != .Normal {
return INVALID_CT_VALUE, flow, ok
@@ -2118,6 +2132,18 @@ ct_eval_binary :: proc(state: ^Ct_State, op: ast.Expr_Kind, left_id, right_id: C
left := state.values[left_id]
right := state.values[right_id]
is_compare := op == .Eq || op == .Ne || op == .Lt || op == .Le || op == .Gt || op == .Ge
if left.kind == .None || right.kind == .None {
if (op != .Eq && op != .Ne) ||
!types.is_optional(left.type, &state.checker.module.types) ||
!types.equal(left.type, right.type) {
return INVALID_CT_VALUE, ct_flow(.Normal), ct_fail(state, .Not_Comptime, span, "'none' only supports '==' and '!=' with an optional value")
}
equal := left.kind == .None && right.kind == .None
if op == .Ne {
equal = !equal
}
return ct_add_value(state, Ct_Value{kind=.Bool, type=types.BOOL, integer=1 if equal else 0}), ct_flow(.Normal), true
}
if left.kind == .Type || right.kind == .Type {
if left.kind != .Type || right.kind != .Type || (op != .Eq && op != .Ne) {
return INVALID_CT_VALUE, ct_flow(.Normal), ct_fail(state, .Not_Comptime, span, "type values only support '==' and '!=' with another type")