Skip to content

Commit

Permalink
v: allow option array element comparison == and != (fix vlang#23108
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Dec 9, 2024
1 parent d2d13a1 commit bc7a844
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 4 deletions.
6 changes: 3 additions & 3 deletions vlib/v/checker/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -897,9 +897,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
right_is_option := right_type.has_flag(.option)
if left_is_option || right_is_option {
opt_infix_pos := if left_is_option { left_pos } else { right_pos }
if (node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|| node.op in [.eq, .ne, .lt, .gt, .le, .ge]) && right_sym.kind != .none
&& !c.inside_sql {
if (node.left !in [ast.Ident, ast.IndexExpr, ast.SelectorExpr, ast.ComptimeSelector]
|| (node.op in [.eq, .ne] && !right_is_option)
|| node.op in [.lt, .gt, .le, .ge]) && right_sym.kind != .none && !c.inside_sql {
c.error('unwrapped Option cannot be used in an infix expression', opt_infix_pos)
}
}
Expand Down
16 changes: 15 additions & 1 deletion vlib/v/gen/c/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
g.gen_plain_infix_expr(node)
return
}
is_none_check := left_type.has_flag(.option) && node.right is ast.None
left_is_option := left_type.has_flag(.option)
right_is_option := right_type.has_flag(.option)
is_none_check := left_is_option && node.right is ast.None
if is_none_check {
g.gen_is_none_check(node)
} else if (left.typ.is_ptr() && right.typ.is_int())
Expand Down Expand Up @@ -367,6 +369,18 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
signed_type: left.unaliased
signed_expr: node.left
)
} else if left_is_option && right_is_option {
old_inside_opt_or_res := g.inside_opt_or_res
g.inside_opt_or_res = true
if node.op == .eq {
g.write('!')
}
g.write('memcmp(')
g.expr(node.left)
g.write('.data, ')
g.expr(node.right)
g.write('.data, sizeof(${g.base_type(left_type)}))')
g.inside_opt_or_res = old_inside_opt_or_res
} else {
g.gen_plain_infix_expr(node)
}
Expand Down
7 changes: 7 additions & 0 deletions vlib/v/tests/options/option_indexexpr_eq_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn test_main() {
x := []?int{len: 5, init: 1}
assert x[0] == x[1]

y := []?int{len: 4, init: 2}
assert !(x[0] == y[1])
}

0 comments on commit bc7a844

Please sign in to comment.