diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index f7c920f493..ba83aacd3d 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 3245c69d22..ea58ed8f37 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 0000000000..9d3075f2a4 --- /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 0000000000..78f3238d0e --- /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 +}