checker: disallow array append in an expression (#9265)
parent
dbbf96702b
commit
9db8a61b92
|
@ -581,6 +581,7 @@ pub struct InfixExpr {
|
||||||
pub:
|
pub:
|
||||||
op token.Kind
|
op token.Kind
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
is_stmt bool
|
||||||
pub mut:
|
pub mut:
|
||||||
left Expr
|
left Expr
|
||||||
right Expr
|
right Expr
|
||||||
|
|
|
@ -155,7 +155,7 @@ fn (mut c Checker) check_shift(left_type table.Type, right_type table.Type, left
|
||||||
// allow `bool << 2` in translated C code
|
// allow `bool << 2` in translated C code
|
||||||
return table.int_type
|
return table.int_type
|
||||||
}
|
}
|
||||||
c.error('invalid operation: shift of type `$sym.name`', left_pos)
|
c.error('invalid operation: shift on type `$sym.name`', left_pos)
|
||||||
return table.void_type
|
return table.void_type
|
||||||
} else if !right_type.is_int() {
|
} else if !right_type.is_int() {
|
||||||
c.error('cannot shift non-integer type `${c.table.get_type_symbol(right_type).name}` into type `${c.table.get_type_symbol(left_type).name}`',
|
c.error('cannot shift non-integer type `${c.table.get_type_symbol(right_type).name}` into type `${c.table.get_type_symbol(left_type).name}`',
|
||||||
|
|
|
@ -875,6 +875,9 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
|
||||||
}
|
}
|
||||||
.left_shift {
|
.left_shift {
|
||||||
if left_final.kind == .array {
|
if left_final.kind == .array {
|
||||||
|
if !infix_expr.is_stmt {
|
||||||
|
c.error('array append cannot be used in an expression', infix_expr.pos)
|
||||||
|
}
|
||||||
// `array << elm`
|
// `array << elm`
|
||||||
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)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
vlib/v/checker/tests/append_err.vv:3:7: error: cannot append `string` to `[]int`
|
||||||
|
1 | fn main() {
|
||||||
|
2 | mut l := []int{}
|
||||||
|
3 | l << 'test'
|
||||||
|
| ~~~~~~
|
||||||
|
4 |
|
||||||
|
5 | _ = l << 3
|
||||||
|
vlib/v/checker/tests/append_err.vv:5:8: error: array append cannot be used in an expression
|
||||||
|
3 | l << 'test'
|
||||||
|
4 |
|
||||||
|
5 | _ = l << 3
|
||||||
|
| ~~
|
||||||
|
6 | _ = (l << 3).len
|
||||||
|
7 | }
|
||||||
|
vlib/v/checker/tests/append_err.vv:6:9: error: array append cannot be used in an expression
|
||||||
|
4 |
|
||||||
|
5 | _ = l << 3
|
||||||
|
6 | _ = (l << 3).len
|
||||||
|
| ~~
|
||||||
|
7 | }
|
|
@ -1,4 +1,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
mut l := []int{}
|
mut l := []int{}
|
||||||
l << 'test'
|
l << 'test'
|
||||||
|
|
||||||
|
_ = l << 3
|
||||||
|
_ = (l << 3).len
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
vlib/v/checker/tests/array_literal_modify_err.vv:2:14: error: array literal can not be modified
|
vlib/v/checker/tests/array_literal_modify_err.vv:2:24: error: array append cannot be used in an expression
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | mut nums := [1, 2, 3] << 4
|
2 | mut nums := [1, 2, 3] << 4
|
||||||
| ~~~~~~~~~
|
| ~~
|
||||||
3 | println(nums)
|
3 | println(nums)
|
||||||
4 | }
|
4 | }
|
||||||
vlib/v/checker/tests/array_literal_modify_err.vv:3:2: error: `println` can not print void expressions
|
vlib/v/checker/tests/array_literal_modify_err.vv:3:2: error: `println` can not print void expressions
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
vlib/v/checker/tests/left_shift_err.vv:3:7: error: cannot append `string` to `[]int`
|
|
||||||
1 | fn main() {
|
|
||||||
2 | mut l := []int{}
|
|
||||||
3 | l << 'test'
|
|
||||||
| ~~~~~~
|
|
||||||
4 | }
|
|
|
@ -1,4 +1,4 @@
|
||||||
vlib/v/checker/tests/rshift_op_wrong_left_type_err.vv:2:10: error: invalid operation: shift of type `float literal`
|
vlib/v/checker/tests/rshift_op_wrong_left_type_err.vv:2:10: error: invalid operation: shift on type `float literal`
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | println(0.5 >> 1)
|
2 | println(0.5 >> 1)
|
||||||
| ~~~
|
| ~~~
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
vlib/v/checker/tests/shift_op_wrong_left_type_err.vv:2:10: error: invalid operation: shift of type `float literal`
|
vlib/v/checker/tests/shift_op_wrong_left_type_err.vv:2:10: error: invalid operation: shift on type `float literal`
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | println(0.5 << 1)
|
2 | println(0.5 << 1)
|
||||||
| ~~~
|
| ~~~
|
||||||
|
|
|
@ -377,6 +377,7 @@ pub fn (mut p Parser) expr_with_left(left ast.Expr, precedence int, is_stmt_iden
|
||||||
right: right
|
right: right
|
||||||
op: tok.kind
|
op: tok.kind
|
||||||
pos: pos
|
pos: pos
|
||||||
|
is_stmt: true
|
||||||
}
|
}
|
||||||
} else if p.tok.kind.is_infix() {
|
} else if p.tok.kind.is_infix() {
|
||||||
if p.tok.kind.is_prefix() && p.tok.line_nr != p.prev_tok.line_nr {
|
if p.tok.kind.is_prefix() && p.tok.line_nr != p.prev_tok.line_nr {
|
||||||
|
@ -473,6 +474,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
|
||||||
right: right
|
right: right
|
||||||
op: op
|
op: op
|
||||||
pos: pos
|
pos: pos
|
||||||
|
is_stmt: p.is_stmt_ident
|
||||||
or_block: ast.OrExpr{
|
or_block: ast.OrExpr{
|
||||||
stmts: or_stmts
|
stmts: or_stmts
|
||||||
kind: or_kind
|
kind: or_kind
|
||||||
|
|
Loading…
Reference in New Issue