1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker, cgen, parser: fix Option/Result error messages (capitalized) (#17486)

This commit is contained in:
Felipe Pena 2023-03-04 03:02:57 -03:00 committed by GitHub
parent 0ba0fb256f
commit c5832379e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 60 additions and 60 deletions

View File

@ -992,7 +992,7 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
return_modifier_kind := if expr_ret_type.has_flag(.option) {
'an Option'
} else {
'a result'
'a Result'
}
return_modifier := if expr_ret_type.has_flag(.option) { '?' } else { '!' }
if expr_ret_type.has_flag(.result) && expr.or_block.kind == .absent {
@ -1010,13 +1010,13 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
}
return ret_type.clear_flag(.result)
} else if expr.or_block.kind == .block {
c.error('unexpected `or` block, the function `${expr.name}` does not return an Option or a result',
c.error('unexpected `or` block, the function `${expr.name}` does not return an Option or a Result',
expr.or_block.pos)
} else if expr.or_block.kind == .propagate_option {
c.error('unexpected `?`, the function `${expr.name}` does not return an Option',
expr.or_block.pos)
} else if expr.or_block.kind == .propagate_result {
c.error('unexpected `!`, the function `${expr.name}` does not return a result',
c.error('unexpected `!`, the function `${expr.name}` does not return a Result',
expr.or_block.pos)
}
} else if expr is ast.SelectorExpr && c.table.sym(ret_type).kind != .chan {
@ -1024,7 +1024,7 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
with_modifier_kind := if expr.typ.has_flag(.option) {
'an Option'
} else {
'a result'
'a Result'
}
with_modifier := if expr.typ.has_flag(.option) { '?' } else { '!' }
if expr.typ.has_flag(.result) && expr.or_block.kind == .absent {
@ -1042,13 +1042,13 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
}
return ret_type.clear_flag(.result)
} else if expr.or_block.kind == .block {
c.error('unexpected `or` block, the field `${expr.field_name}` is neither an Option, nor a result',
c.error('unexpected `or` block, the field `${expr.field_name}` is neither an Option, nor a Result',
expr.or_block.pos)
} else if expr.or_block.kind == .propagate_option {
c.error('unexpected `?`, the field `${expr.field_name}` is not an Option',
expr.or_block.pos)
} else if expr.or_block.kind == .propagate_result {
c.error('unexpected `!`, result fields are not supported', expr.or_block.pos)
c.error('unexpected `!`, Result fields are not supported', expr.or_block.pos)
}
} else if expr is ast.IndexExpr {
if expr.or_expr.kind != .absent {
@ -1077,7 +1077,7 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return
}
if expr !is ast.Ident && !expr_return_type.has_flag(.option) {
if expr_return_type.has_flag(.result) {
c.warn('propagating a result like an Option is deprecated, use `foo()!` instead of `foo()?`',
c.warn('propagating a Result like an Option is deprecated, use `foo()!` instead of `foo()?`',
node.pos)
} else {
c.error('to propagate an Option, the call must also return an Option type',
@ -1090,11 +1090,11 @@ fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_return
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.result)
&& !c.table.cur_fn.is_main && !c.table.cur_fn.is_test && !c.inside_const {
c.add_instruction_for_result_type()
c.error('to propagate the call, `${c.table.cur_fn.name}` must return a result type',
c.error('to propagate the call, `${c.table.cur_fn.name}` must return a Result type',
node.pos)
}
if !expr_return_type.has_flag(.result) {
c.error('to propagate a result, the call must also return a result type',
c.error('to propagate a Result, the call must also return a Result type',
node.pos)
}
return
@ -1307,7 +1307,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
c.error('cannot access fields of an Option, handle the error with `or {...}` or propagate it with `?`',
node.pos)
} else if node.expr_type.has_flag(.result) {
c.error('cannot access fields of a result, handle the error with `or {...}` or propagate it with `!`',
c.error('cannot access fields of a Result, handle the error with `or {...}` or propagate it with `!`',
node.pos)
}
}
@ -2428,13 +2428,13 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
}
if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) {
if node.or_block.kind == .block {
c.error('unexpected `or` block, the function `${node.name}` does not return an Option or a result',
c.error('unexpected `or` block, the function `${node.name}` does not return an Option or a Result',
node.or_block.pos)
} else if node.or_block.kind == .propagate_option {
c.error('unexpected `?`, the function `${node.name}` does not return an Option or a result',
c.error('unexpected `?`, the function `${node.name}` does not return an Option or a Result',
node.or_block.pos)
} else if node.or_block.kind == .propagate_result {
c.error('unexpected `!`, the function `${node.name}` does not return an Option or a result',
c.error('unexpected `!`, the function `${node.name}` does not return an Option or a Result',
node.or_block.pos)
}
}
@ -2527,7 +2527,7 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
else {}
}
if no_opt_or_res {
c.error('expression should either return an Option or a result', node.expr.pos())
c.error('expression should either return an Option or a Result', node.expr.pos())
}
}
return ast.bool_type
@ -2605,13 +2605,13 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) {
if node.or_block.kind == .block {
c.error('unexpected `or` block, the field `${node.field_name}` is neither an Option, nor a result',
c.error('unexpected `or` block, the field `${node.field_name}` is neither an Option, nor a Result',
node.or_block.pos)
} else if node.or_block.kind == .propagate_option {
c.error('unexpected `?`, the field `${node.field_name}` is neither an Option, nor a result',
c.error('unexpected `?`, the field `${node.field_name}` is neither an Option, nor a Result',
node.or_block.pos)
} else if node.or_block.kind == .propagate_result {
c.error('unexpected `!`, the field `${node.field_name}` is neither an Option, nor a result',
c.error('unexpected `!`, the field `${node.field_name}` is neither an Option, nor a Result',
node.or_block.pos)
}
}
@ -2736,7 +2736,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
mut final_to_sym := c.table.final_sym(to_type)
if to_type.has_flag(.result) {
c.error('casting to result type is forbidden', node.pos)
c.error('casting to Result type is forbidden', node.pos)
}
if (to_sym.is_number() && from_sym.name == 'JS.Number')
@ -2852,7 +2852,7 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
msg := if from_type.has_flag(.option) {
'an Option'
} else if from_type.has_flag(.result) {
'a result'
'a Result'
} else {
'a variadic'
}
@ -3872,7 +3872,7 @@ fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_ty
} else {
'(array type `${typ_sym.name}`)'
}
c.error('cannot use option or result as index ${type_str}', pos)
c.error('cannot use Option or Result as index ${type_str}', pos)
}
}
}
@ -3922,7 +3922,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
node.left.pos())
}
} else if typ.has_flag(.result) {
c.error('type `!${typ_sym.name}` is a result, it does not support indexing', node.left.pos())
c.error('type `!${typ_sym.name}` is a Result, it does not support indexing', node.left.pos())
}
if typ_sym.kind == .string && !typ.is_ptr() && node.is_setter {
c.error('cannot assign to s[i] since V strings are immutable\n' +

View File

@ -115,10 +115,10 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
for multi_type in return_sym.info.types {
multi_sym := c.table.sym(multi_type)
if multi_type == ast.error_type {
c.error('type `IError` cannot be used in multi-return, return an option instead',
c.error('type `IError` cannot be used in multi-return, return an Option instead',
node.return_type_pos)
} else if multi_type.has_flag(.result) {
c.error('result cannot be used in multi-return, return a result instead',
c.error('result cannot be used in multi-return, return a Result instead',
node.return_type_pos)
} else if multi_sym.kind == .array_fixed {
c.error('fixed array cannot be used in multi-return', node.return_type_pos)
@ -212,7 +212,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
param.pos)
}
if param.typ.has_flag(.result) {
c.error('result type argument is not supported currently', param.type_pos)
c.error('Result type argument is not supported currently', param.type_pos)
}
arg_typ_sym := c.table.sym(param.typ)
if arg_typ_sym.info is ast.Struct {
@ -513,12 +513,12 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result)
&& !c.table.cur_fn.return_type.has_flag(.option) {
c.add_instruction_for_result_type()
c.error('to propagate the result call, `${c.table.cur_fn.name}` must return a result',
c.error('to propagate the Result call, `${c.table.cur_fn.name}` must return a Result',
node.or_block.pos)
}
if node.or_block.kind == .propagate_option && !c.table.cur_fn.return_type.has_flag(.option) {
c.add_instruction_for_option_type()
c.error('to propagate the option call, `${c.table.cur_fn.name}` must return an option',
c.error('to propagate the Option call, `${c.table.cur_fn.name}` must return an Option',
node.or_block.pos)
}
}
@ -1346,10 +1346,10 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
'unknown method or field: `${left_sym.name}.${method_name}`'
}
if left_type.has_flag(.option) && method_name != 'str' {
c.error('option type cannot be called directly', node.left.pos())
c.error('Option type cannot be called directly', node.left.pos())
return ast.void_type
} else if left_type.has_flag(.result) {
c.error('result type cannot be called directly', node.left.pos())
c.error('Result type cannot be called directly', node.left.pos())
return ast.void_type
}
if left_sym.kind in [.sum_type, .interface_] {

View File

@ -115,7 +115,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
return
}
if !next_fn.return_type.has_flag(.option) {
c.error('iterator method `next()` must return an option', node.cond.pos())
c.error('iterator method `next()` must return an Option', node.cond.pos())
}
return_sym := c.table.sym(next_fn.return_type)
if return_sym.kind == .multi_return {

View File

@ -72,7 +72,7 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
for i, field in node.fields {
if field.typ.has_flag(.result) {
c.error('struct field does not support storing result', field.option_pos)
c.error('struct field does not support storing Result', field.option_pos)
}
c.ensure_type_exists(field.typ, field.type_pos) or { return }
c.ensure_generic_type_specify_type_names(field.typ, field.type_pos) or { return }

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv:15:12: error: ret_abc_result() returns a result, so it should have either an `or {}` block, or `!` at the end
vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv:15:12: error: ret_abc_result() returns a Result, so it should have either an `or {}` block, or `!` at the end
13 | }
14 |
15 | a := Alias(ret_abc_result())

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/as_cast_option_result_unhandled_err.vv:11:6: error: ret_sum_result() returns a result, so it should have either an `or {}` block, or `!` at the end
vlib/v/checker/tests/as_cast_option_result_unhandled_err.vv:11:6: error: ret_sum_result() returns a Result, so it should have either an `or {}` block, or `!` at the end
9 | }
10 |
11 | _ := ret_sum_result() as int

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/expression_should_return_an_option.vv:26:10: error: expression should either return an Option or a result
vlib/v/checker/tests/expression_should_return_an_option.vv:26:10: error: expression should either return an Option or a Result
24 | return_option(true) or { println(err) }
25 | // should be an checker error:
26 | if x := return_string() {

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/fn_return_or_err.vv:6:17: error: unexpected `or` block, the function `pop` does not return an Option or a result
vlib/v/checker/tests/fn_return_or_err.vv:6:17: error: unexpected `or` block, the function `pop` does not return an Option or a Result
4 |
5 | pub fn next(mut v []Typ) Typ {
6 | return v.pop() or { Typ{} }

View File

@ -1,25 +1,25 @@
vlib/v/checker/tests/go_wait_or.vv:11:16: error: unexpected `?`, the function `wait` does not return an Option or a result
vlib/v/checker/tests/go_wait_or.vv:11:16: error: unexpected `?`, the function `wait` does not return an Option or a Result
9 | spawn d(1)
10 | ]
11 | r := tg.wait()?
| ^
12 | println(r)
13 | s := tg[0].wait() or { panic('problem') }
vlib/v/checker/tests/go_wait_or.vv:13:20: error: unexpected `or` block, the function `wait` does not return an Option or a result
vlib/v/checker/tests/go_wait_or.vv:13:20: error: unexpected `or` block, the function `wait` does not return an Option or a Result
11 | r := tg.wait()?
12 | println(r)
13 | s := tg[0].wait() or { panic('problem') }
| ~~~~~~~~~~~~~~~~~~~~~~~
14 | println(s)
15 | tg2 := [
vlib/v/checker/tests/go_wait_or.vv:19:13: error: unexpected `or` block, the function `wait` does not return an Option or a result
vlib/v/checker/tests/go_wait_or.vv:19:13: error: unexpected `or` block, the function `wait` does not return an Option or a Result
17 | spawn e(1)
18 | ]
19 | tg2.wait() or { panic('problem') }
| ~~~~~~~~~~~~~~~~~~~~~~~
20 | tg2[0].wait()?
21 | tg3 := [
vlib/v/checker/tests/go_wait_or.vv:20:15: error: unexpected `?`, the function `wait` does not return an Option or a result
vlib/v/checker/tests/go_wait_or.vv:20:15: error: unexpected `?`, the function `wait` does not return an Option or a Result
18 | ]
19 | tg2.wait() or { panic('problem') }
20 | tg2[0].wait()?

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/ierror_in_return_tuple.vv:1:29: error: type `IError` cannot be used in multi-return, return an option instead
vlib/v/checker/tests/ierror_in_return_tuple.vv:1:29: error: type `IError` cannot be used in multi-return, return an Option instead
1 | fn return_ierror_in_tuple() (bool, IError) {
| ~~~~~~~~~~~~~~
2 | return false, error('')

View File

@ -5,7 +5,7 @@ vlib/v/checker/tests/option_fn_err.vv:40:9: error: assert can be used only with
| ~~~~~~~~~
41 |
42 | // struct
vlib/v/checker/tests/option_fn_err.vv:60:13: error: cannot use option or result as index (array type `[]int`)
vlib/v/checker/tests/option_fn_err.vv:60:13: error: cannot use Option or Result as index (array type `[]int`)
58 | _ := [1]int{init: bar(0)}
59 | // index
60 | println(arr[bar(0)])

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/option_propagate_nested.vv:10:18: error: to propagate the option call, `xx_prop` must return an option
vlib/v/checker/tests/option_propagate_nested.vv:10:18: error: to propagate the Option call, `xx_prop` must return an Option
8 |
9 | fn xx_prop() string {
10 | s := ret(raise()?)
@ -12,7 +12,7 @@ Details: vlib/v/checker/tests/option_propagate_nested.vv:9:14: details: prepend
| ~~~~~~
10 | s := ret(raise()?)
11 | return s
vlib/v/checker/tests/option_propagate_nested.vv:28:21: error: to propagate the result call, `aa_propagate` must return a result
vlib/v/checker/tests/option_propagate_nested.vv:28:21: error: to propagate the Result call, `aa_propagate` must return a Result
26 |
27 | fn (mut s St) aa_propagate() {
28 | f := retf(s.raise()!)

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/option_type_call_err.vv:4:5: error: result type cannot be called directly
vlib/v/checker/tests/option_type_call_err.vv:4:5: error: Result type cannot be called directly
2 |
3 | fn main() {
4 | os.ls('.').filter(it.ends_with('.v')) or { return }

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/propagate_option_with_result_err.vv:6:7: warning: propagating a result like an Option is deprecated, use `foo()!` instead of `foo()?`
vlib/v/checker/tests/propagate_option_with_result_err.vv:6:7: warning: propagating a Result like an Option is deprecated, use `foo()!` instead of `foo()?`
4 |
5 | fn bar() ?string {
6 | foo()?

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/propagate_result_with_option.vv:6:8: error: to propagate a result, the call must also return a result type
vlib/v/checker/tests/propagate_result_with_option.vv:6:8: error: to propagate a Result, the call must also return a Result type
4 |
5 | fn bar() !string {
6 | foo() !

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/result_missing_propagate_err.vv:6:7: error: result() returns a result, so it should have either an `or {}` block, or `!` at the end
vlib/v/checker/tests/result_missing_propagate_err.vv:6:7: error: result() returns a Result, so it should have either an `or {}` block, or `!` at the end
4 |
5 | fn main() {
6 | a := result()

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/result_type_call_err.vv:12:2: error: result type cannot be called directly
vlib/v/checker/tests/result_type_call_err.vv:12:2: error: Result type cannot be called directly
10 |
11 | fn main() {
12 | new_foo().foo()

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/struct_field_option_err.vv:3:6: error: struct field does not support storing result
vlib/v/checker/tests/struct_field_option_err.vv:3:6: error: struct field does not support storing Result
1 | struct Foo {
2 | mut:
3 | foo !int
@ -12,7 +12,7 @@ vlib/v/checker/tests/struct_field_option_err.vv:12:12: error: `+` cannot be used
| ^
13 |
14 | _ = f.bar!
vlib/v/checker/tests/struct_field_option_err.vv:14:11: error: to propagate a result, the call must also return a result type
vlib/v/checker/tests/struct_field_option_err.vv:14:11: error: to propagate a Result, the call must also return a Result type
12 | _ = f.bar + 1
13 |
14 | _ = f.bar!
@ -26,7 +26,7 @@ vlib/v/checker/tests/struct_field_option_err.vv:16:19: error: last statement in
| ^
17 |
18 | _ = f.baz?
vlib/v/checker/tests/struct_field_option_err.vv:18:11: error: unexpected `?`, the field `baz` is neither an Option, nor a result
vlib/v/checker/tests/struct_field_option_err.vv:18:11: error: unexpected `?`, the field `baz` is neither an Option, nor a Result
16 | _ = f.bar or { _ = 1 }
17 |
18 | _ = f.baz?

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/unexpected_or.vv:6:17: error: unexpected `or` block, the function `ret_zero` does not return an Option or a result
vlib/v/checker/tests/unexpected_or.vv:6:17: error: unexpected `or` block, the function `ret_zero` does not return an Option or a Result
4 |
5 | fn main() {
6 | _ = ret_zero() or { 1 }

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero` does not return an Option or a result
vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero` does not return an Option or a Result
4 |
5 | fn opt_fn() ?int {
6 | a := ret_zero()?

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/wrong_propagate_ret_type.vv:10:17: error: to propagate the option call, `opt_call` must return an option
vlib/v/checker/tests/wrong_propagate_ret_type.vv:10:17: error: to propagate the Option call, `opt_call` must return an Option
8 |
9 | fn opt_call() int {
10 | a := ret_none()?
@ -12,7 +12,7 @@ Details: vlib/v/checker/tests/wrong_propagate_ret_type.vv:9:15: details: prepend
| ~~~
10 | a := ret_none()?
11 | return a
vlib/v/checker/tests/wrong_propagate_ret_type.vv:15:17: error: to propagate the result call, `res_call` must return a result
vlib/v/checker/tests/wrong_propagate_ret_type.vv:15:17: error: to propagate the Result call, `res_call` must return a Result
13 |
14 | fn res_call() bool {
15 | a := ret_bool()!

View File

@ -1829,7 +1829,7 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) bool {
// e.g. field default: "foo ?int = 1", field assign: "foo = 1", field init: "foo: 1"
fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.Type, tmp_var string) {
if !ret_typ.has_flag(.option) && !ret_typ.has_flag(.result) {
panic('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an option or result')
panic('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result')
}
stmt_str := g.go_before_stmt(0).trim_space()

View File

@ -114,7 +114,7 @@ fn (mut p Parser) if_expr(is_comptime bool) ast.IfExpr {
comments << p.eat_comments()
expr := p.expr(0)
if expr !in [ast.CallExpr, ast.IndexExpr, ast.PrefixExpr, ast.SelectorExpr] {
p.error_with_pos('if guard condition expression is illegal, it should return an option',
p.error_with_pos('if guard condition expression is illegal, it should return an Option',
expr.pos())
}
p.check_undefined_variables(var_names, expr) or {

View File

@ -465,7 +465,7 @@ pub fn (mut p Parser) parse_type() ast.Type {
}
sym := p.table.sym(typ)
if is_option && sym.info is ast.SumType && (sym.info as ast.SumType).is_anon {
p.error_with_pos('an inline sum type cannot be an option', option_pos.extend(p.prev_tok.pos()))
p.error_with_pos('an inline sum type cannot be an Option', option_pos.extend(p.prev_tok.pos()))
}
}
if is_option {

View File

@ -1,4 +1,4 @@
vlib/v/parser/tests/if_guard_cond_err.vv:16:16: error: if guard condition expression is illegal, it should return an option
vlib/v/parser/tests/if_guard_cond_err.vv:16:16: error: if guard condition expression is illegal, it should return an Option
14 | fp.usage_example('GOOG AAPL')
15 | _ := fp.bool('version', `v`, false, 'version information.')
16 | if args := fp.finalize() && args.len > 0 {

View File

@ -3,7 +3,7 @@ vlib/v/parser/tests/inline_sum_type_option_err.vv:1:11: warning: inline sum type
| ~~~~~~
2 | return 0
3 | }
vlib/v/parser/tests/inline_sum_type_option_err.vv:1:10: error: an inline sum type cannot be an option
vlib/v/parser/tests/inline_sum_type_option_err.vv:1:10: error: an inline sum type cannot be an Option
1 | fn foo() ?string | int {
| ~~~~~~~~~~~~~
2 | return 0

View File

@ -3,7 +3,7 @@ vlib/v/parser/tests/option_sum_type_return_err.vv:1:22: warning: inline sum type
| ~~~~~~
2 | return 0
3 | }
vlib/v/parser/tests/option_sum_type_return_err.vv:1:21: error: an inline sum type cannot be an option
vlib/v/parser/tests/option_sum_type_return_err.vv:1:21: error: an inline sum type cannot be an Option
1 | fn option_sumtype() ?string | int {
| ~~~~~~~~~~~~~
2 | return 0