fix optional-presence comparison
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user