checker: check fixed array init with default expression (#19472)

This commit is contained in:
yuyi 2023-09-30 03:06:30 +08:00 committed by GitHub
parent 24278d82ba
commit ae5b4bbd17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 17 deletions

View file

@ -62,15 +62,7 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
}
}
if node.has_default {
mut default_expr := node.default_expr
default_typ := c.check_expr_opt_call(default_expr, c.expr(mut default_expr))
node.default_type = default_typ
if !node.elem_type.has_flag(.option) && default_typ.has_flag(.option) {
c.error('cannot use unwrapped Option as initializer', default_expr.pos())
}
c.check_expected(default_typ, node.elem_type) or {
c.error(err.msg(), default_expr.pos())
}
c.check_array_init_default_expr(mut node)
}
if node.has_len {
len_typ := c.check_expr_opt_call(node.len_expr, c.expr(mut node.len_expr))
@ -304,12 +296,22 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
node.typ = ast.new_type(idx)
}
if node.has_default {
node.default_type = c.expr(mut node.default_expr)
c.check_array_init_default_expr(mut node)
}
}
return node.typ
}
fn (mut c Checker) check_array_init_default_expr(mut node ast.ArrayInit) {
mut default_expr := node.default_expr
default_typ := c.check_expr_opt_call(default_expr, c.expr(mut default_expr))
node.default_type = default_typ
if !node.elem_type.has_flag(.option) && default_typ.has_flag(.option) {
c.error('cannot use unwrapped Option as initializer', default_expr.pos())
}
c.check_expected(default_typ, node.elem_type) or { c.error(err.msg(), default_expr.pos()) }
}
fn (mut c Checker) check_array_init_para_type(para string, mut expr ast.Expr, pos token.Pos) {
sym := c.table.sym(c.unwrap_generic(c.expr(mut expr)))
if sym.kind !in [.int, .int_literal] {

View file

@ -0,0 +1,27 @@
vlib/v/checker/tests/fixed_array_init_with_default.vv:6:27: error: expected `string`, not `[]string`
4 |
5 | fn main() {
6 | _ := Foo{[2]string{init: ['a', 'b']}}
| ~~~~~~~~~~
7 | _ := Foo{[2]string{init: 2.2}}
8 | _ := Foo{[2]string{init: 22}}
vlib/v/checker/tests/fixed_array_init_with_default.vv:7:27: error: expected `string`, not `float literal`
5 | fn main() {
6 | _ := Foo{[2]string{init: ['a', 'b']}}
7 | _ := Foo{[2]string{init: 2.2}}
| ~~~
8 | _ := Foo{[2]string{init: 22}}
9 | _ := Foo{[2]string{init: true}}
vlib/v/checker/tests/fixed_array_init_with_default.vv:8:27: error: expected `string`, not `int literal`
6 | _ := Foo{[2]string{init: ['a', 'b']}}
7 | _ := Foo{[2]string{init: 2.2}}
8 | _ := Foo{[2]string{init: 22}}
| ~~
9 | _ := Foo{[2]string{init: true}}
10 | }
vlib/v/checker/tests/fixed_array_init_with_default.vv:9:27: error: expected `string`, not `bool`
7 | _ := Foo{[2]string{init: 2.2}}
8 | _ := Foo{[2]string{init: 22}}
9 | _ := Foo{[2]string{init: true}}
| ~~~~
10 | }

View file

@ -0,0 +1,10 @@
struct Foo {
stack_arr [2]string
}
fn main() {
_ := Foo{[2]string{init: ['a', 'b']}}
_ := Foo{[2]string{init: 2.2}}
_ := Foo{[2]string{init: 22}}
_ := Foo{[2]string{init: true}}
}

View file

@ -47,6 +47,13 @@ vlib/v/checker/tests/option_fn_err.vv:56:27: error: cannot use unwrapped Option
| ~~~~~~
57 | _ := [bar(0)]!
58 | _ := [1]int{init: bar(0)}
vlib/v/checker/tests/option_fn_err.vv:58:20: error: cannot use unwrapped Option as initializer
56 | _ := []int{len: 1, init: bar(0)}
57 | _ := [bar(0)]!
58 | _ := [1]int{init: bar(0)}
| ~~~~~~
59 | // index
60 | println(arr[bar(0)])
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