checker: check opt call in more places (#9538)
							parent
							
								
									1a76cb1c36
								
							
						
					
					
						commit
						0d1714cb0d
					
				| 
						 | 
				
			
			@ -414,7 +414,10 @@ pub fn (mut c Checker) struct_decl(mut decl ast.StructDecl) {
 | 
			
		|||
			}
 | 
			
		||||
			if field.has_default_expr {
 | 
			
		||||
				c.expected_type = field.typ
 | 
			
		||||
				field_expr_type := c.expr(field.default_expr)
 | 
			
		||||
				mut field_expr_type := c.expr(field.default_expr)
 | 
			
		||||
				if !field.typ.has_flag(.optional) {
 | 
			
		||||
					c.check_expr_opt_call(field.default_expr, field_expr_type)
 | 
			
		||||
				}
 | 
			
		||||
				struct_sym.info.fields[i].default_expr_typ = field_expr_type
 | 
			
		||||
				c.check_expected(field_expr_type, field.typ) or {
 | 
			
		||||
					if !(sym.kind == .interface_
 | 
			
		||||
| 
						 | 
				
			
			@ -611,7 +614,10 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
 | 
			
		|||
					inited_fields << field_name
 | 
			
		||||
					field_type_sym := c.table.get_type_symbol(info_field.typ)
 | 
			
		||||
					c.expected_type = info_field.typ
 | 
			
		||||
					expr_type := c.expr(field.expr)
 | 
			
		||||
					mut expr_type := c.expr(field.expr)
 | 
			
		||||
					if !info_field.typ.has_flag(.optional) {
 | 
			
		||||
						expr_type = c.check_expr_opt_call(field.expr, expr_type)
 | 
			
		||||
					}
 | 
			
		||||
					expr_type_sym := c.table.get_type_symbol(expr_type)
 | 
			
		||||
					if field_type_sym.kind == .interface_ {
 | 
			
		||||
						c.type_implements(expr_type, info_field.typ, field.pos)
 | 
			
		||||
| 
						 | 
				
			
			@ -948,6 +954,7 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
 | 
			
		|||
					c.error('array append cannot be used in an expression', infix_expr.pos)
 | 
			
		||||
				}
 | 
			
		||||
				// `array << elm`
 | 
			
		||||
				c.check_expr_opt_call(infix_expr.right, right_type)
 | 
			
		||||
				infix_expr.auto_locked, _ = c.fail_if_immutable(infix_expr.left)
 | 
			
		||||
				left_value_type := c.table.value_type(left_type)
 | 
			
		||||
				left_value_sym := c.table.get_type_symbol(left_value_type)
 | 
			
		||||
| 
						 | 
				
			
			@ -2340,7 +2347,8 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
 | 
			
		|||
 | 
			
		||||
pub fn (mut c Checker) check_or_expr(or_expr ast.OrExpr, ret_type table.Type, expr_return_type table.Type) {
 | 
			
		||||
	if or_expr.kind == .propagate {
 | 
			
		||||
		if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main.main' {
 | 
			
		||||
		if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main.main'
 | 
			
		||||
			&& !c.inside_const {
 | 
			
		||||
			c.error('to propagate the optional call, `$c.cur_fn.name` must return an optional',
 | 
			
		||||
				or_expr.pos)
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -2697,12 +2705,7 @@ pub fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
 | 
			
		|||
	for i, field in node.fields {
 | 
			
		||||
		c.const_decl = field.name
 | 
			
		||||
		c.const_deps << field.name
 | 
			
		||||
		mut typ := c.expr(field.expr)
 | 
			
		||||
		if field.expr is ast.CallExpr {
 | 
			
		||||
			if field.expr.or_block.kind != .absent {
 | 
			
		||||
				typ = typ.clear_flag(.optional)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		typ := c.check_expr_opt_call(field.expr, c.expr(field.expr))
 | 
			
		||||
		node.fields[i].typ = c.table.mktyp(typ)
 | 
			
		||||
		for cd in c.const_deps {
 | 
			
		||||
			for j, f in node.fields {
 | 
			
		||||
| 
						 | 
				
			
			@ -3207,9 +3210,10 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type {
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if array_init.has_default {
 | 
			
		||||
			default_typ := c.expr(array_init.default_expr)
 | 
			
		||||
			default_expr := array_init.default_expr
 | 
			
		||||
			default_typ := c.check_expr_opt_call(default_expr, c.expr(default_expr))
 | 
			
		||||
			c.check_expected(default_typ, array_init.elem_type) or {
 | 
			
		||||
				c.error(err.msg, array_init.default_expr.position())
 | 
			
		||||
				c.error(err.msg, default_expr.position())
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if array_init.has_len {
 | 
			
		||||
| 
						 | 
				
			
			@ -3513,7 +3517,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
 | 
			
		|||
 | 
			
		||||
fn (mut c Checker) assert_stmt(node ast.AssertStmt) {
 | 
			
		||||
	cur_exp_typ := c.expected_type
 | 
			
		||||
	assert_type := c.expr(node.expr)
 | 
			
		||||
	assert_type := c.check_expr_opt_call(node.expr, c.expr(node.expr))
 | 
			
		||||
	if assert_type != table.bool_type_idx {
 | 
			
		||||
		atype_name := c.table.get_type_symbol(assert_type).name
 | 
			
		||||
		c.error('assert can be used only with `bool` expressions, but found `$atype_name` instead',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,104 +1,160 @@
 | 
			
		|||
vlib/v/checker/tests/optional_fn_err.vv:25:2: error: foo() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   23 | fn main() {
 | 
			
		||||
   24 |     // Calling foo() without ? or an or block, should be an error.
 | 
			
		||||
   25 |     foo()
 | 
			
		||||
      |     ~~~~~
 | 
			
		||||
   26 | 
 | 
			
		||||
   27 |     _ := bar(0)
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:27:7: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   25 |     foo()
 | 
			
		||||
   26 | 
 | 
			
		||||
   27 |     _ := bar(0)
 | 
			
		||||
      |          ~~~~~~
 | 
			
		||||
   28 |     _ := [bar(0)]
 | 
			
		||||
   29 |
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:28:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   26 | 
 | 
			
		||||
   27 |     _ := bar(0)
 | 
			
		||||
   28 |     _ := [bar(0)]
 | 
			
		||||
      |           ~~~~~~
 | 
			
		||||
   29 | 
 | 
			
		||||
   30 |     // Calling fn with optional argument
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:31:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   29 | 
 | 
			
		||||
   30 |     // Calling fn with optional argument
 | 
			
		||||
   31 |     println(twice(bar(0)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:13:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   11 | 
 | 
			
		||||
   12 | const (
 | 
			
		||||
   13 |     const_value = bar(0)
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   32 |     // method and fn field
 | 
			
		||||
   33 |     mut v := Data{fn (_ int) {}, 1}
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:34:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   32 |     // method and fn field
 | 
			
		||||
   33 |     mut v := Data{fn (_ int) {}, 1}
 | 
			
		||||
   34 |     v.add(bar(0))
 | 
			
		||||
      |           ~~~~~~
 | 
			
		||||
   35 |     v.f(bar(0))
 | 
			
		||||
   36 |     // anon fn
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:35:6: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   33 |     mut v := Data{fn (_ int) {}, 1}
 | 
			
		||||
   34 |     v.add(bar(0))
 | 
			
		||||
   35 |     v.f(bar(0))
 | 
			
		||||
      |         ~~~~~~
 | 
			
		||||
   36 |     // anon fn
 | 
			
		||||
   37 |     fn (_ int) {}(bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:37:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   35 |     v.f(bar(0))
 | 
			
		||||
   36 |     // anon fn
 | 
			
		||||
   37 |     fn (_ int) {}(bar(0))
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   38 |     // array builtin methods
 | 
			
		||||
   39 |     mut arr := [1, 2]
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:40:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   38 |     // array builtin methods
 | 
			
		||||
   39 |     mut arr := [1, 2]
 | 
			
		||||
   40 |     arr.insert(0, bar(0))
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   41 |     arr.prepend(bar(0))
 | 
			
		||||
   42 |     arr.contains(bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:41:14: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   39 |     mut arr := [1, 2]
 | 
			
		||||
   40 |     arr.insert(0, bar(0))
 | 
			
		||||
   41 |     arr.prepend(bar(0))
 | 
			
		||||
   14 | )
 | 
			
		||||
   15 |
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:19:14: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   17 |     f fn (int)
 | 
			
		||||
   18 | mut:
 | 
			
		||||
   19 |     value int = bar(0)
 | 
			
		||||
      |                 ~~~~~~
 | 
			
		||||
   42 |     arr.contains(bar(0))
 | 
			
		||||
   43 |     arr.index(bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:42:15: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   40 |     arr.insert(0, bar(0))
 | 
			
		||||
   41 |     arr.prepend(bar(0))
 | 
			
		||||
   42 |     arr.contains(bar(0))
 | 
			
		||||
   20 |     opt   ?int = bar(0)
 | 
			
		||||
   21 | }
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:33:2: error: foo() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   31 | fn main() {
 | 
			
		||||
   32 |     // call fn
 | 
			
		||||
   33 |     foo()
 | 
			
		||||
      |     ~~~~~
 | 
			
		||||
   34 |     _ := bar(0)
 | 
			
		||||
   35 |     println(twice(bar(0)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:34:7: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   32 |     // call fn
 | 
			
		||||
   33 |     foo()
 | 
			
		||||
   34 |     _ := bar(0)
 | 
			
		||||
      |          ~~~~~~
 | 
			
		||||
   35 |     println(twice(bar(0)))
 | 
			
		||||
   36 |
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:35:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   33 |     foo()
 | 
			
		||||
   34 |     _ := bar(0)
 | 
			
		||||
   35 |     println(twice(bar(0)))
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   36 | 
 | 
			
		||||
   37 |     // anon fn
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:38:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   36 | 
 | 
			
		||||
   37 |     // anon fn
 | 
			
		||||
   38 |     fn (_ int) {}(bar(0))
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   39 | 
 | 
			
		||||
   40 |     // assert
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:41:9: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   39 | 
 | 
			
		||||
   40 |     // assert
 | 
			
		||||
   41 |     assert bar(true)
 | 
			
		||||
      |            ~~~~~~~~~
 | 
			
		||||
   42 | 
 | 
			
		||||
   43 |     // struct
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:46:10: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   44 |     mut v := Data{
 | 
			
		||||
   45 |         f: fn (_ int) {},
 | 
			
		||||
   46 |         value: bar(0),
 | 
			
		||||
      |                ~~~~~~
 | 
			
		||||
   47 |         opt: bar(0),
 | 
			
		||||
   48 |     }
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:49:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   47 |         opt: bar(0),
 | 
			
		||||
   48 |     }
 | 
			
		||||
   49 |     v.add(bar(0)) // call method
 | 
			
		||||
      |           ~~~~~~
 | 
			
		||||
   50 |     v.f(bar(0)) // call fn field
 | 
			
		||||
   51 |
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:50:6: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   48 |     }
 | 
			
		||||
   49 |     v.add(bar(0)) // call method
 | 
			
		||||
   50 |     v.f(bar(0)) // call fn field
 | 
			
		||||
      |         ~~~~~~
 | 
			
		||||
   51 | 
 | 
			
		||||
   52 |     // array
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:54:9: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   52 |     // array
 | 
			
		||||
   53 |     mut arr := [1, 2]
 | 
			
		||||
   54 |     arr << bar(0)
 | 
			
		||||
      |            ~~~~~~
 | 
			
		||||
   55 |     // init
 | 
			
		||||
   56 |     _ := [bar(0)]
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:56:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   54 |     arr << bar(0)
 | 
			
		||||
   55 |     // init
 | 
			
		||||
   56 |     _ := [bar(0)]
 | 
			
		||||
      |           ~~~~~~
 | 
			
		||||
   57 |     _ := []int{init: bar(0)}
 | 
			
		||||
   58 |     _ := [bar(0)]!
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:57:19: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   55 |     // init
 | 
			
		||||
   56 |     _ := [bar(0)]
 | 
			
		||||
   57 |     _ := []int{init: bar(0)}
 | 
			
		||||
      |                      ~~~~~~
 | 
			
		||||
   58 |     _ := [bar(0)]!
 | 
			
		||||
   59 |     _ := [1]int{init: bar(0)}
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:58:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   56 |     _ := [bar(0)]
 | 
			
		||||
   57 |     _ := []int{init: bar(0)}
 | 
			
		||||
   58 |     _ := [bar(0)]!
 | 
			
		||||
      |           ~~~~~~
 | 
			
		||||
   59 |     _ := [1]int{init: bar(0)}
 | 
			
		||||
   60 |     // index
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:61:13: error: cannot use optional as index (array type `[]int`)
 | 
			
		||||
   59 |     _ := [1]int{init: bar(0)}
 | 
			
		||||
   60 |     // index
 | 
			
		||||
   61 |     println(arr[bar(0)])
 | 
			
		||||
      |                ~~~~~~~~
 | 
			
		||||
   62 |     // array builtin methods
 | 
			
		||||
   63 |     arr.insert(0, bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:63:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   61 |     println(arr[bar(0)])
 | 
			
		||||
   62 |     // array builtin methods
 | 
			
		||||
   63 |     arr.insert(0, bar(0))
 | 
			
		||||
      |                   ~~~~~~
 | 
			
		||||
   64 |     arr.prepend(bar(0))
 | 
			
		||||
   65 |     arr.contains(bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:64:14: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   62 |     // array builtin methods
 | 
			
		||||
   63 |     arr.insert(0, bar(0))
 | 
			
		||||
   64 |     arr.prepend(bar(0))
 | 
			
		||||
      |                 ~~~~~~
 | 
			
		||||
   65 |     arr.contains(bar(0))
 | 
			
		||||
   66 |     arr.index(bar(0))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:65:15: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   63 |     arr.insert(0, bar(0))
 | 
			
		||||
   64 |     arr.prepend(bar(0))
 | 
			
		||||
   65 |     arr.contains(bar(0))
 | 
			
		||||
      |                  ~~~~~~
 | 
			
		||||
   43 |     arr.index(bar(0))
 | 
			
		||||
   44 |     println(arr.map(bar(0)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:43:12: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   41 |     arr.prepend(bar(0))
 | 
			
		||||
   42 |     arr.contains(bar(0))
 | 
			
		||||
   43 |     arr.index(bar(0))
 | 
			
		||||
   66 |     arr.index(bar(0))
 | 
			
		||||
   67 |     println(arr.map(bar(0)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:66:12: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   64 |     arr.prepend(bar(0))
 | 
			
		||||
   65 |     arr.contains(bar(0))
 | 
			
		||||
   66 |     arr.index(bar(0))
 | 
			
		||||
      |               ~~~~~~
 | 
			
		||||
   44 |     println(arr.map(bar(0)))
 | 
			
		||||
   45 |     println(arr.filter(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:44:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   42 |     arr.contains(bar(0))
 | 
			
		||||
   43 |     arr.index(bar(0))
 | 
			
		||||
   44 |     println(arr.map(bar(0)))
 | 
			
		||||
   67 |     println(arr.map(bar(0)))
 | 
			
		||||
   68 |     println(arr.filter(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:67:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   65 |     arr.contains(bar(0))
 | 
			
		||||
   66 |     arr.index(bar(0))
 | 
			
		||||
   67 |     println(arr.map(bar(0)))
 | 
			
		||||
      |                     ~~~~~~
 | 
			
		||||
   45 |     println(arr.filter(bar(true)))
 | 
			
		||||
   46 |     println(arr.any(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:45:21: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   43 |     arr.index(bar(0))
 | 
			
		||||
   44 |     println(arr.map(bar(0)))
 | 
			
		||||
   45 |     println(arr.filter(bar(true)))
 | 
			
		||||
   68 |     println(arr.filter(bar(true)))
 | 
			
		||||
   69 |     println(arr.any(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:68:21: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   66 |     arr.index(bar(0))
 | 
			
		||||
   67 |     println(arr.map(bar(0)))
 | 
			
		||||
   68 |     println(arr.filter(bar(true)))
 | 
			
		||||
      |                        ~~~~~~~~~
 | 
			
		||||
   46 |     println(arr.any(bar(true)))
 | 
			
		||||
   47 |     println(arr.all(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:46:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   44 |     println(arr.map(bar(0)))
 | 
			
		||||
   45 |     println(arr.filter(bar(true)))
 | 
			
		||||
   46 |     println(arr.any(bar(true)))
 | 
			
		||||
   69 |     println(arr.any(bar(true)))
 | 
			
		||||
   70 |     println(arr.all(bar(true)))
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:69:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   67 |     println(arr.map(bar(0)))
 | 
			
		||||
   68 |     println(arr.filter(bar(true)))
 | 
			
		||||
   69 |     println(arr.any(bar(true)))
 | 
			
		||||
      |                     ~~~~~~~~~
 | 
			
		||||
   47 |     println(arr.all(bar(true)))
 | 
			
		||||
   48 | }
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:47:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   45 |     println(arr.filter(bar(true)))
 | 
			
		||||
   46 |     println(arr.any(bar(true)))
 | 
			
		||||
   47 |     println(arr.all(bar(true)))
 | 
			
		||||
   70 |     println(arr.all(bar(true)))
 | 
			
		||||
   71 | }
 | 
			
		||||
vlib/v/checker/tests/optional_fn_err.vv:70:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   68 |     println(arr.filter(bar(true)))
 | 
			
		||||
   69 |     println(arr.any(bar(true)))
 | 
			
		||||
   70 |     println(arr.all(bar(true)))
 | 
			
		||||
      |                     ~~~~~~~~~
 | 
			
		||||
   48 | }
 | 
			
		||||
   71 | }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,6 @@
 | 
			
		|||
 | 
			
		||||
// use optional without ? or an or block in places where it is not allowed
 | 
			
		||||
 | 
			
		||||
fn foo() ? {
 | 
			
		||||
	println('foo is called')
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,10 +9,15 @@ fn bar<T>(v T) ?T {
 | 
			
		|||
	return none
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	const_value = bar(0)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
struct Data {
 | 
			
		||||
	f fn (int)
 | 
			
		||||
mut:
 | 
			
		||||
	value int
 | 
			
		||||
	value int = bar(0)
 | 
			
		||||
	opt   ?int = bar(0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut v Data) add(n int) {
 | 
			
		||||
| 
						 | 
				
			
			@ -21,22 +29,37 @@ fn twice(n int) int {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
	// Calling foo() without ? or an or block, should be an error.
 | 
			
		||||
	// call fn
 | 
			
		||||
	foo()
 | 
			
		||||
 | 
			
		||||
	_ := bar(0)
 | 
			
		||||
	_ := [bar(0)]
 | 
			
		||||
 | 
			
		||||
	// Calling fn with optional argument
 | 
			
		||||
	println(twice(bar(0)))
 | 
			
		||||
	// method and fn field
 | 
			
		||||
	mut v := Data{fn (_ int) {}, 1}
 | 
			
		||||
	v.add(bar(0))
 | 
			
		||||
	v.f(bar(0))
 | 
			
		||||
 | 
			
		||||
	// anon fn
 | 
			
		||||
	fn (_ int) {}(bar(0))
 | 
			
		||||
	// array builtin methods
 | 
			
		||||
 | 
			
		||||
	// assert
 | 
			
		||||
	assert bar(true)
 | 
			
		||||
 | 
			
		||||
	// struct
 | 
			
		||||
	mut v := Data{
 | 
			
		||||
		f: fn (_ int) {},
 | 
			
		||||
		value: bar(0),
 | 
			
		||||
		opt: bar(0),
 | 
			
		||||
	}
 | 
			
		||||
	v.add(bar(0)) // call method
 | 
			
		||||
	v.f(bar(0)) // call fn field
 | 
			
		||||
 | 
			
		||||
	// array
 | 
			
		||||
	mut arr := [1, 2]
 | 
			
		||||
	arr << bar(0)
 | 
			
		||||
	// init
 | 
			
		||||
	_ := [bar(0)]
 | 
			
		||||
	_ := []int{init: bar(0)}
 | 
			
		||||
	_ := [bar(0)]!
 | 
			
		||||
	_ := [1]int{init: bar(0)}
 | 
			
		||||
	// index
 | 
			
		||||
	println(arr[bar(0)])
 | 
			
		||||
	// array builtin methods
 | 
			
		||||
	arr.insert(0, bar(0))
 | 
			
		||||
	arr.prepend(bar(0))
 | 
			
		||||
	arr.contains(bar(0))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
vlib/v/checker/tests/optional_index_err.vv:3:14: error: cannot use optional as index (type `string`)
 | 
			
		||||
    1 | fn main() {
 | 
			
		||||
    2 |     v := 'hello'
 | 
			
		||||
    3 |     println(v[v.last_index('l')])
 | 
			
		||||
      |              ~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
    4 | }
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
fn main() {
 | 
			
		||||
    v := 'hello'
 | 
			
		||||
    println(v[v.last_index('l')])
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +0,0 @@
 | 
			
		|||
vlib/v/checker/tests/optional_method_err.vv:17:10: error: inc_to_limit() returns an option, so it should have either an `or {}` block, or `?` at the end
 | 
			
		||||
   15 |     mut a := Abc{}
 | 
			
		||||
   16 |     for _ in 0 .. 4 {
 | 
			
		||||
   17 |         _ := a.inc_to_limit(2)
 | 
			
		||||
      |                ~~~~~~~~~~~~~~~
 | 
			
		||||
   18 |         eprintln('a: $a')
 | 
			
		||||
   19 |     }
 | 
			
		||||
| 
						 | 
				
			
			@ -1,20 +0,0 @@
 | 
			
		|||
struct Abc {
 | 
			
		||||
mut:
 | 
			
		||||
	x int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut a Abc) inc_to_limit(max int) ?int {
 | 
			
		||||
	if a.x >= max {
 | 
			
		||||
		return error('x is already $max')
 | 
			
		||||
	}
 | 
			
		||||
	a.x++
 | 
			
		||||
	return a.x
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
	mut a := Abc{}
 | 
			
		||||
	for _ in 0 .. 4 {
 | 
			
		||||
		_ := a.inc_to_limit(2)
 | 
			
		||||
		eprintln('a: $a')
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue