diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index 27cb2e220f..7f3e4f66c1 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -529,6 +529,10 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { node.auto_locked, _ = c.fail_if_immutable(mut node.left) left_value_type := c.table.value_type(c.unwrap_generic(left_type)) left_value_sym := c.table.sym(c.unwrap_generic(left_value_type)) + if !left_value_type.has_flag(.option) && right_type.has_flag(.option) { + c.error('unwrapped Option cannot be used in an infix expression', + node.pos) + } if left_value_sym.kind == .interface_ { if right_final_sym.kind != .array { // []Animal << Cat diff --git a/vlib/v/checker/tests/non_optional_array_append_optional_type_err.out b/vlib/v/checker/tests/non_optional_array_append_optional_type_err.out new file mode 100644 index 0000000000..fd81fa3b37 --- /dev/null +++ b/vlib/v/checker/tests/non_optional_array_append_optional_type_err.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/non_optional_array_append_optional_type_err.vv:12:10: error: unwrapped Option cannot be used in an infix expression + 10 | fn main() { + 11 | mut foobars := []Foobar{} + 12 | foobars << ?Foobar(.foo) + | ~~ + 13 | foobars << get_foo_or_none(true) + 14 | } +vlib/v/checker/tests/non_optional_array_append_optional_type_err.vv:13:10: error: unwrapped Option cannot be used in an infix expression + 11 | mut foobars := []Foobar{} + 12 | foobars << ?Foobar(.foo) + 13 | foobars << get_foo_or_none(true) + | ~~ + 14 | } diff --git a/vlib/v/checker/tests/non_optional_array_append_optional_type_err.vv b/vlib/v/checker/tests/non_optional_array_append_optional_type_err.vv new file mode 100644 index 0000000000..9715f7a2af --- /dev/null +++ b/vlib/v/checker/tests/non_optional_array_append_optional_type_err.vv @@ -0,0 +1,14 @@ +pub enum Foobar { + foo + bar +} + +fn get_foo_or_none(fail bool) ?Foobar { + return if fail {none} else {.foo} +} + +fn main() { + mut foobars := []Foobar{} + foobars << ?Foobar(.foo) + foobars << get_foo_or_none(true) +} diff --git a/vlib/v/checker/tests/option_fn_err.out b/vlib/v/checker/tests/option_fn_err.out index b1546be2d2..8db4c6ff6b 100644 --- a/vlib/v/checker/tests/option_fn_err.out +++ b/vlib/v/checker/tests/option_fn_err.out @@ -40,6 +40,13 @@ vlib/v/checker/tests/option_fn_err.vv:49:6: error: cannot use `?int` as `int`, i | ~~~~~~ 50 | 51 | // array +vlib/v/checker/tests/option_fn_err.vv:53:6: error: unwrapped Option cannot be used in an infix expression + 51 | // array + 52 | mut arr := [1, 2] + 53 | arr << bar(0) + | ~~ + 54 | // init + 55 | _ := [bar(0)] vlib/v/checker/tests/option_fn_err.vv:56:27: error: cannot use unwrapped Option as initializer 54 | // init 55 | _ := [bar(0)]