mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: ensure expr
is an lvalue with Struct{...expr
(#8489)
This commit is contained in:
parent
d660f2cc6f
commit
c537578481
@ -680,12 +680,17 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
|
||||
if struct_init.has_update_expr {
|
||||
update_type := c.expr(struct_init.update_expr)
|
||||
struct_init.update_expr_type = update_type
|
||||
update_sym := c.table.get_type_symbol(update_type)
|
||||
sym := c.table.get_type_symbol(struct_init.typ)
|
||||
if update_sym.kind != .struct_ {
|
||||
c.error('expected struct `$sym.name`, found `$update_sym.name`', struct_init.update_expr.position())
|
||||
if c.table.type_kind(update_type) != .struct_ {
|
||||
s := c.table.type_to_str(update_type)
|
||||
c.error('expected struct, found `$s`', struct_init.update_expr.position())
|
||||
} else if update_type != struct_init.typ {
|
||||
sym := c.table.get_type_symbol(struct_init.typ)
|
||||
update_sym := c.table.get_type_symbol(update_type)
|
||||
c.error('expected struct `$sym.name`, found struct `$update_sym.name`', struct_init.update_expr.position())
|
||||
} else if !struct_init.update_expr.is_lvalue() {
|
||||
// cgen will repeat `update_expr` for each field
|
||||
// so enforce an lvalue for efficiency
|
||||
c.error('expression is not an lvalue', struct_init.update_expr.position())
|
||||
}
|
||||
}
|
||||
return struct_init.typ
|
||||
|
@ -1,7 +1,28 @@
|
||||
vlib/v/checker/tests/struct_init_update_type_err.vv:11:6: error: expected struct `Foo`, found `int`
|
||||
9 | f3 := 2
|
||||
vlib/v/checker/tests/struct_init_update_type_err.vv:11:6: error: expected struct, found `int`
|
||||
9 | i := 2
|
||||
10 | _ := Foo{
|
||||
11 | ...f3
|
||||
| ~~
|
||||
11 | ...i
|
||||
| ^
|
||||
12 | name: 'f2'
|
||||
13 | }
|
||||
13 | }
|
||||
vlib/v/checker/tests/struct_init_update_type_err.vv:16:6: error: expected struct, found `&int`
|
||||
14 | p := &i
|
||||
15 | _ = Foo{
|
||||
16 | ...p
|
||||
| ^
|
||||
17 | }
|
||||
18 | f2 := Foo2{}
|
||||
vlib/v/checker/tests/struct_init_update_type_err.vv:20:6: error: expected struct `Foo`, found struct `Foo2`
|
||||
18 | f2 := Foo2{}
|
||||
19 | _ = Foo{
|
||||
20 | ...f2
|
||||
| ~~
|
||||
21 | }
|
||||
22 | _ = Foo{
|
||||
vlib/v/checker/tests/struct_init_update_type_err.vv:23:6: error: expression is not an lvalue
|
||||
21 | }
|
||||
22 | _ = Foo{
|
||||
23 | ...Foo{}
|
||||
| ~~~~~
|
||||
24 | }
|
||||
25 | }
|
||||
|
@ -3,13 +3,24 @@ struct Foo {
|
||||
age int
|
||||
}
|
||||
|
||||
struct Foo2 {}
|
||||
struct Foo2 {b bool}
|
||||
|
||||
fn main() {
|
||||
f3 := 2
|
||||
i := 2
|
||||
_ := Foo{
|
||||
...f3
|
||||
...i
|
||||
name: 'f2'
|
||||
}
|
||||
p := &i
|
||||
_ = Foo{
|
||||
...p
|
||||
}
|
||||
f2 := Foo2{}
|
||||
_ = Foo{
|
||||
...f2
|
||||
}
|
||||
_ = Foo{
|
||||
...Foo{}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user