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 {
|
if field.has_default_expr {
|
||||||
c.expected_type = field.typ
|
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
|
struct_sym.info.fields[i].default_expr_typ = field_expr_type
|
||||||
c.check_expected(field_expr_type, field.typ) or {
|
c.check_expected(field_expr_type, field.typ) or {
|
||||||
if !(sym.kind == .interface_
|
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
|
inited_fields << field_name
|
||||||
field_type_sym := c.table.get_type_symbol(info_field.typ)
|
field_type_sym := c.table.get_type_symbol(info_field.typ)
|
||||||
c.expected_type = 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)
|
expr_type_sym := c.table.get_type_symbol(expr_type)
|
||||||
if field_type_sym.kind == .interface_ {
|
if field_type_sym.kind == .interface_ {
|
||||||
c.type_implements(expr_type, info_field.typ, field.pos)
|
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)
|
c.error('array append cannot be used in an expression', infix_expr.pos)
|
||||||
}
|
}
|
||||||
// `array << elm`
|
// `array << elm`
|
||||||
|
c.check_expr_opt_call(infix_expr.right, right_type)
|
||||||
infix_expr.auto_locked, _ = c.fail_if_immutable(infix_expr.left)
|
infix_expr.auto_locked, _ = c.fail_if_immutable(infix_expr.left)
|
||||||
left_value_type := c.table.value_type(left_type)
|
left_value_type := c.table.value_type(left_type)
|
||||||
left_value_sym := c.table.get_type_symbol(left_value_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) {
|
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 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',
|
c.error('to propagate the optional call, `$c.cur_fn.name` must return an optional',
|
||||||
or_expr.pos)
|
or_expr.pos)
|
||||||
}
|
}
|
||||||
|
@ -2697,12 +2705,7 @@ pub fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
c.const_decl = field.name
|
c.const_decl = field.name
|
||||||
c.const_deps << field.name
|
c.const_deps << field.name
|
||||||
mut typ := c.expr(field.expr)
|
typ := c.check_expr_opt_call(field.expr, c.expr(field.expr))
|
||||||
if field.expr is ast.CallExpr {
|
|
||||||
if field.expr.or_block.kind != .absent {
|
|
||||||
typ = typ.clear_flag(.optional)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
node.fields[i].typ = c.table.mktyp(typ)
|
node.fields[i].typ = c.table.mktyp(typ)
|
||||||
for cd in c.const_deps {
|
for cd in c.const_deps {
|
||||||
for j, f in node.fields {
|
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 {
|
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.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 {
|
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) {
|
fn (mut c Checker) assert_stmt(node ast.AssertStmt) {
|
||||||
cur_exp_typ := c.expected_type
|
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 {
|
if assert_type != table.bool_type_idx {
|
||||||
atype_name := c.table.get_type_symbol(assert_type).name
|
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',
|
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
|
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
|
||||||
23 | fn main() {
|
11 |
|
||||||
24 | // Calling foo() without ? or an or block, should be an error.
|
12 | const (
|
||||||
25 | foo()
|
13 | const_value = bar(0)
|
||||||
| ~~~~~
|
|
||||||
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)))
|
|
||||||
| ~~~~~~
|
| ~~~~~~
|
||||||
32 | // method and fn field
|
14 | )
|
||||||
33 | mut v := Data{fn (_ int) {}, 1}
|
15 |
|
||||||
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
|
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
|
||||||
32 | // method and fn field
|
17 | f fn (int)
|
||||||
33 | mut v := Data{fn (_ int) {}, 1}
|
18 | mut:
|
||||||
34 | v.add(bar(0))
|
19 | value int = 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))
|
|
||||||
| ~~~~~~
|
| ~~~~~~
|
||||||
42 | arr.contains(bar(0))
|
20 | opt ?int = bar(0)
|
||||||
43 | arr.index(bar(0))
|
21 | }
|
||||||
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
|
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
|
||||||
40 | arr.insert(0, bar(0))
|
31 | fn main() {
|
||||||
41 | arr.prepend(bar(0))
|
32 | // call fn
|
||||||
42 | arr.contains(bar(0))
|
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))
|
66 | arr.index(bar(0))
|
||||||
44 | println(arr.map(bar(0)))
|
67 | 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
|
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
|
||||||
41 | arr.prepend(bar(0))
|
64 | arr.prepend(bar(0))
|
||||||
42 | arr.contains(bar(0))
|
65 | arr.contains(bar(0))
|
||||||
43 | arr.index(bar(0))
|
66 | arr.index(bar(0))
|
||||||
| ~~~~~~
|
| ~~~~~~
|
||||||
44 | println(arr.map(bar(0)))
|
67 | println(arr.map(bar(0)))
|
||||||
45 | println(arr.filter(bar(true)))
|
68 | 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
|
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
|
||||||
42 | arr.contains(bar(0))
|
65 | arr.contains(bar(0))
|
||||||
43 | arr.index(bar(0))
|
66 | arr.index(bar(0))
|
||||||
44 | println(arr.map(bar(0)))
|
67 | println(arr.map(bar(0)))
|
||||||
| ~~~~~~
|
| ~~~~~~
|
||||||
45 | println(arr.filter(bar(true)))
|
68 | println(arr.filter(bar(true)))
|
||||||
46 | println(arr.any(bar(true)))
|
69 | 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
|
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
|
||||||
43 | arr.index(bar(0))
|
66 | arr.index(bar(0))
|
||||||
44 | println(arr.map(bar(0)))
|
67 | println(arr.map(bar(0)))
|
||||||
45 | println(arr.filter(bar(true)))
|
68 | println(arr.filter(bar(true)))
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
46 | println(arr.any(bar(true)))
|
69 | println(arr.any(bar(true)))
|
||||||
47 | println(arr.all(bar(true)))
|
70 | 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
|
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
|
||||||
44 | println(arr.map(bar(0)))
|
67 | println(arr.map(bar(0)))
|
||||||
45 | println(arr.filter(bar(true)))
|
68 | println(arr.filter(bar(true)))
|
||||||
46 | println(arr.any(bar(true)))
|
69 | println(arr.any(bar(true)))
|
||||||
| ~~~~~~~~~
|
| ~~~~~~~~~
|
||||||
47 | println(arr.all(bar(true)))
|
70 | println(arr.all(bar(true)))
|
||||||
48 | }
|
71 | }
|
||||||
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
|
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
|
||||||
45 | println(arr.filter(bar(true)))
|
68 | println(arr.filter(bar(true)))
|
||||||
46 | println(arr.any(bar(true)))
|
69 | println(arr.any(bar(true)))
|
||||||
47 | println(arr.all(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() ? {
|
fn foo() ? {
|
||||||
println('foo is called')
|
println('foo is called')
|
||||||
}
|
}
|
||||||
|
@ -6,10 +9,15 @@ fn bar<T>(v T) ?T {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
const_value = bar(0)
|
||||||
|
)
|
||||||
|
|
||||||
struct Data {
|
struct Data {
|
||||||
f fn (int)
|
f fn (int)
|
||||||
mut:
|
mut:
|
||||||
value int
|
value int = bar(0)
|
||||||
|
opt ?int = bar(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut v Data) add(n int) {
|
fn (mut v Data) add(n int) {
|
||||||
|
@ -21,22 +29,37 @@ fn twice(n int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Calling foo() without ? or an or block, should be an error.
|
// call fn
|
||||||
foo()
|
foo()
|
||||||
|
|
||||||
_ := bar(0)
|
_ := bar(0)
|
||||||
_ := [bar(0)]
|
|
||||||
|
|
||||||
// Calling fn with optional argument
|
|
||||||
println(twice(bar(0)))
|
println(twice(bar(0)))
|
||||||
// method and fn field
|
|
||||||
mut v := Data{fn (_ int) {}, 1}
|
|
||||||
v.add(bar(0))
|
|
||||||
v.f(bar(0))
|
|
||||||
// anon fn
|
// anon fn
|
||||||
fn (_ int) {}(bar(0))
|
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]
|
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.insert(0, bar(0))
|
||||||
arr.prepend(bar(0))
|
arr.prepend(bar(0))
|
||||||
arr.contains(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