diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 08e068c693..484ab59c3f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -2306,6 +2306,23 @@ pub fn (expr Expr) pos() token.Pos { } } +pub fn (expr Expr) is_constant() bool { + return match expr { + IntegerLiteral, FloatLiteral, BoolLiteral, StringLiteral { + true + } + InfixExpr, CastExpr, ArrayInit { + true + } + UnsafeExpr { + expr.expr.is_constant() + } + else { + return false + } + } +} + pub fn (expr Expr) is_lvalue() bool { return match expr { Ident, CTempVar { true } diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index a7e2bfe80a..e9fc1495ab 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -661,8 +661,13 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', } } if mut left is ast.Ident && left.info is ast.IdentVar { - if left.info.is_static && right_sym.kind == .map { - c.error('maps cannot be static', left.pos) + if left.info.is_static { + if right_sym.kind == .map { + c.error('maps cannot be static', left.pos) + } else if !right.is_constant() { + c.error('cannot initialized static variable with non-constant value', + left.pos) + } } } // Single side check diff --git a/vlib/v/checker/tests/static_init_err.out b/vlib/v/checker/tests/static_init_err.out new file mode 100644 index 0000000000..4d5f81d29d --- /dev/null +++ b/vlib/v/checker/tests/static_init_err.out @@ -0,0 +1,41 @@ +vlib/v/checker/tests/static_init_err.vv:10:2: warning: function `foo` must be called from an `unsafe` block + 8 | + 9 | fn main() { + 10 | foo() + | ~~~~~ + 11 | } +vlib/v/checker/tests/static_init_err.vv:4:9: warning: unused variable: `aa` + 2 | fn foo() { + 3 | b := 23 + 4 | static aa := b + | ~~ + 5 | static bb := 1 + 1 + 6 | static cc := ''.str() +vlib/v/checker/tests/static_init_err.vv:5:9: warning: unused variable: `bb` + 3 | b := 23 + 4 | static aa := b + 5 | static bb := 1 + 1 + | ~~ + 6 | static cc := ''.str() + 7 | } +vlib/v/checker/tests/static_init_err.vv:6:9: warning: unused variable: `cc` + 4 | static aa := b + 5 | static bb := 1 + 1 + 6 | static cc := ''.str() + | ~~ + 7 | } + 8 | +vlib/v/checker/tests/static_init_err.vv:4:9: error: cannot initialized static variable with non-constant value + 2 | fn foo() { + 3 | b := 23 + 4 | static aa := b + | ~~ + 5 | static bb := 1 + 1 + 6 | static cc := ''.str() +vlib/v/checker/tests/static_init_err.vv:6:9: error: cannot initialized static variable with non-constant value + 4 | static aa := b + 5 | static bb := 1 + 1 + 6 | static cc := ''.str() + | ~~ + 7 | } + 8 | diff --git a/vlib/v/checker/tests/static_init_err.vv b/vlib/v/checker/tests/static_init_err.vv new file mode 100644 index 0000000000..a90c397916 --- /dev/null +++ b/vlib/v/checker/tests/static_init_err.vv @@ -0,0 +1,11 @@ +@[unsafe] +fn foo() { + b := 23 + static aa := b + static bb := 1 + 1 + static cc := ''.str() +} + +fn main() { + foo() +}