From 49aac93d874419bd12cd224d401ea8e12bc5fd6a Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sat, 8 Oct 2022 21:57:30 +0530 Subject: [PATCH] checker: disallow literals on the left side of assignments (#15999) --- vlib/v/ast/ast.v | 2 +- vlib/v/checker/assign.v | 4 ++ .../tests/invalid_literal_assign_err.out | 62 +++++++++++++++++++ .../tests/invalid_literal_assign_err.vv | 13 ++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/invalid_literal_assign_err.out create mode 100644 vlib/v/checker/tests/invalid_literal_assign_err.vv diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index f7c920f49..ba83aacd3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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) pub fn (expr Expr) is_literal() bool { match expr { - BoolLiteral, CharLiteral, FloatLiteral, IntegerLiteral { + BoolLiteral, CharLiteral, FloatLiteral, IntegerLiteral, StringLiteral, StringInterLiteral { return true } PrefixExpr { diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 3245c69d2..ea58ed8f3 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -323,6 +323,10 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { if is_decl { 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)) diff --git a/vlib/v/checker/tests/invalid_literal_assign_err.out b/vlib/v/checker/tests/invalid_literal_assign_err.out new file mode 100644 index 000000000..9d3075f2a --- /dev/null +++ b/vlib/v/checker/tests/invalid_literal_assign_err.out @@ -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 | } diff --git a/vlib/v/checker/tests/invalid_literal_assign_err.vv b/vlib/v/checker/tests/invalid_literal_assign_err.vv new file mode 100644 index 000000000..78f3238d0 --- /dev/null +++ b/vlib/v/checker/tests/invalid_literal_assign_err.vv @@ -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 +} -- 2.39.5