1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: disallow literals on the left side of assignments (#15999)

This commit is contained in:
Swastik Baranwal 2022-10-08 21:57:30 +05:30 committed by GitHub
parent 91e641a422
commit 49aac93d87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 1 deletions

View File

@ -2227,7 +2227,7 @@ fn gen_all_registers(mut t Table, without_numbers []string, with_numbers map[str
// is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant) // is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant)
pub fn (expr Expr) is_literal() bool { pub fn (expr Expr) is_literal() bool {
match expr { match expr {
BoolLiteral, CharLiteral, FloatLiteral, IntegerLiteral { BoolLiteral, CharLiteral, FloatLiteral, IntegerLiteral, StringLiteral, StringInterLiteral {
return true return true
} }
PrefixExpr { PrefixExpr {

View File

@ -323,6 +323,10 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if is_decl { if is_decl {
c.error('non-name `$left` on left side of `:=`', left.pos()) c.error('non-name `$left` on left side of `:=`', left.pos())
} }
if node.op == .assign && (left.is_literal() || left is ast.StructInit) {
c.error('non-name literal value `$left` on left side of `=`', left.pos())
}
} }
} }
left_type_unwrapped := c.unwrap_generic(ast.mktyp(left_type)) left_type_unwrapped := c.unwrap_generic(ast.mktyp(left_type))

View File

@ -0,0 +1,62 @@
vlib/v/checker/tests/invalid_literal_assign_err.vv:4:2: error: non-name literal value `1` on left side of `=`
2 |
3 | fn main() {
4 | 1 = 2
| ^
5 | u8(1) = u8(2)
6 | 1.0 = 2.0
vlib/v/checker/tests/invalid_literal_assign_err.vv:5:2: error: non-name literal value `u8(1)` on left side of `=`
3 | fn main() {
4 | 1 = 2
5 | u8(1) = u8(2)
| ~~~~~
6 | 1.0 = 2.0
7 | 'str' = 'string'
vlib/v/checker/tests/invalid_literal_assign_err.vv:6:2: error: non-name literal value `1.0` on left side of `=`
4 | 1 = 2
5 | u8(1) = u8(2)
6 | 1.0 = 2.0
| ~~~
7 | 'str' = 'string'
8 | `a` = `b`
vlib/v/checker/tests/invalid_literal_assign_err.vv:7:2: error: non-name literal value `'str'` on left side of `=`
5 | u8(1) = u8(2)
6 | 1.0 = 2.0
7 | 'str' = 'string'
| ~~~~~
8 | `a` = `b`
9 | Foo{} = Foo{}
vlib/v/checker/tests/invalid_literal_assign_err.vv:8:2: error: non-name literal value ``a`` on left side of `=`
6 | 1.0 = 2.0
7 | 'str' = 'string'
8 | `a` = `b`
| ~~~
9 | Foo{} = Foo{}
10 | true = false
vlib/v/checker/tests/invalid_literal_assign_err.vv:9:2: error: non-name literal value `Foo{....}` on left side of `=`
7 | 'str' = 'string'
8 | `a` = `b`
9 | Foo{} = Foo{}
| ~~~~~
10 | true = false
11 | 3 + 5 = 3 & 4
vlib/v/checker/tests/invalid_literal_assign_err.vv:10:2: error: non-name literal value `true` on left side of `=`
8 | `a` = `b`
9 | Foo{} = Foo{}
10 | true = false
| ~~~~
11 | 3 + 5 = 3 & 4
12 | (3 + 3.5) = 4 + 6.4
vlib/v/checker/tests/invalid_literal_assign_err.vv:11:2: error: non-name literal value `3 + 5` on left side of `=`
9 | Foo{} = Foo{}
10 | true = false
11 | 3 + 5 = 3 & 4
| ~~~~~
12 | (3 + 3.5) = 4 + 6.4
13 | }
vlib/v/checker/tests/invalid_literal_assign_err.vv:12:2: error: non-name literal value `(3 + 3.5)` on left side of `=`
10 | true = false
11 | 3 + 5 = 3 & 4
12 | (3 + 3.5) = 4 + 6.4
| ~~~~~~~~~
13 | }

View File

@ -0,0 +1,13 @@
struct Foo {}
fn main() {
1 = 2
u8(1) = u8(2)
1.0 = 2.0
'str' = 'string'
`a` = `b`
Foo{} = Foo{}
true = false
3 + 5 = 3 & 4
(3 + 3.5) = 4 + 6.4
}