v: allow option array element comparison == and != (fix #23108) (#23113)

This commit is contained in:
Felipe Pena 2024-12-09 15:34:18 -03:00 committed by GitHub
parent d2d13a13f2
commit bc7a844a64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 25 additions and 4 deletions

View file

@ -897,9 +897,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
right_is_option := right_type.has_flag(.option) right_is_option := right_type.has_flag(.option)
if left_is_option || right_is_option { if left_is_option || right_is_option {
opt_infix_pos := if left_is_option { left_pos } else { right_pos } opt_infix_pos := if left_is_option { left_pos } else { right_pos }
if (node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector] if (node.left !in [ast.Ident, ast.IndexExpr, ast.SelectorExpr, ast.ComptimeSelector]
|| node.op in [.eq, .ne, .lt, .gt, .le, .ge]) && right_sym.kind != .none || (node.op in [.eq, .ne] && !right_is_option)
&& !c.inside_sql { || 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) c.error('unwrapped Option cannot be used in an infix expression', opt_infix_pos)
} }
} }

View file

@ -112,7 +112,9 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
g.gen_plain_infix_expr(node) g.gen_plain_infix_expr(node)
return 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 { if is_none_check {
g.gen_is_none_check(node) g.gen_is_none_check(node)
} else if (left.typ.is_ptr() && right.typ.is_int()) } else if (left.typ.is_ptr() && right.typ.is_int())
@ -367,6 +369,18 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
signed_type: left.unaliased signed_type: left.unaliased
signed_expr: node.left 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 { } else {
g.gen_plain_infix_expr(node) g.gen_plain_infix_expr(node)
} }

View file

@ -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])
}